[edk2-devel] [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules

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


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

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

Cc: Sai Chaganty <rangasai.v.chaganty 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/AcpiTables/SaAcpiTables.inf                    |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf                   |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf                       |  116 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf                    |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h                         |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h |  230 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h   | 1567 ++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h     |  203 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h     | 1167 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h       |  237 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h              |   15 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h                      |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h                   |  193 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h                    |   91 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h                       |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h                            |   71 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h                         |  139 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h            |   17 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h                               |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h                |  162 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c                      |  157 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c                   |  570 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c                    |  171 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c                       |  171 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c                            |  496 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c                            |  179 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c                         |  122 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c                               |  717 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c                |  356 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc                      |  250 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl                         |  794 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl                     | 1666 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl               |  472 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl                  |  369 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl               |  129 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl                 |  296 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl               |  262 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl                      |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl                       |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl                    |  147 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl                   |   22 +
 41 files changed, 11970 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
new file mode 100644
index 0000000000..56ddc2957f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
@@ -0,0 +1,50 @@
+## @file
+#  Component description file for the ACPI tables
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION          = 0x00010005
+BASE_NAME            = SaAcpiTables
+FILE_GUID            = 3c0ed5e2-91ea-4b94-820d-9daf9a3bb4a2
+MODULE_TYPE          = USER_DEFINED
+VERSION_STRING       = 1.0
+
+[Sources]
+  Dmar/Dmar.aslc
+  Dmar/Dmar.h
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+################################################################################
+#
+# Library Class Section - list of Library Classes that are required for
+#                         this module.
+#
+################################################################################
+
+[LibraryClasses]
+
+################################################################################
+#
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names
+#                           that this module uses or produces.
+#
+################################################################################
+[Pcd]
+
+[Protocols]
+
+[PPIs]
+
+[Guids]
+
+[Depex]
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
new file mode 100644
index 0000000000..3588565aac
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
@@ -0,0 +1,49 @@
+## @file
+#  Component description file for the ACPI tables
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION          = 0x00010005
+BASE_NAME            = SaSsdt
+FILE_GUID            = ca89914d-2317-452e-b245-36c6fb77a9c6
+MODULE_TYPE          = USER_DEFINED
+VERSION_STRING       = 1.0
+
+[Sources]
+  SaSsdt.asl
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+################################################################################
+#
+# Library Class Section - list of Library Classes that are required for
+#                         this module.
+#
+################################################################################
+
+[LibraryClasses]
+
+################################################################################
+#
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names
+#                           that this module uses or produces.
+#
+################################################################################
+[Pcd]
+
+[Protocols]
+
+[PPIs]
+
+[Guids]
+
+[Depex]
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
new file mode 100644
index 0000000000..9937fc60e5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
@@ -0,0 +1,116 @@
+## @file
+# Component description file for SystemAgent Initialization driver
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SaInitDxe
+FILE_GUID = DE23ACEE-CF55-4fb6-AA77-984AB53DE811
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = SaInitEntryPointDxe
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[LibraryClasses]
+UefiDriverEntryPoint
+UefiLib
+UefiBootServicesTableLib
+DxeServicesTableLib
+DebugLib
+TimerLib
+PciCf8Lib
+PciSegmentLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+IoLib
+S3BootScriptLib
+PmcLib
+PchCycleDecodingLib
+PchInfoLib
+GpioLib
+ConfigBlockLib
+SaPlatformLib
+PchPcieRpLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+PcAtChipsetPkg/PcAtChipsetPkg.dec
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+gSiPkgTokenSpaceGuid.PcdMchBaseAddress
+gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress
+
+[Sources]
+SaInitDxe.h
+SaInitDxe.c
+SaInit.h
+SaInit.c
+VTd.c
+VTd.h
+IgdOpRegionInit.h
+IgdOpRegionInit.c
+GraphicsInit.h
+GraphicsInit.c
+PciExpressInit.h
+PciExpressInit.c
+PcieComplex.c
+PcieComplex.h
+SaAcpi.c
+
+[Protocols]
+gEfiAcpiTableProtocolGuid              ## CONSUMES
+gSaNvsAreaProtocolGuid                 ## PRODUCES
+gSaPolicyProtocolGuid                  ## CONSUMES
+gEfiCpuArchProtocolGuid                ## CONSUMES
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+gEfiPciRootBridgeIoProtocolGuid        ## CONSUMES
+gEfiPciIoProtocolGuid                  ## CONSUMES
+gIgdOpRegionProtocolGuid               ## PRODUCES
+gEfiFirmwareVolume2ProtocolGuid        ## CONSUMES
+gEfiLegacyBiosProtocolGuid             ## CONSUMES
+gGopComponentName2ProtocolGuid         ## CONSUMES
+gSaIotrapSmiProtocolGuid               ## CONSUMES
+
+[Guids]
+gSaConfigHobGuid
+gSgAcpiTablePchStorageGuid
+gSaAcpiTableStorageGuid
+gSgAcpiTableStorageGuid
+gSaSsdtAcpiTableStorageGuid
+gPegSsdtAcpiTableStorageGuid
+gEfiEndOfDxeEventGroupGuid
+gSiConfigHobGuid        ## CONSUMES
+gMiscDxeConfigGuid
+gGraphicsDxeConfigGuid
+gMemoryDxeConfigGuid
+gPcieDxeConfigGuid
+gVbiosDxeConfigGuid
+gPchInfoHobGuid
+
+[Depex]
+gEfiAcpiTableProtocolGuid AND
+gEfiFirmwareVolume2ProtocolGuid AND
+gSaPolicyProtocolGuid AND
+gEfiPciRootBridgeIoProtocolGuid AND
+gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure that PCI MMIO resource has been prepared and available for this driver to allocate.
+gEfiHiiDatabaseProtocolGuid
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
new file mode 100644
index 0000000000..9356781c9e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
@@ -0,0 +1,48 @@
+## @file
+# Component description file for the SmmAccess module
+#
+# {1323C7F8-DAD5-4126-A54B-7A05FBF41515}
+#
+# Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SmmAccess
+FILE_GUID = 1323C7F8-DAD5-4126-A54B-7A05FBF41515
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = SmmAccessDriverEntryPoint
+
+
+[LibraryClasses]
+UefiDriverEntryPoint
+BaseLib
+BaseMemoryLib
+DebugLib
+HobLib
+PciLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SmmAccessDriver.h
+SmmAccessDriver.c
+
+
+[Protocols]
+gEfiSmmAccess2ProtocolGuid       ## PRODUCES
+
+
+[Guids]
+gEfiSmmPeiSmramMemoryReserveGuid
+
+
+[Depex]
+TRUE
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
new file mode 100644
index 0000000000..4339256bba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
@@ -0,0 +1,25 @@
+/** @file
+  This file describes the contents of the ACPI DMA address Remapping
+  Some additional ACPI values are defined in Acpi1_0.h and Acpi2_0.h.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_DMAR_H_
+#define _SA_DMAR_H_
+
+///
+/// Include standard ACPI table definitions
+///
+#include <IndustryStandard/Acpi30.h>
+#include <DmaRemappingTable.h>
+
+#pragma pack(1)
+
+#define EFI_ACPI_DMAR_OEM_TABLE_ID    0x20202020324B4445  ///< "EDK2    "
+#define EFI_ACPI_DMAR_OEM_CREATOR_ID  0x4C544E49  ///< "INTL"
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h
new file mode 100644
index 0000000000..54cb69066d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h
@@ -0,0 +1,230 @@
+/** @file
+  This file contains the definitions common to the MRC API and other APIs.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcCommonTypes_h_
+#define _MrcCommonTypes_h_
+
+#define INT32_MIN                       (0x80000000)
+#ifndef INT32_MAX  //INT32_MAX->Already defined
+#define INT32_MAX                       (0x7FFFFFFF)
+#endif
+#define INT16_MIN                       (0x8000)
+#define INT16_MAX                       (0x7FFF)
+
+///
+/// System boot mode.
+///
+typedef enum {
+  bmCold,                                 ///< Cold boot
+  bmWarm,                                 ///< Warm boot
+  bmS3,                                   ///< S3 resume
+  bmFast,                                 ///< Fast boot
+  MrcBootModeMax,                         ///< MRC_BOOT_MODE enumeration maximum value.
+  MrcBootModeDelim = INT32_MAX            ///< This value ensures the enum size is consistent on both sides of the PPI.
+} MrcBootMode;
+
+///
+/// DIMM memory package
+/// This enum matches SPD Module Type - SPD byte 3, bits [3:0]
+/// Note that DDR4 have different encoding for some module types
+///
+typedef enum {
+  RDimmMemoryPackage          = 1,
+  UDimmMemoryPackage          = 2,
+  SoDimmMemoryPackage         = 3,
+  MicroDimmMemoryPackageDdr3  = 4,
+  LrDimmMemoryPackageDdr4     = 4,
+  MiniRDimmMemoryPackage      = 5,
+  MiniUDimmMemoryPackage      = 6,
+  MiniCDimmMemoryPackage      = 7,
+  LpDimmMemoryPackage         = 7,
+  SoUDimmEccMemoryPackageDdr3 = 8,
+  SoRDimmEccMemoryPackageDdr4 = 8,
+  SoRDimmEccMemoryPackageDdr3 = 9,
+  SoUDimmEccMemoryPackageDdr4 = 9,
+  SoCDimmEccMemoryPackage     = 10,
+  LrDimmMemoryPackage         = 11,
+  SoDimm16bMemoryPackage      = 12,
+  SoDimm32bMemoryPackage      = 13,
+  NonDimmMemoryPackage        = 14,
+  MemoryPackageMax,                       ///< MEMORY_PACKAGE enumeration maximum value.
+  MemoryPackageDelim = INT32_MAX          ///< This value ensures the enum size is consistent on both sides of the PPI.
+} MEMORY_PACKAGE;
+
+///
+/// Memory training I/O levels.
+///
+typedef enum {
+  DdrLevel   = 0,                         ///< Refers to frontside of DIMM
+  LrbufLevel = 1,                         ///< Refers to data level at backside of LRDIMM or AEP buffer
+  RegALevel  = 2,                         ///< Refers to cmd level at backside of register - side A
+  RegBLevel  = 3,                         ///< Refers to cmd level at backside of register - side B
+  GsmLtMax,                               ///< GSM_LT enumeration maximum value.
+  GsmLtDelim = INT32_MAX                  ///< This value ensures the enum size is consistent on both sides of the PPI.
+} GSM_LT;
+
+///
+/// Memory training margin group selectors.
+///
+typedef enum {
+  RecEnDelay       = 0,                   ///< Linear delay (PI ticks), where the positive increment moves the RCVEN sampling window later in time relative to the RX DQS strobes.
+  RxDqsDelay       = 1,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe later in time relative to the RX DQ signal (i.e. toward the hold side of the eye).
+  RxDqDelay        = 2,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQ byte/nibble/bitlane later in time relative to the RX DQS signal (i.e.closing the gap between DQ and DQS in the setup side of the eye).
+  RxDqsPDelay      = 3,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe for "even" chunks later in time relative to the RX DQ signal. Even chunks are 0, 2, 4, 6 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+  RxDqsNDelay      = 4,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe for "odd" chunks later in time relative to the RX DQ signal. Odd chunks are 1, 3, 5, 7 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+  RxVref           = 5,                   ///< Linear increment (Vref ticks), where the positive increment moves the byte/nibble/bitlane RX Vref to a higher voltage.
+  RxEq             = 6,                   ///< RX CTLE setting indicating a set of possible resistances, capacitance, current steering, etc. values, which may be a different set of values per product. The setting combinations are indexed by integer values.
+  RxDqBitDelay     = 7,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQ bitlane later in time relative to the RX DQS signal (i.e.closing the gap between DQ and DQS in the setup side of the eye).
+  RxVoc            = 8,                   ///< Monotonic increment (Sense Amp setting), where the positive increment moves the byte/nibble/bitlane's effective switching point to a lower Vref value.
+  RxOdt            = 9,                   ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  RxOdtUp          = 10,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  RxOdtDn          = 11,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  DramDrvStr       = 12,                  ///< Drive strength setting resistance setting within a set of possible resistances (or currents), which may be a different set of values per product. Indexed by integer values.
+  McOdtDelay       = 13,                  ///<
+  McOdtDuration    = 14,                  ///<
+  SenseAmpDelay    = 15,                  ///< This may be used to indicate CmdToDiffAmpEn for SoC's.
+  SenseAmpDuration = 16,                  ///<
+  RoundTripDelay   = 17,                  ///< This may be used to indicate CmdToRdDataValid for SoC's.
+  RxDqsBitDelay    = 18,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS within the bitlane later in time relative to the RX DQ signal (i.e.closing the gap between DQ and DQS in the hold side of the eye).
+  RxDqDqsDelay     = 19,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS per strobe later in time relative to the RX DQ signal (i.e. closing the gap between DQS and DQ in the hold side of the eye. The difference between this parameter and RxDqsDelay is that both the DQ and DQS timings may be moved in order to increase the total range of DQDQS timings.
+  WrLvlDelay       = 20,                  ///< Linear delay (PI ticks), where the positive increment moves both the TX DQS and TX DQ signals later in time relative to all other bus signals.
+  TxDqsDelay       = 21,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQS strobe later in time relative to all other bus signals.
+  TxDqDelay        = 22,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQ byte/nibble/bitlane later in time relative to all other bus signals.
+  TxVref           = 23,                  ///< Linear increment (Vref ticks), where the positive increment moves the byte/nibble/bitlane TX Vref to a higher voltage. (Assuming this will abstract away from the range specifics for DDR4, for example.)
+  TxEq             = 24,                  ///< TX EQ setting indicating a set of possible equalization levels, which may be a different set of values per product. The setting combinations are indexed by integer values.
+  TxDqBitDelay     = 25,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQ bitlane later in time relative to all other bus signals.
+  TxRon            = 26,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  TxRonUp          = 27,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  TxRonDn          = 28,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  TxSlewRate       = 29,                  ///< Monotonic increment, where the positive increment moves the byte/nibble/bitlane's effective slew rate to a higher slope.
+  TxImode          = 30,                  ///< TX I-Mode Boost setting indicating a set of possible current boost levels, which may be a different set of values per product. The setting combinations are indexed by integer values.
+  WrOdt            = 31,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  NomOdt           = 32,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  ParkOdt          = 33,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  TxTco            = 34,                  ///<
+  RxCtleR          = 36,                  ///<
+  RxCtleC          = 37,                  ///<
+  RxDqsPBitDelay   = 38,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS bitlane timing for "even" chunks later in time relative to the RX DQ bitlane signal. Even chunks are 0, 2, 4, 6 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+  RxDqsNBitDelay   = 39,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS bitlane timing for "odd" chunks later in time relative to the RX DQ bitlane signal. Odd chunks are 1, 3, 5, 7 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+  CmdAll           = 40,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_ALL category later in time relative to all other signals on the bus.
+  CmdGrp0          = 41,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_GRP0 category later in time relative to all other signals on the bus.
+  CmdGrp1          = 42,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_GRP1 category later in time relative to all other signals on the bus.
+  CmdGrp2          = 43,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_GRP2 category later in time relative to all other signals on the bus.
+  CtlAll           = 44,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_ALL category later in time relative to all other signals on the bus.
+  CtlGrp0          = 45,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP0 category later in time relative to all other signals on the bus.
+  CtlGrp1          = 46,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP1 category later in time relative to all other signals on the bus.
+  CtlGrp2          = 47,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP2 category later in time relative to all other signals on the bus.
+  CtlGrp3          = 48,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP3 category later in time relative to all other signals on the bus.
+  CtlGrp4          = 49,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP4 category later in time relative to all other signals on the bus.
+  CtlGrp5          = 50,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP5 category later in time relative to all other signals on the bus.
+  CmdCtlAll        = 51,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_CTL_ALL category later in time relative to all other signals on the bus.
+  CkAll            = 52,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CK_ALL category later in time relative to all other signals on the bus.
+  CmdVref          = 53,                  ///< Linear increment (Vref ticks), where the positive increment moves the CMD Vref to a higher voltage.
+  AlertVref        = 54,                  ///< Linear increment (Vref ticks), where the positive increment moves the ALERT Vref to a higher voltage.
+  CmdRon           = 55,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+
+  EridDelay        = 60,                  ///< Linear delay (PI ticks), where the positive increment moves the ERID signals later in time relative to the internal sampling clock (i.e.closing the gap between ERID and internal sampling clock in the setup side of the eye). This group is applicable for DDRT DIMMs.
+  EridVref         = 61,                  ///< Linear increment (Vref ticks), where the positive increment moves the ERID Vref to a higher voltage. This group is applicable for DDRT DIMMs.
+  ErrorVref        = 62,                  ///< Linear increment (Vref ticks), where the positive increment moves the ERROR Vref to a higher voltage. This group is applicable for DDRT DIMMs.
+  ReqVref          = 63,                  ///< Linear increment (Vref ticks), where the positive increment moves the REQ Vref to a higher voltage. This group is applicable for DDRT DIMMs.
+  RecEnOffset      = 64,                  ///< Linear delay (PI ticks), where the positive increment moves the RCVEN sampling window later in time relative to the RX DQS strobes.
+  RxDqsOffset      = 65,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe later in time relative to the RX DQ signal (i.e. toward the hold side of the eye).
+  RxVrefOffset     = 66,                  ///< Linear increment (Vref ticks), where the positive increment moves the byte/nibble/bitlane RX Vref to a higher voltage.
+  TxDqsOffset      = 67,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQS strobe later in time relative to all other bus signals.
+  TxDqOffset       = 68,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQ byte/nibble/bitlane later in time relative to all other bus signals.
+  GsmGtMax,                               ///< SSA_GSM_GT enumeration maximum value.
+  GsmGtDelim = INT32_MAX                  ///< This value ensures the enum size is consistent on both sides of the PPI.
+} GSM_GT;
+
+typedef enum {
+  SigRasN   = 0,
+  SigCasN   = 1,
+  SigWeN    = 2,
+  SigBa0    = 3,
+  SigBa1    = 4,
+  SigBa2    = 5,
+  SigA0     = 6,
+  SigA1     = 7,
+  SigA2     = 8,
+  SigA3     = 9,
+  SigA4     = 10,
+  SigA5     = 11,
+  SigA6     = 12,
+  SigA7     = 13,
+  SigA8     = 14,
+  SigA9     = 15,
+  SigA10    = 16,
+  SigA11    = 17,
+  SigA12    = 18,
+  SigA13    = 19,
+  SigA14    = 20,
+  SigA15    = 21,
+  SigA16    = 22,
+  SigA17    = 23,
+  SigCs0N   = 24,
+  SigCs1N   = 25,
+  SigCs2N   = 26,
+  SigCs3N   = 27,
+  SigCs4N   = 28,
+  SigCs5N   = 29,
+  SigCs6N   = 30,
+  SigCs7N   = 31,
+  SigCs8N   = 32,
+  SigCs9N   = 33,
+  SigCke0   = 34,
+  SigCke1   = 35,
+  SigCke2   = 36,
+  SigCke3   = 37,
+  SigCke4   = 38,
+  SigCke5   = 39,
+  SigOdt0   = 40,     //could also be used for CA-ODT for LP4
+  SigOdt1   = 41,     //could also be used for CA-ODT for LP4
+  SigOdt2   = 42,
+  SigOdt3   = 43,
+  SigOdt4   = 44,
+  SigOdt5   = 45,
+  SigPar    = 46,
+  SigAlertN = 47,
+  SigBg0    = 48,
+  SigBg1    = 49,
+  SigActN   = 50,
+  SigCid0   = 51,
+  SigCid1   = 52,
+  SigCid2   = 53,
+  SigCk0    = 54,
+  SigCk1    = 55,
+  SigCk2    = 56,
+  SigCk3    = 57,
+  SigCk4    = 58,
+  SigCk5    = 59,
+  SigGnt0   = 60,
+  SigGnt1   = 61,
+  SigErid00 = 62,
+  SigErid01 = 63,
+  SigErid10 = 64,
+  SigErid11 = 65,
+  SigErr0   = 66,
+  SigErr1   = 67,
+  SigCa00   = 68,    // First instantiation of the CA bus for a given channel
+  SigCa01   = 69,
+  SigCa02   = 70,
+  SigCa03   = 71,
+  SigCa04   = 72,
+  SigCa05   = 73,
+  SigCa10   = 74,    // Second instantiation of the CA bus for a given channel
+  SigCa11   = 75,
+  SigCa12   = 76,
+  SigCa13   = 77,
+  SigCa14   = 78,
+  SigCa15   = 79,
+  GsmCsnMax,
+  GsmCsnDelim = INT32_MAX
+} GSM_CSN;
+
+
+#endif // _MrcCommonTypes_h_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h
new file mode 100644
index 0000000000..635906cc2b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h
@@ -0,0 +1,1567 @@
+/** @file
+  This file includes all the data structures that the MRC considers "global data".
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcInterface_h_
+#define _MrcInterface_h_
+
+#define MAX_CPU_SOCKETS          (1)       ///< The maximum number of CPUs per system.
+#define MAX_CONTROLLERS          (1)       ///< The maximum number of memory controllers per CPU socket.
+#define MAX_CHANNEL              (2)       ///< The maximum number of channels per memory controller.
+#define MAX_DIMMS_IN_CHANNEL     (2)       ///< The maximum number of DIMMs per channel.
+#define MAX_RANK_IN_DIMM         (2)       ///< The maximum number of ranks per DIMM.
+#define MAX_RANK_IN_CHANNEL      (MAX_DIMMS_IN_CHANNEL * MAX_RANK_IN_DIMM) ///< The maximum number of ranks per channel.
+#define MAX_SDRAM_IN_DIMM        (9)       ///< The maximum number of SDRAMs per DIMM when ECC is enabled.
+#define MAX_MR_IN_DIMM           (7)       ///< Maximum number of mode registers in a DIMM.
+#define MAX_DEVICES_IN_DDR4      (8)       ///< The maximum number of SDRAMs per DDR4 DIMM.
+#define MAX_BITS                 (8)       ///< BITS per byte.
+#define MAX_STROBE               (18)      ///< Number of strobe groups.
+#define MAX_DQ                   (72)      ///< Number of Dq bits used by the rank.
+#define CHAR_BITS                (8)       ///< Number of bits in a char.
+#define PSMI_SIZE_MB             (64)      ///< Define the max size of PSMI needed in MB
+#define BCLK_DEFAULT             (100 * 1000 * 1000) ///< BCLK default value, in Hertz.
+#define MAX_COMMAND_GROUPS       (2)
+#define MAX_EDGES                (2) ///< Maximum number of edges.
+#define SUPPORT_DDR3             SUPPORT   ///< SUPPORT means that DDR3 is supported by the MRC.
+#define ULT_SUPPORT_LPDDR3       SUPPORT   ///< SUPPORT means that LPDDR3 is supported by the MRC.
+#define TRAD_SUPPORT_LPDDR3      /*UN*/SUPPORT ///< SUPPORT means that LPDDR3 is supported by the MRC.
+#define BDW_SUPPORT_LPDDR3       SUPPORT   ///< SUPPORT means that LPDDR3 is supported by the MRC.
+#define JEDEC_SUPPORT_LPDDR      SUPPORT   ///< SUPPORT means that JEDEC SPD Spec for LPDDR3 is supported by the MRC.
+#define SUPPORT_DDR4             SUPPORT   ///< SUPPORT means that DDR4 is supported by the MRC.
+#define SUPPORT_LPDDR3           (ULT_SUPPORT_LPDDR3 || TRAD_SUPPORT_LPDDR3 || BDW_SUPPORT_LPDDR3 || JEDEC_SUPPORT_LPDDR)
+#define MRC_ALL_DDR_SUPPORTED    ((SUPPORT_DDR4 == SUPPORT) && ((SUPPORT_DDR3 == SUPPORT) && (SUPPORT_LPDDR3 == SUPPORT)))
+#define MRC_DDR3_LPDDR_SUPPORTED ((SUPPORT_DDR3 == SUPPORT) || (SUPPORT_LPDDR3 == SUPPORT))
+#define SPD3_MANUF_START       117         ///< The starting point for the SPD manufacturing data.
+#define SPD3_MANUF_END         127         ///< The ending point for the SPD manufacturing data.
+#if (SUPPORT_DDR4 == SUPPORT)
+#define SPD4_MANUF_START       320         ///< The starting point for the SPD manufacturing data.
+#define SPD4_MANUF_END         328         ///< The ending point for the SPD manufacturing data.
+#endif
+#if (JEDEC_SUPPORT_LPDDR == SUPPORT)
+#define SPDLP_MANUF_START      320         ///< The starting point for the SPD manufacturing data.
+#define SPDLP_MANUF_END        328         ///< The ending point for the SPD manufacturing data.
+#endif
+#include "MrcSpdData.h"
+#include "MrcRmtData.h"
+#include "MrcCommonTypes.h"
+#pragma pack (push, 1)
+
+
+///
+//////////////////////////////////////////////////////////////////////////////////////
+///                           OEM platform  routines and types                      //
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// define the oem check points the OEM can define more point and locate them in the code.
+///
+typedef enum {
+  OemFastBootPermitted,     ///<  before fast boot.
+  OemRestoreNonTraining,
+  OemPrintInputParameters,  ///<  before printing input parameters
+  OemSpdProcessingRun,      ///<  before spd processing code
+  OemSetOverridePreSpd,     ///<  before set overrides pre spd
+  OemSetOverride,           ///<  before set overrides
+  OemMcCapability,          ///<  before MC capability
+  OemMcInitRun,             ///<  before mc init code
+  OemMcMemoryMap,           ///<  before memory map
+  OemMcResetRun,            ///<  before jedec reset
+  OemPreTraining,           ///<  before the training.
+  OemMcTrainingRun,         ///<  before training code
+  OemEarlyCommandTraining,  ///<  before Early Command training
+  OemJedecInitLpddr3,       ///<  before Jedec Init Lpddr3
+  OemSenseAmpTraining,      ///<  before Sense Amp Training
+  OemReadMprTraining,       ///<  before Read MPR Training
+  OemReceiveEnable,         ///<  before Read Leveling
+  OemJedecWriteLeveling,    ///<  before Jedec Write Leveling
+  OemLpddrLatencySetB,      ///<  before LPDDR Latency Set B
+  OemWriteDqDqs,            ///<  before Write Timing Centering
+  OemWriteVoltage,          ///<  before Write Voltage Centering
+  OemEarlyWriteDqDqs2D,     ///<  before Early Write Timing Centering 2D
+  OemEarlyWrDsEq,           ///<  before Early Write Drive Strength / Equalization
+  OemEarlyReadDqDqs2D,      ///<  before Early Read Timing Centering 2D
+  OemEarlyReadMprDqDqs2D,   ///<  before Early MPR Read Timing Centering 2D
+  OemReadDqDqs,             ///<  before Read Timing Centering
+  OemDdr4Map,               ///<  before DDR4 PDA Mapping
+  OemDimmRonTraining,       ///<  before DIMM Ron Training
+  OemDimmODTTraining,       ///<  before DIMM ODT Training
+  OemWriteDriveStrengthEq,  ///<  before Write Drive Strength/Equalization 2D Training
+  OemWriteDriveUpDn,        ///<  before Write Drive Strength Up/Dn 2D Training
+  OemWriteSlewRate,         ///<  before Write Slew Rate Training
+  OemReadODTTraining,       ///<  before Read ODT algorithm.
+  OemReadEQTraining,        ///<  before Read Equalization Training
+  OemReadAmplifierPower,    ///<  before Read Amplifier Power
+  OemOptimizeComp,          ///<  before Comp Optimization Training
+  OemPowerSavingMeter,      ///<  before PowerSavingMeter step
+  OemWriteDqDqs2D,          ///<  before Write Timing Centering 2D
+  OemReadDqDqs2D,           ///<  before Read Timing Centering 2D
+  OemCmdVoltCenterPreLct,   ///<  before Command Voltage Centering that runs pre-LCT
+  OemCmdSlewRate,           ///<  before CMD Slew Rate
+  OemCmdVoltCentering,      ///<  before Command Voltage Centering
+  OemCmdDriveStrengthEq,    ///<  before Command Drive Strength Equalization
+  OemWriteVoltCentering2D,  ///<  before Write Voltage Centering 2D
+  OemReadVoltCentering2D,   ///<  before Read Voltage Centering 2D
+  OemLateCommandTraining,   ///<  before Late Command training
+  OemCmdNormalization,      ///<  before CMD Normalization
+  OemRoundTripLatency,      ///<  before Round Trip Latency Traiing
+  OemTurnAroundTimes,       ///<  before Turn Aorund Times.
+  OemRcvEnCentering1D,      ///<  before Receive Enable Centring
+  OemSaveMCValues,          ///<  before saving memory controller values
+  OemRmt,                   ///<  before RMT crosser tool.
+  OemMemTest,               ///<  before Memory testing
+  OemRestoreTraining,       ///<  before Restoring Training Values
+  OemJedecResetDdr4Fast,    ///<  before JEDEC reset for DDR4 in Fast flow
+  OemSelfRefreshExit,       ///<  before Self Refresh Exit
+  OemNormalMode,            ///<  before Normal Mode on non-cold boots.
+  OemThermalConfig,         ///<  set Thermal config values.
+  OemTxtAliasCheck,         ///<  before TxT Alias Check Call.
+  OemAliasCheck,            ///<  before alias checking on cold boots.
+  OemHwMemInit,
+
+  OemPostTraining,          ///<  after the training.
+  OemForceOltm,             ///<  before MrcForceOltm
+  OemMrcActivate,           ///<  before MrcActivate call.
+  OemMrcRhPrevention,       ///<  before MrcRhPrevention
+  OemSaGvSwitch,            ///<  before SA GV switch
+  OemEngPerfGain,           ///<  before Energy Performance Gain.
+  OemMrcDone,               ///<  call to MrcOemCheckPoint when MRC was done.
+  OemFrequencySet,          ///<  do operation before frequency set.
+  OemFrequencySetDone,      ///<  do operation after frequency set.
+  OemStartMemoryConfiguration,
+  OemBeforeNormalMode,      ///<  call to MrcOemCheckPoint before normal mode is enalbed
+  OemAfterNormalMode,       ///<  call to MrcOemCheckPoint after normal mode is enalbed
+  OemMrcFillBdat,
+  OemRetrainMarginCheck,
+  OemRmtPerBit,             ///< before Rank Margin Tool Per-Bit.
+  OemUpdateSaveMCValues,    ///< before Updating memory controller values.
+  ///
+  ///*********************************************************************************
+  ///
+  OemNumOfCommands          ///<  Should always be last in the list!
+} MrcOemStatusCommand;
+
+typedef UINT8 MrcIteration; ///< Mrc invocation sequence number, start with 0 and increment by one each time MRC library is called.
+#define MRC_ITERATION_MAX ((1 << ((sizeof (MrcIteration) * 8) - 1)) + ((1 << ((sizeof (MrcIteration) * 8) - 1)) - 1))
+
+#define MAX_RCOMP         (3)
+#define MAX_RCOMP_TARGETS (5)
+
+///
+/// Thermal Options
+///
+typedef struct {
+  UINT8  RaplLim2WindX;                                    ///< Offset 110  - Power Limit 2 Time Window X value: 0=Minimal, 3=Maximum, <b>1=Default</b>
+  UINT8  RaplLim2WindY;                                    ///< Offset 111  - Power Limit 2 Time Window Y value: 0=Minimal, 3=Maximum, <b>1=Default</b>
+  UINT8  RaplLim1WindX;                                    ///< Offset 112  - Power Limit 1 Time Window X value: <b>0=Minimal</b>, 3=Maximum
+  UINT8  RaplLim1WindY;                                    ///< Offset 113  - Power Limit 1 Time Window Y value: <b>0=Minimal</b>, 31=Maximum
+  UINT16 RaplLim2Pwr;                                      ///< Offset 114  - Power Limit 2: 0=Minimal, 16383=Maximum, <b>222=Default</b>
+  UINT16 RaplLim1Pwr;                                      ///< Offset 116  - Power Limit 1: <b>0=Minimal</b>, 16383=Maximum
+  UINT8  WarmThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///< Offset 118  - Warm Threshold (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8  HotThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];  ///< Offset 122  - Hot Threshold (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8  WarmBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];    ///< Offset 126  - Warm Budget (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8  HotBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];     ///< Offset 130  - Hot Budget (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8  IdleEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+  UINT8  PdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+  UINT8  ActEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+  UINT8  RdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+  UINT8  WrEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+} ThermalMngmtEn;
+
+
+typedef struct {
+  UINT8      GdxcEnable;   ///< GDXC  MOT enable
+  UINT8      GdxcIotSize;  ///< IOT size in multiples of 8MEG
+  UINT8      GdxcMotSize;  ///< MOT size in multiples of 8MEG
+} MrcGdxc;
+
+typedef struct {
+  UINT32 ECT : 1;        ///< BIT0 - Early Command Training
+  UINT32 SOT : 1;        ///< BIT1 - Sense Amp Offset Training
+  UINT32 ERDMPRTC2D : 1; ///< BIT2 - Early ReadMPR Timing Centering 2D
+  UINT32 RDMPRT : 1;     ///< BIT3 - Read MPR Training
+  UINT32 RCVET : 1;      ///< BIT4 - Read Leveling Training (RcvEn)
+  UINT32 JWRL : 1;       ///< BIT5 - Jedec Write Leveling
+  UINT32 EWRTC2D : 1;    ///< BIT6 - Early Write Time Centering 2D
+  UINT32 ERDTC2D : 1;    ///< BIT7  - Early Read Time Centering 2D
+  UINT32 WRTC1D : 1;     ///< BIT8 - Write Timing Centering 1D
+  UINT32 WRVC1D : 1;     ///< BIT9 - Write Voltage Centering 1D
+  UINT32 RDTC1D : 1;     ///< BIT10 - Read Timing Centering 1D
+  UINT32 DIMMODTT : 1;   ///< BIT11 - Dimm ODT Training
+  UINT32 DIMMRONT : 1;   ///< BIT12 - Dimm Ron Training
+  UINT32 WRDSEQT : 1;    ///< BIT13 - Write Drive Strength / Equalization Training 2D
+  UINT32 WRSRT : 1;      ///< BIT14 - Write Slew Rate Training
+  UINT32 RDODTT : 1;     ///< BIT15 - Read ODT Training
+  UINT32 RDEQT : 1;      ///< BIT16 - Read Equalization Training
+  UINT32 RDAPT : 1;      ///< BIT17 - Read Amplifier Power Training
+  UINT32 WRTC2D : 1;     ///< BIT18 - Write Timing Centering 2D
+  UINT32 RDTC2D : 1;     ///< BIT19 - Read Timing Centering 2D
+  UINT32 WRVC2D : 1;     ///< BIT20 - Write Voltage Centering 2D
+  UINT32 RDVC2D : 1;     ///< BIT21 - Read Voltage Centering 2D
+  UINT32 CMDVC : 1;      ///< BIT22 - Command Voltage Centering
+  UINT32 LCT : 1;        ///< BIT23 - Late Command Training
+  UINT32 RTL : 1;        ///< BIT24 - Round Trip latency
+  UINT32 TAT : 1;        ///< BIT25 - Turn Around Timing
+  UINT32 RMT : 1;        ///< BIT26 - RMT Tool
+  UINT32 MEMTST : 1;     ///< BIT27 - Memory Test
+  UINT32 ALIASCHK: 1;    ///< BIT28 - SPD Alias Check
+  UINT32 RCVENC1D: 1;    ///< BIT29 - Receive Enable Centering 1D
+  UINT32 RMC : 1;        ///< BIT30 - Retrain Margin Check
+  UINT32 WRDSUDT : 1;    ///< BIT31 - Write Drive Strength Up/Dn independently
+} TrainingStepsEn;
+
+typedef struct {
+  UINT32 CMDSR    : 1;   ///< BIT0  - CMD Slew Rate Training
+  UINT32 CMDDSEQ  : 1;   ///< BIT1  - CMD Drive Strength and Tx Equalization
+  UINT32 CMDNORM  : 1;   ///< BIT2  - CMD Normalization
+  UINT32 EWRDSEQ  : 1;   ///< BIT3  - Early DQ Write Drive Strength and Equalization Training
+  UINT32 TeRsv4   : 1;   ///< BIT4 - Reserved
+  UINT32 TeRsv5   : 1;   ///< BIT5 - Reserved
+  UINT32 TeRsv6   : 1;   ///< BIT6 - Reserved
+  UINT32 RsvdBits :25;
+} TrainingStepsEn2;
+
+///
+/// Defines whether the MRC is executing in full or mini BIOS mode.
+///
+typedef enum {
+  MrcModeFull,   ///< Select full BIOS MRC execution.
+  MrcModeMini,   ///< Select mini BIOS MRC execution.
+  MrcModeMaximum ///< Delimiter.
+} MrcMode;
+
+typedef enum {
+  MrcTmPower,
+  MrcTmMargin,
+  MrcTmMax
+} TrainingModeType;
+
+typedef enum {
+  LastRxV,
+  LastRxT,
+  LastTxV,
+  LastTxT,
+  LastRcvEna,
+  LastWrLevel,
+  LastCmdT,
+  LastCmdV,
+  MAX_RESULT_TYPE
+} MrcMarginResult;
+
+typedef enum {
+  MSG_LEVEL_NEVER,
+  MSG_LEVEL_ERROR,
+  MSG_LEVEL_WARNING,
+  MSG_LEVEL_NOTE,
+  MSG_LEVEL_EVENT,
+  MSG_LEVEL_ALGO,
+  MSG_LEVEL_MMIO,
+  MSG_LEVEL_CSV,
+  MSG_LEVEL_TIME,
+  MSG_LEVEL_ALL = MRC_INT32_MAX
+} MrcDebugMsgLevel;
+
+///
+/// Define the frequencies that may be possible in the memory controller.
+/// Note that not all these values may be supported.
+///
+#define fNoInit     (0)
+#define f800        (800)
+#define f1000       (1000)
+#define f1100       (1100)
+#define f1067       (1067)
+#define f1200       (1200)
+#define f1300       (1300)
+#define f1333       (1333)
+#define f1400       (1400)
+#define f1467       (1467)
+#define f1500       (1500)
+#define f1600       (1600)
+#define f1700       (1700)
+#define f1733       (1733)
+#define f1800       (1800)
+#define f1867       (1867)
+#define f1900       (1900)
+#define f2000       (2000)
+#define f2100       (2100)
+#define f2133       (2133)
+#define f2200       (2200)
+#define f2267       (2267)
+#define f2300       (2300)
+#define f2400       (2400)
+#define f2500       (2500)
+#define f2533       (2533)
+#define f2600       (2600)
+#define f2667       (2667)
+#define f2700       (2700)
+#define f2800       (2800)
+#define f2900       (2900)
+#define f2933       (2933)
+#define f3000       (3000)
+#define f3067       (3067)
+#define f3100       (3100)
+#define f3200       (3200)
+#define f3333       (3333)
+#define f3467       (3467)
+#define f3600       (3600)
+#define f3733       (3733)
+#define f3867       (3867)
+#define f4000       (4000)
+#define f4133       (4133)
+#define fInvalid    (0x7FFFFFFF)
+typedef UINT32 MrcFrequency;
+
+//
+// Max supported frequency in OC mode
+// RefClk133: 15*266 + 100 = 4133 (using Odd ratio mode)
+// RefClk100: 15*200 + 100 = 3100 (using Odd ratio mode)
+//
+#define MAX_FREQ_OC_133   f4133
+#define MAX_FREQ_OC_100   f3100
+
+//
+// tCK value in femtoseconds for various frequencies
+// If Freq is in MHz, then tCK[fs] = 10^9 * 1/(Freq/2)
+//
+#define MRC_DDR_800_TCK_MIN      2500000
+#define MRC_DDR_1000_TCK_MIN     2000000
+#define MRC_DDR_1067_TCK_MIN     1875000
+#define MRC_DDR_1100_TCK_MIN     1818182
+#define MRC_DDR_1200_TCK_MIN     1666667
+#define MRC_DDR_1300_TCK_MIN     1538462
+#define MRC_DDR_1333_TCK_MIN     1500000
+#define MRC_DDR_1400_TCK_MIN     1428571
+#define MRC_DDR_1467_TCK_MIN     1363636
+#define MRC_DDR_1500_TCK_MIN     1333333
+#define MRC_DDR_1600_TCK_MIN     1250000
+#define MRC_DDR_1700_TCK_MIN     1176471
+#define MRC_DDR_1733_TCK_MIN     1153846
+#define MRC_DDR_1800_TCK_MIN     1111111
+#define MRC_DDR_1867_TCK_MIN     1071429
+#define MRC_DDR_1900_TCK_MIN     1052632
+#define MRC_DDR_2000_TCK_MIN     1000000
+#define MRC_DDR_2100_TCK_MIN     952381
+#define MRC_DDR_2133_TCK_MIN     938000
+#define MRC_DDR_2200_TCK_MIN     909091
+#define MRC_DDR_2267_TCK_MIN     882353
+#define MRC_DDR_2300_TCK_MIN     869565
+#define MRC_DDR_2400_TCK_MIN     833333
+#define MRC_DDR_2500_TCK_MIN     800000
+#define MRC_DDR_2533_TCK_MIN     789474
+#define MRC_DDR_2600_TCK_MIN     769231
+#define MRC_DDR_2667_TCK_MIN     750000
+#define MRC_DDR_2700_TCK_MIN     740741
+#define MRC_DDR_2800_TCK_MIN     714286
+#define MRC_DDR_2900_TCK_MIN     689655
+#define MRC_DDR_2933_TCK_MIN     681818
+#define MRC_DDR_3000_TCK_MIN     666667
+#define MRC_DDR_3067_TCK_MIN     652174
+#define MRC_DDR_3100_TCK_MIN     645161
+#define MRC_DDR_3200_TCK_MIN     625000
+#define MRC_DDR_3333_TCK_MIN     600000
+#define MRC_DDR_3467_TCK_MIN     576923
+#define MRC_DDR_3600_TCK_MIN     555556
+#define MRC_DDR_3733_TCK_MIN     535714
+#define MRC_DDR_3867_TCK_MIN     517241
+#define MRC_DDR_4000_TCK_MIN     500000
+#define MRC_DDR_4133_TCK_MIN     483871
+
+///
+/// Define the memory nominal voltage (VDD).
+/// Note that not all these values may be supported.
+///
+typedef enum {
+  VDD_INVALID,
+  VDD_1_00    = 1000,
+  VDD_1_05    = 1050,
+  VDD_1_10    = 1100,
+  VDD_1_15    = 1150,
+  VDD_1_20    = 1200,
+  VDD_1_25    = 1250,
+  VDD_1_30    = 1300,
+  VDD_1_35    = 1350,
+  VDD_1_40    = 1400,
+  VDD_1_45    = 1450,
+  VDD_1_50    = 1500,
+  VDD_1_55    = 1550,
+  VDD_1_60    = 1600,
+  VDD_1_65    = 1650,
+  VDD_1_70    = 1700,
+  VDD_1_75    = 1750,
+  VDD_1_80    = 1800,
+  VDD_1_85    = 1850,
+  VDD_1_90    = 1900,
+  VDD_1_95    = 1950,
+  VDD_2_00    = 2000,
+  VDD_2_05    = 2050,
+  VDD_2_10    = 2100,
+  VDD_2_15    = 2150,
+  VDD_2_20    = 2200,
+  VDD_2_25    = 2250,
+  VDD_2_30    = 2300,
+  VDD_2_35    = 2350,
+  VDD_2_40    = 2400,
+  VDD_2_45    = 2450,
+  VDD_2_50    = 2500,
+  VDD_2_55    = 2550,
+  VDD_2_60    = 2600,
+  VDD_2_65    = 2650,
+  VDD_2_70    = 2700,
+  VDD_2_75    = 2750,
+  VDD_2_80    = 2800,
+  VDD_2_85    = 2850,
+  VDD_2_90    = 2900,
+  VDD_2_95    = 2950,
+  VDD_MAXIMUM = 0x7FFFFFFF
+} MrcVddSelect;
+
+///
+/// SA GV points
+///
+typedef enum {
+  MrcSaGvPointLow,
+  MrcSaGvPointHigh,
+} MrcSaGvPoint;
+
+///
+/// SA GV modes
+///  Disabled:  SA GV Disabled, run all MRC tasks
+///  FixedLow:  SA GV Disabled, run only MRC tasks marked with MRC_PF_GV_LOW
+///  FixedHigh: SA GV Disabled, run only MRC tasks marked with MRC_PF_GV_HIGH
+///  Enabled:   SA GV Enabled
+///
+typedef enum {
+  MrcSaGvDisabled,
+  MrcSaGvFixedLow,
+  MrcSaGvFixedHigh,
+  MrcSaGvEnabled,
+} MrcSaGv;
+
+///
+/// DIMM SPD Security Status
+///
+typedef enum {
+  MrcSpdStatusGood,      ///< Memory is in a secure state.
+  MrcSpdStatusAliased,   ///< Memory is aliased.
+  MrcSpdStatusLast       ///< Must be last in the list
+} MrcSpdStatus;
+
+///
+/// Define the virtual channel.
+///
+typedef enum {
+  vcL,  ///< Virtual channel L
+  vcS,  ///< Virtual channel S
+} MrcVirtualChannel;
+
+///
+/// Define the board types.
+///
+typedef enum {
+  btCRBMB,    ///< 0 - CRB Mobile
+  btCRBDT,    ///< 1 - CRB Desktop
+  btUser1,    ///< 2 - SV Karkom
+  btUser2,    ///< 3 - SV desktop
+  btUser3,    ///< 4 - SV miniDVP
+  btUser4,    ///< 5 - Ult
+  btCRBEMB,   ///< 6 - CRB Embedded
+  btUpServer, ///< 7 - Up Server
+  btUnknown,  ///< 8 - Unknown
+  btMaximum   ///< Delimiter
+} MrcBoardType;
+
+///
+/// Define the CPU family/model.
+///
+typedef enum {
+  cmCFL_ULX_ULT   = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX,  ///< Coffeelake ULT/ULX
+  cmCFL_DT_HALO   = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO   ///< Coffeelake DT/Halo
+} MrcCpuModel;
+
+///
+/// Define the CPU Tick/Tock.
+///
+typedef enum {
+  cfCfl    = 0,  ///< Coffeelake
+  cfMax
+} MrcCpuFamily;
+
+///
+/// Define the CPU stepping number.
+///
+typedef enum {
+  ///
+  /// Coffeelake ULX/ULT
+  ///
+  csKblH0         = EnumKblH0,
+  csCflD0         = EnumCflD0,
+  csCflW0         = EnumCflW0,
+  csCflV0         = EnumCflV0,
+  csCflUlxUltLast = csCflV0,
+
+  ///
+  /// Coffeelake DT/Halo
+  ///
+  csCflU0         = EnumCflU0,
+  csCflB0         = EnumCflB0,
+  csCflP0         = EnumCflP0,
+  csCflR0         = EnumCflR0,
+  csCflDtHaloLast = csCflR0,
+} MrcCpuStepping;
+
+typedef enum {
+  CONTROLLER_NOT_PRESENT, ///< There is no controller present in the system.
+  CONTROLLER_DISABLED,    ///< There is a controller present but it is disabled.
+  CONTROLLER_PRESENT,     ///< There is a controller present and it is enabled.
+  MAX_CONTROLLER_STATUS   ///< Delimiter
+} MrcControllerSts;
+
+typedef enum {
+  CHANNEL_NOT_PRESENT,    ///< There is no channel present on the controller.
+  CHANNEL_DISABLED,       ///< There is a channel present but it is disabled.
+  CHANNEL_PRESENT,        ///< There is a channel present and it is enabled.
+  MAX_CHANNEL_STATUS      ///< Delimiter
+} MrcChannelSts;
+
+typedef enum {
+  DIMM_ENABLED,           ///< DIMM/rank Pair is enabled, presence will be detected.
+  DIMM_DISABLED,          ///< DIMM/rank Pair is disabled, regardless of presence.
+  DIMM_PRESENT,           ///< There is a DIMM present in the slot/rank pair and it will be used.
+  DIMM_NOT_PRESENT,       ///< There is no DIMM present in the slot/rank pair.
+  MAX_DIMM_STATUS         ///< Delimiter
+} MrcDimmSts;
+
+typedef enum {
+  STD_PROFILE,            ///< Standard DIMM profile select.
+  USER_PROFILE,           ///< User specifies various override values.
+  XMP_PROFILE1,           ///< XMP enthusiast settings select (XMP profile #1).
+  XMP_PROFILE2,           ///< XMP extreme settings select (XMP profile #2).
+  MAX_PROFILE             ///< Delimiter
+} MrcProfile;
+
+#define XMP_PROFILES_ENABLE   (0x3)
+#define XMP1_PROFILE_ENABLE   (0x1)
+#define XMP2_PROFILE_ENABLE   (0x2)
+
+typedef enum {
+  MRC_REF_CLOCK_133,      ///< 133MHz reference clock
+  MRC_REF_CLOCK_100,      ///< 100MHz reference clock
+  MRC_REF_CLOCK_MAXIMUM   ///< Delimiter
+} MrcRefClkSelect;        ///< This value times the MrcClockRatio determines the MrcFrequency.
+
+typedef enum {
+  MRC_FREQ_INVALID       = 0,
+  MRC_FREQ_133           = (MRC_BIT0 << MRC_REF_CLOCK_133), // Bit 0
+  MRC_FREQ_100           = (MRC_BIT0 << MRC_REF_CLOCK_100), // Bit 1
+  MRC_FREQ_133_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_133), // Bit 2
+  MRC_FREQ_100_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_100), // Bit 3
+  MRC_FREQ_MAX                                              // Delimiter
+} MrcFreqFlag;
+
+typedef UINT32 MrcBClkRef;   ///< Base clock, in Hertz, Default is 100MHz or leave at zero for default.
+
+//
+// This encoding matches CFL SC_GS_CFG.DRAM_technology and MAD_INTER_CHANNEL.DDR_TYPE registers
+//
+typedef enum {
+  MRC_DDR_TYPE_DDR4     = 0,
+  MRC_DDR_TYPE_DDR3     = 1,
+  MRC_DDR_TYPE_LPDDR3   = 2,
+  MRC_DDR_TYPE_UNKNOWN  = 3,
+  MAX_MRC_DDR_TYPE        ///< Delimiter
+} MrcDdrType;
+
+typedef enum {
+  MrcIterationClock,
+  MrcIterationCmdN,
+  MrcIterationCmdS,
+  MrcIterationCke,
+  MrcIterationCtl,
+  MrcIterationCmdV,
+  MrcIterationMax
+} MrcIterationType;
+
+typedef enum {
+  UpmLimit,
+  PowerLimit,
+  RetrainLimit,
+  MarginLimitMax
+} MRC_MARGIN_LIMIT_TYPE;
+
+
+typedef enum {
+  HardwareRhp,
+  Refresh2x
+} MrcRhpType;
+
+typedef enum {
+  OneIn2To1 = 1,
+  OneIn2To2,
+  OneIn2To3,
+  OneIn2To4,
+  OneIn2To5,
+  OneIn2To6,
+  OneIn2To7,
+  OneIn2To8,
+  OneIn2To9,
+  OneIn2To10,
+  OneIn2To11,
+  OneIn2To12,
+  OneIn2To13,
+  OneIn2To14,
+  OneIn2To15
+} MrcRhProbType;
+
+typedef enum {
+  MRC_POST_CODE,
+  MRC_POST_CODE_WRITE,
+  MRC_POST_CODE_READ,
+  MRC_POST_CODE_MAX
+} MrcDebugPostCode;
+
+typedef struct {
+  UINT32 MrcData;
+  UINT32 Stream;
+  UINT32 Start;
+  UINT32 End;
+  UINT32 Current;
+  int Level;
+  UINT16 PostCode[MRC_POST_CODE_MAX];
+  UINT32 TopStackAddr;     ///< Initial stack address.
+  UINT32 LowestStackAddr;  ///< Track the lowest stack address used through MrcPrintfVaList()
+} MrcDebug;
+
+typedef UINT16 MrcPostCode;
+typedef UINT8  MrcClockRatio;  ///< This value times the MrcRefClkSelect determines the MrcFrequency.
+typedef UINT32 MrcGfxDataSize; ///< The size of the stolen graphics data memory, in MBytes.
+typedef UINT32 MrcGfxGttSize;  ///< The size of the graphics translation table, in MBytes.
+
+
+///
+/// This data structure contains all the "DDR power saving data" values that are considered output by the MRC.
+/// The following are memory controller level definitions. All channels on a controller are set to these values.
+///
+typedef struct {
+  BOOLEAN    BaseFlag;      ///< Indicates if the base line of power was already calculated.
+  UINT16     BaseSavingRd;  ///< Indicates the base line of power consume by the ddr on read.
+  UINT16     BaseSavingWr;  ///< Indicates the base line of power consume by the ddr on write.
+  UINT16     BaseSavingCmd; ///< Indicates the base line of power consume by the ddr on command.
+  UINT16     MrcSavingRd;   ///< Indicates the power consume by the ddr on read at the end of MRC.
+  UINT16     MrcSavingWr;   ///< Indicates the power consume by the ddr on write at the end of MRC.
+  UINT16     MrcSavingCmd;  ///< Indicates the power consume by the ddr on command at the end of MRC.
+} MrcOdtPowerSaving;
+
+///
+/// The memory controller capabilities.
+///
+typedef union {
+  UINT32 Data;
+  UINT16 Data16[2];
+  UINT8  Data8[4];
+} MrcCapabilityIdA;
+
+typedef union {
+  UINT32 Data;
+  UINT16 Data16[2];
+  UINT8  Data8[4];
+} MrcCapabilityIdB;
+
+typedef union {
+  UINT64 Data;
+  struct {
+    MrcCapabilityIdA A;
+    MrcCapabilityIdB B;
+  } Data32;
+} MrcCapabilityId;
+
+///
+/// MRC version description.
+///
+typedef struct {
+  UINT8  Major;  ///< Major version number
+  UINT8  Minor;  ///< Minor version number
+  UINT8  Rev;    ///< Revision number
+  UINT8  Build;  ///< Build number
+} MrcVersion;
+
+///
+/// Memory map configuration information.
+///
+typedef struct {
+  UINT32     TomMinusMe;
+  UINT32     ToludBase;
+  UINT32     BdsmBase;
+  UINT32     GttBase;
+  UINT32     GraphicsControlRegister;
+  UINT32     TsegBase;
+  BOOLEAN    ReclaimEnable;
+  UINT32     RemapBase;
+  UINT32     RemapLimit;
+  UINT32     TouudBase;
+  UINT32     TotalPhysicalMemorySize;
+  UINT32     MeStolenBase;
+  UINT32     MeStolenSize;
+  UINT32     GdxcMotBase;
+  UINT32     GdxcMotSize;
+  UINT32     GdxcIotBase;
+  UINT32     GdxcIotSize;
+  UINT32     DprSize;
+  UINT32     PttStolenBase;
+  UINT32     PrmrrBase;
+  UINT32     LowestBase;
+} MrcMemoryMap;
+
+///
+/// Real time clock information.
+///
+typedef struct {
+  UINT8  Seconds;    ///< Seconds, 0-59
+  UINT8  Minutes;    ///< Minutes, 0-59
+  UINT8  Hours;      ///< Hours, 0-23
+  UINT8  DayOfMonth; ///< Day of the month, 1-31
+  UINT8  Month;      ///< Month of the year, 1-12
+  UINT16 Year;       ///< Year, 0-65535
+} MrcBaseTime;
+
+///
+/// DIMM timings
+///
+typedef struct {
+  UINT32 tCK;     ///< Memory cycle time, in femtoseconds.
+  UINT16 NMode;   ///< Number of tCK cycles for the channel DIMM's command rate mode.
+  UINT16 tCL;     ///< Number of tCK cycles for the channel DIMM's CAS latency.
+  UINT16 tCWL;    ///< Number of tCK cycles for the channel DIMM's minimum CAS write latency time.
+  UINT16 tFAW;    ///< Number of tCK cycles for the channel DIMM's minimum four activate window delay time.
+  UINT16 tRAS;    ///< Number of tCK cycles for the channel DIMM's minimum active to precharge delay time.
+  UINT16 tRCDtRP; ///< Number of tCK cycles for the channel DIMM's minimum RAS# to CAS# delay time and Row Precharge delay time.
+  UINT16 tREFI;   ///< Number of tCK cycles for the channel DIMM's minimum Average Periodic Refresh Interval.
+  UINT16 tRFC;    ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+  UINT16 tRFCpb;  ///< Number of tCK cycles for the channel DIMM's minimum per bank refresh recovery delay time.
+  UINT16 tRFC2;   ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+  UINT16 tRFC4;   ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+  UINT16 tRPab;   ///< Number of tCK cycles for the channel DIMM's minimum row precharge delay time for all banks.
+  UINT16 tRRD;    ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time.
+  UINT16 tRRD_L;  ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for same bank groups.
+  UINT16 tRRD_S;  ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for different bank groups.
+  UINT16 tRTP;    ///< Number of tCK cycles for the channel DIMM's minimum internal read to precharge command delay time.
+  UINT16 tWR;     ///< Number of tCK cycles for the channel DIMM's minimum write recovery time.
+  UINT16 tWTR;    ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time.
+  UINT16 tWTR_L;  ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for same bank groups.
+  UINT16 tWTR_S;  ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for different bank groups.
+  UINT16 tCCD_L;  ///< Number of tCK cycles for the channel DIMM's minimum CAS-to-CAS delay for same bank group.
+} MrcTiming;
+
+typedef struct {
+  UINT8 SG;       ///< Number of tCK cycles between transactions in the same bank group.
+  UINT8 DG;       ///< Number of tCK cycles between transactions when switching bank groups.
+  UINT8 DR;       ///< Number of tCK cycles between transactions when switching between Ranks (in the same DIMM).
+  UINT8 DD;       ///< Number of tCK cycles between transactions when switching between DIMMs
+} MrcTurnaroundTimes;
+
+typedef struct {
+  INT32 Mtb;    ///< Medium time base.
+  INT32 Ftb;    ///< Fine time base.
+} MrcTimeBase;
+
+typedef struct {
+  UINT8  Left;   ///< The left side of the timing eye.
+  UINT8  Center; ///< The center of the timing eye.
+  UINT8  Right;  ///< The right side of the timing eye.
+} MrcDqTimeMargin;
+
+typedef struct {
+  UINT8  High;   ///< The high side of the Vref eye.
+  UINT8  Center; ///< The center of the Vref eye.
+  UINT8  Low;    ///< The low side of the Vref eye.
+} MrcDqVrefMargin;
+
+typedef struct {
+  UINT8  Left;   ///< The left side of the command eye.
+  UINT8  Right;  ///< The right side of the command eye.
+  UINT8  High;   ///< The high side of the command eye.
+  UINT8  Low;    ///< The low side of the command eye.
+} MrcCommandMargin;
+
+typedef struct {
+  UINT8  Left;   ///< The left side of the receive enable eye.
+  UINT8  Right;  ///< The right side of the receive enableeye.
+} MrcRecvEnMargin;
+
+typedef struct {
+  UINT8  Left;   ///< The left side of the write leveling eye.
+  UINT8  Right;  ///< The right side of the write leveling eye.
+} MrcWrLevelMargin;
+
+typedef struct {
+  UINT8     SpdValid[sizeof (MrcSpd) / (CHAR_BITS * sizeof (UINT8))]; ///< Each valid bit maps to SPD byte.
+  UINT8     MrcSpdString[3]; ///< The SPD data start marker. This must be located at the start of the SPD data structure. It includes this string plus the following flag.
+  union {
+    struct {
+      UINT8   DimmNumber    : 4; ///< SPD zero based DIMM number.
+      UINT8   ChannelNumber : 3; ///< SPD zero based channel number.
+      UINT8   MdSocket      : 1; ///< 0 = memory down, 1 = socketed.
+    } Bit;
+    UINT8 Data;
+  } Flag;
+  MrcSpd Data;            ///< The SPD data for each DIMM. SPDGeneral field = 0 when absent.
+} MrcSpdData;
+
+typedef UINT8        (*MRC_IO_READ_8)               (UINT32 IoAddress);
+typedef UINT16       (*MRC_IO_READ_16)              (UINT32 IoAddress);
+typedef UINT32       (*MRC_IO_READ_32)              (UINT32 IoAddress);
+typedef void         (*MRC_IO_WRITE_8)              (UINT32 IoAddress, UINT8 Value);
+typedef void         (*MRC_IO_WRITE_16)             (UINT32 IoAddress, UINT16 Value);
+typedef void         (*MRC_IO_WRITE_32)             (UINT32 IoAddress, UINT32 Value);
+typedef UINT8        (*MRC_MMIO_READ_8)             (UINT32 Address);
+typedef UINT16       (*MRC_MMIO_READ_16)            (UINT32 Address);
+typedef UINT32       (*MRC_MMIO_READ_32)            (UINT32 Address);
+typedef UINT64       (*MRC_MMIO_READ_64)            (UINT32 Address);
+typedef UINT8        (*MRC_MMIO_WRITE_8)            (UINT32 Address, UINT8 Value);
+typedef UINT16       (*MRC_MMIO_WRITE_16)           (UINT32 Address, UINT16 Value);
+typedef UINT32       (*MRC_MMIO_WRITE_32)           (UINT32 Address, UINT32 Value);
+typedef UINT64       (*MRC_MMIO_WRITE_64)           (UINT32 Address, UINT64 Value);
+typedef UINT8        (*MRC_SMBUS_READ_8)            (UINT32 Address, UINT32 *Status);
+typedef UINT16       (*MRC_SMBUS_READ_16)           (UINT32 Address, UINT32 *Status);
+typedef UINT8        (*MRC_SMBUS_WRITE_8)           (UINT32 Address, UINT8 Value, UINT32 *Status);
+typedef UINT16       (*MRC_SMBUS_WRITE_16)          (UINT32 Address, UINT16 Value, UINT32 *Status);
+typedef UINT32       (*MRC_GET_PCI_DEVICE_ADDRESS)  (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);
+typedef UINT32       (*MRC_GET_PCIE_DEVICE_ADDRESS) (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);
+typedef void         (*MRC_GET_RTC_TIME)            (UINT8 *Second, UINT8 *Minute, UINT8 *Hour, UINT8 *Day, UINT8 *Month, UINT16 *Year);
+typedef UINT64       (*MRC_GET_CPU_TIME)            (void *MrcData);
+typedef void *       (*MRC_MEMORY_COPY)             (UINT8 *Destination, UINT8 *Source, UINT32 NumBytes);
+typedef void *       (*MRC_MEMORY_SET_BYTE)         (UINT8 *Destination, UINT32 NumBytes, UINT8 Value);
+typedef void *       (*MRC_MEMORY_SET_WORD)         (UINT16 *Destination, UINT32 NumWords, UINT16 Value);
+typedef void *       (*MRC_MEMORY_SET_DWORD)        (UINT32 *Destination, UINT32 NumDwords, UINT32 Value);
+typedef UINT64       (*MRC_LEFT_SHIFT_64)           (UINT64 Data, UINT32 NumBits);
+typedef UINT64       (*MRC_RIGHT_SHIFT_64)          (UINT64 Data, UINT32 NumBits);
+typedef UINT64       (*MRC_MULT_U64_U32)            (UINT64 Multiplicand, UINT32 Multiplier);
+typedef UINT64       (*MRC_DIV_U64_U64)             (UINT64 Dividend, UINT64 Divisor, UINT64 *Remainder);
+typedef BOOLEAN      (*MRC_GET_SPD_DATA)            (UINT8 BootMode, UINT8 SpdAddress, UINT8 *SpdData, UINT8 *Ddr3Table, UINT32 Ddr3TableSize, UINT8 *Ddr4Table, UINT32 Ddr4TableSize, UINT8 *LpddrTable, UINT32 LpddrTableSize);
+typedef BOOLEAN      (*MRC_GET_RANDOM_NUMBER)       (UINT32 *Rand);
+typedef UINT32       (*MRC_CPU_MAILBOX_READ)        (UINT32 Type, UINT32 Command, UINT32 *Value, UINT32 *Status);
+typedef UINT32       (*MRC_CPU_MAILBOX_WRITE)       (UINT32 Type, UINT32 Command, UINT32 Value, UINT32 *Status);
+typedef UINT32       (*MRC_GET_MEMORY_VDD)          (void *MrcData, UINT32 DefaultVdd);
+typedef UINT32       (*MRC_SET_MEMORY_VDD)          (void *MrcData, UINT32 DefaultVdd, UINT32 Value);
+typedef UINT32       (*MRC_CHECKPOINT)              (void *MrcData, UINT32 CheckPoint, void *Scratch);
+typedef void         (*MRC_DEBUG_HOOK)              (void *GlobalData, UINT16 DisplayDebugNumber);
+typedef void         (*MRC_PRINT_STRING)            (void *String);
+typedef UINT8        (*MRC_GET_RTC_CMOS)            (UINT8 Location);
+typedef UINT64       (*MRC_MSR_READ_64)             (UINT32 Location);
+typedef UINT64       (*MRC_MSR_WRITE_64)            (UINT32 Location, UINT64 Data);
+typedef void         (*MRC_RETURN_FROM_SMC)         (void *GlobalData, UINT32 MrcStatus);
+typedef void         (*MRC_DRAM_RESET)              (UINT32 PciEBaseAddress, UINT32 ResetValue);
+typedef void         (*MRC_SET_LOCK_PRMRR)          (UINT32 PrmrrBase, UINT32 PrmrrSize);
+typedef void         (*MRC_TXT_ACHECK)              (void);
+
+///
+/// Function calls that are called external to the MRC.
+///   This structure needs to be aligned with SA_FUNCTION_CALLS.  All functions that are
+///   not apart of SA_FUNCTION_CALLS need to be at the end of the structure.
+///
+typedef struct {
+  MRC_IO_READ_8               MrcIoRead8;
+  MRC_IO_READ_16              MrcIoRead16;
+  MRC_IO_READ_32              MrcIoRead32;
+  MRC_IO_WRITE_8              MrcIoWrite8;
+  MRC_IO_WRITE_16             MrcIoWrite16;
+  MRC_IO_WRITE_32             MrcIoWrite32;
+  MRC_MMIO_READ_8             MrcMmioRead8;
+  MRC_MMIO_READ_16            MrcMmioRead16;
+  MRC_MMIO_READ_32            MrcMmioRead32;
+  MRC_MMIO_READ_64            MrcMmioRead64;
+  MRC_MMIO_WRITE_8            MrcMmioWrite8;
+  MRC_MMIO_WRITE_16           MrcMmioWrite16;
+  MRC_MMIO_WRITE_32           MrcMmioWrite32;
+  MRC_MMIO_WRITE_64           MrcMmioWrite64;
+  MRC_SMBUS_READ_8            MrcSmbusRead8;
+  MRC_SMBUS_READ_16           MrcSmbusRead16;
+  MRC_SMBUS_WRITE_8           MrcSmbusWrite8;
+  MRC_SMBUS_WRITE_16          MrcSmbusWrite16;
+  MRC_GET_PCI_DEVICE_ADDRESS  MrcGetPciDeviceAddress;
+  MRC_GET_PCIE_DEVICE_ADDRESS MrcGetPcieDeviceAddress;
+  MRC_GET_RTC_TIME            MrcGetRtcTime;
+  MRC_GET_CPU_TIME            MrcGetCpuTime;
+  MRC_MEMORY_COPY             MrcCopyMem;
+  MRC_MEMORY_SET_BYTE         MrcSetMem;
+  MRC_MEMORY_SET_WORD         MrcSetMemWord;
+  MRC_MEMORY_SET_DWORD        MrcSetMemDword;
+  MRC_LEFT_SHIFT_64           MrcLeftShift64;
+  MRC_RIGHT_SHIFT_64          MrcRightShift64;
+  MRC_MULT_U64_U32            MrcMultU64x32;
+  MRC_DIV_U64_U64             MrcDivU64x64;
+  MRC_GET_SPD_DATA            MrcGetSpdData;
+  MRC_GET_RANDOM_NUMBER       MrcGetRandomNumber;
+  MRC_CPU_MAILBOX_READ        MrcCpuMailboxRead;
+  MRC_CPU_MAILBOX_WRITE       MrcCpuMailboxWrite;
+  MRC_GET_MEMORY_VDD          MrcGetMemoryVdd;
+  MRC_SET_MEMORY_VDD          MrcSetMemoryVdd;
+  MRC_CHECKPOINT              MrcCheckpoint;
+  MRC_DEBUG_HOOK              MrcDebugHook;
+  MRC_PRINT_STRING            MrcPrintString;
+  MRC_GET_RTC_CMOS            MrcRtcCmos;
+  MRC_MSR_READ_64             MrcReadMsr64;
+  MRC_MSR_WRITE_64            MrcWriteMsr64;
+  MRC_RETURN_FROM_SMC         MrcReturnFromSmc;
+  MRC_DRAM_RESET              MrcDramReset;
+  MRC_SET_LOCK_PRMRR          MrcSetLockPrmrr;
+  MRC_TXT_ACHECK              MrcTxtAcheck;
+} MRC_FUNCTION;
+
+///
+///*****************************************
+/// Output related "global data" structures.
+///*****************************************
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are SDRAM level definitions. All ranks on a rank are set to these values.
+///
+/* Commented out until needed, in order to save space.
+typedef struct {
+} MrcSdramOut;
+*/
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are rank level definitions. All ranks on a DIMM are set to these values.
+///
+typedef struct {
+//MrcSdramOut     Sdram[MAX_SDRAM_IN_DIMM];         ///< The following are SDRAM level definitions.
+  UINT16             MR[MAX_MR_IN_DIMM];            ///< DRAM mode register value.
+  UINT16             MR11;                          ///< LPDDR3 ODT MR
+  UINT8              Ddr4PdaMr6[MAX_SDRAM_IN_DIMM]; ///< DDR4 MR6[6:0] for per-DRAM VrefDQ (PDA)
+#if (SUPPORT_DDR4 == SUPPORT)
+  UINT8              Device[MAX_SDRAM_IN_DIMM];     ///< Which Bytes are tied to which Device where BIT0 set means Byte 0
+#endif //SUPPORT_DDR4
+} MrcRankOut;
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are DIMM level definitions. All ranks on a DIMM are set to these values.
+///
+typedef struct {
+  MrcDimmSts     Status;                    ///< See MrcDimmSts for the definition of this field.
+  MrcTiming      Timing[MAX_PROFILE];       ///< The DIMMs timing values.
+  MrcVddSelect   VddVoltage[MAX_PROFILE];   ///< The voltage (VDD) setting for this DIMM, per profile.
+  BOOLEAN        EccSupport;                ///< TRUE if ECC is enabled and supported on this DIMM.
+  BOOLEAN        IgnoreNonEccDimm;          ///< TRUE if a DIMM without ECC capability should be ignored.
+  BOOLEAN        AddressMirrored;           ///< TRUE if the DIMM is address mirrored.
+  BOOLEAN        SelfRefreshTemp;           ///< TRUE if the DIMM supports self refresh extended operating temperature range (SRT).
+  BOOLEAN        AutoSelfRefresh;           ///< TRUE if the DIMM supports automatic self refresh (ASR).
+  BOOLEAN        PartialSelfRefresh;        ///< TRUE if the DIMM supports Partial Array Self Refresh (PASR).
+  BOOLEAN        OnDieThermalSensor;        ///< TRUE if the DIMM supports On-die Thermal Sensor (ODTS) Readout.
+  BOOLEAN        ExtendedTemperRange;       ///< TRUE if the DIMM supports Extended Temperature Range (ETR).
+  BOOLEAN        ExtendedTemperRefresh;     ///< TRUE if the DIMM supports 1x Extended Temperature Refresh rate, FALSE = 2x.
+  MrcDdrType     DdrType;                   ///< DDR type: DDR3 or LPDDR3
+  MEMORY_PACKAGE ModuleType;                ///< Module type: UDIMM, SO-DIMM, etc.
+  UINT32         SdramCount;                ///< The number of SDRAM components on a DIMM.
+  UINT32         DimmCapacity;              ///< DIMM size in MBytes.
+  UINT32         RowSize;                   ///< The DIMMs row address size.
+  UINT16         ColumnSize;                ///< The DIMMs column address size.
+  UINT16         Crc;                       ///< Calculated CRC16 of the DIMM's provided SPD. Can be used to detect DIMM change.
+  UINT8          RankInDimm;                ///< The number of ranks in this DIMM.
+  UINT8          Banks;                     ///< Number of banks the DIMM contains.
+  UINT8          BankGroups;                ///< Number of bank groups the DIMM contains.
+  UINT8          PrimaryBusWidth;           ///< DIMM primary bus width.
+  UINT8          SdramWidth;                ///< DIMM SDRAM width.
+  UINT8          SdramWidthIndex;           ///< DIMM SDRAM width index (0 = x4, 1 = x8, 2 = x16, 3 = x32).
+  UINT8          DensityIndex;              ///< Total SDRAM capacity index (0 = 256Mb, 1 = 512Mb, 2 = 1Gb, etc).
+  UINT8          tMAC;                      ///< Maximum Activate Count for pTRR.
+  UINT8          ReferenceRawCard;          ///< Indicates which JEDEC reference design raw card was used as the basis for the module assembly.
+  UINT8          ReferenceRawCardRevision;  ///< Indicates which JEDEC reference design raw card revision.
+  UINT8          XmpSupport;                ///< Indicates if XMP profiles are supported. 0 = None, 1 = XMP1 only, 2 = XMP2 only, 3 = All.
+  UINT8          XmpRevision;               ///< Indicates the XMP revision of this DIMM. 0 = None, 12h = 1.2, 13h = 1.3.
+  MrcFrequency   Speed;                     ///< Max DIMM speed in the current profile - needed for SMBIOS.
+  MrcRankOut     Rank[MAX_RANK_IN_DIMM];    ///< The following are rank level definitions.
+} MrcDimmOut;
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are channel level definitions. All DIMMs on a memory channel are set to these values.
+///
+typedef struct {
+  MrcChannelSts       Status;                                                       ///< Indicates whether this channel should be used.
+  MrcVirtualChannel   VirtualChannel;                                               ///< define the virtual channel type A or B.
+  MrcTiming           Timing[MAX_PROFILE];                                          ///< The channel timing values.
+  MrcTimeBase         TimeBase[MAX_DIMMS_IN_CHANNEL][MAX_PROFILE];                  ///< Medium and fine timebases for each DIMM in the channel and each memory profile.
+  UINT32              Capacity;                                                     ///< Amount of memory in this channel, in MBytes.
+  UINT32              DimmCount;                                                    ///< Number of valid DIMMs that exist in the channel.
+  UINT32              DataOffsetTrain[MAX_SDRAM_IN_DIMM];                           ///< DataOffsetTrain CR
+  UINT32              DataCompOffset[MAX_SDRAM_IN_DIMM];                            ///< DataCompOffset CR
+  UINT32              CkeCmdPiCode[MAX_COMMAND_GROUPS];                             ///< CKE  CmdPiCode CR, per group
+  UINT32              CmdsCmdPiCode[MAX_COMMAND_GROUPS];                            ///< CmdS CmdPiCode CR, per group
+  UINT32              CmdnCmdPiCode[MAX_COMMAND_GROUPS];                            ///< CmdN CmdPiCode CR, per group
+  UINT16              TxDqs[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                ///< TxDQS PI Code
+  UINT16              TxDq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                 ///< TxDQ Pi Code
+  UINT16              RcvEn[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                ///< RcvEn PI Code
+  UINT16              WlDelay[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];              ///< WlDelay PI Code
+  UINT8               ClkPiCode[MAX_RANK_IN_CHANNEL];                               ///< Clk Pi Code
+  UINT8               CtlPiCode[MAX_RANK_IN_CHANNEL];                               ///< Ctl Pi Code
+  UINT8               CkePiCode[MAX_RANK_IN_CHANNEL];                               ///< Ctl Pi Code
+  UINT8               TxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                 ///< TxEq setting
+  MrcCommandMargin    Command[MAX_RANK_IN_CHANNEL];                                 ///< Cmd setting
+  MrcDqTimeMargin     RxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];     ///< Rx PerBit Pi Code
+  MrcDqTimeMargin     TxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];     ///< Tx PerBit Pi Code
+  MrcDqVrefMargin     RxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS]; ///< Rx PerBit Vref
+  MrcDqVrefMargin     TxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS]; ///< Rx PerBit Vref
+  MrcRecvEnMargin     ReceiveEnable[MAX_RANK_IN_CHANNEL];                           ///< Receive enable per rank
+  MrcWrLevelMargin    WriteLevel[MAX_RANK_IN_CHANNEL];                              ///< Write leveling per rank
+  UINT8               IoLatency[MAX_RANK_IN_CHANNEL];                               ///< IOLatency
+  UINT8               RTLatency[MAX_RANK_IN_CHANNEL];                               ///< RoundTripLatency
+  UINT32              RTIoComp;                                                     ///< RoundTrip IO Compensation of the Channel
+  UINT8               RxVref[MAX_SDRAM_IN_DIMM];                                    ///< RX Vref in steps of 7.9 mv
+  UINT8               RxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                 ///< RxEQ Setting
+  UINT8               RxDqsP[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];               ///< RxDQSP PI Code
+  UINT8               RxDqsN[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];               ///< RxDQSN PI Code
+  UINT8               ValidRankBitMask;                                             ///< Bit map of the populated ranks per channel
+  UINT8               ValidCkeBitMask;                                              ///< Bit map of the used CKE pins per channel
+  MrcDimmOut          Dimm[MAX_DIMMS_IN_CHANNEL];                                   ///< DIMM specific output variables.
+  MrcTurnaroundTimes  tRd2Rd;                                                       ///< The system's minimal delay timings for Read  command followed by Read  command.
+  MrcTurnaroundTimes  tRd2Wr;                                                       ///< The system's minimal delay timings for Read  command followed by Write command.
+  MrcTurnaroundTimes  tWr2Rd;                                                       ///< The system's minimal delay timings for Write command followed by Read  command.
+  MrcTurnaroundTimes  tWr2Wr;                                                       ///< The system's minimal delay timings for Write command followed by Write command.
+} MrcChannelOut;
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are memory controller level definitions. All channels on a controller are set to these values.
+///
+typedef struct {
+  MrcControllerSts Status;               ///< Indicates whether this controller should be used.
+  UINT16           DeviceId;             ///< The PCI device id of this memory controller.
+  UINT8            RevisionId;           ///< The PCI revision id of this memory controller.
+  UINT8            ChannelCount;         ///< Number of valid channels that exist on the controller.
+  MrcChannelOut    Channel[MAX_CHANNEL]; ///< The following are channel level definitions.
+} MrcControllerOut;
+
+///
+///********************************************
+/// Saved data related "global data" structures.
+///********************************************
+///
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are DIMM level definitions.
+///
+typedef struct {
+  UINT8 SpdDramDeviceType;       ///< Save SPD DramDeviceType information needed for SMBIOS structure creation.
+  UINT8 SpdModuleType;           ///< Save SPD ModuleType information needed for SMBIOS structure creation.
+  UINT8 SpdModuleMemoryBusWidth; ///< Save SPD ModuleMemoryBusWidth information needed for SMBIOS structure creation.
+  UINT8 SpdSave[MAX_SPD_SAVE];   ///< Save SPD Manufacturing information needed for SMBIOS structure creation.
+} MrcDimmSave;
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are channel level definitions.
+///
+typedef struct {
+  MrcChannelSts Status;                               ///< Indicates whether this channel should be used.
+  UINT32        DimmCount;                            ///< Number of valid DIMMs that exist in the channel.
+  UINT8         ValidRankBitMask;                     ///< Bit map of the populated ranks per channel
+  MrcTiming     Timing[MAX_PROFILE];                  ///< The channel timing values.
+  MrcDimmOut    Dimm[MAX_DIMMS_IN_CHANNEL];           ///< Save the DIMM output characteristics.
+  MrcDimmSave   DimmSave[MAX_DIMMS_IN_CHANNEL];       ///< Save SPD information needed for SMBIOS structure creation.
+} MrcChannelSave;
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are controller level definitions.
+///
+typedef struct {
+  MrcControllerSts  Status;               ///< Indicates whether this controller should be used.
+  UINT8             ChannelCount;         ///< Number of valid channels that exist on the controller.
+  MrcChannelSave    Channel[MAX_CHANNEL]; ///< The following are channel level definitions.
+} MrcContSave;
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are system level definitions.
+///
+typedef struct {
+  UINT32 Crc;                  ///< The CRC-32 of the data in this structure.
+} MrcSaveHeader;
+
+//
+// ------- IMPORTANT NOTE --------
+// MRC_MC_REGISTER_COUNT in MrcInterface.h should match the table in MrcSaveRestore.c.
+// Update this define whenever you add/remove registers from this table.
+//
+#define MRC_REGISTER_COUNT_COMMON (1376 / sizeof (UINT32)) ///< The number of MC registers that need to be saved (common)
+#define MRC_REGISTER_COUNT_SAGV   (1528 / sizeof (UINT32)) ///< The number of MC registers that need to be saved (per SA GV point)
+
+typedef struct {
+  MrcCapabilityId McCapId;                                   ///< The memory controller's capabilities.
+  UINT32          RegSaveCommon[MRC_REGISTER_COUNT_COMMON];  ///< The MC registers that are common to both SA GV points
+  UINT32          RegSaveLow[MRC_REGISTER_COUNT_SAGV];       ///< The MC registers for the Low SA GV point
+  UINT32          RegSaveHigh[MRC_REGISTER_COUNT_SAGV];      ///< The MC registers for the High SA GV point, or for SA GV Disabled case
+  UINT32          MeStolenSize;                              ///< The managebility engine memory size, in Mbyte units.
+  MrcCpuStepping  CpuStepping;                               ///< The last cold boot happended with this CPU stepping.
+  MrcCpuModel     CpuModel;                                  ///< The last cold boot happended with this CPU model.
+  MrcCpuFamily    CpuFamily;                                 ///< CPU is Coffeelake
+  MrcVersion      Version;                                   ///< The last cold boot happended with this MRC version.
+  UINT32          SaMemCfgCrc;                               ///< The CRC32 of the system agent memory configuration structure.
+  MrcContSave     Controller[MAX_CONTROLLERS];               ///< The following are controller level definitions.
+  MrcFrequency    FreqMax;                                   ///< The system's requested maximum frequency.
+  MrcFrequency    Frequency;                                 ///< The system's common memory controller frequency.
+  UINT32          MemoryClock;                               ///< The system's common memory controller clock, in femtoseconds.
+  BOOLEAN         OddRatioModeLow;                           ///< If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for SAGV Low point.
+  BOOLEAN         OddRatioModeHigh;                          ///< If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for SAGV High point, or SAGV disabled / fixed high / fixed low
+  MrcRefClkSelect RefClk;                                    ///< The memory controller is going to use this reference clock.
+  MrcClockRatio   Ratio;                                     ///< Request for this memory controller to use this clock ratio.
+  MrcVddSelect    VddVoltage[MAX_PROFILE];                   ///< The voltage (VDD) setting for all DIMMs in the system, per profile.
+  BOOLEAN         EccSupport;                                ///< TRUE if ECC is enabled and supported on this controller.
+  MrcDdrType      DdrType;                                   ///< DDR type: DDR3, DDR4, or LPDDR3
+  UINT32          DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1]; ///< The Default XMP tCK values read from SPD.
+  UINT8           XmpProfileEnable;                          ///< If XMP capable DIMMs are detected, this will indicate which XMP Profiles are common among all DIMMs.
+  BOOLEAN         BinnedLpddrDevices;                        ///< Binned LPDDR3 devices (6Gb/12Gb/etc)
+  BOOLEAN         TCRSensitiveHynixDDR4;                     ///< TCR sensitive Hynix DDR4 in the system
+  BOOLEAN         TCRSensitiveMicronDDR4;                    ///< TCR sensitive Micron DDR4 in the system
+  BOOLEAN         LpddrEctDone;                       ///< Set to TRUE once Early Command Training on LPDDR is done, and we can run JEDEC Init
+  UINT8           BerEnable;                          ///< BER Enable (and # of Addresses)
+  UINT64          BerAddress[4];                      ///< BER Addresses
+  BOOLEAN         DmfcLimitedBoard;                   ///< Indicates if the system has 2DPC Memory Configuration which should be DMFC limited.
+  BOOLEAN         DmfcLimited;                        ///< Indicates if the system has DMFC limited. Should only be set if DmfcLImitedBoard is TRUE.
+  BOOLEAN         MixedUDimmConfig2Dpc;               ///< Indicates if the system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
+  BOOLEAN         ExtendedDdrOverclock;               ///< Indicates if MC is capable of extended Overclock Memory frequencies.
+} MrcSaveData;
+
+typedef struct {
+  UINT32              Size;                        ///< The size of this structure, in bytes. Must be the first entry in this structure.
+  MrcDebug            Debug;                       ///< MRC debug related variables used for serial output and debugging purposes.
+  MrcVersion          Version;                     ///< The memory reference code version.
+  MrcFrequency        FreqMax;                     ///< The requested maximum valid frequency.
+  MrcFrequency        Frequency;                   ///< The system's common memory controller frequency.
+  UINT32              MemoryClockMax;              ///< The system's common memory controller maximum clock, in femtoseconds.
+  UINT32              MemoryClock;                 ///< The system's common memory controller clock, in femtoseconds.
+  MrcRefClkSelect     RefClk;                      ///< The memory controller is going to use this reference clock.
+  MrcClockRatio       Ratio;                       ///< Request for this memory controller to use this clock ratio.
+  MrcMemoryMap        MemoryMapData;               ///< The system's memory map data.
+  MrcGfxDataSize      GraphicsStolenSize;          ///< Graphics Data Stolen Memory size in MB
+  MrcGfxGttSize       GraphicsGttSize;             ///< GTT graphics stolen memory size in MB
+  MrcVddSelect        VddVoltage[MAX_PROFILE];     ///< The currently running voltage (VDD) setting for all DIMMs in the system, per profile.
+  MrcGdxc             Gdxc;                        ///< GDXC enable and size.
+  BOOLEAN             VddVoltageDone;              ///< To determine if VddVoltageDone update has been done already
+  BOOLEAN             EccSupport;                  ///< TRUE if ECC is enabled and supported on this controller.
+  BOOLEAN             EnDumRd;                     ///< Enable/Disable Logic Analyzer
+  BOOLEAN             RestoreMRs;                  ///< Enable/Disable restoring
+  BOOLEAN             LpddrEctDone;                ///< Set to TRUE once Early Command Training on LPDDR is done, and we can run JEDEC Init
+  BOOLEAN             LpddrWLUpdated;              ///< Set to TRUE once LPDDR WL Memory Set has been updated
+  BOOLEAN             JedecInitDone;               ///< Set to TRUE once JEDEC Init on LPDDR/DDR4 is done
+  UINT32              DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1];            ///< The Default XMP tCK values read from SPD.
+  UINT8               XmpProfileEnable;            ///< If XMP capable DIMMs are detected, this will indicate which XMP Profiles are common among all DIMMs.
+  BOOLEAN             Capable100;                  ///< The MC is capable of 100 reference clock (0 = no, 1 = yes).
+  BOOLEAN             AutoSelfRefresh;             ///< Indicates ASR is supported for all the DIMMS for 2xRefresh
+  MrcDdrType          DdrType;                     ///< Current memory type: DDR3, DDR4, or LPDDR3
+  MrcSpdStatus        SpdSecurityStatus;           ///< Status variable to inform BIOS that memory contains an alias.
+  UINT32              MrcTotalChannelLimit;        ///< The maximum allowed memory size per channel, in MBytes.
+  UINT8               SdramCount;                  ///< The number of SDRAM components on a DIMM.
+  UINT16              Qclkps;                      ///< Qclk period in pS
+  UINT8               DQPat;                       ///< Global Variables storing the current DQPat REUT Test
+  INT8                DQPatLC;                     ///< Global Variables storing the current DQPat Loopcount
+  UINT16              NumCL;                       ///< Global Variables storing the current number of Cachelines
+  UINT8               ValidRankMask;               ///< Rank bit map - includes both channels
+  UINT8               ValidChBitMask;              ///< Channel bit map of the populated channels
+  BOOLEAN             UpmPwrRetrainFlag;           ///< A flag that indicates if training with higher UPM/PWR limits.
+  UINT32              MarginResult[MAX_RESULT_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_EDGES]; ///< Stores last margin measurement.
+  BOOLEAN             MarginSignReversed[MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_EDGES]; ///< Indicates if the Margin Sign is Reversed
+  MrcOdtPowerSaving   OdtPowerSavingData;          ///< ODT power savings data.
+  BOOLEAN             TxDIMMVref[MAX_CHANNEL];     ///< Whether Write DIMM Vref is enabled based on Channel
+  UINT32              MchBarWriteCount;            ///< The number of MMIO writes performed during MRC execution.
+  UINT32              MchBarReadCount;             ///< The number of MMIO reads performed during MRC execution.
+  UINT8               BerEnable;                   ///< BER Enable (and # of Addresses)
+  UINT64              BerAddress[4];               ///< BER Addresses
+  UINT8               CmdVLoop;                    ///< Keeps track of the # of CmdV training step runned
+  UINT8               CmdVLoopStatus;              ///< Keeps the last status of the CmdV training step
+  UINT8               tMAC;                        ///< Maximum Activate Count for pTRR.
+  UINT8               LpddrMemWriteLatencySet;     ///< 0 = Set A (WL), 1 = Set B (WL) if supported
+  BOOLEAN             Ddr4PdaEnable;               ///< Current status of PDA - if true all the Mr6 operations need to use PDA mode.
+  BOOLEAN             BinnedLpddrDevices;          ///< Binned LPDDR3 devices (6Gb/12Gb/etc)
+  MrcControllerOut    Controller[MAX_CONTROLLERS]; ///< The following are controller level definitions.
+  BOOLEAN             TCRSensitiveHynixDDR4;       ///< TCR sensitive Hynix DDR4 in the system
+  BOOLEAN             TCRSensitiveMicronDDR4;      ///< TCR sensitive Micron DDR4 in the system
+  BOOLEAN             OddRatioMode;                ///< If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz
+  BOOLEAN             LpddrDramOdt;                ///< Indicates if LPDDR DRAM ODT is used - Only used for 2133+
+  BOOLEAN             ExtendedDdrOverclock;        ///< Indicates if MC is capable of extended Overclock Memory frequencies.
+  BOOLEAN             DmfcLimitedBoard;            ///< Indicates if the system has 2DPC Memory Configuration which should be DMFC limited.
+  BOOLEAN             DmfcLimited;                 ///< Indicates if the system has DMFC has been limited. Should only be set if DmfcLImitedBoard is TRUE.
+  BOOLEAN             MixedUDimmConfig2Dpc;        ///< Indicates if the system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
+#ifdef BDAT_SUPPORT
+  union {
+    MRC_BDAT_SCHEMA_LIST_HOB *Pointer;             ///< Pointer to the BDAT schema list.
+    UINT64                   Data;
+  } BdatSchemasHob;
+  union {
+    BDAT_MEMORY_DATA_HOB *Pointer;                 ///< Pointer to the BDAT memory data HOB.
+    UINT64               Data;
+  } BdatMemoryHob[MAX_SCHEMA_LIST_LENGTH];
+  UINT8               Margin2DResult[MAX_2D_EYE_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_2D_EYE_OFFSETS][MAX_EDGES]; ///< Stores the 2D Eye Margin
+#endif
+
+#ifdef UP_SERVER_FLAG
+  UINT8              ThermOffset[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];                        ///< TSOD Thermal Offset
+#endif
+} MrcOutput;
+
+///
+///****************************************
+/// Input related "global data" structures.
+///****************************************
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are SDRAM level definitions. All ranks on a rank are set to these values.
+///
+/* Commented out until needed, in order to save space.
+typedef struct {
+  UINT8  Placeholder;  ///< TODO: Is there anything that needs to go in here?
+} MrcSdramIn;
+*/
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are rank level definitions. All ranks on a DIMM are set to these values.
+///
+/* Commented out until needed, in order to save space.
+typedef struct {
+  MrcSdramIn  Sdram[MAX_SDRAM_IN_DIMM]; ///< The following are SDRAM level definitions.
+} MrcRankIn;
+*/
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are DIMM level definitions. All ranks on a DIMM are set to these values.
+///
+typedef struct {
+  MrcDimmSts  Status;                 ///< Indicates whether this DIMM should be used.
+  MrcSpdData  Spd;                    ///< The SPD data for each DIMM. SPDGeneral field = 0 when absent.
+  MrcTiming   Timing;                 ///< The DIMMs requested timing overrides.
+  UINT8       SpdAddress;             ///< The SMBus address for the DIMM's SPD data.
+//MrcRankIn   Rank[MAX_RANK_IN_DIMM]; ///< The following are rank level definitions.
+} MrcDimmIn;
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are channel level definitions. All DIMMs on a memory channel are set to these values.
+///
+typedef struct {
+  MrcChannelSts Status;                        ///< Indicates whether this channel should be used.
+  UINT32        DimmCount;                     ///< The maximum number of DIMMs on this channel.
+  MrcDimmIn     Dimm[MAX_DIMMS_IN_CHANNEL];    ///< The following are DIMM level definitions.
+  UINT8         DqsMapCpu2Dram[8];             ///< Mapping from CPU DQS pins to SDRAM DQS pins
+  UINT8         DqMapCpu2Dram[8][MAX_BITS];    ///< Mapping from CPU DQ pins to SDRAM DQ pins
+  UINT8         DQByteMap[MrcIterationMax][2]; ///< Maps which PI clocks are used by what LPDDR DQ Bytes (from CPU side), per group
+                                               ///< DQByteMap[0] - ClkDQByteMap:
+                                               ///<   If clock is per rank, program to [0xFF, 0xFF]
+                                               ///<   If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF]
+                                               ///<   If clock is shared by 2 ranks but does not go to all bytes,
+                                               ///<           Entry[i] defines which DQ bytes Group i services
+                                               ///< DQByteMap[1] - CmdNDQByteMap: Entry[0] is CmdN/CAA and Entry[1] is CmdN/CAB
+                                               ///< DQByteMap[2] - CmdSDQByteMap: Entry[0] is CmdS/CAA and Entry[1] is CmdS/CAB
+                                               ///< DQByteMap[3] - CkeDQByteMap : Entry[0] is CKE /CAA and Entry[1] is CKE /CAB
+                                               ///<                For DDR, DQByteMap[3:1] = [0xFF, 0]
+                                               ///< DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0] since we have 1 CTL / rank
+                                               ///<                               Variable only exists to make the code easier to use
+                                               ///< DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] since we have 1 CA Vref
+                                               ///<                               Variable only exists to make the code easier to use
+} MrcChannelIn;
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are memory controller level definitions. All channels on a controller are set to these values.
+///
+typedef struct {
+  MrcControllerSts  Status;               ///< Indicates whether this controller should be used.
+  UINT8             ChannelCount;         ///< Number of valid channels that are requested on the controller.
+  MrcChannelIn      Channel[MAX_CHANNEL]; ///< The following are channel level definitions.
+} MrcControllerIn;
+
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are system level definitions. All memory controllers in the system are set to these values.
+typedef struct {
+  // Start of synchronization to the SA MEMORY_CONFIGURATION structure.
+  // Alignment of this block must be maintained and field offsets must match.
+  UINT8   Header[28];             ///< Offset 0-27 Config Block Header
+  UINT16  Size;                   ///< Offset 28 The size of this structure, in bytes. Must be the first entry in this structure.
+  UINT8   HobBufferSize;          ///< Offset 30 Size of HOB buffer
+  UINT8   MemoryProfile;          ///< Offset 31 SPD XMP profile selection - for XMP supported DIMM: <b>0=Default DIMM profile</b>, 1=Customized profile, 2=XMP profile 1, 3=XMP profile 2.
+  // The following parameters are used only when MemoryProfile is UserDefined (CUSTOM PROFILE)
+  UINT16  tCL;                    ///< Offset 32 User defined Memory Timing tCL value,   valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 31=Maximum.
+  UINT16  tRCDtRP;                ///< Offset 34 User defined Memory Timing tRCD value (same as tRP), valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 63=Maximum.
+  UINT16  tRAS;                   ///< Offset 36 User defined Memory Timing tRAS value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 64=Maximum.
+  UINT16  tWR;                    ///< Offset 38 User defined Memory Timing tWR value,   valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, legal values: 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 24.
+  UINT16  tRFC;                   ///< Offset 40 User defined Memory Timing tRFC value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 1023=Maximum.
+  UINT16  tRRD;                   ///< Offset 42 User defined Memory Timing tRRD value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tWTR;                   ///< Offset 44 User defined Memory Timing tWTR value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+  UINT16  tRTP;                   ///< Offset 46 User defined Memory Timing tRTP value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum. DDR4 legal values: 5, 6, 7, 8, 9, 10, 12
+  UINT16  tFAW;                   ///< Offset 48 User defined Memory Timing tFAW value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 63=Maximum.
+  UINT16  tCWL;                   ///< Offset 50 User defined Memory Timing tCWL value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 20=Maximum.
+  UINT16  tREFI;                  ///< Offset 52 User defined Memory Timing tREFI value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 65535=Maximum.
+  UINT16  PciIndex;               ///< Offset 54 Pci index register address: <b>0xCF8=Default</b>
+  UINT16  PciData;                ///< Offset 56 Pci data register address: <b>0xCFC=Default</b>
+  UINT16  VddVoltage;             ///< Offset 58 DRAM voltage (Vdd) in millivolts: <b>0=Platform Default (no override)</b>, 1200=1.2V, 1350=1.35V etc.
+  UINT16  Idd3n;                  ///< Offset 60 EPG Active standby current (Idd3N) in milliamps from DIMM datasheet.
+  UINT16  Idd3p;                  ///< Offset 62 EPG Active power-down current (Idd3P) in milliamps from DIMM datasheet.
+
+  UINT32  EccSupport:1;                   ///< Offset 64 DIMM Ecc Support option - for Desktop only: 0=Disable, <b>1=Enable</b>
+  UINT32  MrcSafeConfig:1;                ///<  - MRC Safe Mode: <b>0=Disable</b>, 1=Enable
+  UINT32  RemapEnable:1;                  ///<  - This option is used to control whether to enable/disable memory remap above 4GB: 0=Disable, <b>1=Enable</b>.
+  UINT32  ScramblerEnable:1;              ///<  - Memory scrambler support: 0=Disable, <b>1=Enable</b>
+  UINT32  Vc1ReadMeter:1;                 ///<  - VC1 Read Metering Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  DdrThermalSensor:1;             ///<  - Ddr Thermal Sensor: 0=Disable, <b>1=Enable</b>
+  UINT32  LpddrMemWriteLatencySet:1;      ///<  - LPDDR3 Write Latency Set option: 0=Set A, <b>1=Set B</b>
+  UINT32  Off64Bits7to8Rsvd:2;            ///<  - Bits 7-8 Reserved
+  UINT32  SimicsFlag:1;                   ///<  - Option to Enable SIMICS: 0=Disable, <b>1=Enable</b>
+  UINT32  Ddr4DdpSharedClock:1;           ///<  - New Select if CLK0 is shared between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>, 1=Shared
+  UINT32  Ddr4DdpSharedZq:1;              ///<  - Select if ZQ pin is shared between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>, 1=Shared
+  // Thermal Management
+  UINT32  ThermalManagement:1;            ///<  - Memory Thermal Management Support: <b>0=Disable</b>, 1=Enable.
+  UINT32  PeciInjectedTemp:1;             ///<  - Enable/Disable memory temperatures to be injected to the processor via PECI: <b>0=Disable</b>, 1=Enable.
+  UINT32  ExttsViaTsOnBoard:1;            ///<  - Enable/Disable routing TS-on-Board's ALERT# and THERM# to EXTTS# pins on the PCH: <b>0=Disable</b>, 1=Enable.
+  UINT32  ExttsViaTsOnDimm:1;             ///<  - Enable/Disable routing TS-on-DIMM's ALERT# to EXTTS# pin on the PCH: <b>0=Disable</b>, 1=Enable.
+  UINT32  VirtualTempSensor:1;            ///<  - Enable/Disable Virtual Temperature Sensor (VTS): <b>0=Disable</b>, 1=Enable.
+  UINT32  Lp4DqsOscEn:1;                  ///<  - DqDqsReTraining support: 0=Disable, <b>1=Enable</b>
+  UINT32  DualDimmPerChannelBoardType:1;  ///<  - DualDimmPerChannelBoardType: Option to indicate if the Memory Design for the board includes two DIMMs per channel: <b>0=Single DIMM Design</b>, 1=Dual DIMM Design
+  UINT32  ReservedBits1:13;
+  /**
+   Disables a DIMM slot in the channel even if a DIMM is present\n
+   Array index represents the channel number (0 = channel 0, 1 = channel 1)\n
+     <b>0x0 = DIMM 0 and DIMM 1 enabled</b>\n
+     0x1 = DIMM 0 disabled, DIMM 1 enabled\n
+     0x2 = DIMM 0 enabled, DIMM 1 disabled\n
+     0x3 = DIMM 0 and DIMM 1 disabled (will disable the whole channel)\n
+  **/
+  UINT8   DisableDimmChannel[MAX_CHANNEL];  ///< Offset 68
+  /**
+   Selects the ratio to multiply the reference clock by for the DDR frequency\n
+   When RefClk is 133MHz\n
+   <b>0x00 = Auto</b>, 0x03 through 0x0C are valid values, all others are invalid\n
+   When RefClk is 100MHz\n
+   <b>0x00 = Auto</b>, 0x06 through 0x10 are valid values, all others are invalid\n
+  **/
+  UINT8   Ratio;                  ///< Offset 70
+  UINT8   ProbelessTrace;         ///< Offset 71 Probeless Trace: <b>0=Disabled</b>, <b>1=Enabled</b>
+  UINT32  BClkFrequency;          ///< Offset 72 Base reference clock value, in Hertz: <b>100000000 = 100Hz</b>, 125000000=125Hz, 167000000=167Hz, 250000000=250Hz
+  /**
+     - Channel Hash Enable.\n
+    NOTE: BIT7 will interleave the channels at a 2 cacheline granularity, BIT8 at 4 and BIT9 at 8\n
+    0=BIT6, <B>1=BIT7</B>, 2=BIT8, 3=BIT9
+  **/
+  UINT8   ChHashInterleaveBit;    ///< Offset 76
+  UINT8   EnergyScaleFact;        ///< Offset 77 - Energy Scale Factor. 0=Minimal, 7=Maximum, <b>4=Default</b>
+  UINT8   Reserved0;              ///< Offset 78 - Reserved for future use.
+  UINT8   McLock;                 ///< Offset 79 - Enable/Disable memory configuration register locking: 0=Disable, <b>1=Enable</b>.
+  // Training Algorithms
+  TrainingStepsEn TrainingEnables;    ///< Offset 80 - Options to Enable individual training steps
+  TrainingStepsEn2 TrainingEnables2;  ///< Offset 84 - Options to Enable individual training steps
+
+  UINT32  OddRatioMode:1;             ///< Offset 88 - If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz: <b>0=Disable</b>, 1=Enable
+  UINT32  MrcTimeMeasure:1;           ///< - Enables serial debug level to display the MRC execution times only: <b>0=Disable</b>, 1=Enable
+  UINT32  MrcFastBoot:1;              ///< - Enables the MRC fast boot path for faster cold boot execution: 0=Disable, <b>1=Enable</b>
+  UINT32  DqPinsInterleaved:1;        ///< - Interleaving mode of DQ/DQS pins for HSW_ULT which depends on board routing: <b>0=Disable</b>, 1=Enable
+  UINT32  RankInterleave:1;           ///< - Rank Interleave Mode: 0=Disable, <b>1=Enable</b>
+  UINT32  EnhancedInterleave:1;       ///< - Enhanced Interleave Mode: 0=Disable, <b>1=Enable</b>
+  UINT32  WeaklockEn:1;               ///< - Weak Lock Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  CmdTriStateDis:1;           ///< - CMD Tri-State Support: <b>0=Enable</b>, 1=Disable. Note: This should be set to 1 (Disable) if Command RTT is not present on the platform.
+  UINT32  MemoryTrace:1;              ///< - Memory Trace to second DDR channel using Stacked Mode: <b>0=Disable</b>, 1=Enable
+  UINT32  ChHashEnable:1;             ///< - Channel Hash Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  EnableExtts:1;              ///< - Enable Extts: <b>0=Disable</b>, 1=Enable
+  UINT32  EnableCltm:1;               ///< - Enable Closed Loop Thermal Management: <b>0=Disable</b>, 1=Enable
+  UINT32  EnableOltm:1;               ///< - Enable Open Loop Thermal Management: <b>0=Disable</b>, 1=Enable
+  UINT32  EnablePwrDn:1;              ///< - Enable Power Down control for DDR: 0=PCODE control, <b>1=BIOS control</b>
+  UINT32  EnablePwrDnLpddr:1;         ///< - Enable Power Down for LPDDR: 0=PCODE control, <b>1=BIOS control</b>
+  UINT32  LockPTMregs:1;              ///< - Lock PCU Thermal Management registers: 0=Disable, <b>1=Enable</b>
+  UINT32  UserPowerWeightsEn:1;       ///< - Allows user to explicitly set power weight, scale factor, and channel power floor values: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim2Lock:1;             ///< - Lock DDR_RAPL_LIMIT register: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim2Ena:1;              ///< - Enable Power Limit 2: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim1Ena:1;              ///< - Enable Power Limit 1: <b>0=Disable</b>, 1=Enable
+  UINT32  SrefCfgEna:1;               ///< - Enable Self Refresh: 0=Disable, <b>1=Enable</b>
+  UINT32  ThrtCkeMinDefeatLpddr:1;    ///< - Throttler CKE min defeature for LPDDR: 0=Disable, <b>1=Enable</b>
+  UINT32  ThrtCkeMinDefeat:1;         ///< - Throttler CKE min defeature: <b>0=Disable</b>, 1=Enable
+  UINT32  AutoSelfRefreshSupport:1;   ///< - FALSE = No auto self refresh support, <b>TRUE = auto self refresh support</b>
+  UINT32  ExtTemperatureSupport:1;    ///< - FALSE = No extended temperature support, <b>TRUE = extended temperature support</b>
+  UINT32  MobilePlatform:1;           ///< - Memory controller device id indicates: <b>TRUE if mobile</b>, FALSE if not. Note: This will be auto-detected and updated.
+  UINT32  Force1Dpc:1;                ///< - TRUE means force one DIMM per channel, <b>FALSE means no limit</b>
+  UINT32  ForceSingleRank:1;          ///< - TRUE means use Rank0 only (in each DIMM): <b>0=Disable</b>, 1=Enable
+  UINT32  RhPrevention:1;             ///< - RH Prevention Enable/Disable: 0=Disable, <b>1=Enable</b>
+  UINT32  VttTermination:1;           ///< - Vtt Termination for Data ODT: <b>0=Disable</b>, 1=Enable
+  UINT32  VttCompForVsshi:1;          ///< - Enable/Disable Vtt Comparator For Vsshi: <b>0=Disable</b>, 1=Enable
+  UINT32  ExitOnFailure:1;            ///< - MRC option for exit on failure or continue on failure: 0=Disable, <b>1=Enable</b>
+
+  UINT32  VddSettleWaitTime;      ///< Offset 92 - Amount of time in microseconds to wait for Vdd to settle on top of 200us required by JEDEC spec: <b>Default=0</b>
+  UINT16  FreqSaGvLow;            ///< Offset 96 - SA GV: 0 is Auto/default, otherwise holds the frequency value: <b>0=Default</b>, 1067, 1200, 1333, 1400, 1600, 1800, 1867.
+  UINT16  SrefCfgIdleTmr;         ///< Offset 98 - Self Refresh idle timer: <b>512=Minimal</b>, 65535=Maximum
+  UINT8   RhActProbability;       ///< Offset 100 - Activation probability for Hardware RHP
+  UINT8   SmramMask;              ///< Offset 101 - Reserved memory ranges for SMRAM
+  UINT16  Vc1ReadMeterThreshold;  ///< Offset 102 - VC1 Read Meter Threshold (within Time Window): 0=Minimal, 0xFFFF=Maximum, <b>0x118=Default</b>
+  UINT32  Vc1ReadMeterTimeWindow; ///< Offset 104 - VC1 Read Meter Time Window: 0=Minimal, 0x1FFFF=Maximum, <b>0x320=Default</b>
+  UINT64  BerAddress[4];          ///< Offset 108 - 139 BER Address(es): <b>0=Minimal</b>, 0xFFFFFFFFFFFFFFFF=Maximum (step is 0x40)
+
+  UINT16  ChHashMask;             ///< Offset 140 - Channel Hash Mask: 0x0001=BIT6 set(Minimal), 0x3FFF=BIT[19:6] set(Maximum), <b>0x30CE= BIT[19:18, 13:12 ,9:7] set</b>
+  UINT16  DdrFreqLimit;           ///< Offset 142 - Memory Frequency Limit: <b>0=Auto (limited by SPD/CPU capability)</b>, for valid values see MrcFrequency in MrcInterface.h
+  ThermalMngmtEn  ThermalEnables; ///< Offset 144 - 187
+
+  UINT8   MaxRttWr;               ///< Offset 188 - Maximum DIMM RTT_WR to use in power training: <b>0=ODT Off</b>, 1 = 120 ohms
+  UINT8   ThrtCkeMinTmr;          ///< Offset 189 - Throttler CKE min timer: 0=Minimal, 0xFF=Maximum, <b>0x30=Default</b>
+  UINT8   ThrtCkeMinTmrLpddr;     ///< Offset 190 - Throttler CKE min timer for LPDDR: 0=Minimal, 0xFF=Maximum, <b>0x40=Default</b>
+  UINT8   BerEnable;              ///< Offset 191 - BER Enable and # of Addresses passed in: <b>0=Minimal</b>, 8=Maximum
+  UINT8   CkeRankMapping;         ///< Offset 192 - Bits [7:4] - Channel 1, bits [3:0] - Channel 0. <b>0xAA=Default</b> Bit [i] specifies which rank CKE[i] goes to.
+  UINT8   StrongWkLeaker;         ///< Offset 193 - Strong Weak Leaker: 1=Minimal, <b>7=Maximum</b>
+  UINT8   CaVrefConfig;           ///< Offset 194 - 0=VREF_CA goes to both CH_A and CH_B, 1=VREF_CA to CH_A, VREF_DQ_A to CH_B, <b>2=VREF_CA to CH_A, VREF_DQ_B to CH_B</b>
+  UINT8   SaGv;                   ///< Offset 195 - SA GV: <b>0=Disabled</b>, 1=FixedLow, 2=FixedHigh, 3=Enabled
+  UINT8   RaplPwrFlCh1;           ///< Offset 196 - Power Channel 1 Floor value: <b>0=Minimal</b>, 255=Maximum
+  UINT8   RaplPwrFlCh0;           ///< Offset 197 - Power Channel 0 Floor value: <b>0=Minimal</b>, 255=Maximum
+  UINT8   NModeSupport;           ///< Offset 198 - Memory N Mode Support - Enable user to select Auto, 1N or 2N: <b>0=AUTO</b>, 1=1N, 2=2N.
+  UINT8   RefClk;                 ///< Offset 199 - Selects the DDR base reference clock. 0x01 = 100MHz, <b>0x00 = 133MHz</b>
+  UINT8   EnCmdRate;              ///< Offset 200 - CMD Rate Enable: 0=Disable, 1=1 CMD, 2=2 CMDs, <b>3=3 CMDs</b>, 4=4 CMDs, 5=5 CMDs, 6=6 CMDs, 7=7 CMDs
+  UINT8   Refresh2X;              ///< Offset 201 - Refresh 2x: <b>0=Disable</b>, 1=Enable for WARM or HOT, 2=Enable for HOT only
+  UINT8   EpgEnable;              ///< Offset 202 - Enable Energy Performance Gain.
+  UINT8   RhSolution;             ///< Offset 203 - Type of solution to be used for RHP - 0/1 = HardwareRhp/Refresh2x
+  UINT8   UserThresholdEnable;    ///< Offset 204 - Flag to manually select the DIMM CLTM Thermal Threshold, 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   UserBudgetEnable;       ///< Offset 205 - Flag to manually select the Budget Registers for CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   TsodTcritMax;           ///< Offset 206 - TSOD Tcrit Maximum Value  to be Configure , 0=Minimal, 128=Maximum, , <b>105=Default</b>
+
+  UINT8   TsodEventMode;          ///< Offset 207 - Flag to Enable Event Mode Interruption in TSOD Configuration Register, 0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodEventPolarity;      ///< Offset 208 - Event Signal Polarity in TSOD Configuration Register, 0=Low,  1=High, <b>0=Default</b>
+  UINT8   TsodCriticalEventOnly;  ///< Offset 209 - Critical Trigger Only in TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodEventOutputControl; ///< Offset 210 - Event Output Control in TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodAlarmwindowLockBit; ///< Offset 211 - Alarm Windows Lock Bit in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
+  UINT8   TsodCriticaltripLockBit;///< Offset 212 - Critical Trip Lock Bit in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
+  UINT8   TsodShutdownMode;       ///< Offset 213 - Shutdown Mode TSOD Configuration Register,0=Enable,  1=Disable, <b>0=Default</b>
+  UINT8   TsodThigMax;            ///< Offset 214 - Thigh Max Value In the  for CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   TsodManualEnable;       ///< Offset 215 - Flag to manually select the TSOD Register Values , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   DllBwEn0;               ///< Offset 216 - DllBwEn value for 1067
+  UINT8   DllBwEn1;               ///< Offset 217 - DllBwEn value for 1333
+  UINT8   DllBwEn2;               ///< Offset 218 - DllBwEn value for 1600
+  UINT8   DllBwEn3;               ///< Offset 219 - DllBwEn value for 1867 and up
+  UINT8   RetrainOnFastFail;      ///< Offset 220 - Restart MRC in Cold mode if SW MemTest fails during Fast flow. 0 = Disabled, <b>1 = Enabled</b>
+  UINT8   ForceOltmOrRefresh2x;   ///< Offset 221 - Force OLTM or 2X Refresh when needed. <b>0 = Force OLTM</b>, 1 = Force 2x Refresh
+  UINT8   PowerDownMode;          ///< Offset 222 - CKE Power Down Mode: <b>0xFF=AUTO</b>, 0=No Power Down, 1= APD mode, 6=PPD-DLL Off mode
+  UINT8   PwdwnIdleCounter;       ///< Offset 223 - CKE Power Down Mode Idle Counter: 0=Minimal, 255=Maximum, <b>0x80=0x80 DCLK</b>
+  UINT8   IsvtIoPort;             ///< Offset 224 ISVT IO Port Address: 0=Minimal, 0xFF=Maximum, <b>0x99=Default</b>
+  UINT8   Reserved3;              ///< Offset 225 -  ConfigBlock size must be a multiple of DWORDs
+  MrcGdxc Gdxc;                   ///< Offset 226 - 228 - GDXC enable and size.
+  UINT8   RMTLoopCount;           ///< Offset 229 - Indicates the Loop Count to be used for Rank Margin Tool Testing: 1=Minimal, 32=Maximum, 0=AUTO, <b>0=Default</b>
+  UINT8   Reserved4[2];           ///< Offset 230 - 231 Reserved for DWORD alignment.
+  UINT32  RmtPerTask:1;                 ///< Offset 232 Bit 0: Rank Margin Tool Per Task. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  Off232Bit1Rsvd:2;             ///< Offset 232 Bit 1-2: Reserved
+  UINT32  EnBER:1;                      ///< Offset 232 Bit 3: Define if EnBER is enabled for Rank Margin Tool
+  UINT32  Ddr4MixedUDimm2DpcLimit:1;    ///< Offset 232 Bit 4: Enable/Disable 2667 Frequency Limitation for DDR4 U-DIMM Mixed Dimm 2DPC population. 0 = Disabled, <b>1 = Enabled</b>
+  UINT32  FastBootRmt:1;                ///< Offset 232 Bit 5: Enable/Disable RMT on FastBoot. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  MrcTrainOnWarm:1;             ///< Offset 232 Bit 6: Enalbes MRC trainin on warm boot : <b>0=Disable</b>, 1 = Enabled
+  UINT32  LongFlyByModeEnabled:1;       ///< Offset 232 Bit 7: Long FlyBy Mode Enabled : <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  Off232RsvdBits:24;            ///< Offset 232 Bit 8-31: Reserved
+
+  //
+  // TurnAround Timing
+  //
+  MrcTurnaroundTimes tRd2Rd;      ///< Offset 236 - User-defined overrides for Read-to-Read   Turn Around Timings. <b>0 = AUTO</b>
+  MrcTurnaroundTimes tRd2Wr;      ///< Offset 240 - User-defined overrides for Read-to-Write  Turn Around Timings. <b>0 = AUTO</b>
+  MrcTurnaroundTimes tWr2Rd;      ///< Offset 244 - User-defined overrides for Write-to-Read  Turn Around Timings. <b>0 = AUTO</b>
+  MrcTurnaroundTimes tWr2Wr;      ///< Offset 248 - User-defined overrides for Write-to-Write Turn Around Timings. <b>0 = AUTO</b>
+  UINT16  tRRD_L;                 ///< Offset 252 - User defined DDR4 Memory Timing tRRD_L value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tRRD_S;                 ///< Offset 254 - User defined DDR4 Memory Timing tRRD_S value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tWTR_L;                 ///< Offset 266 - User defined DDR4 Memory Timing tWTR_L value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+  UINT16  tWTR_S;                 ///< Offset 268 - User defined DDR4 Memory Timing tWTR_S value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+
+  //
+  // End of synchronization to the SA MEMORY_CONFIGURATION structure.
+  //
+  MrcFrequency     FreqMax;                     ///< The requested maximum valid frequency.
+  MrcBoardType     BoardType;                   ///< Define the board type (CRBMB,CRBDT,User1,User2). the OEM can add more boards.
+  MrcCpuStepping   CpuStepping;                 ///< Define the CPU stepping.
+  MrcCpuModel      CpuModel;                    ///< Define the CPU model.
+  MrcCpuFamily     CpuFamily;                   ///< CPU is Coffeelake
+  MrcGfxDataSize   GraphicsStolenSize;          ///< Graphics Data Stolen Memory size in MB
+  MrcGfxGttSize    GraphicsGttSize;             ///< GTT graphics stolen memory size in MB
+  MrcBaseTime      BaseTime;                    ///< RTC base time.
+  MrcIteration     Iteration;                   ///< Number of iterations thru the MRC core call table.
+  MrcMode          MrcMode;                     ///< The control for full or MiniBIOS MRC.
+  MrcBootMode      BootMode;                    ///< The requested memory controller boot mode.
+  BOOLEAN          TxtFlag;                     ///< Trusted eXecution Technology flag.
+  BOOLEAN          SetRxDqs32;                  ///< Set DQS Delay to 32 control.
+  BOOLEAN          GfxIsVersatileAcceleration;  ///< iGFX engines are in Versatile Acceleration
+  BOOLEAN          DDR4MAP;                     ///< DDR4 PDA Mapping training control.
+  POINTER_STRUCT   SaMemCfgAddress;             ///< Starting address of the input parameters to CRC.
+  UINT32           SaMemCfgSize;                ///< The size of the input parameters to CRC.
+  UINT32           PciEBaseAddress;             ///< define the PciE base address.
+  UINT32           MchBarBaseAddress;           ///< define the MCH bar base address.
+  UINT32           SmbusBaseAddress;            ///< This field defines the smbus base address.
+  UINT32           GdxcBaseAddress;             ///< This field defines the GDXC base address.
+  UINT32           HpetBaseAddress;             ///< This field defines the hpet base address.
+  UINT32           MeStolenSize;                ///< define the size that the ME need in MB.
+  UINT32           MmioSize;                    ///< define the MMIO size in MB.
+  UINT32           TsegSize;                    ///< TSEG size that require by the system in MB.
+  UINT32           IedSize;                     ///< IED size that require by the system in MB.
+  UINT32           DprSize;                     ///< DPR size required by system in MB.
+  UINT32           PrmrrSize;                   ///< Prmrr size required by the system in MB.
+  POINTER_STRUCT   SerialBuffer;                ///< Pointer to the start of the serial buffer.
+  UINT32           SerialBufferSize;            ///< The size of the serial buffer, in bytes.
+  UINT32           DebugStream;                 ///< The debug port pointer.
+  INT32            DebugLevel;                  ///< Indicates the level of debug messaging.
+  UINT16           VccIomV;                     ///< VccIO logic voltage in mV.
+  MrcControllerIn  Controller[MAX_CONTROLLERS]; ///< The following are controller level definitions.
+  UINT32           HeapBase;                    ///< Starting address of the heap space.
+  UINT32           HeapSize;                    ///< Size of the heap space, in bytes.
+  UINT32           MrcStackTop;                 ///< Top of the stack at the beginning of MRC, for stack usage calculations.
+  BOOLEAN          BdatEnable;                  ///< Option to enable output of training results into BDAT.
+  UINT8            BdatTestType;                ///< When BdatEnable is set to TRUE, this option selects the type of training results data which will be populated into BDAT: <b>0=RMT</b>, 1=RMT Per Bit, 2=Margin 2D.
+  BOOLEAN          LpddrDramOdt;                ///< TRUE if LPDDR DRAM ODT is used - depends on board design
+  BOOLEAN          Ddr3DramOdt;                 ///< TRUE if DDR3  DRAM ODT is used - depends on board design
+  BOOLEAN          Ddr4DramOdt;                 ///< TRUE if DDR4  DRAM ODT is used - depends on board design
+  BOOLEAN          EnableVrefPwrDn;             ///< Setting this limits VrefGen to be off only during CKEPowerDown
+  BOOLEAN          TxEqDis;                     ///< Disable TX Equalization
+  BOOLEAN          EnVttOdt;                    ///< Enable VTT Termination for Data ODT
+  UINT32           CpuidModel;                  ///< Unique CPU identifier.
+  UINT8            CpuidStepping;               ///< Revision of the CPU.
+  UINT8            CpuidSku;                    ///< SKU of the CPU.
+  UINT32           SiPreMemPolicyPpi;
+  TrainingModeType PowerTrainingMode;           ///< 0 - Power Training. 1 - Margin Training.
+  union {
+    MRC_FUNCTION  *Func;                        ///< External to MRC function pointers
+    UINT64        Data;
+  } Call;
+  UINT16          RcompResistor[MAX_RCOMP];     ///< Reference RCOMP resistors on motherboard
+  UINT16          RcompTarget[MAX_RCOMP_TARGETS]; ///< RCOMP target values for DqOdt, DqDrv, CmdDrv, CtlDrv, ClkDrv
+  UINT32          CleanMemory:1;                ///< TRUE to request a memory clean
+  UINT32          OcSupport:1;                  ///< TRUE if Overclocking is enabled in BIOS
+  UINT32          RsvdBits5:30;
+  /**
+   Sets the serial debug message level\n
+     0x00 = Disabled\n
+     0x01 = Errors only\n
+     0x02 = Errors and Warnings\n
+     <b>0x03 = Errors, Warnings, and Info</b>\n
+     0x04 = Errors, Warnings, Info, and Events\n
+     0x05 = Displays Memory Init Execution Time Summary only\n
+  **/
+  UINT8           SerialDebugLevel;
+} MrcInput;
+
+typedef struct {
+  UINT32        Size;   ///< The size of this structure, in bytes. Must be the first entry in this structure.
+  MrcSaveHeader Header; ///< The header portion of the MRC saved data.
+  MrcSaveData   Data;   ///< The data portion of the MRC saved data.
+} MrcSave;
+
+typedef struct {
+  // Global variables that will be copied to the HOB follow.
+  UINT8        MrcDataString[4]; ///< Beginning of global data marker, starts with "MRC". Must be the first entry in this structure.
+  UINT32       MrcDataSize;      ///< The size of the MRC global data area, in bytes. Must be the second entry in this structure.
+  MrcSave      Save;             ///< System specific save variables.
+  MrcInput     Inputs;           ///< System specific input variables.
+  MrcOutput    Outputs;          ///< System specific output variables.
+
+  // Global variables that will remain internal to the MRC library follow.
+  union {
+    void   *Internal; ///< System specific output variables that remain internal to the library.
+    UINT64 Data;
+  } IntOutputs;
+} MrcParameters;
+
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h
new file mode 100644
index 0000000000..9dd9b096ba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h
@@ -0,0 +1,203 @@
+/** @file
+  Copies the memory related timing and configuration information into the
+  Compatible BIOS data (BDAT) table.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcRmtData_h_
+#define _MrcRmtData_h_
+
+#include "MrcTypes.h"
+
+#define VDD_1_350             1350                      ///< VDD in millivolts
+#define VDD_1_500             1500                      ///< VDD in millivolts
+#define PI_STEP_BASE          2048                      ///< Magic number from spec
+#define PI_STEP_INTERVAL      128                       ///< tCK is split into this amount of intervals
+#define PI_STEP               ((PI_STEP_BASE) / (PI_STEP_INTERVAL))
+#define VREF_STEP_BASE        100                       ///< Magic number from spec
+#define TX_VREF_STEP          7800                      ///< TX Vref step in microvolts
+#define TX_VREF(VDD)          (((TX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD)) ///< VDD passed in is in millivolts
+#define RX_VREF_STEP          8000                      ///< TX Vref step in microvolts
+#define RX_VREF(VDD)          (((RX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD)) ///< VDD passed in is in millivolts
+#define CA_VREF_STEP          8000                      ///< TX Vref step in microvolts
+#define CA_VREF(VDD)          (((CA_VREF_STEP) * (VREF_STEP_BASE)) / (VDD)) ///< VDD passed in is in millivolts
+
+#define MAX_SPD_RMT           512                       ///< The maximum amount of data, in bytes, in an SPD structure.
+#define RMT_PRIMARY_VERSION   4                         ///< The BDAT structure that is currently supported.
+#define RMT_SECONDARY_VERSION 0                         ///< The BDAT structure that is currently supported.
+#define MAX_MODE_REGISTER     7                         ///< Number of mode registers
+#define MAX_DRAM_DEVICE       9                         ///< Maximum number of memory devices
+#define MAX_2D_EYE_TYPE       2                         ///< Maximum number of supported Margin 2D Eye Types
+#define MAX_2D_EYE_OFFSETS    7                         ///< Number of 2D Eye Offsets
+
+//
+// Warning: Bdat4.h has its own copy of this #define
+// make sure to change it in both places
+//
+#define MAX_SCHEMA_LIST_LENGTH (10)
+
+
+#ifdef BDAT_SUPPORT
+/*
+  BSSA result Memory Schema GUID
+  {8F4E928-0F5F-46D4-8410-479FDA279DB6}
+*/
+extern EFI_GUID gSsaBiosResultsGuid;
+/*
+  RMT Results Metadata GUID
+  {02CB1552-D659-4232-B51F-CAB1E11FCA87}
+*/
+extern EFI_GUID gRmtResultMetadataGuid;
+/*
+  RMT Results Columns GUID
+  {0E60A1EB-331F-42A1-9DE7-453E84761154}
+*/
+extern EFI_GUID gRmtResultColumnsGuid;
+
+/*
+Margin2D Results Metadata GUID
+{48265582-8E49-4AC7-AA06-E1B9A74C9716}
+*/
+extern EFI_GUID gMargin2DResultMetadataGuid;
+/*
+Margin2D Results Columns GUID
+{91A449EC-8A4A-4736-AD71-A3F6F6D752D9}
+*/
+extern EFI_GUID gMargin2DResultColumnsGuid;
+
+#endif
+/*
+ GUID for Schema List HOB
+ This is private GUID used by MemoryInit internally.
+ {3047C2AC-5E8E-4C55-A1CB-EAAD0A88861B}
+*/
+extern EFI_GUID gMrcSchemaListHobGuid;
+
+#pragma pack(push, 1)
+
+
+///
+/// SSA results buffer header.
+///
+typedef struct {
+  UINT32  Revision;
+  BOOLEAN TransferMode;
+  struct {
+    UINT32   Reserved;
+    UINT32   MetadataSize;
+    EFI_GUID MetadataType;
+  } MdBlock;
+  struct {
+    UINT32   Reserved;
+    EFI_GUID ResultType;
+    UINT32   ResultElementSize;
+    INT32    ResultCapacity;
+    INT32    ResultElementCount;
+  } RsBlock;
+} RESULTS_DATA_HDR;
+
+// start auto-generated by the BSSA CCK sourced from the result xml files.
+typedef enum {
+  DisableScrambler = 0,
+  EnableScrambler = 1,
+  DontTouchScrambler = 2,
+  SCRAMBLER_OVERRIDE_MODE_DELIM = MRC_INT32_MAX
+} SCRAMBLER_OVERRIDE_MODE;
+
+typedef struct _RMT_RESULT_METADATA {
+  BOOLEAN EnableCtlAllMargin;
+  UINT16 SinglesBurstLength;
+  UINT32 SinglesLoopCount;
+  UINT16 TurnaroundsBurstLength;
+  UINT32 TurnaroundsLoopCount;
+  SCRAMBLER_OVERRIDE_MODE ScramblerOverrideMode;
+  UINT8 PiStepUnit[2];
+  UINT16 RxVrefStepUnit[2];
+  UINT16 TxVrefStepUnit[2][2];
+  UINT16 CmdVrefStepUnit[2][2];
+  UINT8 MajorVer;
+  UINT8 MinorVer;
+  UINT8 RevVer;
+  UINT32 BuildVer;
+  UINT16 ResultEleCount;
+} RMT_RESULT_METADATA;
+
+
+typedef struct _RMT_RESULT_ROW_HEADER {
+  UINT32 ResultType : 5;
+  UINT32 Socket : 3;
+  UINT32 Controller : 2;
+  UINT32 Channel : 3;
+  UINT32 DimmA : 1;
+  UINT32 RankA : 3;
+  UINT32 DimmB : 1;
+  UINT32 RankB : 3;
+  UINT32 Lane : 8;
+  UINT32 IoLevel : 1;
+  UINT32 Reserved : 2;
+} RMT_RESULT_ROW_HEADER;
+
+typedef struct _RMT_RESULT_COLUMNS {
+  RMT_RESULT_ROW_HEADER Header;
+  UINT8 Margin[4][2];
+} RMT_RESULT_COLUMNS;
+
+// end of auto-generated by the BSSA CCK sourced from the result xml files.
+
+typedef struct _BASE_RMT_RESULT {
+  RESULTS_DATA_HDR              ResultsHeader;
+  RMT_RESULT_METADATA           Metadata;
+  RMT_RESULT_COLUMNS            Rows[1];
+} BASE_RMT_RESULT;
+
+
+typedef struct {
+  UINT32                      Data1;
+  UINT16                      Data2;
+  UINT16                      Data3;
+  UINT8                       Data4[8];
+} BDAT_EFI_GUID;
+
+typedef struct {
+  UINT16  HobType;
+  UINT16  HobLength;
+  UINT32  Reserved;
+} BDAT_HOB_GENERIC_HEADER;
+
+typedef struct {
+  BDAT_HOB_GENERIC_HEADER  Header;
+  BDAT_EFI_GUID            Name;
+  ///
+  /// Guid specific data goes here
+  ///
+} BDAT_HOB_GUID_TYPE;
+
+typedef struct {
+  BDAT_EFI_GUID               SchemaId;                         ///< The GUID uniquely identifies the format of the data contained within the structure.
+  UINT32                      DataSize;                         ///< The total size of the memory block, including both the header as well as the schema specific data.
+  UINT16                      Crc16;                            ///< Crc16 is computed in the same manner as the field in the BDAT_HEADER_STRUCTURE.
+} MRC_BDAT_SCHEMA_HEADER_STRUCTURE;
+
+typedef struct {
+  MRC_BDAT_SCHEMA_HEADER_STRUCTURE SchemaHeader;                ///< The schema header.
+  BASE_RMT_RESULT          RMT_RESULTS_WITH_META_COLUMNS;
+} BDAT_MEMORY_DATA_STRUCTURE;
+
+typedef struct {
+  BDAT_HOB_GUID_TYPE          HobGuidType;
+  BDAT_MEMORY_DATA_STRUCTURE  MemorySchema;
+} BDAT_MEMORY_DATA_HOB;
+
+#pragma pack (pop)
+
+typedef struct {
+  BDAT_HOB_GUID_TYPE          HobGuidType;
+  UINT16                      SchemaHobCount;
+  UINT16                      Reserved;
+  BDAT_EFI_GUID               SchemaHobGuids[MAX_SCHEMA_LIST_LENGTH];
+} MRC_BDAT_SCHEMA_LIST_HOB;
+
+#endif //_MrcRmtData_h_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h
new file mode 100644
index 0000000000..45de5084c0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h
@@ -0,0 +1,1167 @@
+/** @file
+  SPD data format header file.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcSpdData_h_
+#define _MrcSpdData_h_
+#pragma pack (push, 1)
+
+#include "MrcTypes.h"
+
+#define MAX_XMP_PROFILES  (2)
+#define SPD3_MANUF_SIZE   (SPD3_MANUF_END - SPD3_MANUF_START + 1)   ///< The size of the SPD manufacturing data.
+#define SPD4_MANUF_SIZE   (SPD4_MANUF_END - SPD4_MANUF_START + 1)   ///< The size of the SPD manufacturing data.
+#define SPDLP_MANUF_SIZE  (SPDLP_MANUF_END - SPDLP_MANUF_START + 1) ///< The size of the SPD manufacturing data
+
+typedef union {
+  struct {
+    UINT8  BytesUsed                           :  4; ///< Bits 3:0
+    UINT8  BytesTotal                          :  3; ///< Bits 6:4
+    UINT8  CrcCoverage                         :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_DEVICE_DESCRIPTION_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Minor                               :  4; ///< Bits 3:0
+    UINT8  Major                               :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_REVISION_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Type                                :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_DRAM_DEVICE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ModuleType                          :  4; ///< Bits 3:0
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Density                             :  4; ///< Bits 3:0
+    UINT8  BankAddress                         :  3; ///< Bits 6:4
+    UINT8                                      :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_DENSITY_BANKS_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ColumnAddress                       :  3; ///< Bits 2:0
+    UINT8  RowAddress                          :  3; ///< Bits 5:3
+    UINT8                                      :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_ADDRESSING_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  OperationAt1_50                     :  1; ///< Bits 0:0
+    UINT8  OperationAt1_35                     :  1; ///< Bits 1:1
+    UINT8  OperationAt1_25                     :  1; ///< Bits 2:2
+    UINT8                                      :  5; ///< Bits 7:3
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_NOMINAL_VOLTAGE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  SdramDeviceWidth                    :  3; ///< Bits 2:0
+    UINT8  RankCount                           :  3; ///< Bits 5:3
+    UINT8                                      :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_ORGANIZATION_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  PrimaryBusWidth                     :  3; ///< Bits 2:0
+    UINT8  BusWidthExtension                   :  2; ///< Bits 4:3
+    UINT8                                      :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Divisor                             :  4; ///< Bits 3:0
+    UINT8  Dividend                            :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_FINE_TIMEBASE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Dividend                            :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Divisor                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT;
+
+typedef struct {
+  SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT Dividend; ///< Medium Timebase (MTB) Dividend
+  SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT  Divisor;  ///< Medium Timebase (MTB) Divisor
+} SPD_MEDIUM_TIMEBASE;
+
+typedef union {
+  struct {
+    UINT8  tCKmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TCK_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT16 CL4                                 :  1; ///< Bits 0:0
+    UINT16 CL5                                 :  1; ///< Bits 1:1
+    UINT16 CL6                                 :  1; ///< Bits 2:2
+    UINT16 CL7                                 :  1; ///< Bits 3:3
+    UINT16 CL8                                 :  1; ///< Bits 4:4
+    UINT16 CL9                                 :  1; ///< Bits 5:5
+    UINT16 CL10                                :  1; ///< Bits 6:6
+    UINT16 CL11                                :  1; ///< Bits 7:7
+    UINT16 CL12                                :  1; ///< Bits 8:8
+    UINT16 CL13                                :  1; ///< Bits 9:9
+    UINT16 CL14                                :  1; ///< Bits 10:10
+    UINT16 CL15                                :  1; ///< Bits 11:11
+    UINT16 CL16                                :  1; ///< Bits 12:12
+    UINT16 CL17                                :  1; ///< Bits 13:13
+    UINT16 CL18                                :  1; ///< Bits 14:14
+    UINT16                                     :  1; ///< Bits 15:15
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_CAS_LATENCIES_SUPPORTED_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tAAmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TAA_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tWRmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TWR_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRCDmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRCD_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRRDmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRRD_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRPmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRP_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRPab                               :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRP_AB_MTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRPabFine                            :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRP_AB_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRPpb                               :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRP_PB_MTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRPpbFine                            :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRP_PB_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT16  tRFCab                             :  16; ///< Bits 15:0
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_TRFC_AB_MTB_STRUCT;
+
+typedef union {
+struct {
+    UINT16  tRFCpb                             :  16; ///< Bits 15:0
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_TRFC_PB_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRASminUpper                        :  4; ///< Bits 3:0
+    UINT8  tRCminUpper                         :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_TRAS_TRC_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRASmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRAS_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRCmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRC_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT16 tRFCmin                             :  16; ///< Bits 15:0
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_TRFC_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tWTRmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TWTR_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRTPmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRTP_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tFAWminUpper                        :  4; ///< Bits 3:0
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_TFAW_MIN_MTB_UPPER_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tFAWmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TFAW_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tCWLmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TCWL_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  NMode                               :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_SYSTEM_COMMAND_RATE_STRUCT;
+
+typedef union {
+  struct {
+    UINT16 tREFImin                            :  16; ///< Bits 15:0
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_TREFI_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  RZQ6                                :  1; ///< Bits 0:0
+    UINT8  RZQ7                                :  1; ///< Bits 1:1
+    UINT8                                      :  5; ///< Bits 6:2
+    UINT8  DllOff                              :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_OPTIONAL_FEATURES_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ExtendedTemperatureRange            :  1; ///< Bits 0:0
+    UINT8  ExtendedTemperatureRefreshRate      :  1; ///< Bits 1:1
+    UINT8  AutoSelfRefresh                     :  1; ///< Bits 2:2
+    UINT8  OnDieThermalSensor                  :  1; ///< Bits 3:3
+    UINT8                                      :  3; ///< Bits 6:4
+    UINT8  PartialArraySelfRefresh             :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_THERMAL_REFRESH_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ThermalSensorAccuracy               :  7; ///< Bits 6:0
+    UINT8  ThermalSensorPresence               :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_THERMAL_SENSOR_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  NonStandardDeviceDescription        :  7; ///< Bits 6:0
+    UINT8  SdramDeviceType                     :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_DEVICE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8                                      :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_AUTO_SELF_REFRESH_PERF_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tCKminFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TCK_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tAAminFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TAA_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRCDminFine                          :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRCD_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRPminFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRP_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRCminFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRC_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tMACencoding                        :  4; ///< Bits 3:0
+    UINT8  tMAWencoding                        :  2; ///< Bits 5:4
+    UINT8  Reserved                            :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_PTRR_SUPPORT_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRRDminFine                          :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRRD_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_UNBUF_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  FrontThickness                      :  4; ///< Bits 3:0
+    UINT8  BackThickness                       :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_UNBUF_MODULE_NOMINAL_THICKNESS;
+
+typedef union {
+  struct {
+    UINT8  Card                                :  5; ///< Bits 4:0
+    UINT8  Revision                            :  2; ///< Bits 6:5
+    UINT8  Extension                           :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_UNBUF_REFERENCE_RAW_CARD;
+
+typedef union {
+  struct {
+    UINT8  MappingRank1                        :  1; ///< Bits 0:0
+    UINT8                                      :  7; ///< Bits 7:1
+  } Bits;
+  UINT8  Data;
+} SPD_UNBUF_ADDRESS_MAPPING;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8                                      :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_RDIMM_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  FrontThickness                      :  4; ///< Bits 3:0
+    UINT8  BackThickness                       :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_RDIMM_MODULE_NOMINAL_THICKNESS;
+
+typedef union {
+  struct {
+    UINT8  Card                                :  5; ///< Bits 4:0
+    UINT8  Revision                            :  2; ///< Bits 6:5
+    UINT8  Extension                           :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_RDIMM_REFERENCE_RAW_CARD;
+
+typedef union {
+  struct {
+    UINT8  RegisterCount                       :  2; ///< Bits 1:0
+    UINT8  DramRowCount                        :  2; ///< Bits 3:2
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_RDIMM_MODULE_ATTRIBUTES;
+
+typedef union {
+  struct {
+    UINT16 ContinuationCount                   :  7; ///< Bits 6:0
+    UINT16 ContinuationParity                  :  1; ///< Bits 7:7
+    UINT16 LastNonZeroByte                     :  8; ///< Bits 15:8
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_MANUFACTURER_ID_CODE;
+
+typedef struct {
+  UINT8  Year;                                 ///< Year represented in BCD (00h = 2000)
+  UINT8  Week;                                 ///< Year represented in BCD (47h = week 47)
+} SPD_MANUFACTURING_DATE;
+
+typedef union {
+  UINT32 Data;
+  UINT16 SerialNumber16[2];
+  UINT8  SerialNumber8[4];
+} SPD_MANUFACTURER_SERIAL_NUMBER;
+
+typedef struct {
+  UINT8 Location;                              ///< Module Manufacturing Location
+} SPD_MANUFACTURING_LOCATION;
+
+typedef struct {
+  SPD_MANUFACTURER_ID_CODE            IdCode;                   ///< Module Manufacturer ID Code
+  SPD_MANUFACTURING_LOCATION          Location;                 ///< Module Manufacturing Location
+  SPD_MANUFACTURING_DATE              Date;                     ///< Module Manufacturing Year, in BCD (range: 2000-2255)
+  SPD_MANUFACTURER_SERIAL_NUMBER      SerialNumber;             ///< Module Serial Number
+} SPD_UNIQUE_MODULE_ID;
+
+typedef union {
+  UINT16 Crc[1];
+  UINT8  Data8[2];
+} SPD_CYCLIC_REDUNDANCY_CODE;
+
+typedef union {
+  struct {
+    UINT8  ProfileEnable1                :  1;                     ///< Bits 0:0
+    UINT8  ProfileEnable2                :  1;                     ///< Bits 1:1
+    UINT8  ProfileConfig1                :  2;                     ///< Bits 3:2
+    UINT8  ProfileConfig2                :  2;                     ///< Bits 5:4
+    UINT8                                :  2;                     ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_XMP_ORG_CONFIG;
+
+typedef struct {
+  UINT16                              XmpId;                    ///< 176-177 XMP Identification String
+  SPD_XMP_ORG_CONFIG                  XmpOrgConf;               ///< 178 XMP Organization & Configuration
+  SPD_REVISION_STRUCT                 XmpRevision;              ///< 179 XMP Revision
+  SPD_MEDIUM_TIMEBASE                 MediumTimeBase[MAX_XMP_PROFILES]; ///< 180-183 Medium Timebase (MTB)
+  SPD_FINE_TIMEBASE_STRUCT            FineTimeBase;             ///< 184 Fine Timebase (FTB) Dividend / Divisor
+} SPD_EXTREME_MEMORY_PROFILE_HEADER;
+
+typedef union {
+  struct {
+    UINT8  Decimal : 5;
+    UINT8  Integer : 2;
+    UINT8          : 1;
+  } Bits;
+  UINT8 Data;
+} SPD_VDD_VOLTAGE_LEVEL_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Decimal : 7;
+    UINT8  Integer : 1;
+  } Bits;
+  UINT8 Data;
+} SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0;
+
+typedef union {
+  struct {
+    UINT8  Fine                                :  2; ///< Bits 1:0
+    UINT8  Medium                              :  2; ///< Bits 3:2
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD4_TIMEBASE_STRUCT;
+
+typedef union {
+  struct {
+    UINT32 CL7                                 :  1; ///< Bits 0:0
+    UINT32 CL8                                 :  1; ///< Bits 1:1
+    UINT32 CL9                                 :  1; ///< Bits 2:2
+    UINT32 CL10                                :  1; ///< Bits 3:3
+    UINT32 CL11                                :  1; ///< Bits 4:4
+    UINT32 CL12                                :  1; ///< Bits 5:5
+    UINT32 CL13                                :  1; ///< Bits 6:6
+    UINT32 CL14                                :  1; ///< Bits 7:7
+    UINT32 CL15                                :  1; ///< Bits 8:8
+    UINT32 CL16                                :  1; ///< Bits 9:9
+    UINT32 CL17                                :  1; ///< Bits 10:10
+    UINT32 CL18                                :  1; ///< Bits 11:11
+    UINT32 CL19                                :  1; ///< Bits 12:12
+    UINT32 CL20                                :  1; ///< Bits 13:13
+    UINT32 CL21                                :  1; ///< Bits 14:14
+    UINT32 CL22                                :  1; ///< Bits 15:15
+    UINT32 CL23                                :  1; ///< Bits 16:16
+    UINT32 CL24                                :  1; ///< Bits 17:17
+    UINT32                                     :  14; ///< Bits 31:18
+  } Bits;
+  UINT32 Data;
+  UINT16 Data16[2];
+  UINT8  Data8[4];
+} SPD4_CAS_LATENCIES_SUPPORTED_STRUCT;
+
+typedef struct {
+  SPD_VDD_VOLTAGE_LEVEL_STRUCT        Vdd;                      ///< 185, 220 XMP Module VDD Voltage Level
+  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 186, 221 XMP SDRAM Minimum Cycle Time (tCKmin)
+  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 187, 222 XMP Minimum CAS Latency Time (tAAmin)
+  SPD_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///< 188-189, 223-224 XMP CAS Latencies Supported, Least Significant Byte
+  SPD_TCWL_MIN_MTB_STRUCT             tCWLmin;                  ///< 190, 225 XMP Minimum CAS Write Latency Time (tCWLmin)
+  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 191, 226 XMP Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 192, 227 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TWR_MIN_MTB_STRUCT              tWRmin;                   ///< 193, 228 XMP Minimum Write Recovery Time (tWRmin)
+  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///< 194, 229 XMP Upper Nibbles for tRAS and tRC
+  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 195, 230 XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 196, 231 XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+  SPD_TREFI_MIN_MTB_STRUCT            tREFImin;                 ///< 197-198, 232-233 XMP Maximum tREFI Time (Average Periodic Refresh Interval), Least Significant Byte
+  SPD_TRFC_MIN_MTB_STRUCT             tRFCmin;                  ///< 199-200, 234-235 XMP Minimum Refresh Recovery Delay Time (tRFCmin), Least Significant Byte
+  SPD_TRTP_MIN_MTB_STRUCT             tRTPmin;                  ///< 201, 236 XMP Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
+  SPD_TRRD_MIN_MTB_STRUCT             tRRDmin;                  ///< 202, 237 XMP Minimum Row Active to Row Active Delay Time (tRRDmin)
+  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///< 203, 238 XMP Upper Nibble for tFAW
+  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 204, 239 XMP Minimum Four Activate Window Delay Time (tFAWmin)
+  SPD_TWTR_MIN_MTB_STRUCT             tWTRmin;                  ///< 205, 240 XMP Minimum Internal Write to Read Command Delay Time (tWTRmin)
+  UINT8                               Reserved1[207 - 206 + 1]; ///< 206-207, 241-242 XMP Reserved
+  SPD_SYSTEM_COMMAND_RATE_STRUCT      SystemCmdRate;            ///< 208, 243 XMP System ADD/CMD Rate (1N or 2N mode)
+  SPD_AUTO_SELF_REFRESH_PERF_STRUCT   AsrPerf;                  ///< 209, 244 XMP SDRAM Auto Self Refresh Performance (Sub 1x Refresh and IDD6 impact)
+  UINT8                               VoltageLevel;             ///< 210, 245 XMP Memory Controller Voltage Level
+  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 211, 246 XMP Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 212, 247 XMP Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 213, 248 XMP Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 214, 249 XMP Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 215, 250 XMP Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+  UINT8                               Reserved2[218 - 216 + 1]; ///< 216-218, 251-253 XMP Reserved
+  UINT8                               VendorPersonality;        ///< 219, 254 XMP Vendor Personality
+} SPD_EXTREME_MEMORY_PROFILE_DATA;
+
+typedef struct {
+  SPD_EXTREME_MEMORY_PROFILE_HEADER   Header;                   ///< 176-184 XMP header
+  SPD_EXTREME_MEMORY_PROFILE_DATA     Data[MAX_XMP_PROFILES];   ///< 185-254 XMP profiles
+} SPD_EXTREME_MEMORY_PROFILE;
+
+typedef struct {
+  UINT16                              XmpId;                        ///< 384-385 XMP Identification String
+  SPD_XMP_ORG_CONFIG                  XmpOrgConf;                   ///< 386 XMP Organization & Configuration
+  SPD_REVISION_STRUCT                 XmpRevision;                  ///< 387 XMP Revision
+  SPD4_TIMEBASE_STRUCT                TimeBase[MAX_XMP_PROFILES];   ///< 388-389 Medium and Fine Timebase
+  UINT8                               Reserved[392 - 390 + 1];     ///< 390-392 Reserved
+} SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0;
+
+typedef struct {
+  SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0    Vdd;                      ///< 393, 440 XMP Module VDD Voltage Level
+  UINT8                               Reserved1[395 - 394 + 1]; ///< 394-395, 441-442 XMP Reserved
+  SPD_TCK_MIN_MTB_STRUCT              tCKAVGmin;                ///< 396, 443 XMP SDRAM Minimum Cycle Time (tCKAVGmin)
+  SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies;             ///< 397-400, 444-447 XMP CAS Latencies Supported
+  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 401, 448 XMP Minimum CAS Latency Time (tAAmin)
+  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 402, 449 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 403, 450 XMP Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///< 404, 451 XMP Upper Nibbles for tRAS and tRC
+  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 405, 452 XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 406, 453 XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC1min;                 ///< 407-408, 454-455 XMP Minimum Refresh Recovery Delay Time (tRFC1min)
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC2min;                 ///< 409-410, 456-457 XMP Minimum Refresh Recovery Delay Time (tRFC2min)
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC4min;                 ///< 411-412, 458-459 XMP Minimum Refresh Recovery Delay Time (tRFC4min)
+  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///< 413, 460 Upper Nibble for tFAW
+  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 414, 461 Minimum Four Activate Window Delay Time (tFAWmin)
+  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Smin;                ///< 415, 462 Minimum Activate to Activate Delay Time (tRRD_Smin), different bank group
+  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Lmin;                ///< 416, 463 Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
+  UINT8                               Reserved2[424 - 417 + 1]; ///< 417-424, 464-471 XMP Reserved
+  SPD_TRRD_MIN_FTB_STRUCT             tRRD_LminFine;            ///< 425, 472 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin), different bank group
+  SPD_TRRD_MIN_FTB_STRUCT             tRRD_SminFine;            ///< 426, 473 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin), same bank group
+  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 427, 474 Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 428, 475 Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 429, 476 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 430, 477 Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD_TCK_MIN_FTB_STRUCT              tCKAVGminFine;            ///< 431, 478 Fine Offset for SDRAM Maximum Cycle Time (tCKAVGmin)
+  UINT8                               Reserved3[439 - 432 + 1]; ///< 432-439, 479-486 XMP Reserved
+} SPD_EXTREME_MEMORY_PROFILE_DATA_2_0;
+
+typedef struct {
+  SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0      Header;                   ///< 384-392 XMP header
+  SPD_EXTREME_MEMORY_PROFILE_DATA_2_0        Data[MAX_XMP_PROFILES];   ///< 393-486 XMP profiles
+} SPD_EXTREME_MEMORY_PROFILE_2_0;
+
+typedef struct {
+  SPD_DEVICE_DESCRIPTION_STRUCT       Description;              ///< 0   Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+  SPD_REVISION_STRUCT                 Revision;                 ///< 1   SPD Revision
+  SPD_DRAM_DEVICE_TYPE_STRUCT         DramDeviceType;           ///< 2   DRAM Device Type
+  SPD_MODULE_TYPE_STRUCT              ModuleType;               ///< 3   Module Type
+  SPD_SDRAM_DENSITY_BANKS_STRUCT      SdramDensityAndBanks;     ///< 4   SDRAM Density and Banks
+  SPD_SDRAM_ADDRESSING_STRUCT         SdramAddressing;          ///< 5   SDRAM Addressing
+  SPD_MODULE_NOMINAL_VOLTAGE_STRUCT   ModuleNominalVoltage;     ///< 6   Module Nominal Voltage, VDD
+  SPD_MODULE_ORGANIZATION_STRUCT      ModuleOrganization;       ///< 7   Module Organization
+  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT  ModuleMemoryBusWidth;     ///< 8   Module Memory Bus Width
+  SPD_FINE_TIMEBASE_STRUCT            FineTimebase;             ///< 9   Fine Timebase (FTB) Dividend / Divisor
+  SPD_MEDIUM_TIMEBASE                 MediumTimebase;           ///< 10-11 Medium Timebase (MTB) Dividend
+  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 12  SDRAM Minimum Cycle Time (tCKmin)
+  UINT8                               Reserved1;                ///< 13  Reserved
+  SPD_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///< 14-15 CAS Latencies Supported
+  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 16  Minimum CAS Latency Time (tAAmin)
+  SPD_TWR_MIN_MTB_STRUCT              tWRmin;                   ///< 17  Minimum Write Recovery Time (tWRmin)
+  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 18  Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRRD_MIN_MTB_STRUCT             tRRDmin;                  ///< 19  Minimum Row Active to Row Active Delay Time (tRRDmin)
+  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 20  Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///< 21  Upper Nibbles for tRAS and tRC
+  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 22  Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 23  Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+  SPD_TRFC_MIN_MTB_STRUCT             tRFCmin;                  ///< 24-25  Minimum Refresh Recovery Delay Time (tRFCmin)
+  SPD_TWTR_MIN_MTB_STRUCT             tWTRmin;                  ///< 26  Minimum Internal Write to Read Command Delay Time (tWTRmin)
+  SPD_TRTP_MIN_MTB_STRUCT             tRTPmin;                  ///< 27  Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
+  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///< 28  Upper Nibble for tFAW
+  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 29  Minimum Four Activate Window Delay Time (tFAWmin)
+  SPD_SDRAM_OPTIONAL_FEATURES_STRUCT  SdramOptionalFeatures;    ///< 30  SDRAM Optional Features
+  SPD_SDRAM_THERMAL_REFRESH_STRUCT    ThermalAndRefreshOptions; ///< 31  SDRAMThermalAndRefreshOptions
+  SPD_MODULE_THERMAL_SENSOR_STRUCT    ModuleThermalSensor;      ///< 32  Module Thermal Sensor
+  SPD_SDRAM_DEVICE_TYPE_STRUCT        SdramDeviceType;          ///< 33  SDRAM Device Type
+  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 34  Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 35  Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 36  Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 37  Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 38  Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+  SPD_TRP_AB_MTB_STRUCT               tRPab;                    ///< 39  Minimum Row Precharge Delay Time for all banks (tRPab)
+  SPD_TRP_AB_FTB_STRUCT               tRPabFine;                ///< 40  Fine Offset for Minimum Row Precharge Delay Time for all banks (tRPab)
+  SPD_PTRR_SUPPORT_STRUCT             pTRRsupport;              ///< 41 - pTRR support with TMAC value
+  UINT8                               Reserved3[59 - 42 + 1];   ///< 42 - 59 Reserved
+} SPD_GENERAL_SECTION;
+
+typedef struct {
+  SPD_UNBUF_MODULE_NOMINAL_HEIGHT     ModuleNominalHeight;      ///< 60 Module Nominal Height
+  SPD_UNBUF_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;   ///< 61 Module Maximum Thickness
+  SPD_UNBUF_REFERENCE_RAW_CARD        ReferenceRawCardUsed;     ///< 62 Reference Raw Card Used
+  SPD_UNBUF_ADDRESS_MAPPING           AddressMappingEdgeConn;   ///< 63 Address Mapping from Edge Connector to DRAM
+  UINT8                               Reserved[116 - 64 + 1];   ///< 64-116 Reserved
+} SPD_MODULE_UNBUFFERED;
+
+typedef struct {
+  SPD_RDIMM_MODULE_NOMINAL_HEIGHT     ModuleNominalHeight;      ///< 60 Module Nominal Height
+  SPD_RDIMM_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;   ///< 61 Module Maximum Thickness
+  SPD_RDIMM_REFERENCE_RAW_CARD        ReferenceRawCardUsed;     ///< 62 Reference Raw Card Used
+  SPD_RDIMM_MODULE_ATTRIBUTES         DimmModuleAttributes;     ///< 63 DIMM Module Attributes
+  UINT8                               Reserved[116 - 64 + 1];   ///< 64-116 Reserved
+} SPD_MODULE_REGISTERED;
+
+typedef union {
+  SPD_MODULE_UNBUFFERED               Unbuffered;
+  SPD_MODULE_REGISTERED               Registered;
+} SPD_MODULE_SPECIFIC;
+
+typedef struct {
+  UINT8                          ModulePartNumber[145 - 128 + 1];        ///< 128-145 Module Part Number
+} SPD_MODULE_PART_NUMBER;
+
+typedef struct {
+  UINT8                          ModuleRevisionCode[147 - 146 + 1];      ///< 146-147 Module Revision Code
+} SPD_MODULE_REVISION_CODE;
+
+typedef struct {
+  UINT8                          ManufactureSpecificData[175 - 150 + 1]; ///< 150-175 Manufacturer's Specific Data
+} SPD_MANUFACTURE_SPECIFIC;
+
+///
+/// DDR3 Serial Presence Detect structure
+///
+typedef struct {
+  SPD_GENERAL_SECTION         General;                                ///< 0-59 General Section
+  SPD_MODULE_SPECIFIC         Module;                                 ///< 60-116 Module-Specific Section
+  SPD_UNIQUE_MODULE_ID        ModuleId;                               ///< 117-125 Unique Module ID
+  SPD_CYCLIC_REDUNDANCY_CODE  Crc;                                    ///< 126-127 Cyclical Redundancy Code (CRC)
+  SPD_MODULE_PART_NUMBER      ModulePartNumber;                       ///< 128-145 Module Part Number
+  SPD_MODULE_REVISION_CODE    ModuleRevisionCode;                     ///< 146-147 Module Revision Code
+  SPD_MANUFACTURER_ID_CODE    DramIdCode;                             ///< 148-149 Dram Manufacturer ID Code
+  SPD_MANUFACTURE_SPECIFIC    ManufactureSpecificData;                ///< 150-175 Manufacturer's Specific Data
+  SPD_EXTREME_MEMORY_PROFILE  Xmp;                                    ///< 176-254 Intel(r) Extreme Memory Profile support
+  UINT8                       Reserved;                               ///< 255 Reserved
+} MrcSpdDdr3;
+
+typedef union {
+  struct {
+    UINT8  Density                             :  4; ///< Bits 3:0
+    UINT8  BankAddress                         :  2; ///< Bits 5:4
+    UINT8  BankGroup                           :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD4_SDRAM_DENSITY_BANKS_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  SignalLoading                       :  2; ///< Bits 1:0
+    UINT8                                      :  2; ///< Bits 3:2
+    UINT8  DieCount                            :  3; ///< Bits 6:4
+    UINT8  SdramDeviceType                     :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD4_SDRAM_DEVICE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  OperationAt1_20                     :  1; ///< Bits 0:0
+    UINT8  EndurantAt1_20                      :  1; ///< Bits 1:1
+    UINT8                                      :  6; ///< Bits 7:2
+  } Bits;
+  UINT8  Data;
+} SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tCKmax                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD4_TCK_MAX_MTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tCKmaxFine                          :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD4_TCK_MAX_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8                                      :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD4_SDRAM_THERMAL_REFRESH_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD4_UNBUF_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD4_RDIMM_MODULE_NOMINAL_HEIGHT;
+
+typedef struct {
+  SPD_DEVICE_DESCRIPTION_STRUCT       Description;              ///< 0       Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+  SPD_REVISION_STRUCT                 Revision;                 ///< 1       SPD Revision
+  SPD_DRAM_DEVICE_TYPE_STRUCT         DramDeviceType;           ///< 2       DRAM Device Type
+  SPD_MODULE_TYPE_STRUCT              ModuleType;               ///< 3       Module Type
+  SPD4_SDRAM_DENSITY_BANKS_STRUCT     SdramDensityAndBanks;     ///< 4       SDRAM Density and Banks
+  SPD_SDRAM_ADDRESSING_STRUCT         SdramAddressing;          ///< 5       SDRAM Addressing
+  SPD4_SDRAM_DEVICE_TYPE_STRUCT       SdramDeviceType;          ///< 6       SDRAM Device Type
+  SPD_PTRR_SUPPORT_STRUCT             pTRRsupport;              ///< 7       pTRR support with TMAC value
+  SPD4_SDRAM_THERMAL_REFRESH_STRUCT   ThermalAndRefreshOptions; ///< 8       SDRAM Thermal and Refresh Options
+  UINT8                               Reserved0[10 - 9 + 1];    ///< 9-10    Reserved
+  SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT  ModuleNominalVoltage;     ///< 11      Module Nominal Voltage, VDD
+  SPD_MODULE_ORGANIZATION_STRUCT      ModuleOrganization;       ///< 12      Module Organization
+  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT  ModuleMemoryBusWidth;     ///< 13      Module Memory Bus Width
+  SPD_MODULE_THERMAL_SENSOR_STRUCT    ModuleThermalSensor;      ///< 14      Module Thermal Sensor
+  UINT8                               Reserved1[16 - 15 + 1];   ///< 15-16   Reserved
+  SPD4_TIMEBASE_STRUCT                Timebase;                 ///< 17      Timebases
+  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 18      SDRAM Minimum Cycle Time (tCKmin)
+  SPD4_TCK_MAX_MTB_STRUCT             tCKmax;                   ///< 19      SDRAM Maximum Cycle Time (tCKmax)
+  SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies;             ///< 20-23   CAS Latencies Supported
+  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 24      Minimum CAS Latency Time (tAAmin)
+  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 25      Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 26      Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///< 27      Upper Nibbles for tRAS and tRC
+  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 28      Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 29      Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC1min;                 ///< 30-31   Minimum Refresh Recovery Delay Time (tRFC1min)
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC2min;                 ///< 32-33   Minimum Refresh Recovery Delay Time (tRFC2min)
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC4min;                 ///< 34-35   Minimum Refresh Recovery Delay Time (tRFC4min)
+  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///< 36      Upper Nibble for tFAW
+  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 37      Minimum Four Activate Window Delay Time (tFAWmin)
+  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Smin;                ///< 38      Minimum Activate to Activate Delay Time (tRRD_Smin), different bank group
+  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Lmin;                ///< 39      Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
+  UINT8                               Reserved2[117 - 40 + 1];  ///< 40-117  Reserved
+  SPD_TRRD_MIN_FTB_STRUCT             tRRD_LminFine;            ///< 118     Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin), different bank group
+  SPD_TRRD_MIN_FTB_STRUCT             tRRD_SminFine;            ///< 119     Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin), same bank group
+  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 120     Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 121     Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 122     Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 123     Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD4_TCK_MAX_FTB_STRUCT             tCKmaxFine;               ///< 124     Fine Offset for SDRAM Minimum Cycle Time (tCKmax)
+  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 125     Fine Offset for SDRAM Maximum Cycle Time (tCKmin)
+  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 126-127 Cyclical Redundancy Code (CRC)
+} SPD4_BASE_SECTION;
+
+typedef struct {
+  SPD4_UNBUF_MODULE_NOMINAL_HEIGHT    ModuleNominalHeight;      ///< 128     Module Nominal Height
+  SPD_UNBUF_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;   ///< 129     Module Maximum Thickness
+  SPD_UNBUF_REFERENCE_RAW_CARD        ReferenceRawCardUsed;     ///< 130     Reference Raw Card Used
+  SPD_UNBUF_ADDRESS_MAPPING           AddressMappingEdgeConn;   ///< 131     Address Mapping from Edge Connector to DRAM
+  UINT8                               Reserved[253 - 132 + 1];  ///< 132-253 Reserved
+  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 254-255 Cyclical Redundancy Code (CRC)
+} SPD4_MODULE_UNBUFFERED;
+
+typedef struct {
+  SPD4_RDIMM_MODULE_NOMINAL_HEIGHT    ModuleNominalHeight;      ///< 128     Module Nominal Height
+  SPD_RDIMM_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;   ///< 129     Module Maximum Thickness
+  SPD_RDIMM_REFERENCE_RAW_CARD        ReferenceRawCardUsed;     ///< 130     Reference Raw Card Used
+  SPD_RDIMM_MODULE_ATTRIBUTES         DimmModuleAttributes;     ///< 131     DIMM Module Attributes
+  UINT8                               Reserved[253 - 132 + 1];  ///< 253-132 Reserved
+  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 254-255 Cyclical Redundancy Code (CRC)
+} SPD4_MODULE_REGISTERED;
+
+typedef union {
+  SPD4_MODULE_UNBUFFERED              Unbuffered;               ///< 128-255 Unbuffered Memory Module Types
+  SPD4_MODULE_REGISTERED              Registered;               ///< 128-255 Registered Memory Module Types
+} SPD4_MODULE_SPECIFIC;
+
+typedef struct {
+  UINT8                               ModulePartNumber[348 - 329 + 1]; ///< 329-348 Module Part Number
+} SPD4_MODULE_PART_NUMBER;
+
+typedef struct {
+  UINT8                               ManufactureSpecificData[381 - 353 + 1]; ///< 353-381 Manufacturer's Specific Data
+} SPD4_MANUFACTURE_SPECIFIC;
+
+typedef UINT8                         SPD4_MODULE_REVISION_CODE;///< 349     Module Revision Code
+typedef UINT8                         SPD4_DRAM_STEPPING;       ///< 352     Dram Stepping
+
+typedef struct {
+  SPD_UNIQUE_MODULE_ID                ModuleId;                 ///< 320-328 Unique Module ID
+  SPD4_MODULE_PART_NUMBER             ModulePartNumber;         ///< 329-348 Module Part Number
+  SPD4_MODULE_REVISION_CODE           ModuleRevisionCode;       ///< 349     Module Revision Code
+  SPD_MANUFACTURER_ID_CODE            DramIdCode;               ///< 350-351 Dram Manufacturer ID Code
+  SPD4_DRAM_STEPPING                  DramStepping;             ///< 352     Dram Stepping
+  SPD4_MANUFACTURE_SPECIFIC           ManufactureSpecificData;  ///< 353-381 Manufacturer's Specific Data
+  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 382-383 Cyclical Redundancy Code (CRC)
+} SPD4_MANUFACTURING_DATA;
+
+typedef union {
+  SPD_EXTREME_MEMORY_PROFILE_2_0      Xmp;                      ///< 384-463 Intel(r) Extreme Memory Profile support
+  UINT8                               Reserved0[511 - 384 + 1]; ///< 384-511 Unbuffered Memory Module Types
+} SPD4_END_USER_SECTION;
+
+///
+/// DDR4 Serial Presence Detect structure
+///
+typedef struct {
+  SPD4_BASE_SECTION                   Base;                     ///< 0-127   Base Configuration and DRAM Parameters
+  SPD4_MODULE_SPECIFIC                Module;                   ///< 128-255 Module-Specific Section
+  UINT8                               Reserved0[319 - 256 + 1]; ///< 256-319 Reserved
+  SPD4_MANUFACTURING_DATA             ManufactureInfo;          ///< 320-383 Manufacturing Information
+  SPD4_END_USER_SECTION               EndUser;                  ///< 384-511 End User Programmable
+} MrcSpdDdr4;
+
+typedef union {
+  struct {
+    UINT8  Fine                                :  2; ///< Bits 1:0
+    UINT8  Medium                              :  2; ///< Bits 3:2
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_TIMEBASE_STRUCT;
+
+typedef union {
+  struct {
+    UINT32 CL3                                 :  1;  ///< Bits 0:0
+    UINT32 CL6                                 :  1;  ///< Bits 1:1
+    UINT32 CL8                                 :  1;  ///< Bits 2:2
+    UINT32 CL9                                 :  1;  ///< Bits 3:3
+    UINT32 CL10                                :  1;  ///< Bits 4:4
+    UINT32 CL11                                :  1;  ///< Bits 5:5
+    UINT32 CL12                                :  1;  ///< Bits 6:6
+    UINT32 CL14                                :  1;  ///< Bits 7:7
+    UINT32 CL16                                :  1;  ///< Bits 8:8
+    UINT32                                     :  1;  ///< Bits 9:9
+    UINT32 CL20                                :  1;  ///< Bits 10:10
+    UINT32 CL22                                :  1;  ///< Bits 11:11
+    UINT32 CL24                                :  1;  ///< Bits 12:12
+    UINT32                                     :  1;  ///< Bits 13:13
+    UINT32 CL28                                :  1;  ///< Bits 14:14
+    UINT32                                     :  1;  ///< Bits 15:15
+    UINT32 CL32                                :  1;  ///< Bits 16:16
+    UINT32                                     :  1;  ///< Bits 17:17
+    UINT32 CL36                                :  1;  ///< Bits 18:18
+    UINT32                                     :  1;  ///< Bits 19:19
+    UINT32 CL40                                :  1;  ///< Bits 20:20
+    UINT32                                     :  11; ///< Bits 31:21
+  } Bits;
+  UINT32 Data;
+  UINT16 Data16[2];
+  UINT8  Data8[4];
+} SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Density                             :  4; ///< Bits 3:0
+    UINT8  BankAddress                         :  2; ///< Bits 5:4
+    UINT8  BankGroup                           :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  SignalLoading                       :  2; ///< Bits 1:0
+    UINT8  ChannelsPerDie                      :  2; ///< Bits 3:2
+    UINT8  DieCount                            :  3; ///< Bits 6:4
+    UINT8  SdramPackageType                    :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  OperationAt1_20                     :  1; ///< Bits 0:0
+    UINT8  EndurantAt1_20                      :  1; ///< Bits 1:1
+    UINT8  OperationAt1_10                     :  1; ///< Bits 2:2
+    UINT8  EndurantAt1_10                      :  1; ///< Bits 3:3
+    UINT8  OperationAtTBD2V                    :  1; ///< Bits 4:4
+    UINT8  EndurantAtTBD2V                     :  1; ///< Bits 5:5
+    UINT8                                      :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tCKmax                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_TCK_MAX_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ReadLatencyMode                     :  2; ///< Bits 1:0
+    UINT8  WriteLatencySet                     :  2; ///< Bits 3:2
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_RW_LATENCY_OPTION_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tCKmaxFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_LPDDR_TCK_MAX_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8                                      :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_UNBUF_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_RDIMM_MODULE_NOMINAL_HEIGHT;
+
+typedef struct {
+  SPD_DEVICE_DESCRIPTION_STRUCT             Description;              ///< 0       Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+  SPD_REVISION_STRUCT                       Revision;                 ///< 1       SPD Revision
+  SPD_DRAM_DEVICE_TYPE_STRUCT               DramDeviceType;           ///< 2       DRAM Device Type
+  SPD_MODULE_TYPE_STRUCT                    ModuleType;               ///< 3       Module Type
+  SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT      SdramDensityAndBanks;     ///< 4       SDRAM Density and Banks
+  SPD_SDRAM_ADDRESSING_STRUCT               SdramAddressing;          ///< 5       SDRAM Addressing
+  SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT       SdramPackageType;         ///< 6       SDRAM Package Type
+  SPD_PTRR_SUPPORT_STRUCT                   pTRRsupport;              ///< 7       pTRR support with TMAC value - SDRAM Optional Features
+  SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT    ThermalAndRefreshOptions; ///< 8       SDRAM Thermal and Refresh Options
+  UINT8                                     Reserved0[10 - 9 + 1];    ///< 9-10    Reserved
+  SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT   ModuleNominalVoltage;     ///< 11      Module Nominal Voltage, VDD
+  SPD_MODULE_ORGANIZATION_STRUCT            ModuleOrganization;       ///< 12      Module Organization
+  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT        ModuleMemoryBusWidth;     ///< 13      Module Memory Bus Width
+  SPD_MODULE_THERMAL_SENSOR_STRUCT          ModuleThermalSensor;      ///< 14      Module Thermal Sensor
+  UINT8                                     Reserved1[16 - 15 + 1];   ///< 15-16   Reserved
+  SPD_LPDDR_TIMEBASE_STRUCT                 Timebase;                 ///< 17      Timebases
+  SPD_TCK_MIN_MTB_STRUCT                    tCKmin;                   ///< 18      SDRAM Minimum Cycle Time (tCKmin)
+  SPD_LPDDR_TCK_MAX_MTB_STRUCT              tCKmax;                   ///< 19      SDRAM Maximum Cycle Time (tCKmax)
+  SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///< 20-23   CAS Latencies Supported
+  SPD_TAA_MIN_MTB_STRUCT                    tAAmin;                   ///< 24      Minimum CAS Latency Time (tAAmin)
+  SPD_LPDDR_RW_LATENCY_OPTION_STRUCT        LatencySetOptions;        ///< 25      Read and Write Latency Set Options
+  SPD_TRCD_MIN_MTB_STRUCT                   tRCDmin;                  ///< 26      Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRP_AB_MTB_STRUCT                     tRPab;                    ///< 27      Minimum Row Precharge Delay Time (tRPab), all banks
+  SPD_TRP_PB_MTB_STRUCT                     tRPpb;                    ///< 28      Minimum Row Precharge Delay Time (tRPpb), per bank
+  SPD_TRFC_AB_MTB_STRUCT                    tRFCab;                   ///< 29-30   Minimum Refresh Recovery Delay Time (tRFCab), all banks
+  SPD_TRFC_PB_MTB_STRUCT                    tRFCpb;                   ///< 31-32   Minimum Refresh Recovery Delay Time (tRFCpb), per bank
+  UINT8                                     Reserved2[119 - 33 + 1];  ///< 33-119  Reserved
+  SPD_TRP_PB_FTB_STRUCT                     tRPpbFine;                ///< 120     Fine Offset for Minimum Row Precharge Delay Time (tRPpbFine), per bank
+  SPD_TRP_AB_FTB_STRUCT                     tRPabFine;                ///< 121     Fine Offset for Minimum Row Precharge Delay Time (tRPabFine), all ranks
+  SPD_TRCD_MIN_FTB_STRUCT                   tRCDminFine;              ///< 122     Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TAA_MIN_FTB_STRUCT                    tAAminFine;               ///< 123     Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD_LPDDR_TCK_MAX_FTB_STRUCT              tCKmaxFine;               ///< 124     Fine Offset for SDRAM Maximum Cycle Time (tCKmax)
+  SPD_TCK_MIN_FTB_STRUCT                    tCKminFine;               ///< 125     Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+  SPD_CYCLIC_REDUNDANCY_CODE                Crc;                      ///< 126-127 Cyclical Redundancy Code (CRC)
+} SPD_LPDDR_BASE_SECTION;
+
+typedef union {
+  struct {
+    UINT8  FrontThickness                      :  4; ///< Bits 3:0
+    UINT8  BackThickness                       :  4; ///< Bits 7:4
+  } Bits;
+  UINT8 Data;
+} SPD_LPDDR_MODULE_MAXIMUM_THICKNESS;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  Card                                :  5; ///< Bits 4:0
+    UINT8  Revision                            :  2; ///< Bits 6:5
+    UINT8  Extension                           :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_REFERENCE_RAW_CARD;
+
+typedef struct {
+  SPD_LPDDR_MODULE_NOMINAL_HEIGHT         ModuleNominalHeight;      ///< 128     Module Nominal Height
+  SPD_LPDDR_MODULE_MAXIMUM_THICKNESS      ModuleMaximumThickness;   ///< 129     Module Maximum Thickness
+  SPD_LPDDR_REFERENCE_RAW_CARD            ReferenceRawCardUsed;     ///< 130     Reference Raw Card Used
+  UINT8                                   Reserved[253 - 131 + 1];  ///< 131-253 Reserved
+  SPD_CYCLIC_REDUNDANCY_CODE              Crc;                      ///< 254-255 Cyclical Redundancy Code (CRC)
+} SPD_LPDDR_MODULE_LPDIMM;
+
+typedef union {
+  SPD_LPDDR_MODULE_LPDIMM                 LpDimm;                   ///< 128-255 Unbuffered Memory Module Types
+} SPD_LPDDR_MODULE_SPECIFIC;
+
+typedef struct {
+  UINT8                                   ModulePartNumber[348 - 329 + 1]; ///< 329-348 Module Part Number
+} SPD_LPDDR_MODULE_PART_NUMBER;
+
+typedef struct {
+  UINT8                                   ManufactureSpecificData[381 - 353 + 1]; ///< 353-381 Manufacturer's Specific Data
+} SPD_LPDDR_MANUFACTURE_SPECIFIC;
+
+typedef UINT8                             SPD_LPDDR_MODULE_REVISION_CODE;///< 349     Module Revision Code
+typedef UINT8                             SPD_LPDDR_DRAM_STEPPING;       ///< 352     Dram Stepping
+
+typedef struct {
+  SPD_UNIQUE_MODULE_ID                    ModuleId;                 ///< 320-328 Unique Module ID
+  SPD_LPDDR_MODULE_PART_NUMBER            ModulePartNumber;         ///< 329-348 Module Part Number
+  SPD_LPDDR_MODULE_REVISION_CODE          ModuleRevisionCode;       ///< 349     Module Revision Code
+  SPD_MANUFACTURER_ID_CODE                DramIdCode;               ///< 350-351 Dram Manufacturer ID Code
+  SPD_LPDDR_DRAM_STEPPING                 DramStepping;             ///< 352     Dram Stepping
+  SPD_LPDDR_MANUFACTURE_SPECIFIC          ManufactureSpecificData;  ///< 353-381 Manufacturer's Specific Data
+  UINT8                                   Reserved[383 - 382 + 1];  ///< 382-383 Reserved
+} SPD_LPDDR_MANUFACTURING_DATA;
+
+typedef union {
+  UINT8                                   Reserved0[511 - 384 + 1]; ///< 384-511 End User Programmable
+} SPD_LPDDR_END_USER_SECTION;
+
+typedef struct {
+  SPD_LPDDR_BASE_SECTION                  Base;                     ///< 0-127   Base Configuration and DRAM Parameters
+  SPD_LPDDR_MODULE_SPECIFIC               Module;                   ///< 128-255 Module-Specific Section
+  UINT8                                   Reserved0[319 - 256 + 1]; ///< 256-319 Reserved
+  SPD_LPDDR_MANUFACTURING_DATA            ManufactureInfo;          ///< 320-383 Manufacturing Information
+  SPD_LPDDR_END_USER_SECTION              EndUser;                  ///< 384-511 End User Programmable
+} MrcSpdLpDdr;
+
+typedef union {
+  MrcSpdDdr3  Ddr3;
+  MrcSpdDdr4  Ddr4;
+  MrcSpdLpDdr Lpddr;
+} MrcSpd;
+
+#ifndef MAX_SPD_SAVE
+#define MAX_SPD_SAVE (sizeof (SPD_MANUFACTURER_ID_CODE) + \
+                      sizeof (SPD_MANUFACTURING_LOCATION) + \
+                      sizeof (SPD_MANUFACTURING_DATE) + \
+                      sizeof (SPD_MANUFACTURER_SERIAL_NUMBER) + \
+                      sizeof (SPD4_MODULE_PART_NUMBER))
+#endif
+
+#pragma pack (pop)
+#endif // _MrcSpdData_h_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h
new file mode 100644
index 0000000000..b267315f36
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h
@@ -0,0 +1,237 @@
+/** @file
+  Include the the general MRC types
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MRC_TYPES_H
+#define _MRC_TYPES_H
+
+#ifdef MRC_MINIBIOS_BUILD
+#include "MrcMiniBiosEfiDefs.h"
+#else
+#include <Base.h>
+#endif // MRC_MINIBIOS_BUILD
+
+//
+// Data Types
+//
+typedef union {
+  struct {
+    UINT32  Low;
+    UINT32  High;
+  } Data32;
+  UINT64 Data;
+} UINT64_STRUCT;
+
+typedef union {
+  struct {
+    INT32  Low;
+    INT32  High;
+  } Data32;
+  INT64 Data;
+} INT64_STRUCT;
+
+typedef union {
+  VOID    *Ptr;
+  UINTN   DataN;
+  UINT64  Data64;
+} POINTER_STRUCT;
+
+#define UNSUPPORT 0
+#define SUPPORT   1
+
+typedef enum {
+  mrcSuccess,
+  mrcFail,
+  mrcWrongInputParameter,
+  mrcCasError,
+  mrcTimingError,
+  mrcSenseAmpErr,
+  mrcReadMPRErr,
+  mrcReadLevelingError,
+  mrcWriteLevelingError,
+  mrcDataTimeCentering1DErr,
+  mrcWriteVoltage2DError,
+  mrcReadVoltage2DError,
+  mrcMiscTrainingError,
+  mrcWrError,
+  mrcDimmNotSupport,
+  mrcChannelNotSupport,
+  mrcPiSettingError,
+  mrcDqsPiSettingError,
+  mrcDeviceBusy,
+  mrcFrequencyChange,
+  mrcReutSequenceError,
+  mrcCrcError,
+  mrcFrequencyError,
+  mrcDimmNotExist,
+  mrcColdBootRequired,
+  mrcRoundTripLatencyError,
+  mrcMixedDimmSystem,
+  mrcAliasDetected,
+  mrcRetrain,
+  mrcRtpError,
+  mrcUnsupportedTechnology,
+  mrcMappingError,
+  mrcSocketNotSupported,
+  mrcControllerNotSupported,
+  mrcRankNotSupported,
+  mrcTurnAroundTripError
+} MrcStatus;
+
+//
+// general  macros
+//
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef ABS
+#define ABS(x)  (((x) < 0) ? (-(x)) : (x))
+#endif
+
+//
+// Make sure x is inside the range of [a..b]
+//
+#ifndef RANGE
+#define RANGE(x, a, b) (MIN ((b), MAX ((x), (a))))
+#endif
+
+#ifndef DIVIDECEIL
+#define DIVIDECEIL(a, b)   (((a) + (b) - 1) / (b))
+#endif
+
+#ifndef DIVIDEROUND
+#define DIVIDEROUND(a, b)  (((a) * (b) > 0) ? ((a) + (b) / 2) / (b) : ((a) - (b) / 2) / (b))
+#endif
+
+#ifndef DIVIDEFLOOR
+#define DIVIDEFLOOR(a, b)  ((a) / (b))
+#endif
+
+//
+// Number of elements in a 1D array
+//
+#ifndef ARRAY_COUNT
+#define ARRAY_COUNT(a) (sizeof (a) / sizeof (a[0]))
+#endif
+
+//
+//  use for ignore parames
+//
+// #define MRC_IGNORE_PARAM(x) ((x) = (x))
+//
+#if _MSC_EXTENSIONS
+//
+// Disable warning that make it impossible to compile at /W4
+// This only works for Microsoft* tools
+//
+//
+// Disabling bitfield type checking warnings.
+//
+#pragma warning (disable : 4214)
+//
+// Unreferenced formal parameter - We are object oriented, so we pass parameters even
+//  if we don't need them.
+//
+#pragma warning (disable : 4100)
+//
+// ASSERT(FALSE) or while (TRUE) are legal constructs so supress this warning
+//
+#pragma warning(disable : 4127)
+//
+// The given function was selected for inline expansion, but the compiler did not perform the inlining.
+//
+#pragma warning(disable : 4710)
+
+#endif // _MSC_EXTENSIONS
+#define MRC_BIT0          0x00000001
+#define MRC_BIT1          0x00000002
+#define MRC_BIT2          0x00000004
+#define MRC_BIT3          0x00000008
+#define MRC_BIT4          0x00000010
+#define MRC_BIT5          0x00000020
+#define MRC_BIT6          0x00000040
+#define MRC_BIT7          0x00000080
+#define MRC_BIT8          0x00000100
+#define MRC_BIT9          0x00000200
+#define MRC_BIT10         0x00000400
+#define MRC_BIT11         0x00000800
+#define MRC_BIT12         0x00001000
+#define MRC_BIT13         0x00002000
+#define MRC_BIT14         0x00004000
+#define MRC_BIT15         0x00008000
+#define MRC_BIT16         0x00010000
+#define MRC_BIT17         0x00020000
+#define MRC_BIT18         0x00040000
+#define MRC_BIT19         0x00080000
+#define MRC_BIT20         0x00100000
+#define MRC_BIT21         0x00200000
+#define MRC_BIT22         0x00400000
+#define MRC_BIT23         0x00800000
+#define MRC_BIT24         0x01000000
+#define MRC_BIT25         0x02000000
+#define MRC_BIT26         0x04000000
+#define MRC_BIT27         0x08000000
+#define MRC_BIT28         0x10000000
+#define MRC_BIT29         0x20000000
+#define MRC_BIT30         0x40000000
+#define MRC_BIT31         0x80000000
+#define MRC_BIT32        0x100000000ULL
+#define MRC_BIT33        0x200000000ULL
+#define MRC_BIT34        0x400000000ULL
+#define MRC_BIT35        0x800000000ULL
+#define MRC_BIT36       0x1000000000ULL
+#define MRC_BIT37       0x2000000000ULL
+#define MRC_BIT38       0x4000000000ULL
+#define MRC_BIT39       0x8000000000ULL
+#define MRC_BIT40      0x10000000000ULL
+#define MRC_BIT41      0x20000000000ULL
+#define MRC_BIT42      0x40000000000ULL
+#define MRC_BIT43      0x80000000000ULL
+#define MRC_BIT44     0x100000000000ULL
+#define MRC_BIT45     0x200000000000ULL
+#define MRC_BIT46     0x400000000000ULL
+#define MRC_BIT47     0x800000000000ULL
+#define MRC_BIT48    0x1000000000000ULL
+#define MRC_BIT49    0x2000000000000ULL
+#define MRC_BIT50    0x4000000000000ULL
+#define MRC_BIT51    0x8000000000000ULL
+#define MRC_BIT52   0x10000000000000ULL
+#define MRC_BIT53   0x20000000000000ULL
+#define MRC_BIT54   0x40000000000000ULL
+#define MRC_BIT55   0x80000000000000ULL
+#define MRC_BIT56  0x100000000000000ULL
+#define MRC_BIT57  0x200000000000000ULL
+#define MRC_BIT58  0x400000000000000ULL
+#define MRC_BIT59  0x800000000000000ULL
+#define MRC_BIT60 0x1000000000000000ULL
+#define MRC_BIT61 0x2000000000000000ULL
+#define MRC_BIT62 0x4000000000000000ULL
+#define MRC_BIT63 0x8000000000000000ULL
+
+#define MRC_DEADLOOP() { volatile int __iii; __iii = 1; while (__iii); }
+
+#ifndef ASM
+#define ASM __asm
+#endif
+
+///
+/// Type Max/Min Values
+///
+#define MRC_INT32_MAX   (0x7FFFFFFF)
+#define MRC_INT32_MIN   (0x80000000)
+#define MRC_INT64_MAX   (0x7FFFFFFFFFFFFFFFLL)
+#define MRC_INT64_MIN   (0x8000000000000000LL)
+#define MRC_UINT32_MAX  (0xFFFFFFFF)
+#define MRC_UINT64_MAX  (0xFFFFFFFFFFFFFFFFULL)
+#define MRC_UINT_MIN    (0x0)
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h
new file mode 100644
index 0000000000..d444e937d6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h
@@ -0,0 +1,15 @@
+/** @file
+  This file includes all the data structures that the MRC considers "global data".
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _UNIFIED_MrcInterface_h_
+#define _UNIFIED_MrcInterface_h_
+
+#include "Coffeelake/MrcInterface.h"
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
new file mode 100644
index 0000000000..82d798b783
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
@@ -0,0 +1,50 @@
+/** @file
+  Header file for initialization of GT PowerManagement
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GRAPHICS_INIT_H_
+#define _GRAPHICS_INIT_H_
+
+#include <Library/DxeServicesTableLib.h>
+#include <Guid/DxeServices.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Library/PciSegmentLib.h>
+#include <SaAccess.h>
+#include <Protocol/SaPolicy.h>
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <PchAccess.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+
+
+/**
+  Initialize GT ACPI tables
+
+  @param[in] ImageHandle - Handle for the image of this driver
+  @param[in] SaPolicy    - SA DXE Policy protocol
+
+  @retval EFI_SUCCESS          - GT ACPI initialization complete
+  @retval EFI_NOT_FOUND        - Dxe System Table not found.
+  @retval EFI_OUT_OF_RESOURCES - Mmio not allocated successfully.
+**/
+EFI_STATUS
+GraphicsInit (
+  IN EFI_HANDLE             ImageHandle,
+  IN SA_POLICY_PROTOCOL     *SaPolicy
+  );
+
+/**
+  Do Post GT PM Init Steps after VBIOS Initialization.
+
+  @retval EFI_SUCCESS          Succeed.
+**/
+EFI_STATUS
+PostPmInitEndOfDxe (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h
new file mode 100644
index 0000000000..0e95db3d02
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h
@@ -0,0 +1,193 @@
+/** @file
+  This is part of the implementation of an Intel Graphics drivers OpRegion /
+  Software SCI interface between system BIOS, ASL code, and Graphics drivers.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IGD_OPREGION_INIT_H_
+#define _IGD_OPREGION_INIT_H_
+
+///
+/// Statements that include other header files.
+///
+#include <Uefi/UefiBaseType.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <PchAccess.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PmcLib.h>
+#include <SaAccess.h>
+#include <IndustryStandard/Pci22.h>
+#include <CpuRegs.h>
+#include <SaInit.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/HobLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <SiConfigHob.h>
+
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/SaPolicy.h>
+
+
+#include <Private/Protocol/SaNvsArea.h>
+
+///
+/// Driver Produced Protocol Prototypes
+///
+#include <Protocol/IgdOpRegion.h>
+
+///
+///
+/// OpRegion (Miscellaneous) defines.
+///
+/// OpRegion Header defines.
+///
+typedef UINT16  STRING_REF;
+#define HEADER_SIGNATURE            "IntelGraphicsMem"
+#define HEADER_SIZE                 0x2000
+#define HEADER_OPREGION_VER         0x0200
+#define HEADER_OPREGION_REV         0x00
+#define HEADER_MBOX_SUPPORT         (HD_MBOX5 + HD_MBOX4 + HD_MBOX3 + HD_MBOX2 + HD_MBOX1)
+#define HD_MBOX1                    BIT0
+#define HD_MBOX2                    BIT1
+#define HD_MBOX3                    BIT2
+#define HD_MBOX4                    BIT3
+#define HD_MBOX5                    BIT4
+#define SVER_SIZE                   32
+
+///
+/// OpRegion Mailbox 1 EQUates.
+///
+/// OpRegion Mailbox 3 EQUates.
+///
+#define ALS_ENABLE            BIT0
+#define BLC_ENABLE            BIT1
+#define BACKLIGHT_BRIGHTNESS  0xFF
+#define FIELD_VALID_BIT       BIT31
+#define PFIT_ENABLE           BIT2
+#define PFIT_OPRN_AUTO        0x00000000
+#define PFIT_OPRN_SCALING     0x00000007
+#define PFIT_OPRN_OFF         0x00000000
+#define PFIT_SETUP_AUTO       0
+#define PFIT_SETUP_SCALING    1
+#define PFIT_SETUP_OFF        2
+#define INIT_BRIGHT_LEVEL     0x64
+#define PFIT_STRETCH          6
+
+///
+/// Video BIOS / VBT defines
+///
+#define OPTION_ROM_SIGNATURE    0xAA55
+#define VBIOS_LOCATION_PRIMARY  0xC0000
+
+#define VBT_SIGNATURE           SIGNATURE_32 ('$', 'V', 'B', 'T')
+///
+/// Typedef stuctures
+///
+#pragma pack(1)
+typedef struct {
+  UINT16  Signature;  /// 0xAA55
+  UINT8   Size512;
+  UINT8   Reserved[21];
+  UINT16  PcirOffset;
+  UINT16  VbtOffset;
+} INTEL_VBIOS_OPTION_ROM_HEADER;
+#pragma pack()
+
+#pragma pack(1)
+typedef struct {
+  UINT32  Signature;  /// "PCIR"
+  UINT16  VendorId;   /// 0x8086
+  UINT16  DeviceId;
+  UINT16  Reserved0;
+  UINT16  Length;
+  UINT8   Revision;
+  UINT8   ClassCode[3];
+  UINT16  ImageLength;
+  UINT16  CodeRevision;
+  UINT8   CodeType;
+  UINT8   Indicator;
+  UINT16  Reserved1;
+} INTEL_VBIOS_PCIR_STRUCTURE;
+#pragma pack()
+
+#pragma pack(1)
+typedef struct {
+  UINT8   HeaderSignature[20];
+  UINT16  HeaderVersion;
+  UINT16  HeaderSize;
+  UINT16  HeaderVbtSize;
+  UINT8   HeaderVbtCheckSum;
+  UINT8   HeaderReserved;
+  UINT32  HeaderOffsetVbtDataBlock;
+  UINT32  HeaderOffsetAim1;
+  UINT32  HeaderOffsetAim2;
+  UINT32  HeaderOffsetAim3;
+  UINT32  HeaderOffsetAim4;
+  UINT8   DataHeaderSignature[16];
+  UINT16  DataHeaderVersion;
+  UINT16  DataHeaderSize;
+  UINT16  DataHeaderDataBlockSize;
+  UINT8   CoreBlockId;
+  UINT16  CoreBlockSize;
+  UINT16  CoreBlockBiosSize;
+  UINT8   CoreBlockBiosType;
+  UINT8   CoreBlockReleaseStatus;
+  UINT8   CoreBlockHWSupported;
+  UINT8   CoreBlockIntegratedHW;
+  UINT8   CoreBlockBiosBuild[4];
+  UINT8   CoreBlockBiosSignOn[155];
+} VBIOS_VBT_STRUCTURE;
+#pragma pack()
+///
+/// Driver Private Function definitions
+///
+
+/**
+  Graphics OpRegion / Software SCI driver installation function.
+
+  @retval EFI_SUCCESS     - The driver installed without error.
+  @retval EFI_ABORTED     - The driver encountered an error and could not complete
+                            installation of the ACPI tables.
+**/
+EFI_STATUS
+IgdOpRegionInit (
+  VOID
+  );
+
+/**
+  Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
+  The VBT (Video BIOS Table) is a block of customizable data that is built
+  within the video BIOS and edited by customers.
+
+  @retval EFI_SUCCESS            - Video BIOS VBT information returned.
+  @exception EFI_UNSUPPORTED     - Could not find VBT information (*VBiosVbtPtr = NULL).
+**/
+EFI_STATUS
+GetVBiosVbtEndOfDxe (
+  VOID
+  );
+
+/**
+  Update Graphics OpRegion after PCI enumeration.
+
+  @retval EFI_SUCCESS     - The function completed successfully.
+**/
+EFI_STATUS
+UpdateIgdOpRegionEndOfDxe (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
new file mode 100644
index 0000000000..34a2809f80
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
@@ -0,0 +1,91 @@
+/** @file
+  Header file for PciExpress Initialization Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIEXPRESS_INITIALIZATION_DRIVER_H_
+#define _PCIEXPRESS_INITIALIZATION_DRIVER_H_
+
+#include <Library/HobLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Register/Msr.h>
+#include <SaAccess.h>
+#include <PchAccess.h>
+#include <Private/SaConfigHob.h>
+#include <Library/CpuPlatformLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Private/Protocol/SaNvsArea.h>
+
+#define GEN1      1
+#define GEN2      2
+
+///
+/// Function prototypes
+///
+/**
+  PCI Express Dxe Initialization.
+  Run before PCI Bus Init, where assignment of Bus, Memory,
+    and I/O Resources are assigned.
+
+  @param[in] SaPolicy    -     SA DXE Policy protocol
+
+  @retval EFI_SUCCESS        - Pci Express successfully started and ready to be used
+  @exception EFI_UNSUPPORTED - Pci Express can't be initialized
+**/
+EFI_STATUS
+PciExpressInit (
+  IN SA_POLICY_PROTOCOL *SaPolicy
+  );
+
+/**
+  Find the Offset to a given Capabilities ID
+
+  @param[in] Segment   -   Pci Segment Number
+  @param[in] Bus       -   Pci Bus Number
+  @param[in] Device    -   Pci Device Number
+  @param[in] Function  -   Pci Function Number
+  @param[in] CapId     -   CAPID to search fo
+
+  @retval 0       - CAPID not found
+  @retval Other   - CAPID found, Offset of desired CAPID
+**/
+UINT32
+PcieFindCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT8   CapId
+  );
+
+/**
+  Search and return the offset of desired Pci Express Capability ID
+
+  @param[in] Segment   -   Pci Segment Number
+  @param[in] Bus       -   Pci Bus Number
+  @param[in] Device    -   Pci Device Number
+  @param[in] Function  -   Pci Function Number
+  @param[in] CapId     -   Extended CAPID to search for
+
+  @retval 0       - CAPID not found
+  @retval Other   - CAPID found, Offset of desired CAPID
+**/
+UINT32
+PcieFindExtendedCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT16  CapId
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
new file mode 100644
index 0000000000..73af27e9d7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
@@ -0,0 +1,23 @@
+/** @file
+  This is header file for SA PCIE Root Complex initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+EFI_STATUS
+PegInitBeforeEndOfDxe (
+  VOID
+  );
+
+/**
+  This function performs SA registers Saving/Restoring in EndOfDxe callback
+
+  @retval EFI_SUCCESS     - Save/restore has done
+  @retval EFI_UNSUPPORTED - Save/restore not done successfully
+**/
+EFI_STATUS
+SaSaveRestore (
+  VOID
+  );
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
new file mode 100644
index 0000000000..d7e2423ffd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
@@ -0,0 +1,71 @@
+/** @file
+  Header file for SA Common Initialization Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_INITIALIZATION_DRIVER_H_
+#define _SA_INITIALIZATION_DRIVER_H_
+
+#include <Uefi.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/SaPlatformLib.h>
+#include <Guid/EventGroup.h>
+#include <CpuRegs.h>
+#include <SaAccess.h>
+#include <Library/CpuPlatformLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Private/SaConfigHob.h>
+
+extern SA_POLICY_PROTOCOL              *mSaPolicy;
+extern SA_CONFIG_HOB                   *SaConfigHob;
+
+typedef struct {
+  UINT64  BaseAddr;
+  UINT32  Offset;
+  UINT32  AndMask;
+  UINT32  OrMask;
+} BOOT_SCRIPT_REGISTER_SETTING;
+
+/**
+  SystemAgent Initialization Common Function.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+VOID
+SaInitEntryPoint (
+  VOID
+  );
+
+/**
+  Common function locks the PAM register as part of the SA Security requirements.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+VOID
+SaPamLock (
+  VOID
+  );
+/**
+  This function performs SA Security locking in EndOfDxe callback
+
+  @retval EFI_SUCCESS     - Security lock has done
+  @retval EFI_UNSUPPORTED - Security lock not done successfully
+**/
+EFI_STATUS
+SaSecurityInit (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
new file mode 100644
index 0000000000..1991fd82c4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
@@ -0,0 +1,139 @@
+/** @file
+  Header file for SA Initialization Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_INITIALIZATION_DXE_DRIVER_H_
+#define _SA_INITIALIZATION_DXE_DRIVER_H_
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+#include "VTd.h"
+#include "PcieComplex.h"
+#include "IgdOpRegionInit.h"
+#include <Private/Library/LegacyRegion.h>
+#include "GraphicsInit.h"
+#include "PciExpressInit.h"
+#include "SwitchableGraphicsInit.h"
+#include <Library/CpuPlatformLib.h>
+
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include <Protocol/SaPolicy.h>
+
+extern EFI_GUID gSaAcpiTableStorageGuid;
+extern EFI_GUID gSaSsdtAcpiTableStorageGuid;
+extern EFI_GUID gPegSsdtAcpiTableStorageGuid;
+
+typedef struct {
+  UINT64                Address;
+  EFI_BOOT_SCRIPT_WIDTH Width;
+  UINT32                Value;
+} BOOT_SCRIPT_PCI_REGISTER_SAVE;
+
+///
+/// Function Prototype
+///
+/**
+  This function gets registered as a callback to perform SA initialization before ExitPmAuth
+
+  @param[in] Event     - A pointer to the Event that triggered the callback.
+  @param[in] Context   - A pointer to private data registered with the callback function.
+
+  @retval EFI_SUCCESS   - Always.
+
+**/
+VOID
+EFIAPI
+SaPciEnumCompleteCallback (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  );
+
+/**
+  <b>System Agent Initialization DXE Driver Entry Point</b>
+  - <b>Introduction</b> \n
+    Based on the information/data in SA_POLICY_PROTOCOL, this module performs further SA initialization in DXE phase,
+    e.g. internal devices enable/disable, SSVID/SID programming, graphic power-management, VT-d, IGD OpRegion initialization.
+    From the perspective of a PCI Express hierarchy, the Broadwell System Agent and PCH together appear as a Root Complex with root ports the number of which depends on how the 8 PCH ports and 4 System Agent PCIe ports are configured [4x1, 2x8, 1x16].
+    There is an internal link (DMI or OPI) that connects the System Agent to the PCH component. This driver includes initialization of SA DMI, PCI Express, SA & PCH Root Complex Topology.
+    For iGFX, this module implements the initialization of the Graphics Technology Power Management from the Broadwell System Agent BIOS Specification and the initialization of the IGD OpRegion/Software SCI - BIOS Specification.
+    The ASL files that go along with the driver define the IGD OpRegion mailboxes in ACPI space and implement the software SCI interrupt mechanism.
+    The IGD OpRegion/Software SCI code serves as a communication interface between system BIOS, ASL, and Intel graphics driver including making a block of customizable data (VBT) from the Intel video BIOS available.
+    Reference Code for the SCI service functions "Get BIOS Data" and "System BIOS Callback" can be found in the ASL files, those functions can be platform specific, the sample provided in the reference code are implemented for Intel CRB.
+    This module implements the VT-d functionality described in the Broadwell System Agent BIOS Specification.
+    This module publishes the LegacyRegion protocol to control the read and write accesses to the Legacy BIOS ranges.
+    E000 and F000 segments are the legacy BIOS ranges and contain pointers to the ACPI regions, SMBIOS tables and so on. This is a private protocol used by Intel Framework.
+    This module registers CallBack function that performs SA security registers lockdown at end of post as required from Broadwell Bios Spec.
+    In addition, this module publishes the SaInfo Protocol with information such as current System Agent reference code version#.
+
+  - @pre
+    - EFI_FIRMWARE_VOLUME_PROTOCOL: Documented in Firmware Volume Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+    - SA_POLICY_PROTOCOL: A protocol published by a platform DXE module executed earlier; this is documented in this document as well.
+    - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL: Documented in the Unified Extensible Firmware Interface Specification, version 2.0, available at the URL: http://www.uefi.org/specs/
+    - EFI_BOOT_SCRIPT_SAVE_PROTOCOL: A protocol published by a platform DXE module executed earlier; refer to the Sample Code section of the Framework PCH Reference Code.
+    - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL: Documented in the Unified Extensible Firmware Interface Specification, version 2.0, available at the URL: http://www.uefi.org/specs/
+    - EFI_ACPI_TABLE_PROTOCOL : Documented in PI Specification 1.2
+    - EFI_CPU_IO_PROTOCOL: Documented in CPU I/O Protocol Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+    - EFI_DATA_HUB_PROTOCOL: Documented in EFI Data Hub Infrastructure Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+    - EFI_HII_PROTOCOL (or EFI_HII_DATABASE_PROTOCOL for UEFI 2.1): Documented in Human Interface Infrastructure Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+    (For EFI_HII_DATABASE_PROTOCOL, refer to UEFI Specification Version 2.1 available at the URL: http://www.uefi.org/)
+
+  - @result
+    IGD power-management functionality is initialized;  VT-d is initialized (meanwhile, the DMAR table is updated); IGD OpRegion is initialized - IGD_OPREGION_PROTOCOL installed, IGD OpRegion allocated and mailboxes initialized, chipset initialized and ready to generate Software SCI for Internal graphics events. Publishes the SA_INFO_PROTOCOL with current SA reference code version #. Publishes the EFI_LEGACY_REGION_PROTOCOL documented in the Compatibility Support Module Specification, version 0.9, available at the URL: http://www.intel.com/technology/framework/spec.htm
+
+  - <b>References</b> \n
+    IGD OpRegion/Software SCI for Broadwell
+    Advanced Configuration and Power Interface Specification Revision 4.0a.
+
+  - <b>Porting Recommendations</b> \n
+    No modification of the DXE driver should be typically necessary.
+    This driver should be executed after all related devices (audio, video, ME, etc.) are initialized to ensure correct data in DMAR table and DMA-remapping registers.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+  @param[in] SystemTable             Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaInitEntryPointDxe (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+/**
+  SystemAgent Acpi Initialization.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaAcpiInit (
+  IN EFI_HANDLE         ImageHandle
+  );
+
+/**
+  This function locks the PAM register as part of the SA Security requirements.
+
+  @param[in] Event     - A pointer to the Event that triggered the callback.
+  @param[in] Context   - A pointer to private data registered with the callback function.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+VOID
+EFIAPI
+SaPamLockDxe (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h
new file mode 100644
index 0000000000..2b1b4c5880
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h
@@ -0,0 +1,17 @@
+/** @file
+  Header file for the SwitchableGraphics Dxe driver.
+  This driver loads SwitchableGraphics ACPI tables.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SWITCHABLE_GRAPHICS_DXE_H_
+#define _SWITCHABLE_GRAPHICS_DXE_H_
+
+
+#include <Protocol/FirmwareVolume2.h>
+
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
new file mode 100644
index 0000000000..c4bc47f7fe
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
@@ -0,0 +1,53 @@
+/** @file
+  This code provides a initialization of intel VT-d (Virtualization Technology for Directed I/O).
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _VT_D_H_
+#define _VT_D_H_
+
+///
+/// Include files
+///
+#include <DmaRemappingTable.h>
+#include <SaAccess.h>
+#include <PchAccess.h>
+#include <Uefi.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/AcpiTable.h>
+#include <Library/PciSegmentLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Private/PchConfigHob.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include <IndustryStandard/Pci22.h>
+
+
+#define VTD_ECAP_REG  0x10
+#define IR            BIT3
+
+/**
+  Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
+  Publish the appropriate SSDT based on current configuration and capabilities.
+
+  @param[in] SaPolicy            SA DXE Policy protocol
+
+  @retval EFI_SUCCESS - Vtd initialization complete
+  @retval Other       - No Vtd function initiated
+**/
+EFI_STATUS
+VtdInit (
+  IN  SA_POLICY_PROTOCOL    *SaPolicy
+  );
+
+/**
+  PciEnumerationComplete routine for update DMAR
+**/
+VOID
+UpdateDmarPciEnumCompleteCallback (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h
new file mode 100644
index 0000000000..02c74c0672
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h
@@ -0,0 +1,162 @@
+/** @file
+  Header file for SMM Access Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SMM_ACCESS_DRIVER_H_
+#define _SMM_ACCESS_DRIVER_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PciLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Uefi/UefiBaseType.h>
+
+#include <Guid/SmramMemoryReserve.h>
+#include <Protocol/SmmAccess2.h>
+#include <IndustryStandard/Pci22.h>
+#include <SaAccess.h>
+
+#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5', 's', 'a')
+
+///
+/// Private data
+///
+typedef struct {
+  UINTN                           Signature;
+  EFI_HANDLE                      Handle;
+  EFI_SMM_ACCESS2_PROTOCOL        SmmAccess;
+
+  ///
+  /// Local Data for SMM Access interface goes here
+  ///
+  UINTN                           NumberRegions;
+  EFI_SMRAM_DESCRIPTOR            *SmramDesc;
+} SMM_ACCESS_PRIVATE_DATA;
+
+#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
+  CR (a, \
+      SMM_ACCESS_PRIVATE_DATA, \
+      SmmAccess, \
+      SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
+      )
+
+//
+// Prototypes
+// Driver model protocol interface
+//
+/**
+  <b>SMM Access Driver Entry Point</b>
+  This driver installs an SMM Access Protocol
+  - <b>Introduction</b> \n
+    This module publishes the SMM access protocol.  The protocol is used by the SMM Base driver to access the SMRAM region when the processor is not in SMM.
+    The SMM Base driver uses the services provided by the SMM access protocol to open SMRAM during post and copy the SMM handler.
+    SMM access protocol is also used to close the SMRAM region once the copying is done.
+    Finally, the SMM access protocol provides services to "Lock" the SMRAM region.
+    Please refer the SMM Protocols section in the attached SMM CIS Specification version 0.9 for further details.
+    This driver is required if SMM is supported. Proper configuration of SMM registers is recommended even if SMM is not supported.
+
+  - @result
+    Publishes the _EFI_SMM_ACCESS_PROTOCOL: Documented in the System Management Mode Core Interface Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+
+  - <b>Porting Recommendations</b> \n
+    No modification of this module is recommended.  Any modification should be done in compliance with the _EFI_SMM_ACCESS_PROTOCOL protocol definition.
+
+  @param[in] ImageHandle     - Handle for the image of this driver
+  @param[in] SystemTable     - Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS     - Protocol was installed successfully
+  @exception EFI_UNSUPPORTED - Protocol was not installed
+**/
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+/**
+  This routine accepts a request to "open" a region of SMRAM.  The
+  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all boot-service
+  and SMM agents.
+
+  @param[in] This                  - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully opened.
+  @retval EFI_DEVICE_ERROR      - The region could not be opened because locked by
+                          chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Open (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  );
+
+/**
+  This routine accepts a request to "close" a region of SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "close" means that the memory is only visible from SMM agents,
+  not from BS or RT code.
+
+  @param[in] This                  - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully closed.
+  @retval EFI_DEVICE_ERROR      - The region could not be closed because locked by
+                            chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  );
+
+/**
+  This routine accepts a request to "lock" SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to BS state..
+
+  @param[in] This                  - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully locked.
+  @retval EFI_DEVICE_ERROR      - The region could not be locked because at least
+                          one range is still open.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Lock (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  );
+
+/**
+  This routine services a user request to discover the SMRAM
+  capabilities of this platform.  This will report the possible
+  ranges that are possible for SMRAM access, based upon the
+  memory controller capabilities.
+
+  @param[in] This                  - Pointer to the SMRAM Access Interface.
+  @param[in] SmramMapSize          - Pointer to the variable containing size of the
+                            buffer to contain the description information.
+  @param[in] SmramMap              - Buffer containing the data describing the Smram
+                            region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
+**/
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
+  IN OUT UINTN                   *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR    *SmramMap
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
new file mode 100644
index 0000000000..5daa2367e6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
@@ -0,0 +1,157 @@
+/** @file
+  DXE driver for Initializing SystemAgent Graphics ACPI table initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "GraphicsInit.h"
+#include "SaInit.h"
+#include <Protocol/LegacyBios.h>
+#include <Protocol/GopComponentName2.h>
+#include <SiConfigHob.h>
+
+typedef union {
+  struct {
+    UINT32  Low;
+    UINT32  High;
+  } Data32;
+  UINT64 Data;
+} UINT64_STRUCT;
+
+extern SYSTEM_AGENT_NVS_AREA_PROTOCOL  mSaNvsAreaProtocol;
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64                        mGttMmAdr;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64_STRUCT                 mMchBarBase;
+GLOBAL_REMOVE_IF_UNREFERENCED GOP_COMPONENT_NAME2_PROTOCOL  *GopComponentName2Protocol = NULL;
+
+/**
+    Do Post GT PM Init Steps after VBIOS Initialization.
+
+  @retval EFI_SUCCESS          Succeed.
+**/
+EFI_STATUS
+PostPmInitEndOfDxe (
+  VOID
+  )
+{
+  CHAR16                    *DriverVersion;
+  UINTN                     Index;
+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
+  EFI_STATUS                Status;
+  GRAPHICS_DXE_CONFIG       *GraphicsDxeConfig;
+  EFI_PEI_HOB_POINTERS      HobPtr;
+  SI_CONFIG_HOB_DATA        *SiConfigHobData;
+
+  ///
+  /// Get the platform setup policy.
+  ///
+  DriverVersion = NULL;
+  LegacyBios = NULL;
+  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) &mSaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Get Silicon Config data HOB
+  //
+  HobPtr.Guid   = GetFirstGuidHob (&gSiConfigHobGuid);
+  SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA (HobPtr.Guid);
+
+  if (SiConfigHobData->CsmFlag == 1) {
+    Status = gBS->LocateProtocol (
+                    &gEfiLegacyBiosProtocolGuid,
+                    NULL,
+                    (VOID **) &LegacyBios
+                    );
+  }
+
+  if (LegacyBios == NULL) {
+    Status = gBS->LocateProtocol (&gGopComponentName2ProtocolGuid, NULL, (VOID **)&GopComponentName2Protocol);
+    if (!EFI_ERROR (Status)) {
+      Status = GopComponentName2Protocol->GetDriverVersion (
+                                            GopComponentName2Protocol,
+                                            "en-US",
+                                            &DriverVersion
+                                            );
+      if (!EFI_ERROR (Status)) {
+        for (Index = 0; (DriverVersion[Index] != '\0'); Index++) {
+        }
+        Index = (Index+1)*2;
+        CopyMem (GraphicsDxeConfig->GopVersion, DriverVersion, Index);
+      }
+    }
+  }
+
+  ///
+  /// Return final status
+  ///
+  return EFI_SUCCESS;
+}
+
+
+/**
+Initialize GT ACPI tables
+
+  @param[in] ImageHandle -     Handle for the image of this driver
+  @param[in] SaPolicy -        SA DXE Policy protocol
+
+  @retval EFI_SUCCESS          - GT ACPI initialization complete
+  @retval EFI_NOT_FOUND        - Dxe System Table not found.
+  @retval EFI_OUT_OF_RESOURCES - Mmio not allocated successfully.
+**/
+EFI_STATUS
+GraphicsInit (
+  IN EFI_HANDLE              ImageHandle,
+  IN SA_POLICY_PROTOCOL      *SaPolicy
+  )
+{
+  EFI_STATUS            Status;
+  GRAPHICS_DXE_CONFIG   *GraphicsDxeConfig;
+
+  mGttMmAdr               = 0;
+  Status                  = EFI_SUCCESS;
+  mMchBarBase.Data32.High = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MCHBAR + 4));
+  mMchBarBase.Data32.Low  = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MCHBAR));
+  mMchBarBase.Data       &= (UINT64) ~BIT0;
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Update IGD SA Global NVS
+  ///
+  DEBUG ((DEBUG_INFO, " Update Igd SA Global NVS Area.\n"));
+
+  mSaNvsAreaProtocol.Area->AlsEnable                    = GraphicsDxeConfig->AlsEnable;
+  ///
+  /// Initialize IGD state by checking if IGD Device 2 Function 0 is enabled in the chipset
+  ///
+  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_DEVEN)) & B_SA_DEVEN_D2EN_MASK) {
+    mSaNvsAreaProtocol.Area->IgdState = 1;
+  } else {
+    mSaNvsAreaProtocol.Area->IgdState = 0;
+  }
+
+  mSaNvsAreaProtocol.Area->BrightnessPercentage         = 100;
+  mSaNvsAreaProtocol.Area->IgdBootType                  = GraphicsDxeConfig->IgdBootType;
+  mSaNvsAreaProtocol.Area->IgdPanelType                 = GraphicsDxeConfig->IgdPanelType;
+  mSaNvsAreaProtocol.Area->IgdPanelScaling              = GraphicsDxeConfig->IgdPanelScaling;
+  ///
+  /// Get SFF power mode platform data for the IGD driver.  Flip the bit (bitwise xor)
+  /// since Setup value is opposite of NVS and IGD OpRegion value.
+  ///
+  mSaNvsAreaProtocol.Area->IgdDvmtMemSize               = GraphicsDxeConfig->IgdDvmtMemSize;
+  mSaNvsAreaProtocol.Area->IgdFunc1Enable               = 0;
+  mSaNvsAreaProtocol.Area->IgdHpllVco                   = MmioRead8 (mMchBarBase.Data + 0xC0F) & 0x07;
+  mSaNvsAreaProtocol.Area->IgdSciSmiMode                = 0;
+  mSaNvsAreaProtocol.Area->GfxTurboIMON                 = GraphicsDxeConfig->GfxTurboIMON;
+
+  mSaNvsAreaProtocol.Area->EdpValid                     = 0;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c
new file mode 100644
index 0000000000..6ec0691074
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c
@@ -0,0 +1,570 @@
+/** @file
+  This is part of the implementation of an Intel Graphics drivers OpRegion /
+  Software SCI interface between system BIOS, ASL code, and Graphics drivers.
+  The code in this file will load the driver and initialize the interface
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "IgdOpRegionInit.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED IGD_OPREGION_PROTOCOL           mIgdOpRegion;
+
+/**
+  Get VBT data using SaPlaformPolicy
+
+  @param[out] VbtFileBuffer    Pointer to VBT data buffer.
+
+  @retval EFI_SUCCESS      VBT data was returned.
+  @retval EFI_NOT_FOUND    VBT data not found.
+  @exception EFI_UNSUPPORTED  Invalid signature in VBT data.
+**/
+EFI_STATUS
+GetIntegratedIntelVbtPtr (
+  OUT VBIOS_VBT_STRUCTURE **VbtFileBuffer
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_PHYSICAL_ADDRESS          VbtAddress;
+  UINT32                        Size;
+  GRAPHICS_DXE_CONFIG           *GraphicsDxeConfig;
+
+  ///
+  /// Get the SA policy.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaPolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &mSaPolicy
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  VbtAddress = GraphicsDxeConfig->VbtAddress;
+  Size       = GraphicsDxeConfig->Size;
+
+  if (VbtAddress == 0x00000000) {
+    return EFI_NOT_FOUND;
+  } else {
+    ///
+    /// Check VBT signature
+    ///
+    *VbtFileBuffer  = NULL;
+    *VbtFileBuffer = (VBIOS_VBT_STRUCTURE *) (UINTN) VbtAddress;
+    if ((*((UINT32 *) ((*VbtFileBuffer)->HeaderSignature))) != VBT_SIGNATURE) {
+      FreePool (*VbtFileBuffer);
+      *VbtFileBuffer = NULL;
+      return EFI_UNSUPPORTED;
+    }
+  }
+  if (Size == 0) {
+    return EFI_NOT_FOUND;
+  } else {
+    ///
+    /// Check VBT size
+    ///
+    if ((*VbtFileBuffer)->HeaderVbtSize > Size) {
+      (*VbtFileBuffer)->HeaderVbtSize = (UINT16) Size;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Get a pointer to an uncompressed image of the Intel video BIOS.
+
+  @Note: This function would only be called if the video BIOS at 0xC000 is
+         missing or not an Intel video BIOS.  It may not be an Intel video BIOS
+         if the Intel graphic contoller is considered a secondary adapter.
+
+  @param[out] VBiosImage     - Pointer to an uncompressed Intel video BIOS.  This pointer must
+                               be set to NULL if an uncompressed image of the Intel Video BIOS
+                               is not obtainable.
+
+  @retval EFI_SUCCESS        - VBiosPtr is updated.
+  @exception EFI_UNSUPPORTED - No Intel video BIOS found.
+**/
+EFI_STATUS
+GetIntegratedIntelVBiosPtr (
+  OUT INTEL_VBIOS_OPTION_ROM_HEADER **VBiosImage
+  )
+{
+  EFI_HANDLE                    *HandleBuffer;
+  UINTN                         HandleCount;
+  UINTN                         Index;
+  INTEL_VBIOS_PCIR_STRUCTURE    *PcirBlockPtr;
+  EFI_STATUS                    Status;
+  EFI_PCI_IO_PROTOCOL           *PciIo;
+  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosRomImage;
+
+  ///
+  /// Set as if an umcompressed Intel video BIOS image was not obtainable.
+  ///
+  VBiosRomImage = NULL;
+
+  ///
+  /// Get all PCI IO protocols
+  ///
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiPciIoProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Find the video BIOS by checking each PCI IO handle for an Intel video
+  /// BIOS OPROM.
+  ///
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gEfiPciIoProtocolGuid,
+                    (VOID **) &PciIo
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    VBiosRomImage = PciIo->RomImage;
+
+    ///
+    /// If this PCI device doesn't have a ROM image, skip to the next device.
+    ///
+    if (!VBiosRomImage) {
+      continue;
+    }
+    ///
+    /// Get pointer to PCIR structure
+    ///
+    PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *) VBiosRomImage + VBiosRomImage->PcirOffset);
+
+    ///
+    /// Check if we have an Intel video BIOS OPROM.
+    ///
+    if ((VBiosRomImage->Signature == OPTION_ROM_SIGNATURE) &&
+        (PcirBlockPtr->VendorId == V_SA_MC_VID) &&
+        (PcirBlockPtr->ClassCode[0] == 0x00) &&
+        (PcirBlockPtr->ClassCode[1] == 0x00) &&
+        (PcirBlockPtr->ClassCode[2] == 0x03)
+        ) {
+      ///
+      /// Found Intel video BIOS.
+      ///
+      *VBiosImage = VBiosRomImage;
+      return EFI_SUCCESS;
+    }
+  }
+  ///
+  /// No Intel video BIOS found.
+  ///
+  ///
+  /// Free any allocated buffers
+  ///
+  FreePool (HandleBuffer);
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
+  The VBT (Video BIOS Table) is a block of customizable data that is built
+  within the video BIOS and edited by customers.
+
+  @retval EFI_SUCCESS            - Video BIOS VBT information returned.
+  @exception EFI_UNSUPPORTED     - Could not find VBT information (*VBiosVbtPtr = NULL).
+**/
+EFI_STATUS
+GetVBiosVbtEndOfDxe (
+  VOID
+  )
+{
+  INTEL_VBIOS_PCIR_STRUCTURE    *PcirBlockPtr;
+  UINT32                        PcirBlockAddress;
+  UINT16                        PciVenderId;
+  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosPtr;
+  VBIOS_VBT_STRUCTURE           *VBiosVbtPtr;
+  EFI_LEGACY_BIOS_PROTOCOL      *LegacyBios;
+  EFI_STATUS                    Status;
+  VBIOS_VBT_STRUCTURE           *VbtFileBuffer;
+  UINTN                         Index;
+  UINT8                         LegacyVbtFound;
+  GRAPHICS_DXE_CONFIG           *GraphicsDxeConfig;
+  EFI_PEI_HOB_POINTERS          HobPtr;
+  SI_CONFIG_HOB_DATA            *SiConfigHobData;
+
+  VbtFileBuffer = NULL;
+  LegacyVbtFound = 1;
+
+  ///
+  /// Get the SA policy.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaPolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &mSaPolicy
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  LegacyBios = NULL;
+  VBiosPtr = NULL;
+  //
+  // Get Silicon Config data HOB
+  //
+  HobPtr.Guid = GetFirstGuidHob (&gSiConfigHobGuid);
+  SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA (HobPtr.Guid);
+  if (SiConfigHobData->CsmFlag == 1) {
+    Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
+
+    if (LegacyBios) {
+      VBiosPtr      = (INTEL_VBIOS_OPTION_ROM_HEADER *) (UINTN) (VBIOS_LOCATION_PRIMARY);
+      PcirBlockAddress = VBIOS_LOCATION_PRIMARY + VBiosPtr->PcirOffset;
+      PcirBlockPtr  = (INTEL_VBIOS_PCIR_STRUCTURE *) (UINTN) (PcirBlockAddress);
+      PciVenderId   = PcirBlockPtr->VendorId;
+      ///
+      /// If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get
+      /// the integrated Intel video BIOS (must be uncompressed).
+      ///
+      if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != V_SA_MC_VID)) {
+        GetIntegratedIntelVBiosPtr (&VBiosPtr);
+        if (VBiosPtr != NULL) {
+          ///
+          /// Video BIOS found.
+          ///
+          PcirBlockPtr  = (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *) VBiosPtr + VBiosPtr->PcirOffset);
+          PciVenderId   = PcirBlockPtr->VendorId;
+
+          if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != V_SA_MC_VID)) {
+            ///
+            /// Intel video BIOS not found.
+            ///
+            VBiosVbtPtr = NULL;
+            LegacyVbtFound = 0;
+          }
+        }
+      }
+    }
+  }
+  if ((LegacyBios == NULL) || (LegacyVbtFound == 0)) {
+    ///
+    /// No Video BIOS found, try to get VBT from FV.
+    ///
+    GetIntegratedIntelVbtPtr (&VbtFileBuffer);
+    if (VbtFileBuffer != NULL) {
+      ///
+      /// Video BIOS not found, use VBT from SaPolicy
+      ///
+      DEBUG ((DEBUG_INFO, "VBT data found\n"));
+      for (Index = 0; (GraphicsDxeConfig->GopVersion[Index] != '\0'); Index++) {
+      }
+      Index = (Index+1)*2;
+      CopyMem (mIgdOpRegion.OpRegion->Header.DVER, GraphicsDxeConfig->GopVersion, Index);
+      CopyMem (mIgdOpRegion.OpRegion->MBox4.RVBT, VbtFileBuffer, VbtFileBuffer->HeaderVbtSize);
+      return EFI_SUCCESS;
+    }
+  }
+
+  if (VBiosPtr == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  DEBUG ((DEBUG_INFO, "VBIOS found at 0x%X\n", VBiosPtr));
+  VBiosVbtPtr = (VBIOS_VBT_STRUCTURE *) ((UINT8 *) VBiosPtr + VBiosPtr->VbtOffset);
+
+  if ((*((UINT32 *) (VBiosVbtPtr->HeaderSignature))) != VBT_SIGNATURE) {
+    return EFI_UNSUPPORTED;
+  }
+
+  ///
+  /// Initialize Video BIOS version with its build number.
+  ///
+  mIgdOpRegion.OpRegion->Header.VVER[0] = VBiosVbtPtr->CoreBlockBiosBuild[0];
+  mIgdOpRegion.OpRegion->Header.VVER[1] = VBiosVbtPtr->CoreBlockBiosBuild[1];
+  mIgdOpRegion.OpRegion->Header.VVER[2] = VBiosVbtPtr->CoreBlockBiosBuild[2];
+  mIgdOpRegion.OpRegion->Header.VVER[3] = VBiosVbtPtr->CoreBlockBiosBuild[3];
+  CopyMem (mIgdOpRegion.OpRegion->MBox4.RVBT, VBiosVbtPtr, VBiosVbtPtr->HeaderVbtSize);
+
+  ///
+  /// Return final status
+  ///
+  return EFI_SUCCESS;
+}
+
+/**
+  Graphics OpRegion / Software SCI driver installation function.
+
+  @param[in] void         - None
+  @retval EFI_SUCCESS     - The driver installed without error.
+  @retval EFI_ABORTED     - The driver encountered an error and could not complete
+                            installation of the ACPI tables.
+**/
+EFI_STATUS
+IgdOpRegionInit (
+  VOID
+  )
+{
+  EFI_HANDLE                      Handle;
+  EFI_STATUS                      Status;
+  UINT32                          DwordData;
+  UINT64                          IgdBaseAddress;
+  SA_POLICY_PROTOCOL              *SaPolicy;
+  GRAPHICS_DXE_CONFIG             *GraphicsDxeConfig;
+  UINT8                           Index;
+  SYSTEM_AGENT_NVS_AREA_PROTOCOL  *SaNvsAreaProtocol;
+
+  ///
+  /// Get the SA policy.
+  ///
+  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **)&SaPolicy);
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+  ///
+  ///  Locate the SA Global NVS Protocol.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaNvsAreaProtocolGuid,
+                  NULL,
+                  (VOID **) &SaNvsAreaProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize
+  /// the first 1K, and set the IGD OpRegion pointer in the Global NVS
+  /// area structure.
+  ///
+  Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof (IGD_OPREGION_STRUCTURE), (VOID **) &mIgdOpRegion.OpRegion);
+  ASSERT_EFI_ERROR (Status);
+
+  SetMem (mIgdOpRegion.OpRegion, sizeof (IGD_OPREGION_STRUCTURE), 0);
+  SaNvsAreaProtocol->Area->IgdOpRegionAddress = (UINT32) (UINTN) (mIgdOpRegion.OpRegion);
+
+  ///
+  /// If IGD is disabled return
+  ///
+  IgdBaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0);
+  if (PciSegmentRead32 (IgdBaseAddress + 0) == 0xFFFFFFFF) {
+    return EFI_SUCCESS;
+  }
+  ///
+  /// Initialize OpRegion Header
+  ///
+  CopyMem (mIgdOpRegion.OpRegion->Header.SIGN, HEADER_SIGNATURE, sizeof (HEADER_SIGNATURE));
+  ///
+  /// Set OpRegion Size in KBs
+  ///
+  mIgdOpRegion.OpRegion->Header.SIZE = HEADER_SIZE / 1024;
+  mIgdOpRegion.OpRegion->Header.OVER = (UINT32) (LShiftU64 (HEADER_OPREGION_VER, 16) + LShiftU64 (HEADER_OPREGION_REV, 8));
+
+  ///
+  /// All Mailboxes are supported.
+  ///
+  mIgdOpRegion.OpRegion->Header.MBOX = HEADER_MBOX_SUPPORT;
+
+  ///
+  /// Initialize OpRegion Mailbox 1 (Public ACPI Methods).
+  ///
+  /// Note - The initial setting of mailbox 1 fields is implementation specific.
+  /// Adjust them as needed many even coming from user setting in setup.
+  ///
+  ///
+  /// Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservation).
+  ///
+  /// Note - The initial setting of mailbox 3 fields is implementation specific.
+  /// Adjust them as needed many even coming from user setting in setup.
+  ///
+  ///
+  /// Do not initialize TCHE. This field is written by the graphics driver only.
+  ///
+  ///
+  /// The ALSI field is generally initialized by ASL code by reading the embedded controller.
+  ///
+  mIgdOpRegion.OpRegion->Header.PCON = GraphicsDxeConfig->PlatformConfig;
+  mIgdOpRegion.OpRegion->Header.PCON = mIgdOpRegion.OpRegion->Header.PCON | 0x2;
+
+  mIgdOpRegion.OpRegion->MBox3.BCLP = BACKLIGHT_BRIGHTNESS;
+
+  mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_STRETCH);
+
+  ///
+  /// Reporting to driver for VR IMON Calibration. Bits [5-1] values supported 14A to 31A.
+  ///
+  mIgdOpRegion.OpRegion->MBox3.PCFT = (SaNvsAreaProtocol->Area->GfxTurboIMON << 1) & 0x003E;
+
+  ///
+  /// Set Initial current Brightness
+  ///
+  mIgdOpRegion.OpRegion->MBox3.CBLV = (INIT_BRIGHT_LEVEL | FIELD_VALID_BIT);
+
+  ///
+  /// Static Backlight Brightness Level Duty cycle Mapping Table
+  ///
+  for (Index = 0; Index < MAX_BCLM_ENTRIES; Index++) {
+    mIgdOpRegion.OpRegion->MBox3.BCLM[Index] = GraphicsDxeConfig->BCLM[Index];
+  }
+
+  mIgdOpRegion.OpRegion->MBox3.IUER = 0x00;
+
+  if (!EFI_ERROR (Status)) {
+    mIgdOpRegion.OpRegion->MBox3.IUER =  GraphicsDxeConfig->IuerStatusVal;
+  }
+
+  ///
+  /// Initialize hardware state:
+  ///   Set ASLS Register to the OpRegion physical memory address.
+  ///   Set SWSCI register bit 15 to a "1" to activate SCI interrupts.
+  ///
+  PciSegmentWrite32 (IgdBaseAddress + R_SA_IGD_ASLS_OFFSET, (UINT32) (UINTN) (mIgdOpRegion.OpRegion));
+  PciSegmentAndThenOr16 (IgdBaseAddress + R_SA_IGD_SWSCI_OFFSET, (UINT16) ~(BIT0), BIT15);
+
+  DwordData = PciSegmentRead32 (IgdBaseAddress + R_SA_IGD_ASLS_OFFSET);
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint32,
+    (UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (IgdBaseAddress + R_SA_IGD_ASLS_OFFSET),
+    1,
+    &DwordData
+    );
+  DwordData = PciSegmentRead32 (IgdBaseAddress + R_SA_IGD_SWSCI_OFFSET);
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint32,
+    (UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (IgdBaseAddress + R_SA_IGD_SWSCI_OFFSET),
+    1,
+    &DwordData
+    );
+
+  ///
+  /// Install OpRegion / Software SCI protocol
+  ///
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gIgdOpRegionProtocolGuid,
+                  &mIgdOpRegion,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Return final status
+  ///
+  return EFI_SUCCESS;
+}
+
+/**
+  Update Graphics OpRegion after PCI enumeration.
+
+  @param[in] void         - None
+  @retval EFI_SUCCESS     - The function completed successfully.
+**/
+EFI_STATUS
+UpdateIgdOpRegionEndOfDxe (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  UINTN                         HandleCount;
+  EFI_HANDLE                    *HandleBuffer;
+  UINTN                         Index;
+  EFI_PCI_IO_PROTOCOL           *PciIo;
+  PCI_TYPE00                    Pci;
+  UINTN                         Segment;
+  UINTN                         Bus;
+  UINTN                         Device;
+  UINTN                         Function;
+
+  Bus      = 0;
+  Device   = 0;
+  Function = 0;
+
+  DEBUG ((DEBUG_INFO, "UpdateIgdOpRegionEndOfDxe\n"));
+
+  mIgdOpRegion.OpRegion->Header.PCON |= BIT8; //Set External Gfx Adapter field is valid
+  mIgdOpRegion.OpRegion->Header.PCON &= (UINT32) (~BIT7); //Assume No External Gfx Adapter
+
+  ///
+  /// Get all PCI IO protocols handles
+  ///
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiPciIoProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+
+  if (!EFI_ERROR (Status)) {
+    for (Index = 0; Index < HandleCount; Index++) {
+      ///
+      /// Get the PCI IO Protocol Interface corresponding to each handle
+      ///
+      Status = gBS->HandleProtocol (
+                      HandleBuffer[Index],
+                      &gEfiPciIoProtocolGuid,
+                      (VOID **) &PciIo
+                      );
+
+      if (!EFI_ERROR (Status)) {
+        ///
+        /// Read the PCI configuration space
+        ///
+        Status = PciIo->Pci.Read (
+                              PciIo,
+                              EfiPciIoWidthUint32,
+                              0,
+                              sizeof (Pci) / sizeof (UINT32),
+                              &Pci
+                              );
+
+        ///
+        /// Find the display controllers devices
+        ///
+        if (!EFI_ERROR (Status) && IS_PCI_DISPLAY (&Pci)) {
+          Status = PciIo->GetLocation (
+                            PciIo,
+                            &Segment,
+                            &Bus,
+                            &Device,
+                            &Function
+                            );
+
+          //
+          // Assumption: Onboard devices will be sits on Bus no 0, while external devices will be sits on Bus no > 0
+          //
+          if (!EFI_ERROR (Status) && (Bus > 0)) {
+            //External Gfx Adapter Detected and Available
+            DEBUG ((DEBUG_INFO, "PCON - External Gfx Adapter Detected and Available\n"));
+            mIgdOpRegion.OpRegion->Header.PCON |= BIT7;
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  ///
+  /// Free any allocated buffers
+  ///
+  if (HandleBuffer != NULL) {
+    FreePool (HandleBuffer);
+  }
+
+  ///
+  /// Return final status
+  ///
+  return Status;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
new file mode 100644
index 0000000000..bbdf0d0fab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
@@ -0,0 +1,171 @@
+/** @file
+  This driver does SA PCI Express ACPI table initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PciExpressInit.h"
+
+extern SYSTEM_AGENT_NVS_AREA_PROTOCOL   mSaNvsAreaProtocol;
+extern SA_CONFIG_HOB                    *mSaConfigHob;
+
+/**
+  PCI Express Dxe Initialization.
+  Run before PCI Bus Init, where assignment of Bus, Memory,
+    and I/O Resources are assigned.
+
+  @param[in] SaPolicy     -     SA DXE Policy protocol
+
+  @retval EFI_SUCCESS     - Pci Express successfully started and ready to be used
+**/
+EFI_STATUS
+PciExpressInit (
+  IN SA_POLICY_PROTOCOL *SaPolicy
+  )
+{
+  EFI_STATUS                                    Status;
+  PCIE_DXE_CONFIG                               *PcieDxeConfig;
+  MSR_BROADWELL_PKG_CST_CONFIG_CONTROL_REGISTER Msr;
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+
+  Msr.Uint64 = AsmReadMsr64 (MSR_BROADWELL_PKG_CST_CONFIG_CONTROL);
+  mSaNvsAreaProtocol.Area->PackageCstateLimit  = (UINT8) Msr.Bits.Limit;
+
+  mSaNvsAreaProtocol.Area->PwrDnBundlesGlobalEnable  = 0;
+
+  if (mSaConfigHob != NULL) {
+    mSaNvsAreaProtocol.Area->Peg0PowerDownUnusedBundles  = mSaConfigHob->PowerDownUnusedBundles[0];
+    mSaNvsAreaProtocol.Area->Peg1PowerDownUnusedBundles  = mSaConfigHob->PowerDownUnusedBundles[1];
+    mSaNvsAreaProtocol.Area->Peg2PowerDownUnusedBundles  = mSaConfigHob->PowerDownUnusedBundles[2];
+    if (SA_PEG_MAX_FUN > 3) {
+      mSaNvsAreaProtocol.Area->Peg3PowerDownUnusedBundles  = mSaConfigHob->PowerDownUnusedBundles[3];
+    }
+  }
+  ///
+  /// LTR/OBFF
+  ///
+  mSaNvsAreaProtocol.Area->Peg0LtrEnable                = PcieDxeConfig->PegPwrOpt[0].LtrEnable;
+  mSaNvsAreaProtocol.Area->Peg0ObffEnable               = PcieDxeConfig->PegPwrOpt[0].ObffEnable;
+  mSaNvsAreaProtocol.Area->Peg1LtrEnable                = PcieDxeConfig->PegPwrOpt[1].LtrEnable;
+  mSaNvsAreaProtocol.Area->Peg1ObffEnable               = PcieDxeConfig->PegPwrOpt[1].ObffEnable;
+  mSaNvsAreaProtocol.Area->Peg2LtrEnable                = PcieDxeConfig->PegPwrOpt[2].LtrEnable;
+  mSaNvsAreaProtocol.Area->Peg2ObffEnable               = PcieDxeConfig->PegPwrOpt[2].ObffEnable;
+  mSaNvsAreaProtocol.Area->PegLtrMaxSnoopLatency        = LTR_MAX_SNOOP_LATENCY_VALUE;
+  mSaNvsAreaProtocol.Area->PegLtrMaxNoSnoopLatency      = LTR_MAX_NON_SNOOP_LATENCY_VALUE;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Find the Offset to a given Capabilities ID
+  CAPID list:
+    0x01 = PCI Power Management Interface
+    0x04 = Slot Identification
+    0x05 = MSI Capability
+    0x10 = PCI Express Capability
+
+  @param[in] Segment   -   Pci Segment Number
+  @param[in] Bus       -   Pci Bus Number
+  @param[in] Device    -   Pci Device Number
+  @param[in] Function  -   Pci Function Number
+  @param[in] CapId     -   CAPID to search for
+
+  @retval 0       - CAPID not found
+  @retval Other   - CAPID found, Offset of desired CAPID
+**/
+UINT32
+PcieFindCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT8   CapId
+  )
+{
+  UINT64 DeviceBaseAddress;
+  UINT8  CapHeader;
+
+  ///
+  /// Always start at Offset 0x34
+  ///
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+  CapHeader         = PciSegmentRead8 (DeviceBaseAddress + PCI_CAPBILITY_POINTER_OFFSET);
+  if (CapHeader == 0xFF) {
+    return 0;
+  }
+
+  while (CapHeader != 0) {
+    ///
+    /// Bottom 2 bits of the pointers are reserved per PCI Local Bus Spec 2.2
+    ///
+    CapHeader &= ~(BIT1 + BIT0);
+    ///
+    /// Search for desired CapID
+    ///
+    if (PciSegmentRead8 (DeviceBaseAddress + CapHeader) == CapId) {
+      return CapHeader;
+    }
+
+    CapHeader = PciSegmentRead8 (DeviceBaseAddress + CapHeader + 1);
+  }
+
+  return 0;
+}
+
+/**
+  Search and return the offset of desired Pci Express Capability ID
+  CAPID list:
+    0x0001 = Advanced Error Rreporting Capability
+    0x0002 = Virtual Channel Capability
+    0x0003 = Device Serial Number Capability
+    0x0004 = Power Budgeting Capability
+
+  @param[in] Segment   -   Pci Segment Number
+  @param[in] Bus       -   Pci Bus Number
+  @param[in] Device    -   Pci Device Number
+  @param[in] Function  -   Pci Function Number
+  @param[in] CapId     -   Extended CAPID to search for
+
+  @retval 0       - CAPID not found
+  @retval Other   - CAPID found, Offset of desired CAPID
+**/
+UINT32
+PcieFindExtendedCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT16  CapId
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT16  CapHeaderOffset;
+  UINT16  CapHeaderId;
+
+  ///
+  /// Start to search at Offset 0x100
+  /// Get Capability Header
+  ///
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+  CapHeaderId     = 0;
+  CapHeaderOffset = 0x100;
+
+  while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
+    ///
+    /// Search for desired CapID
+    ///
+    CapHeaderId = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset);
+    if (CapHeaderId == CapId) {
+      return CapHeaderOffset;
+    }
+
+    CapHeaderOffset = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 2) >> 4);
+  }
+
+  return 0;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
new file mode 100644
index 0000000000..1dc37334ae
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
@@ -0,0 +1,171 @@
+/** @file
+  This file will perform SA PCIE Root Complex initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PciExpressInit.h"
+#include <Private/Library/SaPcieLib.h>
+#include "PcieComplex.h"
+#include <Private/Protocol/SaIotrapSmi.h>
+#include "SaInit.h"
+
+///
+/// Global variables
+///
+UINT16                                 mSaIotrapSmiAddress;
+extern SA_CONFIG_HOB                   *mSaConfigHob;
+
+///
+/// Functions
+///
+/**
+    This function gets registered as a callback to perform all SA late initialization
+
+    @param[in] Event     - A pointer to the Event that triggered the callback.
+    @param[in] Context   - A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+SaLateInitSmiCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS                 Status;
+  SA_IOTRAP_SMI_PROTOCOL     *SaIotrapSmiProtocol;
+
+  if (mSaIotrapSmiAddress == 0) {
+    //
+    // Use global variable instead of protocol data since it maybe tampered in unsecure environment
+    // Get IOTrap address when first time this routine calling (gEfiPciEnumerationCompleteProtocolGuid callback)
+    //
+    SaIotrapSmiProtocol = NULL;
+    Status = gBS->LocateProtocol (&gSaIotrapSmiProtocolGuid, NULL, (VOID **) &SaIotrapSmiProtocol);
+    ASSERT_EFI_ERROR (Status);
+    if (SaIotrapSmiProtocol != NULL) {
+      mSaIotrapSmiAddress = SaIotrapSmiProtocol->SaIotrapSmiAddress;
+    }
+  }
+
+  ASSERT (mSaIotrapSmiAddress != 0);
+  if (mSaIotrapSmiAddress != 0) {
+    //
+    // Generate IOTRAP SMI immediately
+    //
+    DEBUG ((DEBUG_INFO, "[SA] Issue IOTRAP SMI %X\n", mSaIotrapSmiAddress));
+    IoWrite8 (mSaIotrapSmiAddress, 0);
+  }
+  if (Event != NULL) {
+    gBS->CloseEvent (Event);
+  }
+  return;
+}
+
+/**
+  This function performs Peg initialization before EndOfDxe.
+  @note This function will be executed as gEfiPciEnumerationCompleteProtocolGuid protocol callback and assumed SA DXE/SMM drivers have been dispatched.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+EFI_STATUS
+PegInitBeforeEndOfDxe (
+  VOID
+  )
+{
+  EFI_EVENT                       ReadyToBoot;
+  EFI_STATUS                      Status;
+  BOOLEAN                         AspmHasBeenHandled;
+
+  DEBUG ((DEBUG_INFO, "[SA] Pcie before EndOfDxe callback.\n"));
+  AspmHasBeenHandled = FALSE;
+  ///
+  /// SMM mode ASPM handling
+  /// Check if supported and enabled
+  ///
+  if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom == TRUE)) {
+    ///
+    /// Do the Phase 1 SMI callback
+    /// This will enumerate PCIe downstream devices
+    ///
+    SaLateInitSmiCallback (NULL, NULL);
+
+    if (mSaIotrapSmiAddress != 0) {
+      ///
+      /// Create an ReadyToBoot call back event to do the Phase 3 SMI callback
+      /// This will handle PEG ASPM programming after OROM execution
+      /// Note: Phase 2 SMI callback will be triggered in EndOfDxe callback
+      ///       to initialize rest of PCIe settings prior to OPROM
+      ///
+      Status = EfiCreateEventReadyToBootEx (
+                 TPL_NOTIFY,
+                 (EFI_EVENT_NOTIFY) SaLateInitSmiCallback,
+                 NULL,
+                 &ReadyToBoot
+                 );
+      ASSERT_EFI_ERROR (Status);
+      AspmHasBeenHandled = TRUE;
+    }
+  }
+
+  ///
+  /// DXE mode ASPM handling
+  /// Check if SMM mode already taken care all things
+  /// TRUE to skip DXE mode task. Otherwise do DXE mode ASPM initialization
+  ///
+  if (AspmHasBeenHandled == FALSE) {
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function performs SA registers Saving/Restoring in EndOfDxe callback
+
+  @retval EFI_SUCCESS     - Save/restore has done
+  @retval EFI_UNSUPPORTED - Save/restore not done successfully
+**/
+EFI_STATUS
+SaSaveRestore (
+  VOID
+  )
+{
+  BOOLEAN                         SaveRestoreHasBeenHandled;
+  UINT8                           SmiData;
+
+  SaveRestoreHasBeenHandled = FALSE;
+
+  if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom == TRUE)) {
+    ///
+    /// Generate the Phase 2 of SA SMI to do SA chipset save/restore and security lock
+    ///
+    SaLateInitSmiCallback (NULL, NULL);
+
+    if (mSaIotrapSmiAddress != 0) {
+      ///
+      /// Store IOTRAP SMI address into Boot Script save table
+      /// This is required to trigger this IOTRAP during S3 resume to restore all settings
+      ///
+      SmiData = 0;
+      S3BootScriptSaveIoWrite (
+        S3BootScriptWidthUint8,
+        (UINTN) mSaIotrapSmiAddress,
+        1,
+        &SmiData
+        );
+      SaveRestoreHasBeenHandled = TRUE;
+    }
+  }
+
+  ///
+  /// Check if SMM mode already taken care this task
+  ///
+  if (SaveRestoreHasBeenHandled == TRUE) {
+    return EFI_SUCCESS;
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
new file mode 100644
index 0000000000..d5a63785b4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
@@ -0,0 +1,496 @@
+/** @file
+  This is the driver that initializes the Intel System Agent.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <Private/SaConfigHob.h>
+#include <Private/Protocol/SaNvsArea.h>
+#include <Library/PchInfoLib.h>
+
+///
+/// Global Variables
+///
+GLOBAL_REMOVE_IF_UNREFERENCED SYSTEM_AGENT_NVS_AREA_PROTOCOL  mSaNvsAreaProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED SA_POLICY_PROTOCOL              *mSaPolicy;
+extern SA_CONFIG_HOB                                          *mSaConfigHob;
+
+/**
+  Initialize System Agent SSDT ACPI tables
+
+  @retval EFI_SUCCESS    ACPI tables are initialized successfully
+  @retval EFI_NOT_FOUND  ACPI tables not found
+**/
+EFI_STATUS
+InitializeSaSsdtAcpiTables (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_HANDLE                    *HandleBuffer;
+  UINTN                         NumberOfHandles;
+  EFI_FV_FILETYPE               FileType;
+  UINT32                        FvStatus;
+  EFI_FV_FILE_ATTRIBUTES        Attributes;
+  UINTN                         Size;
+  UINTN                         i;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+  INTN                          Instance;
+  EFI_ACPI_COMMON_HEADER        *CurrentTable;
+  UINTN                         AcpiTableKey;
+  UINT8                         *CurrPtr;
+  UINT8                         *EndPtr;
+  UINT32                        *Signature;
+  EFI_ACPI_DESCRIPTION_HEADER   *SaAcpiTable;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+
+  FwVol       = NULL;
+  SaAcpiTable = NULL;
+
+  ///
+  /// Locate ACPI Table protocol
+  ///
+  DEBUG ((DEBUG_INFO, "Init SA SSDT table\n"));
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+  if (Status != EFI_SUCCESS) {
+    DEBUG ((DEBUG_WARN, "Fail to locate EfiAcpiTableProtocol.\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  ///
+  /// Locate protocol.
+  /// There is little chance we can't find an FV protocol
+  ///
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &NumberOfHandles,
+                  &HandleBuffer
+                  );
+  ASSERT_EFI_ERROR (Status);
+  ///
+  /// Looking for FV with ACPI storage file
+  ///
+  for (i = 0; i < NumberOfHandles; i++) {
+    ///
+    /// Get the protocol on this handle
+    /// This should not fail because of LocateHandleBuffer
+    ///
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[i],
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID **) &FwVol
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    ///
+    /// See if it has the ACPI storage file
+    ///
+    Size      = 0;
+    FvStatus  = 0;
+    Status = FwVol->ReadFile (
+                      FwVol,
+                      &gSaSsdtAcpiTableStorageGuid,
+                      NULL,
+                      &Size,
+                      &FileType,
+                      &Attributes,
+                      &FvStatus
+                      );
+
+    ///
+    /// If we found it, then we are done
+    ///
+    if (Status == EFI_SUCCESS) {
+      break;
+    }
+  }
+  ///
+  /// Free any allocated buffers
+  ///
+  FreePool (HandleBuffer);
+
+  ///
+  /// Sanity check that we found our data file
+  ///
+  ASSERT (FwVol != NULL);
+  if (FwVol == NULL) {
+    DEBUG ((DEBUG_INFO, "SA Global NVS table not found\n"));
+    return EFI_NOT_FOUND;
+  }
+  ///
+  /// Our exit status is determined by the success of the previous operations
+  /// If the protocol was found, Instance already points to it.
+  /// Read tables from the storage file.
+  ///
+  Instance      = 0;
+  CurrentTable  = NULL;
+  while (Status == EFI_SUCCESS) {
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &gSaSsdtAcpiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID **) &CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+      ///
+      /// Check the table ID to modify the table
+      ///
+      if (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->OemTableId == SIGNATURE_64 ('S', 'a', 'S', 's', 'd', 't', ' ', 0)) {
+        SaAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
+        ///
+        /// Locate the SSDT package
+        ///
+        CurrPtr = (UINT8 *) SaAcpiTable;
+        EndPtr  = CurrPtr + SaAcpiTable->Length;
+
+        for (; CurrPtr <= EndPtr; CurrPtr++) {
+          Signature = (UINT32 *) (CurrPtr + 3);
+          if (*Signature == SIGNATURE_32 ('S', 'A', 'N', 'V')) {
+            ASSERT (*(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) == 0xFFFF0000);
+            ASSERT (*(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) == 0xAA55);
+            ///
+            /// SA Global NVS Area address
+            ///
+            *(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) = (UINT32) (UINTN) mSaNvsAreaProtocol.Area;
+            ///
+            /// SA Global NVS Area size
+            ///
+            *(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) =
+              sizeof (SYSTEM_AGENT_NVS_AREA);
+
+            AcpiTableKey = 0;
+            Status = AcpiTable->InstallAcpiTable (
+                                  AcpiTable,
+                                  SaAcpiTable,
+                                  SaAcpiTable->Length,
+                                  &AcpiTableKey
+                                  );
+            ASSERT_EFI_ERROR (Status);
+            return EFI_SUCCESS;
+          }
+        }
+      }
+      ///
+      /// Increment the instance
+      ///
+      Instance++;
+      CurrentTable = NULL;
+    }
+  }
+
+  return Status;
+
+}
+
+/**
+  Install SSDT Table
+
+  @retval EFI_SUCCESS - SSDT Table load successful.
+**/
+EFI_STATUS
+InstallSsdtAcpiTable (
+  IN GUID   SsdtTableGuid,
+  IN UINT64 Signature
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_HANDLE                    *HandleBuffer;
+  BOOLEAN                       LoadTable;
+  UINTN                         NumberOfHandles;
+  UINTN                         Index;
+  INTN                          Instance;
+  UINTN                         Size;
+  UINT32                        FvStatus;
+  UINTN                         TableHandle;
+  EFI_FV_FILETYPE               FileType;
+  EFI_FV_FILE_ATTRIBUTES        Attributes;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+  EFI_ACPI_DESCRIPTION_HEADER   *TableHeader;
+  EFI_ACPI_COMMON_HEADER        *Table;
+
+  FwVol         = NULL;
+  Table         = NULL;
+
+  DEBUG ((DEBUG_INFO, "Loading SSDT Table GUID: %g\n", SsdtTableGuid));
+
+  ///
+  /// Locate FV protocol.
+  ///
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &NumberOfHandles,
+                  &HandleBuffer
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Look for FV with ACPI storage file
+  ///
+  for (Index = 0; Index < NumberOfHandles; Index++) {
+    ///
+    /// Get the protocol on this handle
+    /// This should not fail because of LocateHandleBuffer
+    ///
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID **) &FwVol
+                    );
+    ASSERT_EFI_ERROR (Status);
+    if (FwVol == NULL) {
+      return EFI_NOT_FOUND;
+    }
+    ///
+    /// See if it has the ACPI storage file
+    ///
+    Size      = 0;
+    FvStatus  = 0;
+    Status = FwVol->ReadFile (
+                      FwVol,
+                      &SsdtTableGuid,
+                      NULL,
+                      &Size,
+                      &FileType,
+                      &Attributes,
+                      &FvStatus
+                      );
+
+    ///
+    /// If we found it, then we are done
+    ///
+    if (!EFI_ERROR (Status)) {
+      break;
+    }
+  }
+  ///
+  /// Our exit status is determined by the success of the previous operations
+  /// If the protocol was found, Instance already points to it.
+  ///
+  ///
+  /// Free any allocated buffers
+  ///
+  FreePool (HandleBuffer);
+
+  ///
+  /// Sanity check that we found our data file
+  ///
+  ASSERT (FwVol);
+
+  ///
+  /// Locate ACPI tables
+  ///
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+
+  ///
+  /// Read tables from the storage file.
+  ///
+  if (FwVol == NULL) {
+    ASSERT_EFI_ERROR (EFI_NOT_FOUND);
+    return EFI_NOT_FOUND;
+  }
+  Instance = 0;
+
+  while (Status == EFI_SUCCESS) {
+    ///
+    /// Read the ACPI tables
+    ///
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &SsdtTableGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID **) &Table,
+                      &Size,
+                      &FvStatus
+                      );
+    if (!EFI_ERROR (Status)) {
+      ///
+      /// check and load SwitchableGraphics SSDT table
+      ///
+      LoadTable   = FALSE;
+      TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+
+      if (((EFI_ACPI_DESCRIPTION_HEADER *) TableHeader)->OemTableId == Signature) {
+        ///
+        /// This is the SSDT table that match the Signature
+        ///
+        DEBUG ((DEBUG_INFO, "Found out SSDT Table GUID: %g\n", SsdtTableGuid));
+        LoadTable = TRUE;
+      }
+
+      ///
+      /// Add the table
+      ///
+      if (LoadTable) {
+        TableHandle = 0;
+        Status = AcpiTable->InstallAcpiTable (
+                              AcpiTable,
+                              TableHeader,
+                              TableHeader->Length,
+                              &TableHandle
+                              );
+      }
+      ///
+      /// Increment the instance
+      ///
+      Instance++;
+      Table = NULL;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function gets registered as a callback to perform Dmar Igd
+
+  @param[in] Event     - A pointer to the Event that triggered the callback.
+  @param[in] Context   - A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+SaAcpiEndOfDxeCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS          Status;
+
+  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 0xFFFF) {
+    Status = PostPmInitEndOfDxe ();
+    if (EFI_SUCCESS != Status) {
+      DEBUG ((DEBUG_WARN, "[SA] EndOfDxe GraphicsInit Error, Status = %r \n", Status));
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+
+  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 0xFFFF) {
+    Status = GetVBiosVbtEndOfDxe ();
+    if (EFI_SUCCESS != Status) {
+      DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Op Region Error, Status = %r \n", Status));
+    }
+
+    Status = UpdateIgdOpRegionEndOfDxe ();
+    if (EFI_SUCCESS != Status) {
+      DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Update Op Region Error, Status = %r \n", Status));
+    }
+  }
+
+  return;
+}
+
+/**
+  SystemAgent Acpi Initialization.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaAcpiInit (
+  IN EFI_HANDLE         ImageHandle
+  )
+{
+  EFI_STATUS                Status;
+  EFI_CPUID_REGISTER        CpuidRegs;
+  CPU_FAMILY                CpuFamilyId;
+  EFI_EVENT                 EndOfDxeEvent;
+
+  CpuFamilyId = GetCpuFamily();
+  AsmCpuid (1, &CpuidRegs.RegEax, 0, 0, 0);
+  ///
+  /// Get the platform setup policy.
+  ///
+  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) &mSaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Install System Agent Global NVS protocol
+  ///
+  DEBUG ((DEBUG_INFO, "Install SA GNVS protocol\n"));
+  Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof (SYSTEM_AGENT_NVS_AREA), (VOID **) &mSaNvsAreaProtocol.Area);
+  ASSERT_EFI_ERROR (Status);
+  ZeroMem ((VOID *) mSaNvsAreaProtocol.Area, sizeof (SYSTEM_AGENT_NVS_AREA));
+  mSaNvsAreaProtocol.Area->XPcieCfgBaseAddress  = (UINT32) (PcdGet64 (PcdPciExpressBaseAddress));
+  mSaNvsAreaProtocol.Area->CpuIdInfo            = CpuidRegs.RegEax;
+  if (mSaConfigHob != NULL) {
+    mSaNvsAreaProtocol.Area->IpuAcpiMode = mSaConfigHob->IpuAcpiMode;
+  }
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gSaNvsAreaProtocolGuid,
+                  &mSaNvsAreaProtocol,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// PciExpress Dxe Initialization
+  ///
+  DEBUG ((DEBUG_INFO, "Initializing PciExpress (Dxe)\n"));
+  PciExpressInit (mSaPolicy);
+
+  ///
+  /// GtPostInit Initialization
+  ///
+  DEBUG ((DEBUG_INFO, "Initializing GT ACPI tables\n"));
+
+  GraphicsInit (ImageHandle, mSaPolicy);
+
+  /// Vtd Initialization
+  ///
+  DEBUG ((DEBUG_INFO, "Initializing VT-d ACPI tables\n"));
+  VtdInit (mSaPolicy);
+
+  ///
+  /// IgdOpRegion Install Initialization
+  ///
+  DEBUG ((DEBUG_INFO, "Initializing IGD OpRegion\n"));
+  IgdOpRegionInit ();
+
+  ///
+  /// Register an end of DXE event for SA ACPI to do tasks before invoking any UEFI drivers,
+  /// applications, or connecting consoles,...
+  ///
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  SaAcpiEndOfDxeCallback,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+
+  ///
+  /// Install System Agent Global NVS ACPI table
+  ///
+  Status = InitializeSaSsdtAcpiTables ();
+
+  ///
+  /// Install PEG SSDT table only if PEG port is present
+  ///
+  if (IsPchLinkDmi (CpuFamilyId)) {
+    if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, SA_PEG0_FUN_NUM, R_SA_PEG_DID_OFFSET)) != V_SA_DEVICE_ID_INVALID) {
+      Status = InstallSsdtAcpiTable (gPegSsdtAcpiTableStorageGuid, SIGNATURE_64 ('P','e','g','S','s','d','t',0));
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
new file mode 100644
index 0000000000..40bb107ad0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
@@ -0,0 +1,179 @@
+/** @file
+  This is the Common driver that initializes the Intel System Agent.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInit.h"
+#include <Library/PciSegmentLib.h>
+#include <Private/SaConfigHob.h>
+#include <Protocol/PciEnumerationComplete.h>
+
+//
+// Declare I/O Ports used to perform PCI Confguration Cycles
+//
+#define PCI_CONFIGURATION_ADDRESS_PORT  0xCF8
+#define PCI_CONFIGURATION_DATA_PORT     0xCFC
+
+/**
+  Convert a PCI Library address to PCI CF8 formatted address.
+
+  Declare macro to convert PCI Library address to PCI CF8 formatted address.
+  Bit fields of PCI Library and CF8 formatted address is as follows:
+  PCI Library formatted address    CF8 Formatted Address
+ =============================    ======================
+    Bits 00..11  Register           Bits 00..07  Register
+    Bits 12..14  Function           Bits 08..10  Function
+    Bits 15..19  Device             Bits 11..15  Device
+    Bits 20..27  Bus                Bits 16..23  Bus
+    Bits 28..31  Reserved(MBZ)      Bits 24..30  Reserved(MBZ)
+                                    Bits 31..31  Must be 1
+
+  @param  A The address to convert.
+
+  @retval The coverted address.
+
+**/
+#define PCI_TO_CF8_ADDRESS(A) \
+  ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
+
+///
+/// Global Variables
+///
+GLOBAL_REMOVE_IF_UNREFERENCED SA_CONFIG_HOB                          *mSaConfigHob;
+BOOLEAN                                                              mSkipPamLock = FALSE;
+
+/*
+  Intel(R) Core Processor Skylake BWG version 0.4.0
+
+  18.6 System Agent Configuration Locking
+   For reliable operation and security, System BIOS must set the following bits:
+   1. For all modern Intel processors, Intel strongly recommends that BIOS should set
+       the D_LCK bit. Set B0:D0:F0.R088h [4] = 1b to lock down SMRAM space.
+  BaseAddr values for mSaSecurityRegisters that uses PciExpressBaseAddress will be initialized at
+  Runtime inside function SaPcieInitPolicy().
+*/
+GLOBAL_REMOVE_IF_UNREFERENCED BOOT_SCRIPT_REGISTER_SETTING mSaSecurityRegisters[] = {
+  {0,  R_SA_SMRAMC,  0xFFFFFFFF,  BIT4}
+};
+
+/**
+  SystemAgent Initialization Common Function.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+
+VOID
+SaInitEntryPoint (
+  VOID
+  )
+{
+  ///
+  /// Get SaConfigHob HOB
+  ///
+  mSaConfigHob              = NULL;
+  mSaConfigHob              = (SA_CONFIG_HOB *) GetFirstGuidHob (&gSaConfigHobGuid);
+  if (mSaConfigHob != NULL) {
+    mSkipPamLock = mSaConfigHob->SkipPamLock;
+  }
+
+  return;
+}
+
+
+
+/**
+  Common function locks the PAM register as part of the SA Security requirements.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+
+VOID
+SaPamLock (
+  VOID
+  )
+{
+  UINT64 BaseAddress;
+  UINT32 Data32Or;
+
+  if (mSkipPamLock == FALSE) {
+    //
+    // Lock PAM by PAM Lock Bit
+    //
+    BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, 0, 0, 0);
+    Data32Or    = BIT0;
+    DEBUG ((DEBUG_INFO, "PAM_LOCK!!\n"));
+    PciSegmentOr32 (BaseAddress + R_SA_PAM0, Data32Or);
+  }
+}
+
+/**
+  This function does SA security lock
+**/
+VOID
+SaSecurityLock (
+  VOID
+  )
+{
+  UINT8           Index;
+  UINT32          RegOffset;
+  UINT32          Data32Or;
+  UINT32          Data32;
+  UINT8           Data8;
+
+  ///
+  /// 17.2 System Agent Security Lock configuration
+  ///
+  DEBUG ((DEBUG_INFO, "DXE SaSecurityLock\n"));
+  for (Index = 0; Index < (sizeof (mSaSecurityRegisters) / sizeof (BOOT_SCRIPT_REGISTER_SETTING)); Index++) {
+    RegOffset   = mSaSecurityRegisters[Index].Offset;
+    Data32Or    = mSaSecurityRegisters[Index].OrMask;
+
+    if (RegOffset == R_SA_SMRAMC) {
+      ///
+      /// SMRAMC LOCK must use CF8/CFC access
+      ///
+      PciCf8Or8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC), (UINT8) Data32Or);
+      Data8 = PciCf8Read8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC));
+      Data32 = PCI_TO_CF8_ADDRESS (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC));
+      S3BootScriptSaveIoWrite (
+        S3BootScriptWidthUint32,
+        (UINTN) (PCI_CONFIGURATION_ADDRESS_PORT),
+        1,
+        &Data32
+        );
+      S3BootScriptSaveIoWrite (
+        S3BootScriptWidthUint8,
+        (UINTN) (PCI_CONFIGURATION_DATA_PORT),
+        1,
+        &Data8
+        );
+    }
+  }
+}
+
+/**
+  This function performs SA Security locking in EndOfDxe callback
+
+  @retval EFI_SUCCESS     - Security lock has done
+  @retval EFI_UNSUPPORTED - Security lock not done successfully
+**/
+EFI_STATUS
+SaSecurityInit (
+  VOID
+  )
+{
+
+  UINT8                     Index;
+
+  for (Index = 0; Index < (sizeof (mSaSecurityRegisters) / sizeof (BOOT_SCRIPT_REGISTER_SETTING)); Index++) {
+    if (mSaSecurityRegisters[Index].BaseAddr != PcdGet64 (PcdMchBaseAddress)) {
+      mSaSecurityRegisters[Index].BaseAddr = PcdGet64 (PcdPciExpressBaseAddress);
+    }
+  }
+  SaSecurityLock ();
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
new file mode 100644
index 0000000000..d646e60618
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
@@ -0,0 +1,122 @@
+/** @file
+  This is the driver that initializes the Intel System Agent.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <Private/SaConfigHob.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <MemInfoHob.h>
+
+///
+/// Global Variables
+///
+extern SA_CONFIG_HOB         *mSaConfigHob;
+
+/**
+  SystemAgent Dxe Initialization.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+  @param[in] SystemTable             Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaInitEntryPointDxe (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                Status;
+  VOID                      *Registration;
+
+  DEBUG ((DEBUG_INFO, "SaInitDxe Start\n"));
+
+  SaInitEntryPoint ();
+
+  Status = SaAcpiInit (ImageHandle);
+
+  ///
+  /// Create PCI Enumeration Completed callback for SA
+  ///
+  EfiCreateProtocolNotifyEvent (
+    &gEfiPciEnumerationCompleteProtocolGuid,
+    TPL_CALLBACK,
+    SaPciEnumCompleteCallback,
+    NULL,
+    &Registration
+    );
+
+  DEBUG ((DEBUG_INFO, "SaInitDxe End\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function gets registered as a callback to perform SA initialization before EndOfDxe
+
+  @param[in] Event     - A pointer to the Event that triggered the callback.
+  @param[in] Context   - A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+SaPciEnumCompleteCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS          Status;
+  VOID                *ProtocolPointer;
+
+  DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback Start\n"));
+  ///
+  /// Check if this is first time called by EfiCreateProtocolNotifyEvent() or not,
+  /// if it is, we will skip it until real event is triggered
+  ///
+  Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, NULL, (VOID **) &ProtocolPointer);
+  if (EFI_SUCCESS != Status) {
+    return;
+  }
+
+  gBS->CloseEvent (Event);
+
+  Status = PegInitBeforeEndOfDxe ();
+  if (EFI_SUCCESS != Status) {
+    DEBUG ((DEBUG_WARN, "[SA] Pcie initialization before EndOfDxe Error, Status = %r \n", Status));
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  SaSaveRestore ();
+  SaSecurityInit ();
+  UpdateDmarPciEnumCompleteCallback ();
+
+  DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback End\n"));
+  return;
+}
+
+/**
+  This function locks the PAM register as part of the SA Security requirements.
+
+  @param[in] Event     - A pointer to the Event that triggered the callback.
+  @param[in] Context   - A pointer to private data registered with the callback function.
+
+**/
+VOID
+EFIAPI
+SaPamLockDxe (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  DEBUG ((DEBUG_INFO, "SaPamLockDxe Start\n"));
+
+  SaPamLock ();
+
+  DEBUG ((DEBUG_INFO, "SaPamLockDxe End\n"));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
new file mode 100644
index 0000000000..acbf6b7aab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
@@ -0,0 +1,717 @@
+/** @file
+  This code provides a initialization of intel VT-d (Virtualization Technology for Directed I/O).
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include "VTd.h"
+#include <CpuRegs.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <PchInfoHob.h>
+#include <PchAccess.h>
+
+
+extern SA_CONFIG_HOB                                          *mSaConfigHob;
+
+/**
+  For device that specified by Device Num and Function Num,
+  mDevEnMap is used to check device presence.
+  0x80 means use Device ID to detemine presence
+  0x8F means force to update
+
+  The structure is used to check if device scope is valid when update DMAR table
+**/
+UINT16  mDevEnMap[][2] = {{0x0200, 0x80}, {0x1400, 0x80}, {0x1401, 0x80}, {0x1607, 0x8F}};
+
+BOOLEAN mInterruptRemappingSupport;
+
+/**
+  Get the corresponding device Enable/Disable bit according DevNum and FunNum
+
+  @param[in] DevNum  - Device Number
+  @param[in] FunNum  - Function Number
+
+  @retval If the device is found, return disable/Enable bit in FD/Deven reigster
+  @retval If not found return 0xFF
+**/
+UINT16
+GetFunDisableBit (
+  UINT8 DevNum,
+  UINT8 FunNum
+  )
+{
+  UINTN Index;
+
+  for (Index = 0; Index < sizeof (mDevEnMap) / 4; Index++) {
+    if (mDevEnMap[Index][0] == ((DevNum << 0x08) | FunNum)) {
+      return mDevEnMap[Index][1];
+    }
+  }
+
+  return 0xFF;
+}
+
+/**
+  Update the DRHD structure
+
+  @param[in, out] DrhdEnginePtr       - A pointer to DRHD structure
+**/
+VOID
+UpdateDrhd (
+  IN OUT VOID *DrhdEnginePtr
+  )
+{
+  UINT16                        Length;
+  UINT16                        DisableBit;
+  BOOLEAN                       NeedRemove;
+  EFI_ACPI_DRHD_ENGINE1_STRUCT  *DrhdEngine;
+
+  //
+  // Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE1_STRUCT Pointer
+  //
+  DrhdEngine      = (EFI_ACPI_DRHD_ENGINE1_STRUCT *) DrhdEnginePtr;
+  Length          = DrhdEngine->DrhdHeader.Header.Length;
+  DisableBit = GetFunDisableBit (
+                 DrhdEngine->DeviceScope[0].PciPath.Device,
+                 DrhdEngine->DeviceScope[0].PciPath.Function
+                 );
+  NeedRemove = FALSE;
+
+  if ((DisableBit == 0xFF) ||
+      (DrhdEngine->DrhdHeader.RegisterBaseAddress == 0) ||
+      ((DisableBit == 0x80) &&
+       (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, DrhdEngine->DeviceScope[0].PciPath.Device, DrhdEngine->DeviceScope[0].PciPath.Function, 0x00)) == 0xFFFFFFFF))
+      ) {
+    NeedRemove = TRUE;
+  }
+  if (NeedRemove) {
+    Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+  }
+  ///
+  /// If no devicescope is left, we set the structure length as 0x00
+  ///
+  if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) || (DrhdEngine->DrhdHeader.Flags == 0x01)) {
+    DrhdEngine->DrhdHeader.Header.Length = Length;
+  } else {
+    DrhdEngine->DrhdHeader.Header.Length = 0;
+  }
+}
+
+/**
+  Get IOAPIC ID from LPC
+
+  @retval APIC ID
+**/
+UINT8
+GetIoApicId (
+  VOID
+  )
+{
+  UINT32                IoApicAddress;
+  UINT32                IoApicId;
+
+  IoApicAddress = PcdGet32 (PcdIoApicBaseAddress);
+  ///
+  /// Get current IO APIC ID
+  ///
+  MmioWrite8 ((UINTN) (IoApicAddress + R_IO_APIC_INDEX_OFFSET), 0);
+  IoApicId = MmioRead32 ((UINTN) (IoApicAddress + R_IO_APIC_DATA_OFFSET)) >> 24;
+
+  return (UINT8) IoApicId;
+}
+
+/**
+  Update the second DRHD structure
+
+  @param[in, out] DrhdEnginePtr       - A pointer to DRHD structure
+**/
+VOID
+UpdateDrhd2 (
+  IN OUT VOID *DrhdEnginePtr
+  )
+{
+  UINT16                        Length;
+  UINTN                         DeviceScopeNum;
+  UINTN                         ValidDeviceScopeNum;
+  UINT16                        Index;
+  UINT8                         Bus;
+  UINT8                         Path[2];
+  BOOLEAN                       NeedRemove;
+  EFI_ACPI_DRHD_ENGINE3_STRUCT  *DrhdEngine;
+  VOID                          *HobPtr;
+  PCH_INFO_HOB                  *PchInfoHob;
+
+  ///
+  /// Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE3_STRUCT Pointer
+  ///
+  DrhdEngine      = (EFI_ACPI_DRHD_ENGINE3_STRUCT *) DrhdEnginePtr;
+
+  Length          = DrhdEngine->DrhdHeader.Header.Length;
+  DeviceScopeNum  = (DrhdEngine->DrhdHeader.Header.Length - EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) / sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+  Bus             = 0;
+  ValidDeviceScopeNum = 0;
+  Path[0]         = 0;
+  Path[1]         = 0;
+
+  HobPtr = GetFirstGuidHob (&gPchInfoHobGuid);
+  ASSERT (HobPtr != NULL);
+  if (HobPtr == NULL) {
+    return;
+  }
+  PchInfoHob = (PCH_INFO_HOB *) GET_GUID_HOB_DATA (HobPtr);
+  ASSERT (PchInfoHob != NULL);
+  if (PchInfoHob == NULL) {
+    return;
+  }
+
+  for (Index = 0; Index < DeviceScopeNum; Index++) {
+    NeedRemove = FALSE;
+    /**
+      For HPET and APIC, update device scope if Interrupt remapping is supported. remove device scope
+      if interrupt remapping is not supported.
+      - Index = 0 - IOAPIC
+      - Index = 1 - HPET
+    **/
+    if (mInterruptRemappingSupport) {
+      if (Index == 0) {
+        ///
+        /// Update source id for IoApic's device scope entry
+        ///
+        Bus = (UINT8) PchInfoHob->IoApicBusNum;
+        Path[0] = (UINT8) PchInfoHob->IoApicDevNum;
+        Path[1] = (UINT8) PchInfoHob->IoApicFuncNum;
+        DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNumber = Bus;
+        DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
+        DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
+        //
+        // Update APIC ID
+        //
+        DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.EnumerationId = GetIoApicId ();
+      }
+      if (Index == 1) {
+        ///
+        /// Update source id for HPET's device scope entry
+        ///
+        Bus     = (UINT8) PchInfoHob->HpetBusNum;
+        Path[0] = (UINT8) PchInfoHob->HpetDevNum;
+        Path[1] = (UINT8) PchInfoHob->HpetFuncNum;
+        DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNumber = Bus;
+        DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
+        DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
+      }
+    } else {
+      if ((Index == 0) || (Index == 1)) {
+        NeedRemove = TRUE;
+      }
+    }
+
+    CopyMem (
+      &DrhdEngine->DeviceScope[ValidDeviceScopeNum],
+      &DrhdEngine->DeviceScope[Index],
+      sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
+      );
+    if (NeedRemove) {
+      Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+    } else {
+      ValidDeviceScopeNum++;
+    }
+  }
+  ///
+  /// If no devicescope is left, we set the structure length as 0x00
+  ///
+  if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) || (DrhdEngine->DrhdHeader.Flags == 0x01)) {
+    DrhdEngine->DrhdHeader.Header.Length = Length;
+  } else {
+    DrhdEngine->DrhdHeader.Header.Length = 0;
+  }
+}
+
+/**
+  Update the RMRR structure
+
+  @param[in, out] RmrrPtr             - A pointer to RMRR structure
+**/
+VOID
+UpdateRmrr (
+  IN OUT VOID *RmrrPtr
+  )
+{
+  UINT16                  Length;
+  UINT16                  DisableBit;
+  UINTN                   DeviceScopeNum;
+  UINTN                   ValidDeviceScopeNum;
+  UINTN                   Index;
+  BOOLEAN                 NeedRemove;
+  EFI_ACPI_RMRR_USB_STRUC *Rmrr;
+
+  ///
+  /// To make sure all devicescope can be checked,
+  /// we convert the RmrrPtr to EFI_ACPI_RMRR_USB_STRUC pointer
+  ///
+  Rmrr                = (EFI_ACPI_RMRR_USB_STRUC *) RmrrPtr;
+
+  Length              = Rmrr->RmrrHeader.Header.Length;
+  ValidDeviceScopeNum = 0;
+  DeviceScopeNum      = (Rmrr->RmrrHeader.Header.Length - EFI_ACPI_RMRR_HEADER_LENGTH) / sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+  for (Index = 0; Index < DeviceScopeNum; Index++) {
+    DisableBit = GetFunDisableBit (
+                   Rmrr->DeviceScope[Index].PciPath.Device,
+                   Rmrr->DeviceScope[Index].PciPath.Function
+                   );
+    NeedRemove = FALSE;
+    if ((DisableBit == 0xFF) ||
+        ((DisableBit == 0x80) &&
+         (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, Rmrr->DeviceScope[Index].PciPath.Device, Rmrr->DeviceScope[Index].PciPath.Function, 0x00)) == 0xFFFFFFFF))
+        ) {
+      NeedRemove = TRUE;
+    } else if (DisableBit == 0x8F) {
+      NeedRemove = FALSE;
+    }
+    CopyMem (
+      &Rmrr->DeviceScope[ValidDeviceScopeNum],
+      &Rmrr->DeviceScope[Index],
+      sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
+      );
+
+    if (Rmrr->RmrrHeader.ReservedMemoryRegionLimitAddress == 0x0) {
+      NeedRemove = TRUE;
+    }
+
+    if (NeedRemove) {
+      Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+    } else {
+      ValidDeviceScopeNum++;
+    }
+  }
+  ///
+  /// If No deviceScope is left, set length as 0x00
+  ///
+  if (Length > EFI_ACPI_RMRR_HEADER_LENGTH) {
+    Rmrr->RmrrHeader.Header.Length = Length;
+  } else {
+    Rmrr->RmrrHeader.Header.Length = 0;
+  }
+}
+
+/**
+  Update the DMAR table
+
+  @param[in, out] TableHeader         - The table to be set
+  @param[in, out] Version             - Version to publish
+**/
+VOID
+DmarTableUpdate (
+  IN OUT   EFI_ACPI_DESCRIPTION_HEADER       *TableHeader,
+  IN OUT   EFI_ACPI_TABLE_VERSION            *Version
+  )
+{
+  EFI_ACPI_DMAR_TABLE *DmarTable;
+  EFI_ACPI_DMAR_TABLE TempDmarTable;
+  UINTN               Offset;
+  UINTN               StructureLen;
+  UINT64              McD0BaseAddress;
+  UINTN               MchBar;
+  UINT16              IgdMode;
+  UINT16              GttMode;
+  UINT32              IgdMemSize;
+  UINT32              GttMemSize;
+  EFI_STATUS          Status;
+  MISC_DXE_CONFIG     *MiscDxeConfig;
+
+  IgdMemSize  = 0;
+  GttMemSize  = 0;
+  DmarTable   = (EFI_ACPI_DMAR_TABLE *) TableHeader;
+
+  Status = GetConfigBlock ((VOID *) mSaPolicy, &gMiscDxeConfigGuid, (VOID *)&MiscDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Set INTR_REMAP bit (BIT 0) if interrupt remapping is supported
+  ///
+  if (mInterruptRemappingSupport) {
+    DmarTable->DmarHeader.Flags |= BIT0;
+  }
+
+  if (mSaConfigHob->VtdData.X2ApicOptOut == 1) {
+    DmarTable->DmarHeader.Flags |= BIT1;
+  } else {
+    DmarTable->DmarHeader.Flags &= 0xFD;
+  }
+
+  ///
+  /// Get OemId
+  ///
+  CopyMem (DmarTable->DmarHeader.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (DmarTable->DmarHeader.Header.OemId));
+  DmarTable->DmarHeader.Header.OemTableId      = PcdGet64 (PcdAcpiDefaultOemTableId);
+  DmarTable->DmarHeader.Header.OemRevision     = PcdGet32 (PcdAcpiDefaultOemRevision);
+  DmarTable->DmarHeader.Header.CreatorId       = PcdGet32 (PcdAcpiDefaultCreatorId);
+  DmarTable->DmarHeader.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+
+  ///
+  /// Calculate IGD memsize
+  ///
+  McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, 0);
+  MchBar          = PciSegmentRead32 (McD0BaseAddress + R_SA_MCHBAR) & ~BIT0;
+  IgdMode = ((PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) & B_SA_GGC_GMS_MASK) >> N_SA_GGC_GMS_OFFSET) & 0xFF;
+  if (IgdMode < 0xF0) {
+    IgdMemSize = IgdMode * 32 * (1024) * (1024);
+  } else {
+    IgdMemSize = 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024);
+  }
+  ///
+  /// Calculate GTT mem size
+  ///
+  GttMemSize = 0;
+  GttMode = (PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) & B_SA_GGC_GGMS_MASK) >> N_SA_GGC_GGMS_OFFSET;
+  if (GttMode <= V_SA_GGC_GGMS_8MB) {
+    GttMemSize = (1 << GttMode) * (1024) * (1024);
+  }
+
+  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress   = (PciSegmentRead32 (McD0BaseAddress + R_SA_TOLUD) & ~(0x01)) - IgdMemSize - GttMemSize;
+  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress  = DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress + IgdMemSize + GttMemSize - 1;
+  DEBUG ((DEBUG_INFO, "RMRR Base  address IGD %016lX\n", DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress));
+  DEBUG ((DEBUG_INFO, "RMRR Limit address IGD %016lX\n", DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress));
+
+  DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress   = MiscDxeConfig->RmrrUsbBaseAddress[0];
+  DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress  = MiscDxeConfig->RmrrUsbBaseAddress[1];
+
+  ///
+  /// Convert to 4KB alignment.
+  ///
+  if (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress != 0x0) {
+    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress  &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
+    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
+    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress += 0x1000-1;
+  }
+
+  DEBUG ((DEBUG_INFO, "RMRR Base  address USB %016lX\n", DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress));
+  DEBUG ((DEBUG_INFO, "RMRR Limit address USB %016lX\n", DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress));
+
+  if (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress == 0) {
+    DEBUG ((DEBUG_WARN, "WARNING:  RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress is 0.\n"));
+  }
+
+  DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress   = MiscDxeConfig->RmrrCsmeBaseAddress[0];
+  DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress  = MiscDxeConfig->RmrrCsmeBaseAddress[1];
+  DEBUG ((DEBUG_INFO, "RMRR Base  address CSME %016lX\n", DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress));
+  DEBUG ((DEBUG_INFO, "RMRR Limit address CSME %016lX\n", DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress));
+  ///
+  /// Update DRHD structures of DmarTable
+  ///
+  DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
+  DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD3_OFFSET) &~1);
+
+  DEBUG ((DEBUG_INFO, "VTD base address1 %x\n", DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress));
+  DEBUG ((DEBUG_INFO, "VTD base address3 %x\n", DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress));
+  ///
+  /// copy DmarTable to TempDmarTable to be processed
+  ///
+  CopyMem (&TempDmarTable, DmarTable, sizeof (EFI_ACPI_DMAR_TABLE));
+
+  ///
+  /// Update DRHD structures of temp DMAR table
+  ///
+  UpdateDrhd (&TempDmarTable.DrhdEngine1);
+  UpdateDrhd2 (&TempDmarTable.DrhdEngine3);
+
+  ///
+  /// Update RMRR structures of temp DMAR table
+  ///
+  UpdateRmrr ((VOID *) &TempDmarTable.RmrrUsb);
+  UpdateRmrr ((VOID *) &TempDmarTable.RmrrIgd);
+  UpdateRmrr ((VOID *) &TempDmarTable.RmrrCsme);
+
+  ///
+  /// Remove unused device scope or entire DRHD structures
+  ///
+  Offset = (UINTN) (&TempDmarTable.DrhdEngine1);
+  if (TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length != 0) {
+    Offset += TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length;
+  }
+  if (TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length != 0) {
+    StructureLen = TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length;
+    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.DrhdEngine3, TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length);
+    Offset += StructureLen;
+  }
+  ///
+  /// Remove unused device scope or entire RMRR structures
+  ///
+  if (TempDmarTable.RmrrUsb.RmrrHeader.Header.Length != 0) {
+    StructureLen = TempDmarTable.RmrrUsb.RmrrHeader.Header.Length;
+    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrUsb, TempDmarTable.RmrrUsb.RmrrHeader.Header.Length);
+    Offset += StructureLen;
+  }
+  if (TempDmarTable.RmrrIgd.RmrrHeader.Header.Length != 0) {
+    StructureLen = TempDmarTable.RmrrIgd.RmrrHeader.Header.Length;
+    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrIgd, TempDmarTable.RmrrIgd.RmrrHeader.Header.Length);
+    Offset += StructureLen;
+  }
+  if (TempDmarTable.RmrrCsme.RmrrHeader.Header.Length != 0) {
+    StructureLen = TempDmarTable.RmrrCsme.RmrrHeader.Header.Length;
+    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrCsme, TempDmarTable.RmrrCsme.RmrrHeader.Header.Length);
+    Offset += StructureLen;
+  }
+
+  Offset = Offset - (UINTN) &TempDmarTable;
+  ///
+  /// Re-calculate DMAR table check sum
+  ///
+  TempDmarTable.DmarHeader.Header.Checksum = (UINT8) (TempDmarTable.DmarHeader.Header.Checksum + TempDmarTable.DmarHeader.Header.Length - Offset);
+  ///
+  /// Set DMAR table length
+  ///
+  TempDmarTable.DmarHeader.Header.Length = (UINT32) Offset;
+  ///
+  /// Replace DMAR table with rebuilt table TempDmarTable
+  ///
+  CopyMem ((VOID *) DmarTable, (VOID *) &TempDmarTable, TempDmarTable.DmarHeader.Header.Length);
+}
+
+/**
+  PciEnumerationComplete routine for update DMAR
+**/
+VOID
+UpdateDmarPciEnumCompleteCallback (
+  VOID
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_HANDLE                      *HandleBuffer;
+  UINTN                           NumberOfHandles;
+  EFI_FV_FILETYPE                 FileType;
+  UINT32                          FvStatus;
+  EFI_FV_FILE_ATTRIBUTES          Attributes;
+  UINTN                           Size;
+  UINTN                           i;
+  INTN                            Instance;
+  EFI_ACPI_TABLE_VERSION          Version;
+  EFI_ACPI_COMMON_HEADER          *CurrentTable;
+  UINTN                           AcpiTableHandle;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL   *FwVol;
+  EFI_ACPI_TABLE_PROTOCOL         *AcpiTable;
+  EFI_ACPI_DESCRIPTION_HEADER     *VtdAcpiTable;
+  STATIC BOOLEAN                  Triggered = FALSE;
+
+
+  if (Triggered) {
+    return;
+  }
+
+  Triggered     = TRUE;
+
+  FwVol         = NULL;
+  AcpiTable     = NULL;
+  VtdAcpiTable  = NULL;
+
+  DEBUG ((DEBUG_INFO, "UpdateDmarPciEnumCompleteCallback \n"));
+
+
+  ///
+  /// Fix DMAR Table always created, skip install when disabled
+  ///
+  if ((mSaConfigHob->VtdData.VtdDisable == TRUE) || (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MC_CAPID0_A_OFFSET)) & BIT23)) {
+    DEBUG ((DEBUG_INFO, "Vtd Disabled, skip DMAR Table install\n"));
+    return;
+  }
+
+
+  ///
+  /// Locate ACPI support protocol
+  ///
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+
+  ///
+  /// Locate protocol.
+  /// There is little chance we can't find an FV protocol
+  ///
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &NumberOfHandles,
+                  &HandleBuffer
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Looking for FV with ACPI storage file
+  ///
+  for (i = 0; i < NumberOfHandles; i++) {
+    ///
+    /// Get the protocol on this handle
+    /// This should not fail because of LocateHandleBuffer
+    ///
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[i],
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID **) &FwVol
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    ///
+    /// See if it has the ACPI storage file
+    ///
+    Size      = 0;
+    FvStatus  = 0;
+    Status = FwVol->ReadFile (
+                      FwVol,
+                      &gSaAcpiTableStorageGuid,
+                      NULL,
+                      &Size,
+                      &FileType,
+                      &Attributes,
+                      &FvStatus
+                      );
+
+    ///
+    /// If we found it, then we are done
+    ///
+    if (Status == EFI_SUCCESS) {
+      break;
+    }
+  }
+  ///
+  /// Our exit status is determined by the success of the previous operations
+  /// If the protocol was found, Instance already points to it.
+  ///
+  ///
+  /// Free any allocated buffers
+  ///
+  FreePool (HandleBuffer);
+
+  ///
+  /// Sanity check that we found our data file
+  ///
+  ASSERT (FwVol);
+  if (FwVol == NULL) {
+    return;
+  }
+  ///
+  /// By default, a table belongs in all ACPI table versions published.
+  ///
+  Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
+
+  ///
+  /// Read tables from the storage file.
+  ///
+  Instance      = 0;
+  CurrentTable  = NULL;
+
+  while (Status == EFI_SUCCESS) {
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &gSaAcpiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID **) &CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+      ///
+      /// Check the Signature ID to modify the table
+      ///
+      switch (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Signature) {
+
+        case EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE:
+          VtdAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
+          DmarTableUpdate (VtdAcpiTable, &Version);
+          break;
+
+        default:
+          break;
+      }
+      ///
+      /// Increment the instance
+      ///
+      Instance++;
+      CurrentTable = NULL;
+    }
+  }
+  ///
+  /// Update the VTD table in the ACPI tables.
+  ///
+  AcpiTableHandle = 0;
+  if (VtdAcpiTable != NULL) {
+    Status = AcpiTable->InstallAcpiTable (
+                          AcpiTable,
+                          VtdAcpiTable,
+                          VtdAcpiTable->Length,
+                          &AcpiTableHandle
+                          );
+    FreePool (VtdAcpiTable);
+  }
+}
+
+/**
+  Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
+  Publish the appropriate SSDT based on current configuration and capabilities.
+
+  @param[in] SaPolicy     -  SA DXE Policy protocol
+
+  @retval EFI_SUCCESS     - Vtd initialization complete
+  @exception EFI_UNSUPPORTED - Vtd is not enabled by policy
+**/
+EFI_STATUS
+VtdInit (
+  IN  SA_POLICY_PROTOCOL    *SaPolicy
+  )
+{
+  EFI_STATUS                      Status;
+  UINT64                          McD0BaseAddress;
+  UINT64                          McD2BaseAddress;
+  UINTN                           MchBar;
+  SYSTEM_AGENT_NVS_AREA_PROTOCOL  *SaNvsAreaProtocol;
+
+  mInterruptRemappingSupport  = FALSE;
+  mSaConfigHob       = NULL;
+  mSaConfigHob = GetFirstGuidHob (&gSaConfigHobGuid);
+  if (mSaConfigHob != NULL) {
+    mInterruptRemappingSupport  = mSaConfigHob->VtdData.InterruptRemappingSupport;
+  }
+
+  ///
+  ///  Locate the SA Global NVS Protocol.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaNvsAreaProtocolGuid,
+                  NULL,
+                  (VOID **) &SaNvsAreaProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  McD0BaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, 0);
+  McD2BaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0);
+  mSaPolicy        = SaPolicy;
+  MchBar           = PciSegmentRead32(McD0BaseAddress + R_SA_MCHBAR) & ~BIT0;
+
+  if (mSaConfigHob != NULL) {
+    SaNvsAreaProtocol->Area->VtdDisable = mSaConfigHob->VtdData.VtdDisable;
+  }
+  SaNvsAreaProtocol->Area->VtdBaseAddress1 = (MmioRead32(MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
+  SaNvsAreaProtocol->Area->VtdBaseAddress3 = (MmioRead32(MchBar + R_SA_MCHBAR_VTD3_OFFSET) &~1);
+  SaNvsAreaProtocol->Area->VtdEngine1Vid = PciSegmentRead16(McD2BaseAddress + PCI_VENDOR_ID_OFFSET);
+
+  if (mSaConfigHob != NULL) {
+    if ((mSaConfigHob->VtdData.VtdDisable) || (PciSegmentRead32 (McD0BaseAddress + R_SA_MC_CAPID0_A_OFFSET) & BIT23)) {
+      DEBUG ((DEBUG_WARN, "VTd disabled or no capability!\n"));
+      return EFI_UNSUPPORTED;
+    }
+  }
+  ///
+  /// Check SA supports VTD and VTD is enabled in setup menu
+  ///
+  DEBUG ((DEBUG_INFO, "VTd enabled\n"));
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c
new file mode 100644
index 0000000000..08fd9266c6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c
@@ -0,0 +1,356 @@
+/** @file
+  This is the driver that publishes the SMM Access Protocol
+  instance for System Agent.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SmmAccessDriver.h"
+
+static SMM_ACCESS_PRIVATE_DATA  mSmmAccess;
+
+
+/**
+  This is the standard EFI driver point that
+  installs an SMM Access Protocol
+
+  @param[in] ImageHandle     - Handle for the image of this driver
+  @param[in] SystemTable     - Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS           - Protocol was installed successfully
+  @exception EFI_UNSUPPORTED    - Protocol was not installed
+  @retval EFI_NOT_FOUND         - Protocol can't be found.
+  @retval EFI_OUT_OF_RESOURCES  - Protocol does not have enough resources to initialize the driver.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           Index;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
+  EFI_PEI_HOB_POINTERS            *Hob;
+
+  ///
+  /// --cr-- INITIALIZE_SCRIPT (ImageHandle, SystemTable);
+  ///
+  /// Initialize Global variables
+  ///
+  ZeroMem (&mSmmAccess, sizeof (mSmmAccess));
+
+  mSmmAccess.Signature        = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
+  mSmmAccess.Handle           = NULL;
+
+  ///
+  /// Get Hob list
+  ///
+  Hob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
+  if (Hob == NULL) {
+    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  DescriptorBlock = (VOID *) ((UINT8 *) Hob + sizeof (EFI_HOB_GUID_TYPE));
+
+  ///
+  /// Alloc space for mSmmAccess.SmramDesc
+  ///
+  mSmmAccess.SmramDesc = AllocateZeroPool ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof (EFI_SMRAM_DESCRIPTOR));
+  if (mSmmAccess.SmramDesc == NULL) {
+    DEBUG ((DEBUG_WARN, "Alloc mSmmAccess.SmramDesc fail.\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  DEBUG ((DEBUG_INFO, "Alloc mSmmAccess.SmramDesc success.\n"));
+
+  ///
+  /// Use the HOB to publish SMRAM capabilities
+  ///
+  for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+    mSmmAccess.SmramDesc[Index].PhysicalStart = DescriptorBlock->Descriptor[Index].PhysicalStart;
+    mSmmAccess.SmramDesc[Index].CpuStart      = DescriptorBlock->Descriptor[Index].CpuStart;
+    mSmmAccess.SmramDesc[Index].PhysicalSize  = DescriptorBlock->Descriptor[Index].PhysicalSize;
+    mSmmAccess.SmramDesc[Index].RegionState   = DescriptorBlock->Descriptor[Index].RegionState;
+  }
+
+  mSmmAccess.NumberRegions              = Index;
+  mSmmAccess.SmmAccess.Open             = Open;
+  mSmmAccess.SmmAccess.Close            = Close;
+  mSmmAccess.SmmAccess.Lock             = Lock;
+  mSmmAccess.SmmAccess.GetCapabilities  = GetCapabilities;
+  mSmmAccess.SmmAccess.LockState        = FALSE;
+  mSmmAccess.SmmAccess.OpenState        = FALSE;
+
+  ///
+  /// Install our protocol interfaces on the device's handle
+  ///
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mSmmAccess.Handle,
+                  &gEfiSmmAccess2ProtocolGuid,
+                  &mSmmAccess.SmmAccess,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_WARN, "InstallMultipleProtocolInterfaces returned %r\n", Status));
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "open" a region of SMRAM.  The
+  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all boot-service
+  and SMM agents.
+
+  @param[in] This               - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully opened.
+  @retval EFI_DEVICE_ERROR      - The region could not be opened because locked by
+                          chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Open (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINT64                  Address;
+  UINT8                   SmramControl;
+  UINTN                   DescriptorIndex;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
+      return EFI_DEVICE_ERROR;
+    }
+  }
+
+  ///
+  /// BEGIN CHIPSET SPECIFIC CODE
+  ///
+  ///
+  /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
+  ///
+  Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+
+  SmramControl = PciRead8 (Address);
+  ///
+  ///  Is SMRAM locked?
+  ///
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
+      ///
+      /// Cannot Open a locked region
+      ///
+      SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
+      return EFI_DEVICE_ERROR;
+    }
+  }
+  ///
+  /// Open SMRAM region
+  ///
+  SmramControl |= B_SA_SMRAMC_D_OPEN_MASK;
+  SmramControl &= ~(B_SA_SMRAMC_D_CLS_MASK);
+
+  PciWrite8 (Address, SmramControl);
+  ///
+  /// END CHIPSET SPECIFIC CODE
+  ///
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64) ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) EFI_SMRAM_OPEN;
+  }
+  SmmAccess->SmmAccess.OpenState = TRUE;
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "close" a region of SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "close" means that the memory is only visible from SMM agents,
+  not from BS or RT code.
+
+  @param[in] This               - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully closed.
+  @retval EFI_DEVICE_ERROR      - The region could not be closed because locked by chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINT64                  Address;
+  UINT8                   SmramControl;
+  BOOLEAN                 OpenState;
+  UINT8                   Index;
+  UINTN                   DescriptorIndex;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
+      continue;
+    }
+
+    ///
+    /// BEGIN CHIPSET SPECIFIC CODE
+    ///
+    ///
+    /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
+    ///
+    Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+
+    SmramControl = PciRead8 (Address);
+    ///
+    ///  Is SMRAM locked?
+    ///
+    if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
+      ///
+      /// Cannot Close a locked region
+      ///
+      SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
+      return EFI_DEVICE_ERROR;
+    }
+    ///
+    /// Close SMRAM region
+    ///
+    SmramControl &= ~(B_SA_SMRAMC_D_OPEN_MASK);
+
+    PciWrite8 (Address, SmramControl);
+    ///
+    /// END CHIPSET SPECIFIC CODE
+    ///
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64) ~EFI_SMRAM_OPEN;
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+  }
+
+  ///
+  /// Find out if any regions are still open
+  ///
+  OpenState = FALSE;
+  for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
+    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) == EFI_SMRAM_OPEN) {
+      OpenState = TRUE;
+    }
+  }
+
+  SmmAccess->SmmAccess.OpenState = OpenState;
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "lock" SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to BS state..
+
+  @param[in] This               - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully locked.
+  @retval EFI_DEVICE_ERROR      - The region could not be locked because at least
+                                  one range is still open.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Lock (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINT64                  Address;
+  UINT8                   SmramControl;
+  UINTN                   DescriptorIndex;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  if (SmmAccess->SmmAccess.OpenState) {
+    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are still open\n"));
+    return EFI_DEVICE_ERROR;
+  }
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+  }
+  SmmAccess->SmmAccess.LockState = TRUE;
+
+  ///
+  /// BEGIN CHIPSET SPECIFIC CODE
+  ///
+  ///
+  /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
+  ///
+  Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+
+  SmramControl = PciRead8 (Address);
+  ///
+  /// Lock the SMRAM
+  ///
+  SmramControl |= B_SA_SMRAMC_D_LCK_MASK;
+
+  PciWrite8 (Address, SmramControl);
+  ///
+  /// END CHIPSET SPECIFIC CODE
+  ///
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine services a user request to discover the SMRAM
+  capabilities of this platform.  This will report the possible
+  ranges that are possible for SMRAM access, based upon the
+  memory controller capabilities.
+
+  @param[in] This                  - Pointer to the SMRAM Access Interface.
+  @param[in] SmramMapSize          - Pointer to the variable containing size of the
+                                     buffer to contain the description information.
+  @param[in] SmramMap              - Buffer containing the data describing the Smram
+                                     region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
+**/
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+{
+  EFI_STATUS              Status;
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINTN                   NecessaryBufferSize;
+
+  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof (EFI_SMRAM_DESCRIPTOR);
+
+  if (*SmramMapSize < NecessaryBufferSize) {
+    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
+    Status = EFI_BUFFER_TOO_SMALL;
+  } else {
+    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
+    Status = EFI_SUCCESS;
+  }
+
+  *SmramMapSize = NecessaryBufferSize;
+
+  return Status;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
new file mode 100644
index 0000000000..c864a0ca8f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
@@ -0,0 +1,250 @@
+/** @file
+  This file describes the contents of the ACPI DMA address Remapping
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Dmar.h"
+#include <Register/PchRegsP2sb.h>
+
+EFI_ACPI_DMAR_TABLE DmarTable = {
+  //
+  // EFI_ACPI_DMAR_HEADER
+  //
+  {
+    //
+    // EFI_ACPI_DESCRIPTION_HEADER
+    //
+    {
+      EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE,
+      sizeof (EFI_ACPI_DMAR_TABLE),
+      EFI_ACPI_DMAR_TABLE_REVISION,
+
+      //
+      // Checksum will be updated at runtime
+      //
+      0x00,
+
+      //
+      // It is expected that these values will be programmed at runtime
+      //
+      { 'I', 'N', 'T', 'E', 'L', ' ' },
+      EFI_ACPI_DMAR_OEM_TABLE_ID,
+      0x1,
+      EFI_ACPI_DMAR_OEM_CREATOR_ID,
+      1
+    },
+
+    //
+    // DMAR table specific entries below:
+    //
+
+    //
+    // 39-bit addressing Host Address Width
+    //
+    38,
+
+    //
+    // Flags
+    //
+    0,
+
+    //
+    // Reserved fields
+    //
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+  },
+
+  //
+  // First DRHD structure, VT-d Engine #1
+  //
+  {
+    //
+    // EFI_ACPI_DMAR_DRHD_HEADER
+    //
+    {
+      {0,                                         // Type = 0 (DRHD)
+      sizeof (EFI_ACPI_DRHD_ENGINE1_STRUCT)},     // Length of structure
+      0,                                          // Flag - Do not include all
+      0,                                          // Reserved fields
+      0,                                          // Segment
+      0                                           // Base address of DMA-remapping hardware - Updated at boot time
+    },
+    //
+    // Device Scopes
+    //
+    {
+      {
+        {1,                                     // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),  // Length
+        0,                                      // Segment number
+        0,                                      // Reserved
+        0},                                     // Start bus number
+        {2, 0}                                  // PCI path
+      }
+    }
+  },
+
+  //
+  //Third DRHD structure VT-d Engine# 3
+  //
+  {
+    //
+    // EFI_ACPI_DMAR_DRHD_HEADER
+    //
+    {
+      {0,                                        // Type = 0 (DRHD)
+      sizeof (EFI_ACPI_DRHD_ENGINE3_STRUCT)},    // Length of strucure.
+      1,                                         // Flag - Include all
+      0,                                         // Reserved
+      0,                                         // Segment Number
+      0                                          // Base address of DMA-remapping hardware.
+    },
+    {
+      //
+      // Device Scopes
+      //
+      {
+        {3,                                          // Type=IO APIC
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),       // Length
+        0,                                           // Reserved
+        2,                                           // Enumeration ID
+        V_P2SB_CFG_IBDF_BUS},                        // Start bus number
+        {V_P2SB_CFG_IBDF_DEV, V_P2SB_CFG_IBDF_FUNC}  // PCI path
+      },
+      //
+      // Device Scopes
+      //
+      {
+        {4,                                          // Type=HPET
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),       // Length
+        0,                                           // Reserved
+        0,                                           // Enumeration ID
+        V_P2SB_CFG_HBDF_BUS},                        // Start bus number
+        {V_P2SB_CFG_HBDF_DEV, V_P2SB_CFG_HBDF_FUNC}  // PCI path
+      }
+    }
+  },
+  //RMRR structure for USB devices.
+  {
+    //
+    // EFI_ACPI_DMAR_RMRR_HEADER
+    //
+    {
+      {
+        0x1,                                     // Type 1 - RMRR structure
+        sizeof(EFI_ACPI_RMRR_USB_STRUC)          // Length
+      },
+      { 0x00, 0x00 },                            // Reserved
+      0x0000,                                    // Segment Num
+      0x00000000000E0000,                        // RMRR Base address - Updated in runtime.
+      0x00000000000EFFFF                         // RMRR Limit address - Updated in runtime.
+    },
+    //
+    // Device Scopes
+    //
+    {
+      {
+        {1,                                    // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+        0,                                     // Reserved
+        0,                                     // Enum ID
+        0},                                    // Start bus number
+        {20, 0}                                // PCI path
+      },
+      {
+        {1,                                    // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+        0,                                     // Reserved
+        0,                                     // Enum ID
+        0},                                    // Start bus number
+        {20, 1}                                // PCI path
+      }
+    }
+  },
+
+  //RMRR structure for IGD device.
+  {
+    //
+    // EFI_ACPI_DMAR_RMRR_HEADER
+    //
+    {
+      {1,                                       // Type 1 - RMRR structure
+      sizeof (EFI_ACPI_RMRR_IGD_STRUC)},        // Length
+      {0x0000},                                 // Reserved
+      0x0000,                                   // Segment Num
+      0x0000000000000000,                       // RMRR Base address - Updated in runtime.
+      0x0000000000000000                        // RMRR Limit address - Updated in runtime.
+    },
+    //
+    // Device Scopes
+    //
+    {
+      {
+        {1,                                   // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+        0,                                    // Reserved
+        0,                                    // Enum ID
+        0},                                   // Start bus number
+        {2, 0}                                // PCI path
+      }
+    }
+  },
+
+  // RMRR structure for WiAMT DMA access.
+  // Keep this device in end of RMRR queue.
+  {
+    //
+    // EFI_ACPI_DMAR_RMRR_HEADER
+    //
+    {
+      {1,                                       // Type 1 - RMRR structure
+      sizeof (EFI_ACPI_RMRR_CSME_STRUC)},       // Length
+      {0x0000},                                 // Reserved
+      0x0000,                                   // Segment Num
+      0x0000000000000000,                       // RMRR Base address - Updated in runtime.
+      0x0000000000000000                        // RMRR Limit address - Updated in runtime.
+    },
+    //
+    // Device Scopes
+    //
+    {
+      {
+        {1,                                   // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+        0,                                    // Reserved
+        0,                                    // Enum ID
+        0},                                   // Start bus number
+        {22, 7}                               // PCI path
+      }
+    }
+  }
+};
+
+//
+// Dummy function required for build tools
+//
+#if defined (__GNUC__)
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+
+{
+  //
+  // Reference the table being generated to prevent the optimizer from removing the
+  // data structure from the exeutable
+  //
+  return (VOID*)&DmarTable;
+}
+#else
+int
+main (
+  VOID
+  )
+{
+  return 0;
+}
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
new file mode 100644
index 0000000000..b431a77f05
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
@@ -0,0 +1,794 @@
+/** @file
+  This file contains the SystemAgent PCI Configuration space
+  definition.
+  It defines various System Agent PCI Configuration Space registers
+  which will be used to dynamically produce all resources in the Host Bus.
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(M64B)
+External(M64L)
+External(M32B)
+External(M32L)
+
+//
+// Define various System Agent (SA) PCI Configuration Space
+// registers which will be used to dynamically produce all
+// resources in the Host Bus _CRS.
+//
+OperationRegion (HBUS, PCI_Config, 0x00, 0x100)
+Field (HBUS, DWordAcc, NoLock, Preserve)
+{
+  Offset(0x40),   // EPBAR (0:0:0:40)
+  EPEN, 1,        // Enable
+      , 11,
+  EPBR, 20,       // EPBAR [31:12]
+
+  Offset(0x48),   // MCHBAR (0:0:0:48)
+  MHEN, 1,        // Enable
+      , 14,
+  MHBR, 17,       // MCHBAR [31:15]
+
+  Offset(0x50),   // GGC (0:0:0:50)
+  GCLK, 1,        // GGCLCK
+
+  Offset(0x54),   // DEVEN (0:0:0:54)
+  D0EN, 1,        // DEV0 Enable
+  D1F2, 1,        // DEV1 FUN2 Enable
+  D1F1, 1,        // DEV1 FUN1 Enable
+  D1F0, 1,        // DEV1 FUN0 Enable
+
+  Offset(0x60),   // PCIEXBAR (0:0:0:60)
+  PXEN, 1,        // Enable
+  PXSZ, 2,        // PCI Express Size
+      , 23,
+  PXBR, 6,        // PCI Express BAR [31:26]
+
+  Offset(0x68),   // DMIBAR (0:0:0:68)
+  DIEN, 1,        // Enable
+      , 11,
+  DIBR, 20,       // DMIBAR [31:12]
+
+  Offset(0x70),   // MESEG_BASE (0:0:0:70)
+      , 20,
+  MEBR, 12,       // MESEG_BASE [31:20]
+
+  Offset(0x80),   // PAM0 Register (0:0:0:80)
+  PMLK, 1,        // PAM Lock bit.
+      , 3,
+  PM0H, 2,        // PAM 0, High Nibble
+      , 2,
+
+  Offset(0x81),   // PAM1 Register (0:0:0:81)
+  PM1L, 2,        // PAM1, Low  Nibble
+      , 2,
+  PM1H, 2,        // PAM1, High Nibble
+      , 2,
+
+  Offset(0x82),   // PAM2 Register (0:0:0:82)
+  PM2L, 2,        // PAM2, Low  Nibble
+      , 2,
+  PM2H, 2,        // PAM2, High Nibble
+      , 2,
+
+  Offset(0x83),   // PAM3 Register (0:0:0:83)
+  PM3L, 2,        // PAM3, Low  Nibble
+      , 2,
+  PM3H, 2,        // PAM3, High Nibble
+      , 2,
+
+  Offset(0x84),   // PAM4 Register (0:0:0:84)
+  PM4L, 2,        // PAM4, Low  Nibble
+      , 2,
+  PM4H, 2,        // PAM4, High Nibble
+      , 2,
+
+  Offset(0x85),   // PAM5 Register (0:0:0:85)
+  PM5L, 2,        // PAM5, Low  Nibble
+      , 2,
+  PM5H, 2,        // PAM5, High Nibble
+      , 2,
+
+  Offset(0x86),   // PAM6 Register (0:0:0:86)
+  PM6L, 2,        // PAM6, Low  Nibble
+      , 2,
+  PM6H, 2,        // PAM6, High Nibble
+      , 2,
+
+  Offset(0xA8),   // Top of Upper Usable DRAM Register (0:0:0:A8)
+      , 20,
+  TUUD, 19,       // TOUUD [38:20]
+
+  Offset(0xBC),   // Top of Lower Usable DRAM Register (0:0:0:BC)
+      , 20,
+  TLUD, 12,       // TOLUD [31:20]
+
+  Offset(0xC8),   // ERRSTS register (0:0:0:C8)
+      , 7,
+  HTSE, 1         // Host Thermal Sensor Event for SMI/SCI/SERR
+}
+//
+// Define a buffer that will store all the bus, memory, and IO information
+// relating to the Host Bus.  This buffer will be dynamically altered in
+// the _CRS and passed back to the OS.
+//
+Name(BUF0,ResourceTemplate()
+{
+  //
+  // Bus Number Allocation: Bus 0 to 0xFF
+  //
+  WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00,
+    0x0000,0x00FF,0x00,0x0100,,,PB00)
+
+  //
+  // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 )
+  //
+  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+    0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00)
+
+  //
+  // PCI Configuration Registers ( 0x0CF8 - 0x0CFF )
+  //
+  Io(Decode16,0x0CF8,0x0CF8,1,0x08)
+
+  //
+  // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF )
+  //
+  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+    0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01)
+
+  //
+  // Video Buffer Area ( 0xA0000 - 0xBFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800)
+
+  //
+  // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800)
+
+  //
+  // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00)
+
+  //
+  // BIOS Extension Area ( 0xE0000 - 0xE3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000)
+
+  //
+  // BIOS Extension Area ( 0xE4000 - 0xE7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400)
+
+  //
+  // BIOS Extension Area ( 0xE8000 - 0xEBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800)
+
+  //
+  // BIOS Extension Area ( 0xEC000 - 0xEFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00)
+
+  //
+  // BIOS Area ( 0xF0000 - 0xFFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000)
+
+//  //
+//  // Memory Hole Region ( 0xF00000 - 0xFFFFFF )
+//  //
+//  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+//    ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE)
+
+  //
+  // PCI Memory Region ( TOLUD - 0xDFFFFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01)
+
+  //
+  // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) )
+  // (This is dummy range for OS compatibility, will patch it in _CRS)
+  //
+  QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
+
+  //
+  // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03)
+})
+
+  //
+  // SA reserved resources
+  //
+  Device(SRRE) {
+    Name(_HID,EISAID("PNP0C02")) // motherboard resource
+    Name(_UID,"SARESV")
+    Method(_STA,0,Serialized) // device present and decodes its resources, but not to be displayed in OSPM
+    {
+      If(LGreaterEqual(TLUD, 0x404)) {
+        Return (3)
+      } Else {
+        Return (0)
+      }
+    }
+
+    Method(_CRS,0,Serialized)
+    {
+      Name(BUF0,ResourceTemplate(){
+        //
+        // Reserve the 0x40000000 ~ 0x403FFFFF to prevent other driver use this memory range
+        //
+        Memory32Fixed(ReadOnly,0x40000000,0x400000)
+      })
+      If(LGreaterEqual(TLUD, 0x404)) {
+        Return (BUF0)
+      } Else {
+        Return (Buffer(){})
+      }
+    }
+  }
+
+Name(EP_B, 0) // to store EP BAR
+Name(MH_B, 0) // to store MCH BAR
+Name(PC_B, 0) // to store PCIe BAR
+Name(PC_L, 0) // to store PCIe BAR Length
+Name(DM_B, 0) // to store DMI BAR
+
+//
+// Get EP BAR
+//
+Method(GEPB,0,Serialized)
+{
+  if(LEqual(EP_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.EPBR,12,EP_B)
+  }
+  Return(EP_B)
+}
+
+//
+// Get MCH BAR
+//
+Method(GMHB,0,Serialized)
+{
+  if(LEqual(MH_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.MHBR,15,MH_B)
+  }
+  Return(MH_B)
+}
+
+//
+// Get PCIe BAR
+//
+Method(GPCB,0,Serialized)
+{
+  if(LEqual(PC_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.PXBR,26,PC_B)
+  }
+  Return(PC_B)
+}
+
+//
+// Get PCIe Length
+//
+Method(GPCL,0,Serialized)
+{
+  if(LEqual(PC_L,0)) {
+    ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L)
+  }
+  Return(PC_L)
+}
+
+//
+// Get DMI BAR
+//
+Method(GDMB,0,Serialized)
+{
+  if(LEqual(DM_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.DIBR,12,DM_B)
+  }
+  Return(DM_B)
+}
+
+
+Method(_CRS,0,Serialized)
+{
+  //
+  // Fix up Max Bus Number and Length
+  //
+  Store(\_SB.PCI0.GPCL(),Local0)
+  CreateWordField(BUF0, ^PB00._MAX, PBMX)
+  Store(Subtract(ShiftRight(Local0,20),2), PBMX)
+  CreateWordField(BUF0, ^PB00._LEN, PBLN)
+  Store(Subtract(ShiftRight(Local0,20),1), PBLN)
+  //
+  // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF.
+  //
+  If(PM1L)  // \_SB.PCI0
+  {
+    // PAMx != 0.  Set length = 0.
+
+    CreateDwordField(BUF0, ^C000._LEN,C0LN)
+    Store(Zero,C0LN)
+  }
+
+  If(LEqual(PM1L,1))
+  {
+    CreateBitField(BUF0, ^C000._RW,C0RW)
+    Store(Zero,C0RW)
+  }
+
+  If(PM1H)
+  {
+    CreateDwordField(BUF0, ^C400._LEN,C4LN)
+    Store(Zero,C4LN)
+  }
+
+  If(LEqual(PM1H,1))
+  {
+    CreateBitField(BUF0, ^C400._RW,C4RW)
+    Store(Zero,C4RW)
+  }
+
+  If(PM2L)
+  {
+    CreateDwordField(BUF0, ^C800._LEN,C8LN)
+    Store(Zero,C8LN)
+  }
+
+  If(LEqual(PM2L,1))
+  {
+    CreateBitField(BUF0, ^C800._RW,C8RW)
+    Store(Zero,C8RW)
+  }
+
+  If(PM2H)
+  {
+    CreateDwordField(BUF0, ^CC00._LEN,CCLN)
+    Store(Zero,CCLN)
+  }
+
+  If(LEqual(PM2H,1))
+  {
+    CreateBitField(BUF0, ^CC00._RW,CCRW)
+    Store(Zero,CCRW)
+  }
+
+  If(PM3L)
+  {
+    CreateDwordField(BUF0, ^D000._LEN,D0LN)
+    Store(Zero,D0LN)
+  }
+
+  If(LEqual(PM3L,1))
+  {
+    CreateBitField(BUF0, ^D000._RW,D0RW)
+    Store(Zero,D0RW)
+  }
+
+  If(PM3H)
+  {
+    CreateDwordField(BUF0, ^D400._LEN,D4LN)
+    Store(Zero,D4LN)
+  }
+
+  If(LEqual(PM3H,1))
+  {
+    CreateBitField(BUF0, ^D400._RW,D4RW)
+    Store(Zero,D4RW)
+  }
+
+  If(PM4L)
+  {
+    CreateDwordField(BUF0, ^D800._LEN,D8LN)
+    Store(Zero,D8LN)
+  }
+
+  If(LEqual(PM4L,1))
+  {
+    CreateBitField(BUF0, ^D800._RW,D8RW)
+    Store(Zero,D8RW)
+  }
+
+  If(PM4H)
+  {
+    CreateDwordField(BUF0, ^DC00._LEN,DCLN)
+    Store(Zero,DCLN)
+  }
+
+  If(LEqual(PM4H,1))
+  {
+    CreateBitField(BUF0, ^DC00._RW,DCRW)
+    Store(Zero,DCRW)
+  }
+
+  If(PM5L)
+  {
+    CreateDwordField(BUF0, ^E000._LEN,E0LN)
+    Store(Zero,E0LN)
+  }
+
+  If(LEqual(PM5L,1))
+  {
+    CreateBitField(BUF0, ^E000._RW,E0RW)
+    Store(Zero,E0RW)
+  }
+
+  If(PM5H)
+  {
+    CreateDwordField(BUF0, ^E400._LEN,E4LN)
+    Store(Zero,E4LN)
+  }
+
+  If(LEqual(PM5H,1))
+  {
+    CreateBitField(BUF0, ^E400._RW,E4RW)
+    Store(Zero,E4RW)
+  }
+
+  If(PM6L)
+  {
+    CreateDwordField(BUF0, ^E800._LEN,E8LN)
+    Store(Zero,E8LN)
+  }
+
+  If(LEqual(PM6L,1))
+  {
+    CreateBitField(BUF0, ^E800._RW,E8RW)
+    Store(Zero,E8RW)
+  }
+
+  If(PM6H)
+  {
+    CreateDwordField(BUF0, ^EC00._LEN,ECLN)
+    Store(Zero,ECLN)
+  }
+
+  If(LEqual(PM6H,1))
+  {
+    CreateBitField(BUF0, ^EC00._RW,ECRW)
+    Store(Zero,ECRW)
+  }
+
+  If(PM0H)
+  {
+    CreateDwordField(BUF0, ^F000._LEN,F0LN)
+    Store(Zero,F0LN)
+  }
+
+  If(LEqual(PM0H,1))
+  {
+    CreateBitField(BUF0, ^F000._RW,F0RW)
+    Store(Zero,F0RW)
+  }
+
+  // Enable the 1MB region between 15-16MB if HENA = 1.
+  //
+  // If( MCHC.HENA)
+  // {
+  // CreateDwordField(BUF0, HOLE._LEN,H0LN)
+  // Store(0x100000,H0LN)
+  // }
+
+  //
+  // Create pointers to Memory Sizing values.
+  //
+  CreateDwordField(BUF0, ^PM01._MIN,M1MN)
+  CreateDwordField(BUF0, ^PM01._MAX,M1MX)
+  CreateDwordField(BUF0, ^PM01._LEN,M1LN)
+
+  //
+  // Set Memory Size Values. TLUD represents bits 31:20 of phyical
+  // TOM, so shift these bits into the correct position and fix up
+  // the Memory Region available to PCI.
+  //
+  Store (M32L, M1LN)
+  Store (M32B, M1MN)
+  Subtract (Add (M1MN, M1LN), 1, M1MX)
+
+  //
+  // Create pointers to Memory Sizing values.
+  // Patch PM02 range basing on memory size and OS type
+  //
+  If (LEqual(M64L, 0)) {
+    CreateQwordField(BUF0, ^PM02._LEN,MSLN)
+    //
+    // Set resource length to 0
+    //
+    Store (0, MSLN)
+  }
+  Else {
+    CreateQwordField(BUF0, ^PM02._LEN,M2LN)
+    CreateQwordField(BUF0, ^PM02._MIN,M2MN)
+    CreateQwordField(BUF0, ^PM02._MAX,M2MX)
+    //
+    // Set 64bit MMIO resource Base and Length
+    //
+    Store (M64L, M2LN)
+    Store (M64B, M2MN)
+    Subtract (Add (M2MN, M2LN), 1, M2MX)
+  }
+  Return(BUF0)
+}
+
+//
+//Name(GUID,UUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))
+//
+Name(GUID,Buffer(){0x5b, 0x4d, 0xdb, 0x33,
+          0xf7, 0x1f,
+          0x1c, 0x40,
+          0x96, 0x57,
+          0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66})
+
+
+Name(SUPP,0)  // PCI _OSC Support Field value
+Name(CTRL,0)  // PCI _OSC Control Field value
+Name(XCNT, 0) // Variable used in _OSC for counting
+
+Method(_OSC,4,Serialized)
+{
+  //
+  // Check for proper UUID
+  // Save the capabilities buffer
+  //
+  Store(Arg3,Local0)
+
+  //
+  // Create DWord-adressable fields from the Capabilties Buffer
+  //
+  CreateDWordField(Local0,0,CDW1)
+  CreateDWordField(Local0,4,CDW2)
+  CreateDWordField(Local0,8,CDW3)
+
+
+  //
+  // Check for proper UUID
+  //
+  If(LEqual(Arg0,GUID))
+  {
+    // Save Capabilities DWord2 & 3
+    Store(CDW2,SUPP)
+    Store(CDW3,CTRL)
+
+    //
+    // You can clear bits in CTRL here if you don't want OS to take
+    // control
+    //
+    If(LNot(NEXP))
+    {
+      And(CTRL, 0xFFFFFFF8, CTRL)       // disable Native hot plug, PME
+    }
+
+    If(LEqual(TBTS, 1)) {
+      // \_OSC disallow only Advanced Error Reporting control
+      And(CTRL, 0xFFFFFFF7, CTRL)
+    }
+
+    If(Not(And(CDW1,1)))  // Query flag clear?
+    { // Disable GPEs for features granted native control.
+      If(And(CTRL,0x01))
+      {
+        NHPG()
+      }
+      If(And(CTRL,0x04))  // PME control granted?
+      {
+        NPME()
+      }
+    }
+
+    If(LNotEqual(Arg1,One))
+    {
+      //
+      // Unknown revision
+      //
+      Or(CDW1,0x08,CDW1)
+    }
+
+    If(LNotEqual(CDW3,CTRL))
+    {
+      //
+      // Capabilities bits were masked
+      //
+      Or(CDW1,0x10,CDW1)
+    }
+    //
+    // Update DWORD3 in the buffer
+    //
+    Store(CTRL,CDW3)
+    Store(CTRL,OSCC)
+    Return(Local0)
+  } Else {
+    Or(CDW1,4,CDW1)   // Unrecognized UUID
+    Return(Local0)
+  }
+} // End _OSC
+
+//
+// Added code for Dual IRQ support. Two set of ACPI IRQ tables were generated.
+// Code has been added to select the appropriate IRQ table by checking the CPUID.
+//
+Scope(\_SB.PCI0)
+{
+  Method(AR00) {
+    Return(\_SB.AR00)
+  }
+
+  Method(PD00) {
+    Return(\_SB.PD00)
+  }
+
+  Method(AR02) {
+    Return(\_SB.AR02)
+  }
+
+  Method(PD02) {
+    Return(\_SB.PD02)
+  }
+
+  Method(AR04) {
+    Return(\_SB.AR04)
+  }
+
+  Method(PD04) {
+    Return(\_SB.PD04)
+  }
+
+  Method(AR05) {
+    Return(\_SB.AR05)
+  }
+
+  Method(PD05) {
+    Return(\_SB.PD05)
+  }
+
+  Method(AR06) {
+    Return(\_SB.AR06)
+  }
+
+  Method(PD06) {
+    Return(\_SB.PD06)
+  }
+
+  Method(AR07) {
+    Return(\_SB.AR07)
+  }
+
+  Method(PD07) {
+    Return(\_SB.PD07)
+  }
+
+  Method(AR08) {
+    Return(\_SB.AR08)
+  }
+
+  Method(PD08) {
+    Return(\_SB.PD08)
+  }
+
+  Method(AR09) {
+    Return(\_SB.AR09)
+  }
+
+  Method(PD09) {
+    Return(\_SB.PD09)
+  }
+
+  Method(AR0A) {
+    Return(\_SB.AR0A)
+  }
+
+  Method(PD0A) {
+    Return(\_SB.PD0A)
+  }
+
+  Method(AR0B) {
+    Return(\_SB.AR0B)
+  }
+
+  Method(PD0B) {
+    Return(\_SB.PD0B)
+  }
+
+  //
+  // Add device scope definition for System Agent
+  // P.E.G. Root Port D1F0
+  //
+  Device(PEG0) {
+    Name(_ADR, 0x00010000)
+    Device(PEGP) { // P.E.G. Port Slot x16
+      Name(_ADR, 0x00000000)
+    }
+  }
+  //
+  // P.E.G. Root Port D1F1
+  //
+  Device(PEG1) {
+    Name(_ADR, 0x00010001)
+    Device(PEGP) { // P.E.G. Port Slot x8
+      Name(_ADR, 0x00000000)
+    }
+  }
+  //
+  // P.E.G. Root Port D1F2
+  //
+  Device(PEG2) {
+    Name(_ADR, 0x00010002)
+    Device(PEGP) { // P.E.G. Port Slot x4
+      Name(_ADR, 0x00000000)
+    }
+  }
+  //
+  // I.G.D
+  //
+  Device(GFX0) {
+    Name(_ADR, 0x00020000)
+  }
+  //
+  // SA Thermal Device
+  //
+  Device(B0D4) {
+    Method(_DSM,4,serialized){if(PCIC(Arg0)) { return(PCID(Arg0,Arg1,Arg2,Arg3)) }; Return(Buffer() {0})}
+    Name(_ADR, 0x00040000)
+  }
+  //
+  // Device IPU0 is the IPU PCI device
+  //
+  Device(IPU0) {
+    Name(_ADR, 0x00050000)
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
new file mode 100644
index 0000000000..e7a797c973
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
@@ -0,0 +1,1666 @@
+/** @file
+  This file contains the IGD OpRegion/Software ACPI Reference
+  Code.
+  It defines the methods to enable/disable output switching,
+  store display switching and LCD brightness BIOS control
+  and return valid addresses for all display device encoders
+  present in the system, etc.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(\ECST, MethodObj)
+External(\PBCL, MethodObj)
+External(HDOS, MethodObj)
+External(\ECON, IntObj)
+External(\PNHM, IntObj)
+External(OSYS, IntObj)
+External(CPSC)
+External(\GUAM, MethodObj)
+External(DSEN)
+External(S0ID)
+
+Name(TMP1,Package() {0xFFFFFFFF})
+Name(TMP2,Package() {0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP3,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP4,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP5,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP6,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP7,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP8,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF})
+Name(TMP9,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPA,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF })
+Name(TMPB,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPC,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPD,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPE,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPF,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF})
+Name(TMPG,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF})
+
+// Enable/Disable Output Switching.  In WIN2K/WINXP, _DOS = 0 will
+// get called during initialization to prepare for an ACPI Display
+// Switch Event.  During an ACPI Display Switch, the OS will call
+// _DOS = 2 immediately after a Notify=0x80 to temporarily disable
+// all Display Switching.  After ACPI Display Switching is complete,
+// the OS will call _DOS = 0 to re-enable ACPI Display Switching.
+Method(_DOS,1)
+{
+  //
+  // Store Display Switching and LCD brightness BIOS control bit
+  //
+  Store(And(Arg0,7),DSEN)
+
+  If(LEqual(And(Arg0,  0x3), 0))     // If _DOS[1:0]=0
+  {
+    If(CondRefOf(HDOS))
+    {
+      HDOS()
+    }
+  }
+}
+
+//
+// Enumerate the Display Environment.  This method will return
+// valid addresses for all display device encoders present in the
+// system.  The Miniport Driver will reject the addresses for every
+// encoder that does not have an attached display device.  After
+// enumeration is complete, the OS will call the _DGS methods
+// during a display switch only for the addresses accepted by the
+// Miniport Driver.  For hot-insertion and removal of display
+// devices, a re-enumeration notification will be required so the
+// address of the newly present display device will be accepted by
+// the Miniport Driver.
+//
+Method(_DOD,0)
+{
+  If (LEqual(IPTP,1)) {
+    //
+    // Increment number of devices if IPU is enabled
+    //
+    Store(1, NDID)
+  } Else {
+    Store(0, NDID)
+  }
+
+  If(LNotEqual(DIDL, Zero))
+  {
+    Store(SDDL(DIDL),DID1)
+  }
+  If(LNotEqual(DDL2, Zero))
+  {
+    Store(SDDL(DDL2),DID2)
+  }
+  If(LNotEqual(DDL3, Zero))
+  {
+    Store(SDDL(DDL3),DID3)
+  }
+  If(LNotEqual(DDL4, Zero))
+  {
+    Store(SDDL(DDL4),DID4)
+  }
+  If(LNotEqual(DDL5, Zero))
+  {
+    Store(SDDL(DDL5),DID5)
+  }
+  If(LNotEqual(DDL6, Zero))
+  {
+    Store(SDDL(DDL6),DID6)
+  }
+  If(LNotEqual(DDL7, Zero))
+  {
+    Store(SDDL(DDL7),DID7)
+  }
+  If(LNotEqual(DDL8, Zero))
+  {
+    Store(SDDL(DDL8),DID8)
+  }
+  If(LNotEqual(DDL9, Zero))
+  {
+    Store(SDDL(DDL9),DID9)
+  }
+  If(LNotEqual(DD10, Zero))
+  {
+    Store(SDDL(DD10),DIDA)
+  }
+  If(LNotEqual(DD11, Zero))
+  {
+    Store(SDDL(DD11),DIDB)
+  }
+  If(LNotEqual(DD12, Zero))
+  {
+    Store(SDDL(DD12),DIDC)
+  }
+  If(LNotEqual(DD13, Zero))
+  {
+    Store(SDDL(DD13),DIDD)
+  }
+  If(LNotEqual(DD14, Zero))
+  {
+    Store(SDDL(DD14),DIDE)
+  }
+  If(LNotEqual(DD15, Zero))
+  {
+    Store(SDDL(DD15),DIDF)
+  }
+
+  //
+  // Enumerate the encoders. Note that for
+  // current silicon, the maximum number of encoders
+  // possible is 15.
+  //
+  If(LEqual(NDID,1))
+  {
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP1,0))
+    } Else {
+      Store(Or(0x10000,DID1),Index(TMP1,0))
+    }
+    Return(TMP1)
+  }
+
+  If(LEqual(NDID,2))
+  {
+    Store(Or(0x10000,DID1),Index(TMP2,0))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP2,1))
+    } Else {
+      Store(Or(0x10000,DID2),Index(TMP2,1))
+    }
+    Return(TMP2)
+  }
+
+  If(LEqual(NDID,3))
+  {
+    Store(Or(0x10000,DID1),Index(TMP3,0))
+    Store(Or(0x10000,DID2),Index(TMP3,1))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP3,2))
+    } Else {
+      Store(Or(0x10000,DID3),Index(TMP3,2))
+    }
+    Return(TMP3)
+  }
+
+  If(LEqual(NDID,4))
+  {
+    Store(Or(0x10000,DID1),Index(TMP4,0))
+    Store(Or(0x10000,DID2),Index(TMP4,1))
+    Store(Or(0x10000,DID3),Index(TMP4,2))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP4,3))
+    } Else {
+      Store(Or(0x10000,DID4),Index(TMP4,3))
+    }
+    Return(TMP4)
+  }
+
+  If(LEqual(NDID,5))
+  {
+    Store(Or(0x10000,DID1),Index(TMP5,0))
+    Store(Or(0x10000,DID2),Index(TMP5,1))
+    Store(Or(0x10000,DID3),Index(TMP5,2))
+    Store(Or(0x10000,DID4),Index(TMP5,3))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP5,4))
+    } Else {
+      Store(Or(0x10000,DID5),Index(TMP5,4))
+    }
+    Return(TMP5)
+  }
+
+  If(LEqual(NDID,6))
+  {
+    Store(Or(0x10000,DID1),Index(TMP6,0))
+    Store(Or(0x10000,DID2),Index(TMP6,1))
+    Store(Or(0x10000,DID3),Index(TMP6,2))
+    Store(Or(0x10000,DID4),Index(TMP6,3))
+    Store(Or(0x10000,DID5),Index(TMP6,4))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP6,5))
+    } Else {
+      Store(Or(0x10000,DID6),Index(TMP6,5))
+    }
+    Return(TMP6)
+  }
+
+  If(LEqual(NDID,7))
+  {
+    Store(Or(0x10000,DID1),Index(TMP7,0))
+    Store(Or(0x10000,DID2),Index(TMP7,1))
+    Store(Or(0x10000,DID3),Index(TMP7,2))
+    Store(Or(0x10000,DID4),Index(TMP7,3))
+    Store(Or(0x10000,DID5),Index(TMP7,4))
+    Store(Or(0x10000,DID6),Index(TMP7,5))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP7,6))
+    } Else {
+      Store(Or(0x10000,DID7),Index(TMP7,6))
+    }
+    Return(TMP7)
+  }
+
+  If(LEqual(NDID,8))
+  {
+    Store(Or(0x10000,DID1),Index(TMP8,0))
+    Store(Or(0x10000,DID2),Index(TMP8,1))
+    Store(Or(0x10000,DID3),Index(TMP8,2))
+    Store(Or(0x10000,DID4),Index(TMP8,3))
+    Store(Or(0x10000,DID5),Index(TMP8,4))
+    Store(Or(0x10000,DID6),Index(TMP8,5))
+    Store(Or(0x10000,DID7),Index(TMP8,6))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP8,7))
+    } Else {
+      Store(Or(0x10000,DID8),Index(TMP8,7))
+    }
+    Return(TMP8)
+  }
+
+  If(LEqual(NDID,9))
+  {
+    Store(Or(0x10000,DID1),Index(TMP9,0))
+    Store(Or(0x10000,DID2),Index(TMP9,1))
+    Store(Or(0x10000,DID3),Index(TMP9,2))
+    Store(Or(0x10000,DID4),Index(TMP9,3))
+    Store(Or(0x10000,DID5),Index(TMP9,4))
+    Store(Or(0x10000,DID6),Index(TMP9,5))
+    Store(Or(0x10000,DID7),Index(TMP9,6))
+    Store(Or(0x10000,DID8),Index(TMP9,7))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP9,8))
+    } Else {
+      Store(Or(0x10000,DID9),Index(TMP9,8))
+    }
+    Return(TMP9)
+  }
+
+  If(LEqual(NDID,0x0A))
+  {
+    Store(Or(0x10000,DID1),Index(TMPA,0))
+    Store(Or(0x10000,DID2),Index(TMPA,1))
+    Store(Or(0x10000,DID3),Index(TMPA,2))
+    Store(Or(0x10000,DID4),Index(TMPA,3))
+    Store(Or(0x10000,DID5),Index(TMPA,4))
+    Store(Or(0x10000,DID6),Index(TMPA,5))
+    Store(Or(0x10000,DID7),Index(TMPA,6))
+    Store(Or(0x10000,DID8),Index(TMPA,7))
+    Store(Or(0x10000,DID9),Index(TMPA,8))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMPA,9))
+    } Else {
+      Store(Or(0x10000,DIDA),Index(TMPA,9))
+    }
+    Return(TMPA)
+  }
+
+  If(LEqual(NDID,0x0B))
+  {
+    Store(Or(0x10000,DID1),Index(TMPB,0))
+    Store(Or(0x10000,DID2),Index(TMPB,1))
+    Store(Or(0x10000,DID3),Index(TMPB,2))
+    Store(Or(0x10000,DID4),Index(TMPB,3))
+    Store(Or(0x10000,DID5),Index(TMPB,4))
+    Store(Or(0x10000,DID6),Index(TMPB,5))
+    Store(Or(0x10000,DID7),Index(TMPB,6))
+    Store(Or(0x10000,DID8),Index(TMPB,7))
+    Store(Or(0x10000,DID9),Index(TMPB,8))
+    Store(Or(0x10000,DIDA),Index(TMPB,9))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMPB,10))
+    } Else {
+      Store(Or(0x10000,DIDB),Index(TMPB,10))
+    }
+    Return(TMPB)
+  }
+
+  If(LEqual(NDID,0x0C))
+  {
+    Store(Or(0x10000,DID1),Index(TMPC,0))
+    Store(Or(0x10000,DID2),Index(TMPC,1))
+    Store(Or(0x10000,DID3),Index(TMPC,2))
+    Store(Or(0x10000,DID4),Index(TMPC,3))
+    Store(Or(0x10000,DID5),Index(TMPC,4))
+    Store(Or(0x10000,DID6),Index(TMPC,5))
+    Store(Or(0x10000,DID7),Index(TMPC,6))
+    Store(Or(0x10000,DID8),Index(TMPC,7))
+    Store(Or(0x10000,DID9),Index(TMPC,8))
+    Store(Or(0x10000,DIDA),Index(TMPC,9))
+    Store(Or(0x10000,DIDB),Index(TMPC,10))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMPC,11))
+    } Else {
+      Store(Or(0x10000,DIDC),Index(TMPC,11))
+    }
+    Return(TMPC)
+  }
+
+  If(LEqual(NDID,0x0D))
+  {
+    Store(Or(0x10000,DID1),Index(TMPD,0))
+    Store(Or(0x10000,DID2),Index(TMPD,1))
+    Store(Or(0x10000,DID3),Index(TMPD,2))
+    Store(Or(0x10000,DID4),Index(TMPD,3))
+    Store(Or(0x10000,DID5),Index(TMPD,4))
+    Store(Or(0x10000,DID6),Index(TMPD,5))
+    Store(Or(0x10000,DID7),Index(TMPD,6))
+    Store(Or(0x10000,DID8),Index(TMPD,7))
+    Store(Or(0x10000,DID9),Index(TMPD,8))
+    Store(Or(0x10000,DIDA),Index(TMPD,9))
+    Store(Or(0x10000,DIDB),Index(TMPD,10))
+    Store(Or(0x10000,DIDC),Index(TMPD,11))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMPD,12))
+    } Else {
+      Store(Or(0x10000,DIDD),Index(TMPD,12))
+    }
+    Return(TMPD)
+  }
+
+  If(LEqual(NDID,0x0E))
+  {
+    Store(Or(0x10000,DID1),Index(TMPE,0))
+    Store(Or(0x10000,DID2),Index(TMPE,1))
+    Store(Or(0x10000,DID3),Index(TMPE,2))
+    Store(Or(0x10000,DID4),Index(TMPE,3))
+    Store(Or(0x10000,DID5),Index(TMPE,4))
+    Store(Or(0x10000,DID6),Index(TMPE,5))
+    Store(Or(0x10000,DID7),Index(TMPE,6))
+    Store(Or(0x10000,DID8),Index(TMPE,7))
+    Store(Or(0x10000,DID9),Index(TMPE,8))
+    Store(Or(0x10000,DIDA),Index(TMPE,9))
+    Store(Or(0x10000,DIDB),Index(TMPE,10))
+    Store(Or(0x10000,DIDC),Index(TMPE,11))
+    Store(Or(0x10000,DIDD),Index(TMPE,12))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMPE,13))
+    } Else {
+      Store(Or(0x10000,DIDE),Index(TMPE,13))
+    }
+    Return(TMPE)
+  }
+
+  If(LEqual(NDID,0x0F))
+  {
+    Store(Or(0x10000,DID1),Index(TMPF,0))
+    Store(Or(0x10000,DID2),Index(TMPF,1))
+    Store(Or(0x10000,DID3),Index(TMPF,2))
+    Store(Or(0x10000,DID4),Index(TMPF,3))
+    Store(Or(0x10000,DID5),Index(TMPF,4))
+    Store(Or(0x10000,DID6),Index(TMPF,5))
+    Store(Or(0x10000,DID7),Index(TMPF,6))
+    Store(Or(0x10000,DID8),Index(TMPF,7))
+    Store(Or(0x10000,DID9),Index(TMPF,8))
+    Store(Or(0x10000,DIDA),Index(TMPF,9))
+    Store(Or(0x10000,DIDB),Index(TMPF,10))
+    Store(Or(0x10000,DIDC),Index(TMPF,11))
+    Store(Or(0x10000,DIDD),Index(TMPF,12))
+    Store(Or(0x10000,DIDE),Index(TMPF,13))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMPF,14))
+    } Else {
+      Store(Or(0x10000,DIDF),Index(TMPF,14))
+    }
+    Return(TMPF)
+  }
+
+  If(LEqual(NDID,0x10))
+  {
+    Store(Or(0x10000,DID1),Index(TMPG,0))
+    Store(Or(0x10000,DID2),Index(TMPG,1))
+    Store(Or(0x10000,DID3),Index(TMPG,2))
+    Store(Or(0x10000,DID4),Index(TMPG,3))
+    Store(Or(0x10000,DID5),Index(TMPG,4))
+    Store(Or(0x10000,DID6),Index(TMPG,5))
+    Store(Or(0x10000,DID7),Index(TMPG,6))
+    Store(Or(0x10000,DID8),Index(TMPG,7))
+    Store(Or(0x10000,DID9),Index(TMPG,8))
+    Store(Or(0x10000,DIDA),Index(TMPG,9))
+    Store(Or(0x10000,DIDB),Index(TMPG,10))
+    Store(Or(0x10000,DIDC),Index(TMPG,11))
+    Store(Or(0x10000,DIDD),Index(TMPG,12))
+    Store(Or(0x10000,DIDE),Index(TMPG,13))
+    Store(Or(0x10000,DIDF),Index(TMPG,14))
+    //
+    // IGFX need report IPUA as GFX0 child
+    // NDID can only be 0x10 if IPU is enabled
+    //
+    Store(0x00023480,Index(TMPG,15))
+    Return(TMPG)
+  }
+
+  //
+  // If nothing else, return Unknown LFP.
+  // (Prevents compiler warning.)
+  //
+  Return(Package() {0x00000400})
+}
+
+Device(DD01)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID1),0x400))
+    {
+      Store(0x1, EDPV)
+      Store(NXD1, NXDX)
+      Store(DID1, DIDX)
+      Return(1)
+    }
+    If(LEqual(DID1,0))
+    {
+      Return(1)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID1))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    Return(CDDS(DID1))
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD1)
+    }
+    Return(NDDS(DID1))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD02)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID2),0x400))
+    {
+      Store(0x2, EDPV)
+      Store(NXD2, NXDX)
+      Store(DID2, DIDX)
+      Return(2)
+    }
+    If(LEqual(DID2,0))
+    {
+      Return(2)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID2))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(LIDS,0))
+    {
+      Return(0x0)
+    }
+    Return(CDDS(DID2))
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    //
+    // Return the Next State.
+    //
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD2)
+    }
+    Return(NDDS(DID2))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD03)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID3),0x400))
+    {
+      Store(0x3, EDPV)
+      Store(NXD3, NXDX)
+      Store(DID3, DIDX)
+      Return(3)
+    }
+    If(LEqual(DID3,0))
+    {
+      Return(3)
+    }
+    Else
+    {
+    Return(And(0xFFFF,DID3))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID3,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID3))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD3)
+    }
+    Return(NDDS(DID3))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD04)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID4),0x400))
+    {
+      Store(0x4, EDPV)
+      Store(NXD4, NXDX)
+      Store(DID4, DIDX)
+      Return(4)
+    }
+    If(LEqual(DID4,0))
+    {
+      Return(4)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID4))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID4,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID4))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD4)
+    }
+    Return(NDDS(DID4))
+  }
+
+  //
+  // Device Set State. (See table above.)
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD05)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID5),0x400))
+    {
+      Store(0x5, EDPV)
+      Store(NXD5, NXDX)
+      Store(DID5, DIDX)
+      Return(5)
+    }
+    If(LEqual(DID5,0))
+    {
+      Return(5)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID5))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID5,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID5))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD5)
+    }
+    Return(NDDS(DID5))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD06)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID6),0x400))
+    {
+      Store(0x6, EDPV)
+      Store(NXD6, NXDX)
+      Store(DID6, DIDX)
+      Return(6)
+    }
+    If(LEqual(DID6,0))
+    {
+      Return(6)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID6))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID6,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID6))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD6)
+    }
+    Return(NDDS(DID6))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD07)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID7),0x400))
+    {
+      Store(0x7, EDPV)
+      Store(NXD7, NXDX)
+      Store(DID7, DIDX)
+      Return(7)
+    }
+    If(LEqual(DID7,0))
+    {
+      Return(7)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID7))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID7,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID7))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD7)
+    }
+    Return(NDDS(DID7))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD08)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID8),0x400))
+    {
+      Store(0x8, EDPV)
+      Store(NXD8, NXDX)
+      Store(DID8, DIDX)
+      Return(8)
+    }
+    If(LEqual(DID8,0))
+    {
+      Return(8)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID8))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID8,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID8))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DID8))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD09)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID9),0x400))
+    {
+      Store(0x9, EDPV)
+      Store(NXD8, NXDX)
+      Store(DID9, DIDX)
+      Return(9)
+    }
+    If(LEqual(DID9,0))
+    {
+      Return(9)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID9))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID9,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID9))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DID9))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD0A)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DIDA),0x400))
+    {
+      Store(0xA, EDPV)
+      Store(NXD8, NXDX)
+      Store(DIDA, DIDX)
+      Return(0x0A)
+    }
+    If(LEqual(DIDA,0))
+    {
+      Return(0x0A)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDA))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DIDA,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DIDA))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DIDA))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD0B)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DIDB),0x400))
+    {
+      Store(0xB, EDPV)
+      Store(NXD8, NXDX)
+      Store(DIDB, DIDX)
+      Return(0X0B)
+    }
+    If(LEqual(DIDB,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDB))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DIDB,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DIDB))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DIDB))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD0C)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DIDC),0x400))
+    {
+      Store(0xC, EDPV)
+      Store(NXD8, NXDX)
+      Store(DIDC, DIDX)
+      Return(0X0C)
+    }
+    If(LEqual(DIDC,0))
+    {
+      Return(0x0C)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDC))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DIDC,0))
+    {
+      Return(0x0C)
+    }
+    Else
+    {
+      Return(CDDS(DIDC))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DIDC))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD0D)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DIDD),0x400))
+    {
+      Store(0xD, EDPV)
+      Store(NXD8, NXDX)
+      Store(DIDD, DIDX)
+      Return(0X0D)
+    }
+    If(LEqual(DIDD,0))
+    {
+      Return(0x0D)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDD))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DIDD,0))
+    {
+      Return(0x0D)
+    }
+    Else
+    {
+      Return(CDDS(DIDD))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DIDD))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD0E)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DIDE),0x400))
+    {
+      Store(0xE, EDPV)
+      Store(NXD8, NXDX)
+      Store(DIDE, DIDX)
+      Return(0X0E)
+    }
+    If(LEqual(DIDE,0))
+    {
+      Return(0x0E)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDE))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DIDE,0))
+    {
+      Return(0x0E)
+    }
+    Else
+    {
+      Return(CDDS(DIDE))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DIDE))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD0F)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DIDF),0x400))
+    {
+      Store(0xF, EDPV)
+      Store(NXD8, NXDX)
+      Store(DIDF, DIDX)
+      Return(0X0F)
+    }
+    If(LEqual(DIDF,0))
+    {
+      Return(0x0F)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDF))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DIDC,0))
+    {
+      Return(0x0F)
+    }
+    Else
+    {
+      Return(CDDS(DIDF))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DIDF))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+//
+//Device for eDP
+//
+Device(DD1F)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(EDPV, 0x0))
+    {
+      Return(0x1F)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDX))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(EDPV, 0x0))
+    {
+      Return(0x00)
+    }
+    Else
+    {
+      Return(CDDS(DIDX))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXDX)
+    }
+    Return(NDDS(DIDX))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+
+  //
+  // Query List of Brightness Control Levels Supported.
+  //
+  Method(_BCL,0)
+  {
+    //
+    // List of supported brightness levels in the following sequence.
+    // Level when machine has full power.
+    // Level when machine is on batteries.
+    // Other supported levels.
+    //
+    If(CondRefOf(\PBCL)) {
+      Return (PBCL())
+    } Else {
+      Return(Package(){80, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100})
+    }
+  }
+
+  //
+  // Set the Brightness Level.
+  //
+  Method (_BCM,1)
+  {
+    //
+    // Set the requested level if it is between 0 and 100%.
+    //
+    If(LAnd(LGreaterEqual(Arg0,0),LLessEqual(Arg0,100)))
+    {
+      \_SB.PCI0.GFX0.AINT(1, Arg0)
+      Store(Arg0,BRTL)  // Store Brightness Level.
+    }
+  }
+
+  //
+  // Brightness Query Current level.
+  //
+  Method (_BQC,0)
+  {
+    Return(BRTL)
+  }
+}
+
+Method(SDDL,1)
+{
+  Increment(NDID)
+  Store(And(Arg0,0xF0F),Local0)
+  Or(0x80000000,Local0, Local1)
+  If(LEqual(DIDL,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL2,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL3,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL4,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL5,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL6,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL7,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL8,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL9,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DD10,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DD11,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DD12,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DD13,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DD14,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DD15,Local0))
+  {
+    Return(Local1)
+  }
+  Return(0)
+}
+
+Method(CDDS,1)
+{
+  Store(And(Arg0,0xF0F),Local0)
+
+  If(LEqual(0, Local0))
+  {
+    Return(0x1D)
+  }
+  If(LEqual(CADL, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL2, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL3, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL4, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL5, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL6, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL7, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL8, Local0))
+  {
+    Return(0x1F)
+  }
+  Return(0x1D)
+}
+
+Method(NDDS,1)
+{
+  Store(And(Arg0,0xF0F),Local0)
+
+  If(LEqual(0, Local0))
+  {
+    Return(0)
+  }
+  If(LEqual(NADL, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL2, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL3, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL4, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL5, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL6, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL7, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL8, Local0))
+  {
+    Return(1)
+  }
+  Return(0)
+}
+
+//
+// Device Set State Table
+//  BIT31  BIT30  Execution
+//  0  0  Don't implement.
+//  0  1  Cache change.  Nothing to Implement.
+//  1  0  Don't Implement.
+//  1  1  Display Switch Complete.  Implement.
+//
+Method(DSST,1)
+{
+  If(LEqual(And(Arg0,0xC0000000),0xC0000000))
+  {
+    //
+    // State change was performed by the
+    // Video Drivers.  Simply update the
+    // New State.
+    //
+    Store(NSTE,CSTE)
+  }
+}
+
+//
+// Include IGD OpRegion/Software SCI interrupt handler/DSM which is used by
+// the graphics drivers to request data from system BIOS.
+//
+include ("IgfxOpRn.asl")
+include ("IgfxDsm.asl")
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl
new file mode 100644
index 0000000000..7edbe45e2e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl
@@ -0,0 +1,472 @@
+/** @file
+  IGD OpRegion/Software SCI Reference Code.
+  This file contains ASL code with the purpose of handling events
+  i.e. hotkeys and other system interrupts.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+/************************************************************************;
+;* ACPI Notification Methods
+;************************************************************************/
+
+
+/************************************************************************;
+;*
+;* Name:        PDRD
+;*
+;* Description: Check if the graphics driver is ready to process
+;*              notifications and video extensions.
+;*
+;* Usage:       This method is to be called prior to performing any
+;*              notifications or handling video extensions.
+;*              Ex: If (PDRD()) {Return (FAIL)}
+;*
+;* Input:       None
+;*
+;* Output:      None
+;*
+;* References:  DRDY (Driver ready status), ASLP (Driver recommended
+;*              sleep timeout value).
+;*
+;************************************************************************/
+
+External(HNOT, MethodObj)
+
+Method(PDRD)
+{
+  //
+  // If DRDY is clear, the driver is not ready.  If the return value is
+  // !=0, do not perform any notifications or video extension handling.
+  //
+  Return(LNot(DRDY))
+}
+
+/************************************************************************;
+;*
+;* Name:        PSTS
+;*
+;* Description: Check if the graphics driver has completed the previous
+;*              "notify" command.
+;*
+;* Usage:       This method is called before every "notify" command.  A
+;*              "notify" should only be set if the driver has completed the
+;*              previous command.  Else, ignore the event and exit the parent
+;*              method.
+;*              Ex: If (PSTS()) {Return (FAIL)}
+;*
+;* Input:       None
+;*
+;* Output:      None
+;*
+;* References:  CSTS (Notification status), ASLP (Driver recommended sleep
+;*              timeout value).
+;*
+;************************************************************************/
+
+Method(PSTS)
+{
+  If(LGreater(CSTS, 2))
+  {
+    //
+    // Sleep for ASLP milliseconds if the status is not "success,
+    // failure, or pending"
+    //
+    Sleep(ASLP)
+  }
+
+  Return(LEqual(CSTS, 3)) // Return True if still Dispatched
+}
+
+/************************************************************************;
+;*
+;* Name:  GNOT
+;*
+;* Description: Call the appropriate methods to query the graphics driver
+;*              status.  If all methods return success, do a notification of
+;*              the graphics device.
+;*
+;* Usage:       This method is to be called when a graphics device
+;*              notification is required (display switch hotkey, etc).
+;*
+;* Input:       Arg0 = Current event type:
+;*                1 = display switch
+;*                2 = lid
+;*                3 = dock
+;*              Arg1 = Notification type:
+;*                0 = Re-enumeration
+;*                0x80 = Display switch
+;*
+;* Output:      Returns 0 = success, 1 = failure
+;*
+;* References:  PDRD and PSTS methods.  OSYS (OS version)
+;*
+;************************************************************************/
+
+Method(GNOT, 2)
+{
+  //
+  // Check for 1. Driver loaded, 2. Driver ready.
+  // If any of these cases is not met, skip this event and return failure.
+  //
+  If(PDRD())
+  {
+    Return(0x1) // Return failure if driver not loaded.
+  }
+
+  Store(Arg0, CEVT) // Set up the current event value
+  Store(3, CSTS) // CSTS=BIOS dispatched an event
+
+  If(LAnd(LEqual(CHPD, 0), LEqual(Arg1, 0))) // Do not re-enum if driver supports hotplug
+  {
+    //
+    // Re-enumerate the Graphics Device for non-XP operating systems.
+    //
+    Notify(\_SB.PCI0.GFX0, Arg1)
+  }
+
+  If(CondRefOf(HNOT))
+  {
+    HNOT(Arg0)  //Notification handler for Switchable graphics
+  }
+  Else
+  {
+    Notify(\_SB.PCI0.GFX0,0x80)
+  }
+
+  Return(0x0) // Return success
+}
+
+/************************************************************************;
+;*
+;* Name:        GHDS
+;*
+;* Description: Handle a hotkey display switching event (performs a
+;*              Notify(GFX0, 0).
+;*
+;* Usage:       This method must be called when a hotkey event occurs and the
+;*              purpose of that hotkey is to do a display switch.
+;*
+;* Input:       Arg0 = Toggle table number.
+;*
+;* Output:      Returns 0 = success, 1 = failure.
+;*              CEVT and TIDX are indirect outputs.
+;*
+;* References:  TIDX, GNOT
+;*
+;************************************************************************/
+
+Method(GHDS, 1)
+{
+  Store(Arg0, TIDX) // Store the table number
+  //
+  // Call GNOT for CEVT = 1 = hotkey, notify value = 0
+  //
+  Return(GNOT(1, 0)) // Return stats from GNOT
+}
+
+/************************************************************************;
+;*
+;* Name:        GLID
+;*
+;* Description: Handle a lid event (performs the Notify(GFX0, 0), but not the
+;*              lid notify).
+;*
+;* Usage:       This method must be called when a lid event occurs.  A
+;*              Notify(LID0, 0x80) must follow the call to this method.
+;*
+;* Input:       Arg0 = Lid state:
+;*                0 = All closed
+;*                1 = internal LFP lid open
+;*                2 = external lid open
+;*                3 = both external and internal open
+;*
+;* Output:      Returns 0=success, 1=failure.
+;*              CLID and CEVT are indirect outputs.
+;*
+;* References:  CLID, GNOT
+;*
+;************************************************************************/
+
+Method(GLID, 1)
+{
+
+  If (LEqual(Arg0,1))
+  {
+    Store(3,CLID)
+  }
+  Else
+  {
+    Store(Arg0, CLID)
+  }
+  //
+  //Store(Arg0, CLID) // Store the current lid state
+  // Call GNOT for CEVT=2=Lid, notify value = 0
+  //
+  if (GNOT(2, 0)) {
+    Or (CLID, 0x80000000, CLID)
+    Return (1) // Return Fail
+  }
+
+  Return (0) // Return Pass
+}
+
+/************************************************************************;
+;*
+;* Name:  GDCK
+;*
+;* Description: Handle a docking event by updating the current docking status
+;*              and doing a notification.
+;*
+;* Usage:       This method must be called when a docking event occurs.
+;*
+;* Input:       Arg0 = Docking state:
+;*                0 = Undocked
+;*                1 = Docked
+;*
+;* Output:      Returns 0=success, 1=failure.
+;*              CDCK and CEVT are indirect outputs.
+;*
+;* References:  CDCK, GNOT
+;*
+;************************************************************************/
+
+Method(GDCK, 1)
+{
+  Store(Arg0, CDCK) // Store the current dock state
+  //
+  // Call GNOT for CEVT=4=Dock, notify value = 0
+  //
+  Return(GNOT(4, 0)) // Return stats from GNOT
+}
+
+/************************************************************************;
+;* ASLE Interrupt Methods
+;************************************************************************/
+
+/************************************************************************;
+;*
+;* Name:        PARD
+;*
+;* Description: Check if the driver is ready to handle ASLE interrupts
+;*              generate by the system BIOS.
+;*
+;* Usage:       This method must be called before generating each ASLE
+;*              interrupt.
+;*
+;* Input:       None
+;*
+;* Output:      Returns 0 = success, 1 = failure.
+;*
+;* References:  ARDY (Driver readiness), ASLP (Driver recommended sleep
+;*              timeout value)
+;*
+;************************************************************************/
+
+Method(PARD)
+{
+  If(LNot(ARDY))
+  {
+    //
+    // Sleep for ASLP milliseconds if the driver is not ready.
+    //
+    Sleep(ASLP)
+  }
+  //
+  // If ARDY is clear, the driver is not ready.  If the return value is
+  // !=0, do not generate the ASLE interrupt.
+  //
+  Return(LNot(ARDY))
+}
+
+//
+// Intel Ultrabook Event Handler.  Arg0 represents the Ultrabook Event Bit # to pass
+// to the Intel Graphics Driver.  Note that this is a serialized method, meaning
+// sumultaneous events are not allowed.
+//
+Method(IUEH,1,Serialized)
+{
+  And(IUER,0xC0,IUER) // Clear all button events on entry.
+  XOr(IUER,Shiftleft(1,Arg0),IUER) // Toggle status.
+
+  If(LLessEqual(Arg0,4)) // Button Event?
+  {
+    Return(AINT(5,0)) // Generate event and return status.
+
+  }
+  Else // Indicator Event.
+  {
+    Return(AINT(Arg0,0)) // Generate event and return status.
+  }
+}
+
+/************************************************************************;
+;*
+;* Name:        AINT
+;*
+;* Description: Call the appropriate methods to generate an ASLE interrupt.
+;*              This process includes ensuring the graphics driver is ready
+;*              to process the interrupt, ensuring the driver supports the
+;*              interrupt of interest, and passing information about the event
+;*              to the graphics driver.
+;*
+;* Usage:       This method must called to generate an ASLE interrupt.
+;*
+;* Input:       Arg0 = ASLE command function code:
+;*                0 = Set ALS illuminance
+;*                1 = Set backlight brightness
+;*                2 = Do Panel Fitting
+;*                4 = Reserved
+;*                5 = Button Indicator Event
+;*                6 = Convertible Indicator Event
+;*                7 = Docking Indicator Event
+;*              Arg1 = If Arg0 = 0, current ALS reading:
+;*                0 = Reading below sensor range
+;*                1-0xFFFE = Current sensor reading
+;*                0xFFFF = Reading above sensor range
+;*              Arg1 = If Arg0 = 1, requested backlight percentage
+;*
+;* Output:      Returns 0 = success, 1 = failure
+;*
+;* References:  PARD method.
+;*
+;************************************************************************/
+
+Method(AINT, 2)
+{
+  //
+  // Return failure if the requested feature is not supported by the
+  // driver.
+  //
+  If(LNot(And(TCHE, ShiftLeft(1, Arg0))))
+  {
+    Return(0x1)
+  }
+  //
+  // Return failure if the driver is not ready to handle an ASLE
+  // interrupt.
+  //
+  If(PARD())
+  {
+    Return(0x1)
+  }
+  //
+  // Handle Intel Ultrabook Events.
+  //
+  If(LAnd(LGreaterEqual(Arg0,5),LLessEqual(Arg0,7)))
+  {
+    Store(ShiftLeft(1,Arg0), ASLC) // Set Ultrbook Event [6:4].
+    Store(0x01, ASLE) // Generate ASLE interrupt
+
+    Store(0,Local2) // Use Local2 as a timeout counter.  Intialize to zero.
+
+    While(LAnd(LLess(Local2,250),LNotEqual(ASLC,0))) // Wait 1 second or until Driver ACKs a success.
+    {
+      Sleep(4) // Delay 4 ms.
+      Increment(Local2) // Increment Timeout.
+    }
+
+    Return(0) // Return success
+  }
+  //
+  // Evaluate the first argument (Panel fitting, backlight brightness, or ALS).
+  //
+  If(LEqual(Arg0, 2))         // Arg0 = 2, so request a panel fitting mode change.
+  {
+    If(CPFM)                  // If current mode field is non-zero use it.
+    {
+      And(CPFM, 0x0F, Local0) // Create variables without reserved
+      And(EPFM, 0x0F, Local1) // or valid bits.
+
+      If(LEqual(Local0, 1))   // If current mode is centered,
+      {
+        If(And(Local1, 6))    // and if stretched is enabled,
+        {
+          Store(6, PFIT)      // request stretched.
+        }
+        Else                  // Otherwise,
+        {
+          If(And(Local1, 8))  // if aspect ratio is enabled,
+          {
+            Store(8, PFIT)    // request aspect ratio.
+          }
+          Else                // Only centered mode is enabled
+          {
+            Store(1, PFIT)    // so request centered. (No change.)
+          }
+        }
+      }
+      If(LEqual(Local0, 6))   // If current mode is stretched,
+      {
+        If(And(Local1, 8))    // and if aspect ratio is enabled,
+        {
+          Store(8, PFIT)      // request aspect ratio.
+        }
+        Else                  // Otherwise,
+        {
+          If(And(Local1, 1))  // if centered is enabled,
+          {
+            Store(1, PFIT)    // request centered.
+          }
+          Else                // Only stretched mode is enabled
+          {
+            Store(6, PFIT)    // so request stretched. (No change.)
+          }
+        }
+      }
+      If(LEqual(Local0, 8))   // If current mode is aspect ratio,
+      {
+        If(And(Local1, 1))    // and if centered is enabled,
+        {
+          Store(1, PFIT)      // request centered.
+        }
+        Else                  // Otherwise,
+        {
+          If(And(Local1, 6))  // if stretched is enabled,
+          {
+            Store(6, PFIT)    // request stretched.
+          }
+          Else                // Only aspect ratio mode is enabled
+          {
+            Store(8, PFIT)    // so request aspect ratio. (No change.)
+          }
+        }
+      }
+    }
+    //
+    // The following code for panel fitting (within the Else condition) is retained for backward compatiblity.
+    //
+    Else                      // If CFPM field is zero use PFIT and toggle the
+    {
+      Xor(PFIT,7,PFIT)        // mode setting between stretched and centered only.
+    }
+    Or(PFIT,0x80000000,PFIT)  // Set the valid bit for all cases.
+    Store(4, ASLC)            // Store "Panel fitting event" to ASLC[31:1]
+  }
+  Else
+  {
+    If(LEqual(Arg0, 1)) // Arg0=1, so set the backlight brightness.
+    {
+      Store(Divide(Multiply(Arg1, 255), 100), BCLP) // Convert from percent to 0-255.
+      Or(BCLP, 0x80000000, BCLP) // Set the valid bit.
+      Store(2, ASLC) // Store "Backlight control event" to ASLC[31:1]
+    }
+    Else
+    {
+      If(LEqual(Arg0, 0)) // Arg0=0, so set the ALS illuminace
+      {
+        Store(Arg1, ALSI)
+        Store(1, ASLC) // Store "ALS event" to ASLC[31:1]
+      }
+      Else
+      {
+        Return(0x1) // Unsupported function
+      }
+    }
+  }
+
+  Store(0x01, ASLE) // Generate ASLE interrupt
+  Return(0x0) // Return success
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl
new file mode 100644
index 0000000000..e7b3c92cda
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl
@@ -0,0 +1,369 @@
+/** @file
+  IGD OpRegion/_DSM Reference Code.
+  This file contains Get BIOS Data and Callback functions for
+  the Integrated Graphics Device (IGD) OpRegion/DSM mechanism
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// _DSM Device Specific Method
+//
+// Arg0: UUID Unique function identifier
+// Arg1: Integer Revision Level
+// Arg2: Integer Function Index (1 = Return Supported Functions)
+// Arg3: Additional Inputs/Package Parameters Bits [31:0] input as {Byte0, Byte1, Byte2, Byte3} to BIOS which is passed as 32 bit DWORD by Driver
+//
+Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj}) {
+
+  If (LEqual(Arg0, ToUUID ("3E5B41C6-EB1D-4260-9D15-C71FBADAE414"))) {
+    //
+    // _DSM Definition for Igd functions
+    // Arguments:
+    // Arg0: UUID: 3E5B41C6-EB1D-4260-9D15-C71FBADAE414
+    // Arg1: Revision ID: 1
+    // Arg2: Function Index: 16
+    // Arg3: Additional Inputs Bits[31:0] Arg3 {Byte0, Byte1, Byte2, Byte3}
+    //
+    // Return:
+    // Success for simple notification, Opregion update for some routines and a Package for AKSV
+    //
+    //
+    // Switch by function index
+    //
+    Switch(ToInteger(Arg2)) {
+      //
+      // Function Index: 0
+      // Standard query - A bitmask of functions supported
+      //
+      // Return: A bitmask of functions supported
+      //
+      Case (0)
+      {
+        If (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+          Store("iGfx Supported Functions Bitmap ", Debug)
+          Return (0x1E7FF)   // bit 11 and 12 is not supported
+        }
+      }
+
+      //
+      // Function Index: 1
+      // Adapter Power State Notification
+      // Arg3 Bits [7:0]: Adapter Power State bits [7:0] from Driver 00h = D0; 01h = D1; 02h = D2; 04h = D3 (Cold/Hot); 08h = D4 (Hibernate Notification)
+      // Return: Success
+      //
+      Case(1) {
+        If (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+          Store(" Adapter Power State Notification ", Debug)
+
+          //
+          // Handle Low Power S0 Idle Capability if enabled
+          //
+          If(LAnd(LEqual(S0ID, 1),LLess(OSYS, 2015))) {
+            //
+            // Call GUAM to trigger CS Entry
+            //   If Adapter Power State Notification = D1 (Arg3[0]=0x01)
+            //
+            If (LEqual (And(DerefOf (Index (Arg3,0)), 0xFF), 0x01)) {
+              // GUAM - Global User Absent Mode Notification Method
+              \GUAM(One) // 0x01 - Power State Standby (CS Entry)
+            }
+            Store(And(DerefOf (Index (Arg3,1)), 0xFF), Local0)
+            //
+            // Call GUAM
+            // If Display Turn ON Notification (Arg3 [1] == 0) for CS Exit
+            //
+            If (LEqual (Local0, 0)) {
+              // GUAM - Global User Absent Mode Notification Method
+              \GUAM(0)
+            }
+          }
+
+          // Upon notification from driver that the Adapter Power State = D0,
+          // check if previous lid event failed.  If it did, retry the lid
+          // event here.
+          If(LEqual(DerefOf (Index (Arg3,0)), 0)) {
+            Store(CLID, Local0)
+            If(And(0x80000000,Local0)) {
+              And(CLID, 0x0000000F, CLID)
+              GLID(CLID)
+            }
+          }
+          Return(0x01)
+        }
+      }
+      //
+      // Function Index: 2
+      // Display Power State Notification
+      // Arg3: Display Power State Bits [15:8]
+      // 00h = On
+      // 01h = Standby
+      // 02h = Suspend
+      // 04h = Off
+      // 08h = Reduced On
+      // Return: Success
+      //
+     Case(2) {
+        if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+
+          Store("Display Power State Notification ", Debug)
+          Return(0x01)
+        }
+      }
+
+      //
+      // Function Index: 3
+      // BIOS POST Completion Notification
+      // Return: Success
+      //
+      Case(3) {
+        if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+          Store("BIOS POST Completion Notification ", Debug)
+          Return(0x01)      // Not supported, but no failure
+        }
+      }
+
+      //
+      // Function Index: 4
+      // Pre-Hires Set Mode
+      // Return: Success
+      //
+      Case(4) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          Store("Pre-Hires Set Mode ", Debug)
+          Return(0x01)      // Not supported, but no failure
+        }
+      }
+
+      //
+      // Function Index: 5
+      // Post-Hires Set Mode
+      // Return: Success
+      //
+      Case(5) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          Store("Post-Hires Set Mode ", Debug)
+          Return(0x01)      // Not supported, but no failure
+        }
+      }
+
+      //
+      // Function Index: 6
+      // SetDisplayDeviceNotification (Display Switch)
+      // Return: Success
+      //
+      Case(6) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          Store("SetDisplayDeviceNotification", Debug)
+          Return(0x01)      // Not supported, but no failure
+        }
+      }
+
+      //
+      // Function Index: 7
+      // SetBootDevicePreference
+      // Return: Success
+      //
+      Case(7) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          //<TODO> An OEM may elect to implement this method.  In that case,
+          // the input values must be saved into non-volatile storage for
+          // parsing during the next boot.  The following Sample code is Intel
+          // validated implementation.
+
+          Store("SetBootDevicePreference ", Debug)
+          And(DerefOf (Index (Arg3,0)), 0xFF, IBTT) // Save the boot display to NVS
+          Return(0x01)
+        }
+      }
+
+      //
+      // Function Index: 8
+      // SetPanelPreference
+      // Return: Success
+      //
+      Case(8) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          // An OEM may elect to implement this method.  In that case,
+          // the input values must be saved into non-volatile storage for
+          // parsing during the next boot.  The following Sample code is Intel
+          // validated implementation.
+
+          Store("SetPanelPreference ", Debug)
+
+          // Set the panel-related NVRAM variables based the input from the driver.
+          And(DerefOf (Index (Arg3,0)), 0xFF, IPSC)
+
+          // Change panel type if a change is requested by the driver (Change if
+          // panel type input is non-zero).  Zero=No change requested.
+          If(And(DerefOf (Index (Arg3,1)), 0xFF)) {
+            And(DerefOf (Index (Arg3,1)), 0xFF, IPAT)
+            Decrement(IPAT)    // 0 = no change, so fit to CMOS map
+          }
+          And(ShiftRight(DerefOf (Index (Arg3,2)), 4), 0x7, IBIA)
+          Return(0x01)         // Success
+        }
+      }
+
+      //
+      // Function Index: 9
+      // FullScreenDOS
+      // Return: Success
+      //
+      Case(9) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          Store("FullScreenDOS ", Debug)
+          Return(0x01)      // Not supported, but no failure
+        }
+      }
+
+      //
+      // Function Index: 10
+      // APM Complete
+      // Return: Adjusted Lid State
+      //
+     Case(10) {
+        if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+
+          Store("APM Complete ", Debug)
+          Store(ShiftLeft(LIDS, 8), Local0) // Report the lid state
+          Add(Local0, 0x100, Local0)        // Adjust the lid state, 0 = Unknown
+          Return(Local0)
+        }
+      }
+
+      //
+      //
+      // Function Index: 13
+      // GetBootDisplayPreference
+      // Arg3 Bits [30:16] : Boot Device Ports
+      // Arg3 Bits [7:0] : Boot Device Type
+      // Return: Boot device port and Boot device type from saved configuration
+      //
+     Case(13) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+
+          Store("GetBootDisplayPreference ", Debug)
+          Or(ShiftLeft(DerefOf (Index (Arg3,3)), 24), ShiftLeft(DerefOf (Index (Arg3,2)), 16), Local0) // Combine Arg3 Bits [31:16]
+          And(Local0, 0xEFFF0000, Local0)
+          And(Local0, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), Local0)
+          Or(IBTT, Local0, Local0) // Arg3 Bits [7:0] = Boot device type
+          Return(Local0)
+        }
+      }
+
+      //
+      // Function Index: 14
+      // GetPanelDetails
+      // Return: Different Panel Settings
+      //
+      Case(14) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          Store("GetPanelDetails ", Debug)
+
+          // Report the scaling setting
+          // Bits [7:0] - Panel Scaling
+          // Bits contain the panel scaling user setting from CMOS
+          // 00h = On: Auto
+          // 01h = On: Force Scaling
+          // 02h = Off
+          // 03h = Maintain Aspect Ratio
+
+          Store(IPSC, Local0)
+          Or(Local0, ShiftLeft(IPAT, 8), Local0)
+
+          // Adjust panel type, 0 = VBT default
+          // Bits [15:8] - Panel Type
+          // Bits contain the panel type user setting from CMOS
+          // 00h = Not Valid, use default Panel Type & Timings from VBT
+          // 01h - 0Fh = Panel Number
+
+          Add(Local0, 0x100, Local0)
+
+          // Report the lid state and Adjust it
+          // Bits [16] - Lid State
+          // Bits contain the current panel lid state
+          // 0 = Lid Open
+          // 1 = Lid Closed
+
+          Or(Local0, ShiftLeft(LIDS, 16), Local0)
+          Add(Local0, 0x10000, Local0)
+
+         // Report the BIA setting
+         // Bits [22:20] - Backlight Image Adaptation (BIA) Control
+         // Bits contain the backlight image adaptation control user setting from CMOS
+         // 000 = VBT Default
+         // 001 = BIA Disabled (BLC may still be enabled)
+         // 010 - 110 = BIA Enabled at Aggressiveness Level [1 - 5]
+
+          Or(Local0, ShiftLeft(IBIA, 20), Local0)
+          Return(Local0)
+        }
+      }
+
+      //
+      // Function Index: 15
+      // GetInternalGraphics
+      // Return: Different Internal Grahics Settings
+      //
+
+      Case(15) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          Store("GetInternalGraphics ", Debug)
+
+          Store(GIVD, Local0)                    // Local0[0]      - VGA mode(1=VGA)
+          Xor(Local0, 1, Local0)                 // Invert the VGA mode polarity
+
+          Or(Local0, ShiftLeft(GMFN, 1), Local0) // Local0[1]      - # IGD PCI functions-1
+                                                 // Local0[3:2]    - Reserved
+                                                 // Local0[4]      - IGD D3 support(0=cold)
+                                                 // Local0[10:5]   - Reserved
+          Or(Local0, ShiftLeft(3, 11), Local0)   // Local0[12:11]  - DVMT version (11b = 5.0)
+
+          //
+          // Report DVMT 5.0 Total Graphics memory size.
+          //
+          Or(Local0, ShiftLeft(IDMS, 17), Local0) // Bits 20:17 are for Gfx total memory size
+
+          // If the "Set Internal Graphics" call is supported, the modified
+          // settings flag must be programmed per the specification.  This means
+          // that the flag must be set to indicate that system BIOS requests
+          // these settings.  Once "Set Internal Graphics" is called, the
+          //  modified settings flag must be cleared on all subsequent calls to
+          // this function.
+
+          // Report the graphics frequency based on B0:D2:F0:RF0h[12].  Must
+          // take into account the current VCO.
+
+          Or(ShiftLeft(DeRefOf(Index(DeRefOf(Index(CDCT, HVCO)), CDVL)), 21),Local0, Local0)
+          Return(Local0)
+        }
+      }
+
+      //
+      // Function Index: 16
+      // GetAKSV
+      // Retrun: 5 bytes of AKSV
+      //
+      Case(16) {
+        if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+
+          Store("GetAKSV ", Debug)
+          Name (KSVP, Package()
+          {
+             0x80000000,
+             0x8000
+          })
+          Store(KSV0, Index(KSVP,0)) // First four bytes of AKSV
+          Store(KSV1, Index(KSVP,1)) // Fifth byte of AKSV
+          Return(KSVP) // Success
+        }
+      }
+    } // End of switch(Arg2)
+
+  } // End of if (ToUUID("3E5B41C6-EB1D-4260-9D15-C71FBADAE414D"))
+
+  Return (Buffer () {0x00})
+} // End of _DSM
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl
new file mode 100644
index 0000000000..26e560a358
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl
@@ -0,0 +1,129 @@
+/** @file
+  IGD OpRegion/Software SCI Reference Code.
+  This file contains Get BIOS Data Area funciton support for
+  the Integrated Graphics Device (IGD) OpRegion/Software SCI mechanism
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+Method (GBDA, 0, Serialized)
+{
+  //
+  // Supported calls: Sub-function 0
+  //
+  If (LEqual(GESF, 0))
+  {
+    //
+    //<NOTE> Reference code is set to Intel's validated implementation.
+    //
+    Store(0x0000659, PARM)
+    Store(Zero, GESF) // Clear the exit parameter
+    Return(SUCC) // Success
+  }
+  //
+  // Requested callbacks: Sub-function 1
+  //
+  If (LEqual(GESF, 1))
+  {
+    //
+    //<NOTE> Call back functions are where the driver calls the
+    // system BIOS at function indicated event.
+    //
+    Store(0x300482, PARM)
+    If(LEqual(S0ID, One)){
+      Or(PARM, 0x100, PARM) //Request Fn 8 callback in CS systems
+    }
+    Store(Zero, GESF) // Clear the exit parameter
+    Return(SUCC) // Success
+  }
+  //
+  // Get Boot display Preferences: Sub-function 4
+  //
+  If (LEqual(GESF, 4))
+  {
+    //
+    //<NOTE> Get Boot Display Preferences function.
+    //
+    And(PARM, 0xEFFF0000, PARM) // PARM[30:16] = Boot device ports
+    And(PARM, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), PARM)
+    Or(IBTT, PARM, PARM) // PARM[7:0] = Boot device type
+    Store(Zero, GESF) // Clear the exit parameter
+    Return(SUCC) // Success
+  }
+  //
+  // Panel details: Sub-function 5
+  //
+  If (LEqual(GESF, 5))
+  {
+    //
+    //<NOTE> Get Panel Details function.
+    //
+    Store(IPSC, PARM) // Report the scaling setting
+    Or(PARM, ShiftLeft(IPAT, 8), PARM)
+    Add(PARM, 0x100, PARM) // Adjust panel type, 0 = VBT default
+    Or(PARM, ShiftLeft(LIDS, 16), PARM) // Report the lid state
+    Add(PARM, 0x10000, PARM) // Adjust the lid state, 0 = Unknown
+    Or(PARM, ShiftLeft(IBIA, 20), PARM) // Report the BIA setting
+    Store(Zero, GESF)
+    Return(SUCC)
+  }
+  //
+  // Internal graphics: Sub-function 7
+  //
+  If (LEqual(GESF, 7))
+  {
+    Store(GIVD, PARM) // PARM[0]      - VGA mode(1=VGA)
+    Xor(PARM, 1, PARM) // Invert the VGA mode polarity
+    Or(PARM, ShiftLeft(GMFN, 1), PARM) // PARM[1]   - # IGD PCI functions-1
+                                       // PARM[3:2]    - Reserved
+                                       // PARM[4]      - IGD D3 support(0=cold)
+                                       // PARM[10:5]   - Reserved
+    Or(PARM, ShiftLeft(3, 11), PARM) // PARM[12:11] - DVMT mode(11b = 5.0)
+
+    //
+    // Report DVMT 5.0 Total Graphics memory size.
+    //
+    Or(PARM, ShiftLeft(IDMS, 17), PARM) // Bits 20:17 are for Gfx total memory size
+    //
+    // If the "Set Internal Graphics" call is supported, the modified
+    // settings flag must be programmed per the specification.  This means
+    // that the flag must be set to indicate that system BIOS requests
+    // these settings.  Once "Set Internal Graphics" is called, the
+    //  modified settings flag must be cleared on all subsequent calls to
+    // this function.
+    // Report the graphics frequency based on B0:D2:F0:RF0h[12].  Must
+    // take into account the current VCO.
+    //
+    Or(ShiftLeft(Derefof(Index(Derefof(Index(CDCT, HVCO)), CDVL)), 21),PARM, PARM)
+    Store(1, GESF) // Set the modified settings flag
+    Return(SUCC)
+  }
+  //
+  // Spread spectrum clocks: Sub-function 10
+  //
+  If (LEqual(GESF, 10))
+  {
+    Store(0, PARM) // Assume SSC is disabled
+    If(ISSC)
+    {
+      Or(PARM, 3, PARM) // If SSC enabled, return SSC1+Enabled
+    }
+    Store(0, GESF) // Set the modified settings flag
+    Return(SUCC) // Success
+  }
+
+  If (LEqual(GESF, 11))
+  {
+    Store(KSV0, PARM) // First four bytes of AKSV
+    Store(KSV1, GESF) // Fifth byte of AKSV
+
+    Return(SUCC) // Success
+  }
+  //
+  // A call to a reserved "Get BIOS data" function was received.
+  //
+  Store(Zero, GESF) // Clear the exit parameter
+  Return(CRIT) // Reserved, "Critical failure"
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl
new file mode 100644
index 0000000000..a26cbdb00c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl
@@ -0,0 +1,296 @@
+/** @file
+  IGD OpRegion/Software SCI Reference Code.
+  This file contains the interrupt handler code for the Integrated
+  Graphics Device (IGD) OpRegion/Software SCI mechanism.
+  It defines OperationRegions to cover the IGD PCI configuration space
+  as described in the IGD OpRegion specification.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//  Define an OperationRegion to cover the GMCH PCI configuration space as
+//  described in the IGD OpRegion specificiation.
+//
+Scope(\_SB.PCI0)
+{
+  OperationRegion(MCHP, PCI_Config, 0x40, 0xC0)
+  Field(MCHP, AnyAcc, NoLock, Preserve)
+  {
+    Offset(0x14),
+    AUDE, 8,
+
+    Offset(0x60), // Top of Memory register
+    TASM, 10,     // Total system memory (64MB gran)
+        , 6,
+  }
+}
+
+//
+//  Define an OperationRegion to cover the IGD PCI configuration space as
+//  described in the IGD OpRegion specificiation.
+//
+OperationRegion(IGDP, PCI_Config, 0x40, 0xC0)
+Field(IGDP, AnyAcc, NoLock, Preserve)
+{
+  Offset(0x10), // Mirror of gfx control reg
+      , 1,
+  GIVD, 1,      // IGD VGA disable bit
+      , 2,
+  GUMA, 3,      // Stolen memory size
+      , 9,
+  Offset(0x14),
+      , 4,
+  GMFN, 1,      // Gfx function 1 enable
+      , 27,
+  Offset(0xA4),
+  ASLE, 8,      // Reg 0xE4, ASLE interrupt register
+      , 24,     // Only use first byte of ASLE reg
+  Offset(0xA8), // Reg 0xE8, SWSCI control register
+  GSSE, 1,      // Graphics SCI event (1=event pending)
+  GSSB, 14,     // Graphics SCI scratchpad bits
+  GSES, 1,      // Graphics event select (1=SCI)
+  Offset(0xB0), // Gfx Clk Frequency and Gating Control
+      , 12,
+  CDVL, 1,      // Core display clock value
+      , 3,      // Graphics Core Display Clock Select
+  Offset(0xB5),
+  LBPC, 8,      // Legacy brightness control
+  Offset(0xBC),
+  ASLS, 32,     // Reg 0xFC, Address of the IGD OpRegion
+}
+
+//
+//  Define an OperationRegion to cover the IGD OpRegion layout.
+//
+OperationRegion(IGDM, SystemMemory, ASLB, 0x2000)
+Field(IGDM, AnyAcc, NoLock, Preserve)
+{
+  //
+  // OpRegion Header
+  //
+  SIGN, 128,     // Signature-"IntelGraphicsMem"
+  SIZE, 32,      // OpRegion Size
+  OVER, 32,      // OpRegion Version
+  SVER, 256,     // System BIOS Version
+  VVER, 128,     // VBIOS Version
+  GVER, 128,     // Driver version
+  MBOX, 32,      // Mailboxes supported
+  DMOD, 32,      // Driver Model
+  PCON, 32,      // Platform Configuration
+  DVER, 64,      // GOP Version
+  //
+  // OpRegion Mailbox 1 (Public ACPI Methods)
+  // Note: Mailbox 1 is normally reserved for desktop platforms.
+  //
+  Offset(0x100),
+  DRDY, 32,      // Driver readiness (ACPI notification)
+  CSTS, 32,      // Notification status
+  CEVT, 32,      // Current event
+  Offset(0x120),
+  DIDL, 32,      // Supported display device ID list
+  DDL2, 32,      // Allows for 8 devices
+  DDL3, 32,
+  DDL4, 32,
+  DDL5, 32,
+  DDL6, 32,
+  DDL7, 32,
+  DDL8, 32,
+  CPDL, 32,      // Currently present display list
+  CPL2, 32,      // Allows for 8 devices
+  CPL3, 32,
+  CPL4, 32,
+  CPL5, 32,
+  CPL6, 32,
+  CPL7, 32,
+  CPL8, 32,
+  CADL, 32,      // Currently active display list
+  CAL2, 32,      // Allows for 8 devices
+  CAL3, 32,
+  CAL4, 32,
+  CAL5, 32,
+  CAL6, 32,
+  CAL7, 32,
+  CAL8, 32,
+  NADL, 32,      // Next active display list
+  NDL2, 32,      // Allows for 8 devices
+  NDL3, 32,
+  NDL4, 32,
+  NDL5, 32,
+  NDL6, 32,
+  NDL7, 32,
+  NDL8, 32,
+  ASLP, 32,      // ASL sleep timeout
+  TIDX, 32,      // Toggle table index
+  CHPD, 32,      // Current hot plug enable indicator
+  CLID, 32,      // Current lid state indicator
+  CDCK, 32,      // Current docking state indicator
+  SXSW, 32,      // Display switch notify on resume
+  EVTS, 32,      // Events supported by ASL (diag only)
+  CNOT, 32,      // Current OS notifications (diag only)
+  NRDY, 32,
+  //
+  //Extended DIDL list
+  //
+  DDL9, 32,
+  DD10, 32,
+  DD11, 32,
+  DD12, 32,
+  DD13, 32,
+  DD14, 32,
+  DD15, 32,
+  //
+  //Extended Currently attached Display Device List  CPD2
+  //
+  CPL9, 32,
+  CP10, 32,
+  CP11, 32,
+  CP12, 32,
+  CP13, 32,
+  CP14, 32,
+  CP15, 32,
+  //
+  // OpRegion Mailbox 2 (Software SCI Interface)
+  //
+  Offset(0x200), // SCIC
+  SCIE, 1,       // SCI entry bit (1=call unserviced)
+  GEFC, 4,       // Entry function code
+  GXFC, 3,       // Exit result
+  GESF, 8,       // Entry/exit sub-function/parameter
+      , 16,      // SCIC[31:16] reserved
+  Offset(0x204), // PARM
+  PARM, 32,      // PARM register (extra parameters)
+  DSLP,  32,     // Driver sleep time out
+  //
+  // OpRegion Mailbox 3 (BIOS to Driver Notification)
+  // Note: Mailbox 3 is normally reserved for desktop platforms.
+  //
+  Offset(0x300),
+  ARDY, 32,      // Driver readiness (power conservation)
+  ASLC, 32,      // ASLE interrupt command/status
+  TCHE, 32,      // Technology enabled indicator
+  ALSI, 32,      // Current ALS illuminance reading
+  BCLP, 32,      // Backlight brightness
+  PFIT, 32,      // Panel fitting state or request
+  CBLV, 32,      // Current brightness level
+  BCLM, 320,     // Backlight brightness level duty cycle mapping table
+  CPFM, 32,      // Current panel fitting mode
+  EPFM, 32,      // Enabled panel fitting modes
+  PLUT, 592,     // Optional. 74-byte Panel LUT Table
+  PFMB, 32,      // Optional. PWM Frequency and Minimum Brightness
+  CCDV, 32,      // Optional. Gamma, Brightness, Contrast values.
+  PCFT, 32,      // Optional. Power Conservation Features
+  SROT, 32,      // Supported rotation angle.
+  IUER, 32,      // Optional. Intel Ultrabook Event Register.
+  FDSS, 64,      // Optional. FFS Display Physical address
+  FDSP, 32,      // Optional. FFS Display Size
+  STAT, 32,      // State Indicator
+  //
+  // OpRegion Mailbox 4 (VBT)
+  //
+  Offset(0x400),
+  RVBT, 0xC000,  // 6K bytes maximum VBT image
+  //
+  // OpRegion Mailbox 5 (BIOS to Driver Notification Extension)
+  //
+  Offset(0x1C00),
+  PHED, 32,      // Panel Header
+  BDDC, 2048,    // Panel EDID (Max 256 bytes)
+
+}
+
+//
+// Convert boot display type into a port mask.
+//
+Name (DBTB, Package()
+{
+  0x0000,        // Automatic
+  0x0007,        // Port-0 : Integrated CRT
+  0x0038,        // Port-1 : DVO-A, or Integrated LVDS
+  0x01C0,        // Port-2 : SDVO-B, or SDVO-B/C
+  0x0E00,        // Port-3 : SDVO-C
+  0x003F,        // [CRT + DVO-A / Integrated LVDS]
+  0x01C7,        // [CRT + SDVO-B] or [CRT + SDVO-B/C]
+  0x0E07,        // [CRT + SDVO-C]
+  0x01F8,        // [DVO-A / Integrated LVDS + SDVO-B]
+  0x0E38,        // [DVO-A / Integrated LVDS + SDVO-C]
+  0x0FC0,        // [SDVO-B + SDVO-C]
+  0x0000,        // Reserved
+  0x0000,        // Reserved
+  0x0000,        // Reserved
+  0x0000,        // Reserved
+  0x0000,        // Reserved
+  0x7000,        // Port-4: Integrated TV
+  0x7007,        // [Integrated TV + CRT]
+  0x7038,        // [Integrated TV + LVDS]
+  0x71C0,        // [Integrated TV + DVOB]
+  0x7E00         // [Integrated TV + DVOC]
+})
+
+//
+// Core display clock value table.
+//
+Name (CDCT, Package()
+{
+  Package() {228, 320},
+  Package() {222, 333},
+  Package() {222, 333},
+  Package() {  0,   0},
+  Package() {222, 333},
+})
+
+//
+// Defined exit result values:
+//
+Name (SUCC, 1)   // Exit result: Success
+Name (NVLD, 2)   // Exit result: Invalid parameter
+Name (CRIT, 4)   // Exit result: Critical failure
+Name (NCRT, 6)   // Exit result: Non-critical failure
+
+/************************************************************************;
+;*
+;* Name: GSCI
+;*
+;* Description: Handles an SCI generated by the graphics driver.  The
+;*              PARM and SCIC input fields are parsed to determine the
+;*              functionality requested by the driver.  GBDA or SBCB
+;*              is called based on the input data in SCIC.
+;*
+;* Usage:       The method must be called in response to a GPE 06 event
+;*              which will be generated by the graphics driver.
+;*              Ex: Method(\_GPE._L06) {Return(\_SB.PCI0.GFX0.GSCI())}
+;*
+;* Input:       PARM and SCIC are indirect inputs
+;*
+;* Output:      PARM and SIC are indirect outputs
+;*
+;* References:  GBDA (Get BIOS Data method), SBCB (System BIOS Callback
+;*              method)
+;*
+;************************************************************************/
+
+Method (GSCI, 0, Serialized)
+{
+  Include("IgfxOpGbda.asl")  // "Get BIOS Data" Functions
+  Include("IgfxOpSbcb.asl")  // "System BIOS CallBacks"
+
+  If (LEqual(GEFC, 4))
+  {
+    Store(GBDA(), GXFC)    // Process Get BIOS Data functions
+  }
+
+  If (LEqual(GEFC, 6))
+  {
+    Store(SBCB(), GXFC)    // Process BIOS Callback functions
+  }
+
+  Store(0, GEFC)           // Wipe out the entry function code
+  Store(1, CPSC)           // Clear CPUSCI_STS to clear the PCH TCO SCI status
+  Store(0, GSSE)           // Clear the SCI generation bit in PCI space.
+  Store(0, SCIE)           // Clr SCI serviced bit to signal completion
+
+  Return(Zero)
+}
+
+Include("IgfxCommon.asl")    // IGD SCI mobile features
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl
new file mode 100644
index 0000000000..0167d922ff
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl
@@ -0,0 +1,262 @@
+/** @file
+  This file contains the system BIOS call back functionality for the
+  OpRegion/Software SCI mechanism.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+Method (SBCB, 0, Serialized)
+{
+  //
+  // Supported Callbacks: Sub-function 0
+  //
+  If (LEqual(GESF, 0x0))
+  {
+    //
+    //<NOTE> An OEM may support the driver->SBIOS status callbacks, but
+    // the supported callbacks value must be modified.  The code that is
+    // executed upon reception of the callbacks must be also be updated
+    // to perform the desired functionality.
+    //
+    Store(0x00000000, PARM)   // No callbacks supported
+    //Store(0x000787FD, PARM) // Used for Intel test implementaion
+    Store(0x000F87DD, PARM)
+    Store(Zero, GESF)         // Clear the exit parameter
+    Return(SUCC)              // "Success"
+  }
+  //
+  // BIOS POST Completion: Sub-function 1
+  //
+  If (LEqual(GESF, 1))
+  {
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // Pre-Hires Set Mode: Sub-function 3
+  //
+  If (LEqual(GESF, 3))
+  {
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // Post-Hires Set Mode: Sub-function 4
+  //
+  If (LEqual(GESF, 4))
+  {
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // Display Switch: Sub-function 5
+  //
+  If (LEqual(GESF, 5))
+  {
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // Adapter Power State: Sub-function 7
+  //
+  If (LEqual(GESF, 7))
+  {
+    //
+    // Handle Low Power S0 Idle Capability if enabled
+    //
+    If(LAnd(LEqual(S0ID, 1),LLess(OSYS, 2015))) {
+      //
+      // Call GUAM to trigger CS Entry
+      //   If Adapter Power State Notification = D1 (PARM[7:0]=0x01)
+      //
+      If (LEqual (And(PARM,0xFF), 0x01)) {
+        // GUAM - Global User Absent Mode Notification Method
+        \GUAM(One) // 0x01 - Power State Standby (CS Entry)
+      }
+      If (LEqual (And(PARM,0xFF), 0x00)) {
+        // GUAM - Global User Absent Mode Notification Method
+        \GUAM(0)
+      }
+    }
+    //
+    // Upon notification from driver that the Adapter Power State = D0,
+    // check if previous lid event failed.  If it did, retry the lid
+    // event here.
+    //
+    If(LEqual(PARM, 0))
+    {
+      Store(CLID, Local0)
+      If(And(0x80000000,Local0))
+      {
+        And(CLID, 0x0000000F, CLID)
+        GLID(CLID)
+      }
+    }
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // Display Power State: Sub-function 8
+  //
+  If (LEqual(GESF, 8))
+  {
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // Set Boot Display: Sub-function 9
+  //
+  If (LEqual(GESF, 9))
+  {
+    //
+    //<NOTE> An OEM may elect to implement this method.  In that case,
+    // the input values must be saved into non-volatile storage for
+    // parsing during the next boot.  The following Sample code is Intel
+    // validated implementation.
+    //
+    And(PARM, 0xFF, IBTT) // Save the boot display to NVS
+    Store(Zero, GESF)     // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)          // Reserved, "Critical failure"
+  }
+  //
+  // Set Panel Details: Sub-function 10 (0Ah)
+  //
+  If (LEqual(GESF, 10))
+  {
+    //
+    //<NOTE> An OEM may elect to implement this method.  In that case,
+    // the input values must be saved into non-volatile storage for
+    // parsing during the next boot.  The following Sample code is Intel
+    // validated implementation.
+    // Set the panel-related NVRAM variables based the input from the driver.
+    //
+    And(PARM, 0xFF, IPSC)
+    //
+    // Change panel type if a change is requested by the driver (Change if
+    // panel type input is non-zero).  Zero=No change requested.
+    //
+    If(And(ShiftRight(PARM, 8), 0xFF))
+    {
+      And(ShiftRight(PARM, 8), 0xFF, IPAT)
+      Decrement(IPAT)    // 0 = no change, so fit to CMOS map
+    }
+    And(ShiftRight(PARM, 20), 0x7, IBIA)
+    Store(Zero, GESF)    // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)         // Success
+  }
+  //
+  // Set Internal Graphics: Sub-function 11 (0Bh)
+  //
+  If (LEqual(GESF, 11))
+  {
+    //
+    //<NOTE> An OEM may elect to implement this method.  In that case,
+    // the input values must be saved into non-volatile storage for
+    // parsing during the next boot.  The following Sample code is Intel
+    // validated implementation.
+    //
+    And(ShiftRight(PARM, 1), 1, IF1E)      // Program the function 1 option
+    If(And(PARM, ShiftLeft(0xF, 13)))      // Use fixed memory if fixed size != 0
+    {
+      //
+      // Fixed memory
+      //
+      And(ShiftRight(PARM, 13), 0xF, IDMS) // Program fixed memory size
+    }
+    Else
+    {
+      //
+      // DVMT memory
+      //
+      And(ShiftRight(PARM, 17), 0xF, IDMS) // Program fixed memory size
+    }
+    Store(Zero, GESF)                      // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                           // Success
+  }
+  //
+  // Post-Hires to DOS FS: Sub-function 16 (10h)
+  //
+  If (LEqual(GESF, 16))
+  {
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // APM Complete:  Sub-function 17 (11h)
+  //
+  If (LEqual(GESF, 17))
+  {
+    Store(ShiftLeft(LIDS, 8), PARM) // Report the lid state
+    Add(PARM, 0x100, PARM)          // Adjust the lid state, 0 = Unknown
+    Store(Zero, GESF)               // Clear the exit parameter
+    Return(SUCC)                    // Not supported, but no failure
+  }
+  //
+  // Set Spread Spectrum Clocks: Sub-function 18 (12h)
+  //
+  If (LEqual(GESF, 18))
+  {
+    //
+    //<NOTE> An OEM may elect to implement this method.  In that case,
+    // the input values must be saved into non-volatile storage for
+    // parsing during the next boot.  The following Sample code is Intel
+    // validated implementation.
+    //
+    If(And(PARM, 1))
+    {
+      If(LEqual(ShiftRight(PARM, 1), 1))
+      {
+        Store(1, ISSC)  // Enable HW SSC, only for clock 1
+      }
+      Else
+      {
+        Store(Zero, GESF)
+        Return(CRIT)    // Failure, as the SSC clock must be 1
+      }
+    }
+    Else
+    {
+      Store(0, ISSC)    // Disable SSC
+    }
+    Store(Zero, GESF)   // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)        // Success
+  }
+  //
+  // Post VBE/PM Callback: Sub-function 19 (13h)
+  //
+  If (LEqual(GESF, 19))
+  {
+    Store(Zero, GESF)  // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)       // Not supported, but no failure
+  }
+  //
+  // Set PAVP Data: Sub-function 20 (14h)
+  //
+  If (LEqual(GESF, 20))
+  {
+    And(PARM, 0xF, PAVP) // Store PAVP info
+    Store(Zero, GESF)    // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)         // Success
+  }
+
+  //
+  // A call to a reserved "System BIOS callbacks" function was received
+  //
+  Store(Zero, GESF) // Clear the exit parameter
+  Return(SUCC)      // Reserved, "Critical failure"
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
new file mode 100644
index 0000000000..e4e47ddf1e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
@@ -0,0 +1,87 @@
+/** @file
+  This file contains the device definition of the System Agent
+  ACPI reference code.
+  Currently defines the device objects for the
+  System Agent IPU device
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Device IPUA is the IPU AVStream virtual device and it appears under GFX0
+//
+Scope (\_SB.PCI0.GFX0)
+{
+  Device(IPUA) // IPU AVStream virtual device name
+  {
+    /*
+      The identifier for this device (Same as in
+      _DOD above). This is required so GFX driver can
+      associate a matching device ID for the AVStream
+      driver and provide it to PnP (this device ID
+      should appear in the INF file of the AVStream
+      driver).
+    */
+    Name(_ADR, 0x00003480)
+    /*
+      The following is a technique that may be used (per OEM needs) to prevent
+      the load of the camera device in one of the following cases:
+      - Camera device is fused out
+      - If the platform setup requires that in a secured boot the camera device
+      should not be enabled
+    */
+    Method (_STA, 0, NotSerialized) {
+      If(LEqual(IPTP,1)){ // IGFX need report IPU AVStream virtual device as GFX0 child
+        Return (0xF)
+      } Else { // IGFX should NOT report IPU AVStream virtual device as GFX0 child
+        Return (0x0)
+      }
+    }
+  } // End SKC0
+} // end I.G.D
+
+Scope(\_SB.PCI0.IPU0)
+{
+//----------------------------------------------------------------------------------------
+//  Intel Proprietary Passing LTR information from BIOS to IPU Driver. DSM Method
+//
+//  Method(_DSM, 0x4, Serialized, 0, {IntObj, BuffObj}, {BuffObj, IntObj, IntObj, PkgObj})
+//  Arguments:
+//  Arg0: GUID: "9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90"
+//  Arg1: Integer Revision Level (Current revision is 0)
+//  Arg2: Integer Function Index
+//                0x1 - return UINT 32bit LTR values
+//                0x2 - return UINT 32bit Fill Time
+//
+//-----------------------------------------------------------------------------------------
+Method (_DSM, 4, NotSerialized) { // _DSM: Device-Specific Method
+    If (LEqual(Arg0, ToUUID("9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90")))
+    {
+      // Function 0 : Query Function
+      If (LEqual(Arg2, 0))
+      {
+        // Revision 0
+        If (LEqual(Arg1, 0)) // The current revision is 0
+        {
+          Return(Buffer() { 0x07 }) // There are 2 function defined other than Query.
+        } Else {
+          Return(0) // Revision mismatch
+        }
+      }
+      // Function 1 : Return UINT 32bit LTR values
+      If(LEqual(Arg2, 1))
+      {
+        Return(0x64503C19)
+      }
+      // Function 2 : Return UINT 32bit Fill Time
+      If(LEqual(Arg2, 2))
+      {
+        Return(0xFFF0783C)
+      }
+    }
+
+    Return(0) // Function number or GUID mismatch but normal return.
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
new file mode 100644
index 0000000000..4817968240
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
@@ -0,0 +1,31 @@
+/** @file
+  This file contains the device definition of the System Agent
+  ACPI reference code.
+  Currently defines the device objects for the
+  System Agent PCI Express* ports (PEG), iGfx and other devices.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(\_SB.PCI0, DeviceObj)
+External(\_SB.PCI0.GFX0, DeviceObj)
+External(\_SB.PCI0.IPU0, DeviceObj)
+External(\_SB.PCI0.B0D3, DeviceObj)
+External(\_SB.PCI0.PCIC, MethodObj)
+External(\_SB.PCI0.PCID, MethodObj)
+
+
+///
+/// I.G.D
+///
+Scope (\_SB.PCI0.GFX0)
+{
+  include("Igfx.asl")
+} // end I.G.D
+
+///
+/// IPU Device
+///
+include("Ipu.asl")
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
new file mode 100644
index 0000000000..09d36ade53
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
@@ -0,0 +1,147 @@
+/** @file
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define SA NVS Area operatino region.
+  //
+
+
+
+  OperationRegion(SANV,SystemMemory, 0xFFFF0000,0xAA55)
+  Field(SANV,AnyAcc,Lock,Preserve)
+  {  Offset(0),      ASLB, 32, // Offset(0),     IGD OpRegion base address
+  Offset(4),      IMON, 8,  // Offset(4),     IMON Current Value
+  Offset(5),      IGDS, 8,  // Offset(5),     IGD State (Primary Display = 1)
+  Offset(6),      IBTT, 8,  // Offset(6),     IGD Boot Display Device
+  Offset(7),      IPAT, 8,  // Offset(7),     IGD Panel Type CMOS option
+  Offset(8),      IPSC, 8,  // Offset(8),     IGD Panel Scaling
+  Offset(9),      IBIA, 8,  // Offset(9),     IGD BIA Configuration
+  Offset(10),     ISSC, 8,  // Offset(10),    IGD SSC Configuration
+  Offset(11),     IDMS, 8,  // Offset(11),    IGD DVMT Memory Size
+  Offset(12),     IF1E, 8,  // Offset(12),    IGD Function 1 Enable
+  Offset(13),     HVCO, 8,  // Offset(13),    HPLL VCO
+  Offset(14),     GSMI, 8,  // Offset(14),    GMCH SMI/SCI mode (0=SCI)
+  Offset(15),     PAVP, 8,  // Offset(15),    IGD PAVP data
+  Offset(16),     CADL, 8,  // Offset(16),    Current Attached Device List
+  Offset(17),     CSTE, 16, // Offset(17),    Current Display State
+  Offset(19),     NSTE, 16, // Offset(19),    Next Display State
+  Offset(21),     NDID, 8,  // Offset(21),    Number of Valid Device IDs
+  Offset(22),     DID1, 32, // Offset(22),    Device ID 1
+  Offset(26),     DID2, 32, // Offset(26),    Device ID 2
+  Offset(30),     DID3, 32, // Offset(30),    Device ID 3
+  Offset(34),     DID4, 32, // Offset(34),    Device ID 4
+  Offset(38),     DID5, 32, // Offset(38),    Device ID 5
+  Offset(42),     DID6, 32, // Offset(42),    Device ID 6
+  Offset(46),     DID7, 32, // Offset(46),    Device ID 7
+  Offset(50),     DID8, 32, // Offset(50),    Device ID 8
+  Offset(54),     DID9, 32, // Offset(54),    Device ID 9
+  Offset(58),     DIDA, 32, // Offset(58),    Device ID 10
+  Offset(62),     DIDB, 32, // Offset(62),    Device ID 11
+  Offset(66),     DIDC, 32, // Offset(66),    Device ID 12
+  Offset(70),     DIDD, 32, // Offset(70),    Device ID 13
+  Offset(74),     DIDE, 32, // Offset(74),    Device ID 14
+  Offset(78),     DIDF, 32, // Offset(78),    Device ID 15
+  Offset(82),     DIDX, 32, // Offset(82),    Device ID for eDP device
+  Offset(86),     NXD1, 32, // Offset(86),    Next state DID1 for _DGS
+  Offset(90),     NXD2, 32, // Offset(90),    Next state DID2 for _DGS
+  Offset(94),     NXD3, 32, // Offset(94),    Next state DID3 for _DGS
+  Offset(98),     NXD4, 32, // Offset(98),    Next state DID4 for _DGS
+  Offset(102),    NXD5, 32, // Offset(102),   Next state DID5 for _DGS
+  Offset(106),    NXD6, 32, // Offset(106),   Next state DID6 for _DGS
+  Offset(110),    NXD7, 32, // Offset(110),   Next state DID7 for _DGS
+  Offset(114),    NXD8, 32, // Offset(114),   Next state DID8 for _DGS
+  Offset(118),    NXDX, 32, // Offset(118),   Next state DID for eDP
+  Offset(122),    LIDS, 8,  // Offset(122),   Lid State (Lid Open = 1)
+  Offset(123),    KSV0, 32, // Offset(123),   First four bytes of AKSV (manufacturing mode)
+  Offset(127),    KSV1, 8,  // Offset(127),   Fifth byte of AKSV (manufacturing mode)
+  Offset(128),    BRTL, 8,  // Offset(128),   Brightness Level Percentage
+  Offset(129),    ALSE, 8,  // Offset(129),   Ambient Light Sensor Enable
+  Offset(130),    ALAF, 8,  // Offset(130),   Ambient Light Adjusment Factor
+  Offset(131),    LLOW, 8,  // Offset(131),   LUX Low Value
+  Offset(132),    LHIH, 8,  // Offset(132),   LUX High Value
+  Offset(133),    ALFP, 8,  // Offset(133),   Active LFP
+  Offset(134),    IPTP, 8,  // Offset(134),   IPU ACPI device type (0=Disabled, 1=AVStream virtual device as child of GFX)
+  Offset(135),    EDPV, 8,  // Offset(135),   Check for eDP display device
+  Offset(136),    SGMD, 8,  // Offset(136),   SG Mode (0=Disabled, 1=SG Muxed, 2=SG Muxless, 3=DGPU Only)
+  Offset(137),    SGFL, 8,  // Offset(137),   SG Feature List
+  Offset(138),    SGGP, 8,  // Offset(138),   PCIe0 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  Offset(139),    HRE0, 8,  // Offset(139),   PCIe0 HLD RST IO Expander Number
+  Offset(140),    HRG0, 32, // Offset(140),   PCIe0 HLD RST GPIO Number
+  Offset(144),    HRA0, 8,  // Offset(144),   PCIe0 HLD RST GPIO Active Information
+  Offset(145),    PWE0, 8,  // Offset(145),   PCIe0 PWR Enable IO Expander Number
+  Offset(146),    PWG0, 32, // Offset(146),   PCIe0 PWR Enable GPIO Number
+  Offset(150),    PWA0, 8,  // Offset(150),   PCIe0 PWR Enable GPIO Active Information
+  Offset(151),    P1GP, 8,  // Offset(151),   PCIe1 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  Offset(152),    HRE1, 8,  // Offset(152),   PCIe1 HLD RST IO Expander Number
+  Offset(153),    HRG1, 32, // Offset(153),   PCIe1 HLD RST GPIO Number
+  Offset(157),    HRA1, 8,  // Offset(157),   PCIe1 HLD RST GPIO Active Information
+  Offset(158),    PWE1, 8,  // Offset(158),   PCIe1 PWR Enable IO Expander Number
+  Offset(159),    PWG1, 32, // Offset(159),   PCIe1 PWR Enable GPIO Number
+  Offset(163),    PWA1, 8,  // Offset(163),   PCIe1 PWR Enable GPIO Active Information
+  Offset(164),    P2GP, 8,  // Offset(164),   PCIe2 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  Offset(165),    HRE2, 8,  // Offset(165),   PCIe2 HLD RST IO Expander Number
+  Offset(166),    HRG2, 32, // Offset(166),   PCIe2 HLD RST GPIO Number
+  Offset(170),    HRA2, 8,  // Offset(170),   PCIe2 HLD RST GPIO Active Information
+  Offset(171),    PWE2, 8,  // Offset(171),   PCIe2 PWR Enable IO Expander Number
+  Offset(172),    PWG2, 32, // Offset(172),   PCIe2 PWR Enable GPIO Number
+  Offset(176),    PWA2, 8,  // Offset(176),   PCIe2 PWR Enable GPIO Active Information
+  Offset(177),    DLPW, 16, // Offset(177),   Delay after power enable for PCIe
+  Offset(179),    DLHR, 16, // Offset(179),   Delay after Hold Reset for PCIe
+  Offset(181),    EECP, 8,  // Offset(181),   PCIe0 Endpoint Capability Structure Offset
+  Offset(182),    XBAS, 32, // Offset(182),   Any Device's PCIe Config Space Base Address
+  Offset(186),    GBAS, 16, // Offset(186),   GPIO Base Address
+  Offset(188),    NVGA, 32, // Offset(188),   NVIG opregion address
+  Offset(192),    NVHA, 32, // Offset(192),   NVHM opregion address
+  Offset(196),    AMDA, 32, // Offset(196),   AMDA opregion address
+  Offset(200),    LTRX, 8,  // Offset(200),   Latency Tolerance Reporting Enable
+  Offset(201),    OBFX, 8,  // Offset(201),   Optimized Buffer Flush and Fill
+  Offset(202),    LTRY, 8,  // Offset(202),   Latency Tolerance Reporting Enable
+  Offset(203),    OBFY, 8,  // Offset(203),   Optimized Buffer Flush and Fill
+  Offset(204),    LTRZ, 8,  // Offset(204),   Latency Tolerance Reporting Enable
+  Offset(205),    OBFZ, 8,  // Offset(205),   Optimized Buffer Flush and Fill
+  Offset(206),    LTRW, 8,  // Offset(206),   Latency Tolerance Reporting Enable
+  Offset(207),    OBFA, 8,  // Offset(207),   Optimized Buffer Flush and Fill
+  Offset(208),    SMSL, 16, // Offset(208),   SA Peg Latency Tolerance Reporting Max Snoop Latency
+  Offset(210),    SNSL, 16, // Offset(210),   SA Peg Latency Tolerance Reporting Max No Snoop Latency
+  Offset(212),    P0UB, 8,  // Offset(212),   Peg0 Unused Bundle Control
+  Offset(213),    P1UB, 8,  // Offset(213),   Peg1 Unused Bundle Control
+  Offset(214),    P2UB, 8,  // Offset(214),   Peg2 Unused Bundle Control
+  Offset(215),    P3UB, 8,  // Offset(215),   Peg3 Unused Bundle Control
+  Offset(216),    PCSL, 8,  // Offset(216),   The lowest C-state for the package
+  Offset(217),    PBGE, 8,  // Offset(217),   Pegx Unused Bundle Control Global Enable (0=Disabled, 1=Enabled)
+  Offset(218),    M64B, 64, // Offset(218),   Base of above 4GB MMIO resource
+  Offset(226),    M64L, 64, // Offset(226),   Length of above 4GB MMIO resource
+  Offset(234),    CPEX, 32, // Offset(234),   CPU ID info to get Family Id or Stepping
+  Offset(238),    EEC1, 8,  // Offset(238),   PCIe1 Endpoint Capability Structure Offset
+  Offset(239),    EEC2, 8,  // Offset(239),   PCIe2 Endpoint Capability Structure Offset
+  Offset(240),    SBN0, 8,  // Offset(240),   PCIe0 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  Offset(241),    SBN1, 8,  // Offset(241),   PCIe1 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  Offset(242),    SBN2, 8,  // Offset(242),   PCIe2 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  Offset(243),    M32B, 32, // Offset(243),   Base of below 4GB MMIO resource
+  Offset(247),    M32L, 32, // Offset(247),   Length of below 4GB MMIO resource
+  Offset(251),    P0WK, 32, // Offset(251),   PCIe0 RTD3 Device Wake GPIO Number
+  Offset(255),    P1WK, 32, // Offset(255),   PCIe1 RTD3 Device Wake GPIO Number
+  Offset(259),    P2WK, 32, // Offset(259),   PCIe2 RTD3 Device Wake GPIO Number
+  Offset(263),    VTDS, 8,  // Offset(263),   VT-d Enable/Disable
+  Offset(264),    VTB1, 32, // Offset(264),   VT-d Base Address 1
+  Offset(268),    VTB2, 32, // Offset(268),   VT-d Base Address 2
+  Offset(272),    VTB3, 32, // Offset(272),   VT-d Base Address 3
+  Offset(276),    VE1V, 16, // Offset(276),   VT-d Engine#1 Vendor ID
+  Offset(278),    VE2V, 16, // Offset(278),   VT-d Engine#2 Vendor ID
+  Offset(280),    SBN3, 8,  // Offset(280),   PCIe3 Secondary Bus Number (PCIe3 Endpoint Bus Number)
+  Offset(281),    P3GP, 8,  // Offset(281),   PCIe3 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  Offset(282),    HRE3, 8,  // Offset(282),   PCIe3 HLD RST IO Expander Number
+  Offset(283),    HRG3, 32, // Offset(283),   PCIe3 HLD RST GPIO Number
+  Offset(287),    HRA3, 8,  // Offset(287),   PCIe3 HLD RST GPIO Active Information
+  Offset(288),    PWE3, 8,  // Offset(288),   PCIe3 PWR Enable IO Expander Number
+  Offset(289),    PWG3, 32, // Offset(289),   PCIe3 PWR Enable GPIO Number
+  Offset(293),    PWA3, 8,  // Offset(293),   PCIe3 PWR Enable GPIO Active Information
+  Offset(294),    P3WK, 32, // Offset(294),   PCIe3 RTD3 Device Wake GPIO Number
+  Offset(298),    EEC3, 8,  // Offset(298),   PCIe3 Endpoint Capability Structure Offset
+  Offset(299),    RPIN, 8,  // Offset(299),   RootPort Number
+  Offset(300),    RPBA, 32, // Offset(300),   RootPortAddress
+  Offset (500),             // Offset(304) : Offset(499), Reserved bytes
+  }
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
new file mode 100644
index 0000000000..0db354901d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
@@ -0,0 +1,22 @@
+/** @file
+  This file contains the SystemAgent SSDT Table ASL code.
+  It defines a Global NVS table which exchanges datas between OS
+  and BIOS.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+DefinitionBlock (
+  "SaSsdt.aml",
+  "SSDT",
+  0x02,
+  "SaSsdt",
+  "SaSsdt ",
+  0x3000
+  )
+{
+  include ("SaNvs.asl")
+  include ("Sa.asl")
+}
-- 
2.16.2.windows.1


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

View/Reply Online (#45906): https://edk2.groups.io/g/devel/message/45906
Mute This Topic: https://groups.io/mt/32918199/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