[edk2-devel] [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add library instances

Kubacki, Michael A michael.a.kubacki at intel.com
Sat Aug 17 00:15:51 UTC 2019


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 at intel.com>
Cc: Chasel Chiu <chasel.chiu at intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone at intel.com>
Cc: Liming Gao <liming.gao at intel.com>
Cc: Michael D Kinney <michael.d.kinney at intel.com>
Cc: Ankit Sinha <ankit.sinha at intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki at 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


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#45902): https://edk2.groups.io/g/devel/message/45902
Mute This Topic: https://groups.io/mt/32918195/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list