public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Chiu, Chasel" <chasel.chiu@intel.com>
To: "Kubacki, Michael A" <michael.a.kubacki@intel.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Chaganty, Rangasai V" <rangasai.v.chaganty@intel.com>,
	"Desimone, Nathaniel L" <nathaniel.l.desimone@intel.com>,
	"Gao, Liming" <liming.gao@intel.com>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>,
	"Sinha, Ankit" <ankit.sinha@intel.com>
Subject: Re: [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules
Date: Sat, 17 Aug 2019 01:15:10 +0000	[thread overview]
Message-ID: <3C3EFB470A303B4AB093197B6777CCEC504623CD@PGSMSX111.gar.corp.intel.com> (raw)
In-Reply-To: <20190817001603.30632-29-michael.a.kubacki@intel.com>

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


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent:
> Add modules
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> * SaAcpiTables - SA (DMAR) ACPI tables.
> * SaSsdt - SA SSDT ACPI tables.
> * SaInitDxe - Generic DXE SA initialization.
> * SmmAccess - Produces an instance of EFI_SMM_ACCESS2_PROTOCOL.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
> |   50 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
> |   49 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> |  116 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess
> .inf                    |   48 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
> |   25 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcCommonTypes.h |  230 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcInterface.h   | 1567 ++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcRmtData.h     |  203 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcSpdData.h     | 1167 ++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcTypes.h       |  237 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInt
> erface.h              |   15 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
> |   50 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.
> h                   |  193 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
> |   91 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
> |   23 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
> |   71 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
> |  139 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraph
> icsInit.h            |   17 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
> |   53 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess
> Driver.h                |  162 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
> |  157 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.
> c                   |  570 +++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
> |  171 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
> |  171 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
> |  496 ++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
> |  179 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
> |  122 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
> |  717 +++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess
> Driver.c                |  356 +++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
> |  250 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
> |  794 ++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
> | 1666 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCom
> mon.asl               |  472 ++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.a
> sl                  |  369 +++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGb
> da.asl               |  129 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.
> asl                 |  296 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbc
> b.asl               |  262 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
> |   87 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
> |   31 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
> |  147 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
> |   22 +
>  41 files changed, 11970 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.i
> nf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.i
> nf
> new file mode 100644
> index 0000000000..56ddc2957f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.i
> nf
> @@ -0,0 +1,50 @@
> +## @file
> +#  Component description file for the ACPI tables
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION          = 0x00010005
> +BASE_NAME            = SaAcpiTables
> +FILE_GUID            = 3c0ed5e2-91ea-4b94-820d-9daf9a3bb4a2
> +MODULE_TYPE          = USER_DEFINED
> +VERSION_STRING       = 1.0
> +
> +[Sources]
> +  Dmar/Dmar.aslc
> +  Dmar/Dmar.h
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +###############################################################
> #################
> +#
> +# Library Class Section - list of Library Classes that are required for
> +#                         this module.
> +#
> +###############################################################
> #################
> +
> +[LibraryClasses]
> +
> +###############################################################
> #################
> +#
> +# Protocol C Name Section - list of Protocol and Protocol Notify C Names
> +#                           that this module uses or produces.
> +#
> +###############################################################
> #################
> +[Pcd]
> +
> +[Protocols]
> +
> +[PPIs]
> +
> +[Guids]
> +
> +[Depex]
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.i
> nf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> inf
> new file mode 100644
> index 0000000000..3588565aac
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> inf
> @@ -0,0 +1,49 @@
> +## @file
> +#  Component description file for the ACPI tables
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION          = 0x00010005
> +BASE_NAME            = SaSsdt
> +FILE_GUID            = ca89914d-2317-452e-b245-36c6fb77a9c6
> +MODULE_TYPE          = USER_DEFINED
> +VERSION_STRING       = 1.0
> +
> +[Sources]
> +  SaSsdt.asl
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +###############################################################
> #################
> +#
> +# Library Class Section - list of Library Classes that are required for
> +#                         this module.
> +#
> +###############################################################
> #################
> +
> +[LibraryClasses]
> +
> +###############################################################
> #################
> +#
> +# Protocol C Name Section - list of Protocol and Protocol Notify C Names
> +#                           that this module uses or produces.
> +#
> +###############################################################
> #################
> +[Pcd]
> +
> +[Protocols]
> +
> +[PPIs]
> +
> +[Guids]
> +
> +[Depex]
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> new file mode 100644
> index 0000000000..9937fc60e5
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> @@ -0,0 +1,116 @@
> +## @file
> +# Component description file for SystemAgent Initialization driver
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = SaInitDxe
> +FILE_GUID = DE23ACEE-CF55-4fb6-AA77-984AB53DE811
> +VERSION_STRING = 1.0
> +MODULE_TYPE = DXE_DRIVER
> +ENTRY_POINT = SaInitEntryPointDxe
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[LibraryClasses]
> +UefiDriverEntryPoint
> +UefiLib
> +UefiBootServicesTableLib
> +DxeServicesTableLib
> +DebugLib
> +TimerLib
> +PciCf8Lib
> +PciSegmentLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +CpuPlatformLib
> +IoLib
> +S3BootScriptLib
> +PmcLib
> +PchCycleDecodingLib
> +PchInfoLib
> +GpioLib
> +ConfigBlockLib
> +SaPlatformLib
> +PchPcieRpLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +UefiCpuPkg/UefiCpuPkg.dec
> +IntelSiliconPkg/IntelSiliconPkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +PcAtChipsetPkg/PcAtChipsetPkg.dec
> +
> +[Pcd]
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
> +gSiPkgTokenSpaceGuid.PcdMchBaseAddress
> +gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress
> +
> +[Sources]
> +SaInitDxe.h
> +SaInitDxe.c
> +SaInit.h
> +SaInit.c
> +VTd.c
> +VTd.h
> +IgdOpRegionInit.h
> +IgdOpRegionInit.c
> +GraphicsInit.h
> +GraphicsInit.c
> +PciExpressInit.h
> +PciExpressInit.c
> +PcieComplex.c
> +PcieComplex.h
> +SaAcpi.c
> +
> +[Protocols]
> +gEfiAcpiTableProtocolGuid              ## CONSUMES
> +gSaNvsAreaProtocolGuid                 ## PRODUCES
> +gSaPolicyProtocolGuid                  ## CONSUMES
> +gEfiCpuArchProtocolGuid                ## CONSUMES
> +gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
> +gEfiPciRootBridgeIoProtocolGuid        ## CONSUMES
> +gEfiPciIoProtocolGuid                  ## CONSUMES
> +gIgdOpRegionProtocolGuid               ## PRODUCES
> +gEfiFirmwareVolume2ProtocolGuid        ## CONSUMES
> +gEfiLegacyBiosProtocolGuid             ## CONSUMES
> +gGopComponentName2ProtocolGuid         ## CONSUMES
> +gSaIotrapSmiProtocolGuid               ## CONSUMES
> +
> +[Guids]
> +gSaConfigHobGuid
> +gSgAcpiTablePchStorageGuid
> +gSaAcpiTableStorageGuid
> +gSgAcpiTableStorageGuid
> +gSaSsdtAcpiTableStorageGuid
> +gPegSsdtAcpiTableStorageGuid
> +gEfiEndOfDxeEventGroupGuid
> +gSiConfigHobGuid        ## CONSUMES
> +gMiscDxeConfigGuid
> +gGraphicsDxeConfigGuid
> +gMemoryDxeConfigGuid
> +gPcieDxeConfigGuid
> +gVbiosDxeConfigGuid
> +gPchInfoHobGuid
> +
> +[Depex]
> +gEfiAcpiTableProtocolGuid AND
> +gEfiFirmwareVolume2ProtocolGuid AND
> +gSaPolicyProtocolGuid AND
> +gEfiPciRootBridgeIoProtocolGuid AND
> +gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure
> that PCI MMIO resource has been prepared and available for this driver to
> allocate.
> +gEfiHiiDatabaseProtocolGuid
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ss.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ss.inf
> new file mode 100644
> index 0000000000..9356781c9e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ss.inf
> @@ -0,0 +1,48 @@
> +## @file
> +# Component description file for the SmmAccess module
> +#
> +# {1323C7F8-DAD5-4126-A54B-7A05FBF41515}
> +#
> +# Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = SmmAccess
> +FILE_GUID = 1323C7F8-DAD5-4126-A54B-7A05FBF41515
> +VERSION_STRING = 1.0
> +MODULE_TYPE = DXE_DRIVER
> +ENTRY_POINT = SmmAccessDriverEntryPoint
> +
> +
> +[LibraryClasses]
> +UefiDriverEntryPoint
> +BaseLib
> +BaseMemoryLib
> +DebugLib
> +HobLib
> +PciLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +SmmAccessDriver.h
> +SmmAccessDriver.c
> +
> +
> +[Protocols]
> +gEfiSmmAccess2ProtocolGuid       ## PRODUCES
> +
> +
> +[Guids]
> +gEfiSmmPeiSmramMemoryReserveGuid
> +
> +
> +[Depex]
> +TRUE
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
> new file mode 100644
> index 0000000000..4339256bba
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
> @@ -0,0 +1,25 @@
> +/** @file
> +  This file describes the contents of the ACPI DMA address Remapping
> +  Some additional ACPI values are defined in Acpi1_0.h and Acpi2_0.h.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_DMAR_H_
> +#define _SA_DMAR_H_
> +
> +///
> +/// Include standard ACPI table definitions
> +///
> +#include <IndustryStandard/Acpi30.h>
> +#include <DmaRemappingTable.h>
> +
> +#pragma pack(1)
> +
> +#define EFI_ACPI_DMAR_OEM_TABLE_ID    0x20202020324B4445  ///<
> "EDK2    "
> +#define EFI_ACPI_DMAR_OEM_CREATOR_ID  0x4C544E49  ///< "INTL"
> +#pragma pack()
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcCommonTypes.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcCommonTypes.h
> new file mode 100644
> index 0000000000..54cb69066d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcCommonTypes.h
> @@ -0,0 +1,230 @@
> +/** @file
> +  This file contains the definitions common to the MRC API and other APIs.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MrcCommonTypes_h_
> +#define _MrcCommonTypes_h_
> +
> +#define INT32_MIN                       (0x80000000)
> +#ifndef INT32_MAX  //INT32_MAX->Already defined
> +#define INT32_MAX                       (0x7FFFFFFF)
> +#endif
> +#define INT16_MIN                       (0x8000)
> +#define INT16_MAX                       (0x7FFF)
> +
> +///
> +/// System boot mode.
> +///
> +typedef enum {
> +  bmCold,                                 ///< Cold boot
> +  bmWarm,                                 ///< Warm boot
> +  bmS3,                                   ///< S3 resume
> +  bmFast,                                 ///< Fast boot
> +  MrcBootModeMax,                         ///< MRC_BOOT_MODE enumeration
> maximum value.
> +  MrcBootModeDelim = INT32_MAX            ///< This value ensures the
> enum size is consistent on both sides of the PPI.
> +} MrcBootMode;
> +
> +///
> +/// DIMM memory package
> +/// This enum matches SPD Module Type - SPD byte 3, bits [3:0]
> +/// Note that DDR4 have different encoding for some module types
> +///
> +typedef enum {
> +  RDimmMemoryPackage          = 1,
> +  UDimmMemoryPackage          = 2,
> +  SoDimmMemoryPackage         = 3,
> +  MicroDimmMemoryPackageDdr3  = 4,
> +  LrDimmMemoryPackageDdr4     = 4,
> +  MiniRDimmMemoryPackage      = 5,
> +  MiniUDimmMemoryPackage      = 6,
> +  MiniCDimmMemoryPackage      = 7,
> +  LpDimmMemoryPackage         = 7,
> +  SoUDimmEccMemoryPackageDdr3 = 8,
> +  SoRDimmEccMemoryPackageDdr4 = 8,
> +  SoRDimmEccMemoryPackageDdr3 = 9,
> +  SoUDimmEccMemoryPackageDdr4 = 9,
> +  SoCDimmEccMemoryPackage     = 10,
> +  LrDimmMemoryPackage         = 11,
> +  SoDimm16bMemoryPackage      = 12,
> +  SoDimm32bMemoryPackage      = 13,
> +  NonDimmMemoryPackage        = 14,
> +  MemoryPackageMax,                       ///< MEMORY_PACKAGE
> enumeration maximum value.
> +  MemoryPackageDelim = INT32_MAX          ///< This value ensures the
> enum size is consistent on both sides of the PPI.
> +} MEMORY_PACKAGE;
> +
> +///
> +/// Memory training I/O levels.
> +///
> +typedef enum {
> +  DdrLevel   = 0,                         ///< Refers to frontside of DIMM
> +  LrbufLevel = 1,                         ///< Refers to data level at backside of
> LRDIMM or AEP buffer
> +  RegALevel  = 2,                         ///< Refers to cmd level at backside of
> register - side A
> +  RegBLevel  = 3,                         ///< Refers to cmd level at backside of
> register - side B
> +  GsmLtMax,                               ///< GSM_LT enumeration maximum
> value.
> +  GsmLtDelim = INT32_MAX                  ///< This value ensures the enum
> size is consistent on both sides of the PPI.
> +} GSM_LT;
> +
> +///
> +/// Memory training margin group selectors.
> +///
> +typedef enum {
> +  RecEnDelay       = 0,                   ///< Linear delay (PI ticks), where the
> positive increment moves the RCVEN sampling window later in time relative to
> the RX DQS strobes.
> +  RxDqsDelay       = 1,                   ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS strobe later in time relative to the RX DQ
> signal (i.e. toward the hold side of the eye).
> +  RxDqDelay        = 2,                   ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQ byte/nibble/bitlane later in time relative
> to the RX DQS signal (i.e.closing the gap between DQ and DQS in the setup side
> of the eye).
> +  RxDqsPDelay      = 3,                   ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS strobe for "even" chunks later in time
> relative to the RX DQ signal. Even chunks are 0, 2, 4, 6 within the 0 to 7 chunks
> of an 8 burst length cacheline, for example.
> +  RxDqsNDelay      = 4,                   ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS strobe for "odd" chunks later in time
> relative to the RX DQ signal. Odd chunks are 1, 3, 5, 7 within the 0 to 7 chunks
> of an 8 burst length cacheline, for example.
> +  RxVref           = 5,                   ///< Linear increment (Vref ticks), where the
> positive increment moves the byte/nibble/bitlane RX Vref to a higher voltage.
> +  RxEq             = 6,                   ///< RX CTLE setting indicating a set of
> possible resistances, capacitance, current steering, etc. values, which may be a
> different set of values per product. The setting combinations are indexed by
> integer values.
> +  RxDqBitDelay     = 7,                   ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQ bitlane later in time relative to the RX DQS
> signal (i.e.closing the gap between DQ and DQS in the setup side of the eye).
> +  RxVoc            = 8,                   ///< Monotonic increment (Sense Amp
> setting), where the positive increment moves the byte/nibble/bitlane's
> effective switching point to a lower Vref value.
> +  RxOdt            = 9,                   ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  RxOdtUp          = 10,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  RxOdtDn          = 11,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  DramDrvStr       = 12,                  ///< Drive strength setting resistance
> setting within a set of possible resistances (or currents), which may be a
> different set of values per product. Indexed by integer values.
> +  McOdtDelay       = 13,                  ///<
> +  McOdtDuration    = 14,                  ///<
> +  SenseAmpDelay    = 15,                  ///< This may be used to indicate
> CmdToDiffAmpEn for SoC's.
> +  SenseAmpDuration = 16,                  ///<
> +  RoundTripDelay   = 17,                  ///< This may be used to indicate
> CmdToRdDataValid for SoC's.
> +  RxDqsBitDelay    = 18,                  ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS within the bitlane later in time relative
> to the RX DQ signal (i.e.closing the gap between DQ and DQS in the hold side of
> the eye).
> +  RxDqDqsDelay     = 19,                  ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS per strobe later in time relative to the RX
> DQ signal (i.e. closing the gap between DQS and DQ in the hold side of the eye.
> The difference between this parameter and RxDqsDelay is that both the DQ
> and DQS timings may be moved in order to increase the total range of DQDQS
> timings.
> +  WrLvlDelay       = 20,                  ///< Linear delay (PI ticks), where the
> positive increment moves both the TX DQS and TX DQ signals later in time
> relative to all other bus signals.
> +  TxDqsDelay       = 21,                  ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQS strobe later in time relative to all other
> bus signals.
> +  TxDqDelay        = 22,                  ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQ byte/nibble/bitlane later in time relative
> to all other bus signals.
> +  TxVref           = 23,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the byte/nibble/bitlane TX Vref to a higher
> voltage. (Assuming this will abstract away from the range specifics for DDR4, for
> example.)
> +  TxEq             = 24,                  ///< TX EQ setting indicating a set of
> possible equalization levels, which may be a different set of values per product.
> The setting combinations are indexed by integer values.
> +  TxDqBitDelay     = 25,                  ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQ bitlane later in time relative to all other
> bus signals.
> +  TxRon            = 26,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  TxRonUp          = 27,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  TxRonDn          = 28,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  TxSlewRate       = 29,                  ///< Monotonic increment, where the
> positive increment moves the byte/nibble/bitlane's effective slew rate to a
> higher slope.
> +  TxImode          = 30,                  ///< TX I-Mode Boost setting indicating a
> set of possible current boost levels, which may be a different set of values per
> product. The setting combinations are indexed by integer values.
> +  WrOdt            = 31,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  NomOdt           = 32,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  ParkOdt          = 33,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  TxTco            = 34,                  ///<
> +  RxCtleR          = 36,                  ///<
> +  RxCtleC          = 37,                  ///<
> +  RxDqsPBitDelay   = 38,                  ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS bitlane timing for "even" chunks later in
> time relative to the RX DQ bitlane signal. Even chunks are 0, 2, 4, 6 within the
> 0 to 7 chunks of an 8 burst length cacheline, for example.
> +  RxDqsNBitDelay   = 39,                  ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS bitlane timing for "odd" chunks later in
> time relative to the RX DQ bitlane signal. Odd chunks are 1, 3, 5, 7 within the 0
> to 7 chunks of an 8 burst length cacheline, for example.
> +  CmdAll           = 40,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_ALL category later in
> time relative to all other signals on the bus.
> +  CmdGrp0          = 41,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_GRP0 category later
> in time relative to all other signals on the bus.
> +  CmdGrp1          = 42,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_GRP1 category later
> in time relative to all other signals on the bus.
> +  CmdGrp2          = 43,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_GRP2 category later
> in time relative to all other signals on the bus.
> +  CtlAll           = 44,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_ALL category later in
> time relative to all other signals on the bus.
> +  CtlGrp0          = 45,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP0 category later
> in time relative to all other signals on the bus.
> +  CtlGrp1          = 46,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP1 category later
> in time relative to all other signals on the bus.
> +  CtlGrp2          = 47,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP2 category later
> in time relative to all other signals on the bus.
> +  CtlGrp3          = 48,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP3 category later
> in time relative to all other signals on the bus.
> +  CtlGrp4          = 49,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP4 category later
> in time relative to all other signals on the bus.
> +  CtlGrp5          = 50,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP5 category later
> in time relative to all other signals on the bus.
> +  CmdCtlAll        = 51,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_CTL_ALL category
> later in time relative to all other signals on the bus.
> +  CkAll            = 52,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CK_ALL category later in
> time relative to all other signals on the bus.
> +  CmdVref          = 53,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the CMD Vref to a higher voltage.
> +  AlertVref        = 54,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the ALERT Vref to a higher voltage.
> +  CmdRon           = 55,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +
> +  EridDelay        = 60,                  ///< Linear delay (PI ticks), where the
> positive increment moves the ERID signals later in time relative to the internal
> sampling clock (i.e.closing the gap between ERID and internal sampling clock in
> the setup side of the eye). This group is applicable for DDRT DIMMs.
> +  EridVref         = 61,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the ERID Vref to a higher voltage. This group is
> applicable for DDRT DIMMs.
> +  ErrorVref        = 62,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the ERROR Vref to a higher voltage. This group is
> applicable for DDRT DIMMs.
> +  ReqVref          = 63,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the REQ Vref to a higher voltage. This group is
> applicable for DDRT DIMMs.
> +  RecEnOffset      = 64,                  ///< Linear delay (PI ticks), where the
> positive increment moves the RCVEN sampling window later in time relative to
> the RX DQS strobes.
> +  RxDqsOffset      = 65,                  ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS strobe later in time relative to the RX DQ
> signal (i.e. toward the hold side of the eye).
> +  RxVrefOffset     = 66,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the byte/nibble/bitlane RX Vref to a higher
> voltage.
> +  TxDqsOffset      = 67,                  ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQS strobe later in time relative to all other
> bus signals.
> +  TxDqOffset       = 68,                  ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQ byte/nibble/bitlane later in time relative
> to all other bus signals.
> +  GsmGtMax,                               ///< SSA_GSM_GT enumeration
> maximum value.
> +  GsmGtDelim = INT32_MAX                  ///< This value ensures the enum
> size is consistent on both sides of the PPI.
> +} GSM_GT;
> +
> +typedef enum {
> +  SigRasN   = 0,
> +  SigCasN   = 1,
> +  SigWeN    = 2,
> +  SigBa0    = 3,
> +  SigBa1    = 4,
> +  SigBa2    = 5,
> +  SigA0     = 6,
> +  SigA1     = 7,
> +  SigA2     = 8,
> +  SigA3     = 9,
> +  SigA4     = 10,
> +  SigA5     = 11,
> +  SigA6     = 12,
> +  SigA7     = 13,
> +  SigA8     = 14,
> +  SigA9     = 15,
> +  SigA10    = 16,
> +  SigA11    = 17,
> +  SigA12    = 18,
> +  SigA13    = 19,
> +  SigA14    = 20,
> +  SigA15    = 21,
> +  SigA16    = 22,
> +  SigA17    = 23,
> +  SigCs0N   = 24,
> +  SigCs1N   = 25,
> +  SigCs2N   = 26,
> +  SigCs3N   = 27,
> +  SigCs4N   = 28,
> +  SigCs5N   = 29,
> +  SigCs6N   = 30,
> +  SigCs7N   = 31,
> +  SigCs8N   = 32,
> +  SigCs9N   = 33,
> +  SigCke0   = 34,
> +  SigCke1   = 35,
> +  SigCke2   = 36,
> +  SigCke3   = 37,
> +  SigCke4   = 38,
> +  SigCke5   = 39,
> +  SigOdt0   = 40,     //could also be used for CA-ODT for LP4
> +  SigOdt1   = 41,     //could also be used for CA-ODT for LP4
> +  SigOdt2   = 42,
> +  SigOdt3   = 43,
> +  SigOdt4   = 44,
> +  SigOdt5   = 45,
> +  SigPar    = 46,
> +  SigAlertN = 47,
> +  SigBg0    = 48,
> +  SigBg1    = 49,
> +  SigActN   = 50,
> +  SigCid0   = 51,
> +  SigCid1   = 52,
> +  SigCid2   = 53,
> +  SigCk0    = 54,
> +  SigCk1    = 55,
> +  SigCk2    = 56,
> +  SigCk3    = 57,
> +  SigCk4    = 58,
> +  SigCk5    = 59,
> +  SigGnt0   = 60,
> +  SigGnt1   = 61,
> +  SigErid00 = 62,
> +  SigErid01 = 63,
> +  SigErid10 = 64,
> +  SigErid11 = 65,
> +  SigErr0   = 66,
> +  SigErr1   = 67,
> +  SigCa00   = 68,    // First instantiation of the CA bus for a given channel
> +  SigCa01   = 69,
> +  SigCa02   = 70,
> +  SigCa03   = 71,
> +  SigCa04   = 72,
> +  SigCa05   = 73,
> +  SigCa10   = 74,    // Second instantiation of the CA bus for a given channel
> +  SigCa11   = 75,
> +  SigCa12   = 76,
> +  SigCa13   = 77,
> +  SigCa14   = 78,
> +  SigCa15   = 79,
> +  GsmCsnMax,
> +  GsmCsnDelim = INT32_MAX
> +} GSM_CSN;
> +
> +
> +#endif // _MrcCommonTypes_h_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcInterface.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcInterface.h
> new file mode 100644
> index 0000000000..635906cc2b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcInterface.h
> @@ -0,0 +1,1567 @@
> +/** @file
> +  This file includes all the data structures that the MRC considers "global
> data".
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MrcInterface_h_
> +#define _MrcInterface_h_
> +
> +#define MAX_CPU_SOCKETS          (1)       ///< The maximum number of
> CPUs per system.
> +#define MAX_CONTROLLERS          (1)       ///< The maximum number of
> memory controllers per CPU socket.
> +#define MAX_CHANNEL              (2)       ///< The maximum number of
> channels per memory controller.
> +#define MAX_DIMMS_IN_CHANNEL     (2)       ///< The maximum number of
> DIMMs per channel.
> +#define MAX_RANK_IN_DIMM         (2)       ///< The maximum number of
> ranks per DIMM.
> +#define MAX_RANK_IN_CHANNEL      (MAX_DIMMS_IN_CHANNEL *
> MAX_RANK_IN_DIMM) ///< The maximum number of ranks per channel.
> +#define MAX_SDRAM_IN_DIMM        (9)       ///< The maximum number of
> SDRAMs per DIMM when ECC is enabled.
> +#define MAX_MR_IN_DIMM           (7)       ///< Maximum number of mode
> registers in a DIMM.
> +#define MAX_DEVICES_IN_DDR4      (8)       ///< The maximum number of
> SDRAMs per DDR4 DIMM.
> +#define MAX_BITS                 (8)       ///< BITS per byte.
> +#define MAX_STROBE               (18)      ///< Number of strobe groups.
> +#define MAX_DQ                   (72)      ///< Number of Dq bits used by the
> rank.
> +#define CHAR_BITS                (8)       ///< Number of bits in a char.
> +#define PSMI_SIZE_MB             (64)      ///< Define the max size of PSMI
> needed in MB
> +#define BCLK_DEFAULT             (100 * 1000 * 1000) ///< BCLK default value,
> in Hertz.
> +#define MAX_COMMAND_GROUPS       (2)
> +#define MAX_EDGES                (2) ///< Maximum number of edges.
> +#define SUPPORT_DDR3             SUPPORT   ///< SUPPORT means that DDR3
> is supported by the MRC.
> +#define ULT_SUPPORT_LPDDR3       SUPPORT   ///< SUPPORT means that
> LPDDR3 is supported by the MRC.
> +#define TRAD_SUPPORT_LPDDR3      /*UN*/SUPPORT ///< SUPPORT means
> that LPDDR3 is supported by the MRC.
> +#define BDW_SUPPORT_LPDDR3       SUPPORT   ///< SUPPORT means that
> LPDDR3 is supported by the MRC.
> +#define JEDEC_SUPPORT_LPDDR      SUPPORT   ///< SUPPORT means that
> JEDEC SPD Spec for LPDDR3 is supported by the MRC.
> +#define SUPPORT_DDR4             SUPPORT   ///< SUPPORT means that DDR4
> is supported by the MRC.
> +#define SUPPORT_LPDDR3           (ULT_SUPPORT_LPDDR3 ||
> TRAD_SUPPORT_LPDDR3 || BDW_SUPPORT_LPDDR3 ||
> JEDEC_SUPPORT_LPDDR)
> +#define MRC_ALL_DDR_SUPPORTED    ((SUPPORT_DDR4 == SUPPORT) &&
> ((SUPPORT_DDR3 == SUPPORT) && (SUPPORT_LPDDR3 == SUPPORT)))
> +#define MRC_DDR3_LPDDR_SUPPORTED ((SUPPORT_DDR3 == SUPPORT) ||
> (SUPPORT_LPDDR3 == SUPPORT))
> +#define SPD3_MANUF_START       117         ///< The starting point for the
> SPD manufacturing data.
> +#define SPD3_MANUF_END         127         ///< The ending point for the
> SPD manufacturing data.
> +#if (SUPPORT_DDR4 == SUPPORT)
> +#define SPD4_MANUF_START       320         ///< The starting point for the
> SPD manufacturing data.
> +#define SPD4_MANUF_END         328         ///< The ending point for the
> SPD manufacturing data.
> +#endif
> +#if (JEDEC_SUPPORT_LPDDR == SUPPORT)
> +#define SPDLP_MANUF_START      320         ///< The starting point for the
> SPD manufacturing data.
> +#define SPDLP_MANUF_END        328         ///< The ending point for the
> SPD manufacturing data.
> +#endif
> +#include "MrcSpdData.h"
> +#include "MrcRmtData.h"
> +#include "MrcCommonTypes.h"
> +#pragma pack (push, 1)
> +
> +
> +///
> +//////////////////////////////////////////////////////////////////////////////
> ////////
> +///                           OEM platform  routines and types                      //
> +//////////////////////////////////////////////////////////////////////////////
> ////////
> +///
> +/// define the oem check points the OEM can define more point and locate
> them in the code.
> +///
> +typedef enum {
> +  OemFastBootPermitted,     ///<  before fast boot.
> +  OemRestoreNonTraining,
> +  OemPrintInputParameters,  ///<  before printing input parameters
> +  OemSpdProcessingRun,      ///<  before spd processing code
> +  OemSetOverridePreSpd,     ///<  before set overrides pre spd
> +  OemSetOverride,           ///<  before set overrides
> +  OemMcCapability,          ///<  before MC capability
> +  OemMcInitRun,             ///<  before mc init code
> +  OemMcMemoryMap,           ///<  before memory map
> +  OemMcResetRun,            ///<  before jedec reset
> +  OemPreTraining,           ///<  before the training.
> +  OemMcTrainingRun,         ///<  before training code
> +  OemEarlyCommandTraining,  ///<  before Early Command training
> +  OemJedecInitLpddr3,       ///<  before Jedec Init Lpddr3
> +  OemSenseAmpTraining,      ///<  before Sense Amp Training
> +  OemReadMprTraining,       ///<  before Read MPR Training
> +  OemReceiveEnable,         ///<  before Read Leveling
> +  OemJedecWriteLeveling,    ///<  before Jedec Write Leveling
> +  OemLpddrLatencySetB,      ///<  before LPDDR Latency Set B
> +  OemWriteDqDqs,            ///<  before Write Timing Centering
> +  OemWriteVoltage,          ///<  before Write Voltage Centering
> +  OemEarlyWriteDqDqs2D,     ///<  before Early Write Timing Centering 2D
> +  OemEarlyWrDsEq,           ///<  before Early Write Drive Strength /
> Equalization
> +  OemEarlyReadDqDqs2D,      ///<  before Early Read Timing Centering 2D
> +  OemEarlyReadMprDqDqs2D,   ///<  before Early MPR Read Timing
> Centering 2D
> +  OemReadDqDqs,             ///<  before Read Timing Centering
> +  OemDdr4Map,               ///<  before DDR4 PDA Mapping
> +  OemDimmRonTraining,       ///<  before DIMM Ron Training
> +  OemDimmODTTraining,       ///<  before DIMM ODT Training
> +  OemWriteDriveStrengthEq,  ///<  before Write Drive Strength/Equalization
> 2D Training
> +  OemWriteDriveUpDn,        ///<  before Write Drive Strength Up/Dn 2D
> Training
> +  OemWriteSlewRate,         ///<  before Write Slew Rate Training
> +  OemReadODTTraining,       ///<  before Read ODT algorithm.
> +  OemReadEQTraining,        ///<  before Read Equalization Training
> +  OemReadAmplifierPower,    ///<  before Read Amplifier Power
> +  OemOptimizeComp,          ///<  before Comp Optimization Training
> +  OemPowerSavingMeter,      ///<  before PowerSavingMeter step
> +  OemWriteDqDqs2D,          ///<  before Write Timing Centering 2D
> +  OemReadDqDqs2D,           ///<  before Read Timing Centering 2D
> +  OemCmdVoltCenterPreLct,   ///<  before Command Voltage Centering that
> runs pre-LCT
> +  OemCmdSlewRate,           ///<  before CMD Slew Rate
> +  OemCmdVoltCentering,      ///<  before Command Voltage Centering
> +  OemCmdDriveStrengthEq,    ///<  before Command Drive Strength
> Equalization
> +  OemWriteVoltCentering2D,  ///<  before Write Voltage Centering 2D
> +  OemReadVoltCentering2D,   ///<  before Read Voltage Centering 2D
> +  OemLateCommandTraining,   ///<  before Late Command training
> +  OemCmdNormalization,      ///<  before CMD Normalization
> +  OemRoundTripLatency,      ///<  before Round Trip Latency Traiing
> +  OemTurnAroundTimes,       ///<  before Turn Aorund Times.
> +  OemRcvEnCentering1D,      ///<  before Receive Enable Centring
> +  OemSaveMCValues,          ///<  before saving memory controller values
> +  OemRmt,                   ///<  before RMT crosser tool.
> +  OemMemTest,               ///<  before Memory testing
> +  OemRestoreTraining,       ///<  before Restoring Training Values
> +  OemJedecResetDdr4Fast,    ///<  before JEDEC reset for DDR4 in Fast flow
> +  OemSelfRefreshExit,       ///<  before Self Refresh Exit
> +  OemNormalMode,            ///<  before Normal Mode on non-cold boots.
> +  OemThermalConfig,         ///<  set Thermal config values.
> +  OemTxtAliasCheck,         ///<  before TxT Alias Check Call.
> +  OemAliasCheck,            ///<  before alias checking on cold boots.
> +  OemHwMemInit,
> +
> +  OemPostTraining,          ///<  after the training.
> +  OemForceOltm,             ///<  before MrcForceOltm
> +  OemMrcActivate,           ///<  before MrcActivate call.
> +  OemMrcRhPrevention,       ///<  before MrcRhPrevention
> +  OemSaGvSwitch,            ///<  before SA GV switch
> +  OemEngPerfGain,           ///<  before Energy Performance Gain.
> +  OemMrcDone,               ///<  call to MrcOemCheckPoint when MRC was
> done.
> +  OemFrequencySet,          ///<  do operation before frequency set.
> +  OemFrequencySetDone,      ///<  do operation after frequency set.
> +  OemStartMemoryConfiguration,
> +  OemBeforeNormalMode,      ///<  call to MrcOemCheckPoint before
> normal mode is enalbed
> +  OemAfterNormalMode,       ///<  call to MrcOemCheckPoint after normal
> mode is enalbed
> +  OemMrcFillBdat,
> +  OemRetrainMarginCheck,
> +  OemRmtPerBit,             ///< before Rank Margin Tool Per-Bit.
> +  OemUpdateSaveMCValues,    ///< before Updating memory controller
> values.
> +  ///
> +
> ///*************************************************************
> ********************
> +  ///
> +  OemNumOfCommands          ///<  Should always be last in the list!
> +} MrcOemStatusCommand;
> +
> +typedef UINT8 MrcIteration; ///< Mrc invocation sequence number, start with
> 0 and increment by one each time MRC library is called.
> +#define MRC_ITERATION_MAX ((1 << ((sizeof (MrcIteration) * 8) - 1)) + ((1 <<
> ((sizeof (MrcIteration) * 8) - 1)) - 1))
> +
> +#define MAX_RCOMP         (3)
> +#define MAX_RCOMP_TARGETS (5)
> +
> +///
> +/// Thermal Options
> +///
> +typedef struct {
> +  UINT8  RaplLim2WindX;                                    ///< Offset 110  - Power
> Limit 2 Time Window X value: 0=Minimal, 3=Maximum, <b>1=Default</b>
> +  UINT8  RaplLim2WindY;                                    ///< Offset 111  - Power
> Limit 2 Time Window Y value: 0=Minimal, 3=Maximum, <b>1=Default</b>
> +  UINT8  RaplLim1WindX;                                    ///< Offset 112  - Power
> Limit 1 Time Window X value: <b>0=Minimal</b>, 3=Maximum
> +  UINT8  RaplLim1WindY;                                    ///< Offset 113  - Power
> Limit 1 Time Window Y value: <b>0=Minimal</b>, 31=Maximum
> +  UINT16 RaplLim2Pwr;                                      ///< Offset 114  - Power
> Limit 2: 0=Minimal, 16383=Maximum, <b>222=Default</b>
> +  UINT16 RaplLim1Pwr;                                      ///< Offset 116  - Power
> Limit 1: <b>0=Minimal</b>, 16383=Maximum
> +  UINT8  WarmThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///<
> Offset 118  - Warm Threshold (Channel 0, Dimm 0): 0=Minimal,
> <b>255=Maximum</b>
> +  UINT8  HotThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];  ///<
> Offset 122  - Hot Threshold (Channel 0, Dimm 0): 0=Minimal,
> <b>255=Maximum</b>
> +  UINT8  WarmBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];    ///<
> Offset 126  - Warm Budget (Channel 0, Dimm 0): 0=Minimal,
> <b>255=Maximum</b>
> +  UINT8  HotBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];     ///<
> Offset 130  - Hot Budget (Channel 0, Dimm 0): 0=Minimal,
> <b>255=Maximum</b>
> +  UINT8  IdleEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> +  UINT8  PdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> +  UINT8  ActEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> +  UINT8  RdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> +  UINT8  WrEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> +} ThermalMngmtEn;
> +
> +
> +typedef struct {
> +  UINT8      GdxcEnable;   ///< GDXC  MOT enable
> +  UINT8      GdxcIotSize;  ///< IOT size in multiples of 8MEG
> +  UINT8      GdxcMotSize;  ///< MOT size in multiples of 8MEG
> +} MrcGdxc;
> +
> +typedef struct {
> +  UINT32 ECT : 1;        ///< BIT0 - Early Command Training
> +  UINT32 SOT : 1;        ///< BIT1 - Sense Amp Offset Training
> +  UINT32 ERDMPRTC2D : 1; ///< BIT2 - Early ReadMPR Timing Centering 2D
> +  UINT32 RDMPRT : 1;     ///< BIT3 - Read MPR Training
> +  UINT32 RCVET : 1;      ///< BIT4 - Read Leveling Training (RcvEn)
> +  UINT32 JWRL : 1;       ///< BIT5 - Jedec Write Leveling
> +  UINT32 EWRTC2D : 1;    ///< BIT6 - Early Write Time Centering 2D
> +  UINT32 ERDTC2D : 1;    ///< BIT7  - Early Read Time Centering 2D
> +  UINT32 WRTC1D : 1;     ///< BIT8 - Write Timing Centering 1D
> +  UINT32 WRVC1D : 1;     ///< BIT9 - Write Voltage Centering 1D
> +  UINT32 RDTC1D : 1;     ///< BIT10 - Read Timing Centering 1D
> +  UINT32 DIMMODTT : 1;   ///< BIT11 - Dimm ODT Training
> +  UINT32 DIMMRONT : 1;   ///< BIT12 - Dimm Ron Training
> +  UINT32 WRDSEQT : 1;    ///< BIT13 - Write Drive Strength / Equalization
> Training 2D
> +  UINT32 WRSRT : 1;      ///< BIT14 - Write Slew Rate Training
> +  UINT32 RDODTT : 1;     ///< BIT15 - Read ODT Training
> +  UINT32 RDEQT : 1;      ///< BIT16 - Read Equalization Training
> +  UINT32 RDAPT : 1;      ///< BIT17 - Read Amplifier Power Training
> +  UINT32 WRTC2D : 1;     ///< BIT18 - Write Timing Centering 2D
> +  UINT32 RDTC2D : 1;     ///< BIT19 - Read Timing Centering 2D
> +  UINT32 WRVC2D : 1;     ///< BIT20 - Write Voltage Centering 2D
> +  UINT32 RDVC2D : 1;     ///< BIT21 - Read Voltage Centering 2D
> +  UINT32 CMDVC : 1;      ///< BIT22 - Command Voltage Centering
> +  UINT32 LCT : 1;        ///< BIT23 - Late Command Training
> +  UINT32 RTL : 1;        ///< BIT24 - Round Trip latency
> +  UINT32 TAT : 1;        ///< BIT25 - Turn Around Timing
> +  UINT32 RMT : 1;        ///< BIT26 - RMT Tool
> +  UINT32 MEMTST : 1;     ///< BIT27 - Memory Test
> +  UINT32 ALIASCHK: 1;    ///< BIT28 - SPD Alias Check
> +  UINT32 RCVENC1D: 1;    ///< BIT29 - Receive Enable Centering 1D
> +  UINT32 RMC : 1;        ///< BIT30 - Retrain Margin Check
> +  UINT32 WRDSUDT : 1;    ///< BIT31 - Write Drive Strength Up/Dn
> independently
> +} TrainingStepsEn;
> +
> +typedef struct {
> +  UINT32 CMDSR    : 1;   ///< BIT0  - CMD Slew Rate Training
> +  UINT32 CMDDSEQ  : 1;   ///< BIT1  - CMD Drive Strength and Tx Equalization
> +  UINT32 CMDNORM  : 1;   ///< BIT2  - CMD Normalization
> +  UINT32 EWRDSEQ  : 1;   ///< BIT3  - Early DQ Write Drive Strength and
> Equalization Training
> +  UINT32 TeRsv4   : 1;   ///< BIT4 - Reserved
> +  UINT32 TeRsv5   : 1;   ///< BIT5 - Reserved
> +  UINT32 TeRsv6   : 1;   ///< BIT6 - Reserved
> +  UINT32 RsvdBits :25;
> +} TrainingStepsEn2;
> +
> +///
> +/// Defines whether the MRC is executing in full or mini BIOS mode.
> +///
> +typedef enum {
> +  MrcModeFull,   ///< Select full BIOS MRC execution.
> +  MrcModeMini,   ///< Select mini BIOS MRC execution.
> +  MrcModeMaximum ///< Delimiter.
> +} MrcMode;
> +
> +typedef enum {
> +  MrcTmPower,
> +  MrcTmMargin,
> +  MrcTmMax
> +} TrainingModeType;
> +
> +typedef enum {
> +  LastRxV,
> +  LastRxT,
> +  LastTxV,
> +  LastTxT,
> +  LastRcvEna,
> +  LastWrLevel,
> +  LastCmdT,
> +  LastCmdV,
> +  MAX_RESULT_TYPE
> +} MrcMarginResult;
> +
> +typedef enum {
> +  MSG_LEVEL_NEVER,
> +  MSG_LEVEL_ERROR,
> +  MSG_LEVEL_WARNING,
> +  MSG_LEVEL_NOTE,
> +  MSG_LEVEL_EVENT,
> +  MSG_LEVEL_ALGO,
> +  MSG_LEVEL_MMIO,
> +  MSG_LEVEL_CSV,
> +  MSG_LEVEL_TIME,
> +  MSG_LEVEL_ALL = MRC_INT32_MAX
> +} MrcDebugMsgLevel;
> +
> +///
> +/// Define the frequencies that may be possible in the memory controller.
> +/// Note that not all these values may be supported.
> +///
> +#define fNoInit     (0)
> +#define f800        (800)
> +#define f1000       (1000)
> +#define f1100       (1100)
> +#define f1067       (1067)
> +#define f1200       (1200)
> +#define f1300       (1300)
> +#define f1333       (1333)
> +#define f1400       (1400)
> +#define f1467       (1467)
> +#define f1500       (1500)
> +#define f1600       (1600)
> +#define f1700       (1700)
> +#define f1733       (1733)
> +#define f1800       (1800)
> +#define f1867       (1867)
> +#define f1900       (1900)
> +#define f2000       (2000)
> +#define f2100       (2100)
> +#define f2133       (2133)
> +#define f2200       (2200)
> +#define f2267       (2267)
> +#define f2300       (2300)
> +#define f2400       (2400)
> +#define f2500       (2500)
> +#define f2533       (2533)
> +#define f2600       (2600)
> +#define f2667       (2667)
> +#define f2700       (2700)
> +#define f2800       (2800)
> +#define f2900       (2900)
> +#define f2933       (2933)
> +#define f3000       (3000)
> +#define f3067       (3067)
> +#define f3100       (3100)
> +#define f3200       (3200)
> +#define f3333       (3333)
> +#define f3467       (3467)
> +#define f3600       (3600)
> +#define f3733       (3733)
> +#define f3867       (3867)
> +#define f4000       (4000)
> +#define f4133       (4133)
> +#define fInvalid    (0x7FFFFFFF)
> +typedef UINT32 MrcFrequency;
> +
> +//
> +// Max supported frequency in OC mode
> +// RefClk133: 15*266 + 100 = 4133 (using Odd ratio mode)
> +// RefClk100: 15*200 + 100 = 3100 (using Odd ratio mode)
> +//
> +#define MAX_FREQ_OC_133   f4133
> +#define MAX_FREQ_OC_100   f3100
> +
> +//
> +// tCK value in femtoseconds for various frequencies
> +// If Freq is in MHz, then tCK[fs] = 10^9 * 1/(Freq/2)
> +//
> +#define MRC_DDR_800_TCK_MIN      2500000
> +#define MRC_DDR_1000_TCK_MIN     2000000
> +#define MRC_DDR_1067_TCK_MIN     1875000
> +#define MRC_DDR_1100_TCK_MIN     1818182
> +#define MRC_DDR_1200_TCK_MIN     1666667
> +#define MRC_DDR_1300_TCK_MIN     1538462
> +#define MRC_DDR_1333_TCK_MIN     1500000
> +#define MRC_DDR_1400_TCK_MIN     1428571
> +#define MRC_DDR_1467_TCK_MIN     1363636
> +#define MRC_DDR_1500_TCK_MIN     1333333
> +#define MRC_DDR_1600_TCK_MIN     1250000
> +#define MRC_DDR_1700_TCK_MIN     1176471
> +#define MRC_DDR_1733_TCK_MIN     1153846
> +#define MRC_DDR_1800_TCK_MIN     1111111
> +#define MRC_DDR_1867_TCK_MIN     1071429
> +#define MRC_DDR_1900_TCK_MIN     1052632
> +#define MRC_DDR_2000_TCK_MIN     1000000
> +#define MRC_DDR_2100_TCK_MIN     952381
> +#define MRC_DDR_2133_TCK_MIN     938000
> +#define MRC_DDR_2200_TCK_MIN     909091
> +#define MRC_DDR_2267_TCK_MIN     882353
> +#define MRC_DDR_2300_TCK_MIN     869565
> +#define MRC_DDR_2400_TCK_MIN     833333
> +#define MRC_DDR_2500_TCK_MIN     800000
> +#define MRC_DDR_2533_TCK_MIN     789474
> +#define MRC_DDR_2600_TCK_MIN     769231
> +#define MRC_DDR_2667_TCK_MIN     750000
> +#define MRC_DDR_2700_TCK_MIN     740741
> +#define MRC_DDR_2800_TCK_MIN     714286
> +#define MRC_DDR_2900_TCK_MIN     689655
> +#define MRC_DDR_2933_TCK_MIN     681818
> +#define MRC_DDR_3000_TCK_MIN     666667
> +#define MRC_DDR_3067_TCK_MIN     652174
> +#define MRC_DDR_3100_TCK_MIN     645161
> +#define MRC_DDR_3200_TCK_MIN     625000
> +#define MRC_DDR_3333_TCK_MIN     600000
> +#define MRC_DDR_3467_TCK_MIN     576923
> +#define MRC_DDR_3600_TCK_MIN     555556
> +#define MRC_DDR_3733_TCK_MIN     535714
> +#define MRC_DDR_3867_TCK_MIN     517241
> +#define MRC_DDR_4000_TCK_MIN     500000
> +#define MRC_DDR_4133_TCK_MIN     483871
> +
> +///
> +/// Define the memory nominal voltage (VDD).
> +/// Note that not all these values may be supported.
> +///
> +typedef enum {
> +  VDD_INVALID,
> +  VDD_1_00    = 1000,
> +  VDD_1_05    = 1050,
> +  VDD_1_10    = 1100,
> +  VDD_1_15    = 1150,
> +  VDD_1_20    = 1200,
> +  VDD_1_25    = 1250,
> +  VDD_1_30    = 1300,
> +  VDD_1_35    = 1350,
> +  VDD_1_40    = 1400,
> +  VDD_1_45    = 1450,
> +  VDD_1_50    = 1500,
> +  VDD_1_55    = 1550,
> +  VDD_1_60    = 1600,
> +  VDD_1_65    = 1650,
> +  VDD_1_70    = 1700,
> +  VDD_1_75    = 1750,
> +  VDD_1_80    = 1800,
> +  VDD_1_85    = 1850,
> +  VDD_1_90    = 1900,
> +  VDD_1_95    = 1950,
> +  VDD_2_00    = 2000,
> +  VDD_2_05    = 2050,
> +  VDD_2_10    = 2100,
> +  VDD_2_15    = 2150,
> +  VDD_2_20    = 2200,
> +  VDD_2_25    = 2250,
> +  VDD_2_30    = 2300,
> +  VDD_2_35    = 2350,
> +  VDD_2_40    = 2400,
> +  VDD_2_45    = 2450,
> +  VDD_2_50    = 2500,
> +  VDD_2_55    = 2550,
> +  VDD_2_60    = 2600,
> +  VDD_2_65    = 2650,
> +  VDD_2_70    = 2700,
> +  VDD_2_75    = 2750,
> +  VDD_2_80    = 2800,
> +  VDD_2_85    = 2850,
> +  VDD_2_90    = 2900,
> +  VDD_2_95    = 2950,
> +  VDD_MAXIMUM = 0x7FFFFFFF
> +} MrcVddSelect;
> +
> +///
> +/// SA GV points
> +///
> +typedef enum {
> +  MrcSaGvPointLow,
> +  MrcSaGvPointHigh,
> +} MrcSaGvPoint;
> +
> +///
> +/// SA GV modes
> +///  Disabled:  SA GV Disabled, run all MRC tasks
> +///  FixedLow:  SA GV Disabled, run only MRC tasks marked with
> MRC_PF_GV_LOW
> +///  FixedHigh: SA GV Disabled, run only MRC tasks marked with
> MRC_PF_GV_HIGH
> +///  Enabled:   SA GV Enabled
> +///
> +typedef enum {
> +  MrcSaGvDisabled,
> +  MrcSaGvFixedLow,
> +  MrcSaGvFixedHigh,
> +  MrcSaGvEnabled,
> +} MrcSaGv;
> +
> +///
> +/// DIMM SPD Security Status
> +///
> +typedef enum {
> +  MrcSpdStatusGood,      ///< Memory is in a secure state.
> +  MrcSpdStatusAliased,   ///< Memory is aliased.
> +  MrcSpdStatusLast       ///< Must be last in the list
> +} MrcSpdStatus;
> +
> +///
> +/// Define the virtual channel.
> +///
> +typedef enum {
> +  vcL,  ///< Virtual channel L
> +  vcS,  ///< Virtual channel S
> +} MrcVirtualChannel;
> +
> +///
> +/// Define the board types.
> +///
> +typedef enum {
> +  btCRBMB,    ///< 0 - CRB Mobile
> +  btCRBDT,    ///< 1 - CRB Desktop
> +  btUser1,    ///< 2 - SV Karkom
> +  btUser2,    ///< 3 - SV desktop
> +  btUser3,    ///< 4 - SV miniDVP
> +  btUser4,    ///< 5 - Ult
> +  btCRBEMB,   ///< 6 - CRB Embedded
> +  btUpServer, ///< 7 - Up Server
> +  btUnknown,  ///< 8 - Unknown
> +  btMaximum   ///< Delimiter
> +} MrcBoardType;
> +
> +///
> +/// Define the CPU family/model.
> +///
> +typedef enum {
> +  cmCFL_ULX_ULT   = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX,
> ///< Coffeelake ULT/ULX
> +  cmCFL_DT_HALO   = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO
> ///< Coffeelake DT/Halo
> +} MrcCpuModel;
> +
> +///
> +/// Define the CPU Tick/Tock.
> +///
> +typedef enum {
> +  cfCfl    = 0,  ///< Coffeelake
> +  cfMax
> +} MrcCpuFamily;
> +
> +///
> +/// Define the CPU stepping number.
> +///
> +typedef enum {
> +  ///
> +  /// Coffeelake ULX/ULT
> +  ///
> +  csKblH0         = EnumKblH0,
> +  csCflD0         = EnumCflD0,
> +  csCflW0         = EnumCflW0,
> +  csCflV0         = EnumCflV0,
> +  csCflUlxUltLast = csCflV0,
> +
> +  ///
> +  /// Coffeelake DT/Halo
> +  ///
> +  csCflU0         = EnumCflU0,
> +  csCflB0         = EnumCflB0,
> +  csCflP0         = EnumCflP0,
> +  csCflR0         = EnumCflR0,
> +  csCflDtHaloLast = csCflR0,
> +} MrcCpuStepping;
> +
> +typedef enum {
> +  CONTROLLER_NOT_PRESENT, ///< There is no controller present in the
> system.
> +  CONTROLLER_DISABLED,    ///< There is a controller present but it is
> disabled.
> +  CONTROLLER_PRESENT,     ///< There is a controller present and it is
> enabled.
> +  MAX_CONTROLLER_STATUS   ///< Delimiter
> +} MrcControllerSts;
> +
> +typedef enum {
> +  CHANNEL_NOT_PRESENT,    ///< There is no channel present on the
> controller.
> +  CHANNEL_DISABLED,       ///< There is a channel present but it is disabled.
> +  CHANNEL_PRESENT,        ///< There is a channel present and it is enabled.
> +  MAX_CHANNEL_STATUS      ///< Delimiter
> +} MrcChannelSts;
> +
> +typedef enum {
> +  DIMM_ENABLED,           ///< DIMM/rank Pair is enabled, presence will be
> detected.
> +  DIMM_DISABLED,          ///< DIMM/rank Pair is disabled, regardless of
> presence.
> +  DIMM_PRESENT,           ///< There is a DIMM present in the slot/rank pair
> and it will be used.
> +  DIMM_NOT_PRESENT,       ///< There is no DIMM present in the slot/rank
> pair.
> +  MAX_DIMM_STATUS         ///< Delimiter
> +} MrcDimmSts;
> +
> +typedef enum {
> +  STD_PROFILE,            ///< Standard DIMM profile select.
> +  USER_PROFILE,           ///< User specifies various override values.
> +  XMP_PROFILE1,           ///< XMP enthusiast settings select (XMP profile #1).
> +  XMP_PROFILE2,           ///< XMP extreme settings select (XMP profile #2).
> +  MAX_PROFILE             ///< Delimiter
> +} MrcProfile;
> +
> +#define XMP_PROFILES_ENABLE   (0x3)
> +#define XMP1_PROFILE_ENABLE   (0x1)
> +#define XMP2_PROFILE_ENABLE   (0x2)
> +
> +typedef enum {
> +  MRC_REF_CLOCK_133,      ///< 133MHz reference clock
> +  MRC_REF_CLOCK_100,      ///< 100MHz reference clock
> +  MRC_REF_CLOCK_MAXIMUM   ///< Delimiter
> +} MrcRefClkSelect;        ///< This value times the MrcClockRatio determines
> the MrcFrequency.
> +
> +typedef enum {
> +  MRC_FREQ_INVALID       = 0,
> +  MRC_FREQ_133           = (MRC_BIT0 << MRC_REF_CLOCK_133), // Bit 0
> +  MRC_FREQ_100           = (MRC_BIT0 << MRC_REF_CLOCK_100), // Bit 1
> +  MRC_FREQ_133_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_133), // Bit
> 2
> +  MRC_FREQ_100_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_100), // Bit
> 3
> +  MRC_FREQ_MAX                                              // Delimiter
> +} MrcFreqFlag;
> +
> +typedef UINT32 MrcBClkRef;   ///< Base clock, in Hertz, Default is 100MHz or
> leave at zero for default.
> +
> +//
> +// This encoding matches CFL SC_GS_CFG.DRAM_technology and
> MAD_INTER_CHANNEL.DDR_TYPE registers
> +//
> +typedef enum {
> +  MRC_DDR_TYPE_DDR4     = 0,
> +  MRC_DDR_TYPE_DDR3     = 1,
> +  MRC_DDR_TYPE_LPDDR3   = 2,
> +  MRC_DDR_TYPE_UNKNOWN  = 3,
> +  MAX_MRC_DDR_TYPE        ///< Delimiter
> +} MrcDdrType;
> +
> +typedef enum {
> +  MrcIterationClock,
> +  MrcIterationCmdN,
> +  MrcIterationCmdS,
> +  MrcIterationCke,
> +  MrcIterationCtl,
> +  MrcIterationCmdV,
> +  MrcIterationMax
> +} MrcIterationType;
> +
> +typedef enum {
> +  UpmLimit,
> +  PowerLimit,
> +  RetrainLimit,
> +  MarginLimitMax
> +} MRC_MARGIN_LIMIT_TYPE;
> +
> +
> +typedef enum {
> +  HardwareRhp,
> +  Refresh2x
> +} MrcRhpType;
> +
> +typedef enum {
> +  OneIn2To1 = 1,
> +  OneIn2To2,
> +  OneIn2To3,
> +  OneIn2To4,
> +  OneIn2To5,
> +  OneIn2To6,
> +  OneIn2To7,
> +  OneIn2To8,
> +  OneIn2To9,
> +  OneIn2To10,
> +  OneIn2To11,
> +  OneIn2To12,
> +  OneIn2To13,
> +  OneIn2To14,
> +  OneIn2To15
> +} MrcRhProbType;
> +
> +typedef enum {
> +  MRC_POST_CODE,
> +  MRC_POST_CODE_WRITE,
> +  MRC_POST_CODE_READ,
> +  MRC_POST_CODE_MAX
> +} MrcDebugPostCode;
> +
> +typedef struct {
> +  UINT32 MrcData;
> +  UINT32 Stream;
> +  UINT32 Start;
> +  UINT32 End;
> +  UINT32 Current;
> +  int Level;
> +  UINT16 PostCode[MRC_POST_CODE_MAX];
> +  UINT32 TopStackAddr;     ///< Initial stack address.
> +  UINT32 LowestStackAddr;  ///< Track the lowest stack address used through
> MrcPrintfVaList()
> +} MrcDebug;
> +
> +typedef UINT16 MrcPostCode;
> +typedef UINT8  MrcClockRatio;  ///< This value times the MrcRefClkSelect
> determines the MrcFrequency.
> +typedef UINT32 MrcGfxDataSize; ///< The size of the stolen graphics data
> memory, in MBytes.
> +typedef UINT32 MrcGfxGttSize;  ///< The size of the graphics translation
> table, in MBytes.
> +
> +
> +///
> +/// This data structure contains all the "DDR power saving data" values that
> are considered output by the MRC.
> +/// The following are memory controller level definitions. All channels on a
> controller are set to these values.
> +///
> +typedef struct {
> +  BOOLEAN    BaseFlag;      ///< Indicates if the base line of power was
> already calculated.
> +  UINT16     BaseSavingRd;  ///< Indicates the base line of power consume by
> the ddr on read.
> +  UINT16     BaseSavingWr;  ///< Indicates the base line of power consume
> by the ddr on write.
> +  UINT16     BaseSavingCmd; ///< Indicates the base line of power consume
> by the ddr on command.
> +  UINT16     MrcSavingRd;   ///< Indicates the power consume by the ddr on
> read at the end of MRC.
> +  UINT16     MrcSavingWr;   ///< Indicates the power consume by the ddr on
> write at the end of MRC.
> +  UINT16     MrcSavingCmd;  ///< Indicates the power consume by the ddr on
> command at the end of MRC.
> +} MrcOdtPowerSaving;
> +
> +///
> +/// The memory controller capabilities.
> +///
> +typedef union {
> +  UINT32 Data;
> +  UINT16 Data16[2];
> +  UINT8  Data8[4];
> +} MrcCapabilityIdA;
> +
> +typedef union {
> +  UINT32 Data;
> +  UINT16 Data16[2];
> +  UINT8  Data8[4];
> +} MrcCapabilityIdB;
> +
> +typedef union {
> +  UINT64 Data;
> +  struct {
> +    MrcCapabilityIdA A;
> +    MrcCapabilityIdB B;
> +  } Data32;
> +} MrcCapabilityId;
> +
> +///
> +/// MRC version description.
> +///
> +typedef struct {
> +  UINT8  Major;  ///< Major version number
> +  UINT8  Minor;  ///< Minor version number
> +  UINT8  Rev;    ///< Revision number
> +  UINT8  Build;  ///< Build number
> +} MrcVersion;
> +
> +///
> +/// Memory map configuration information.
> +///
> +typedef struct {
> +  UINT32     TomMinusMe;
> +  UINT32     ToludBase;
> +  UINT32     BdsmBase;
> +  UINT32     GttBase;
> +  UINT32     GraphicsControlRegister;
> +  UINT32     TsegBase;
> +  BOOLEAN    ReclaimEnable;
> +  UINT32     RemapBase;
> +  UINT32     RemapLimit;
> +  UINT32     TouudBase;
> +  UINT32     TotalPhysicalMemorySize;
> +  UINT32     MeStolenBase;
> +  UINT32     MeStolenSize;
> +  UINT32     GdxcMotBase;
> +  UINT32     GdxcMotSize;
> +  UINT32     GdxcIotBase;
> +  UINT32     GdxcIotSize;
> +  UINT32     DprSize;
> +  UINT32     PttStolenBase;
> +  UINT32     PrmrrBase;
> +  UINT32     LowestBase;
> +} MrcMemoryMap;
> +
> +///
> +/// Real time clock information.
> +///
> +typedef struct {
> +  UINT8  Seconds;    ///< Seconds, 0-59
> +  UINT8  Minutes;    ///< Minutes, 0-59
> +  UINT8  Hours;      ///< Hours, 0-23
> +  UINT8  DayOfMonth; ///< Day of the month, 1-31
> +  UINT8  Month;      ///< Month of the year, 1-12
> +  UINT16 Year;       ///< Year, 0-65535
> +} MrcBaseTime;
> +
> +///
> +/// DIMM timings
> +///
> +typedef struct {
> +  UINT32 tCK;     ///< Memory cycle time, in femtoseconds.
> +  UINT16 NMode;   ///< Number of tCK cycles for the channel DIMM's
> command rate mode.
> +  UINT16 tCL;     ///< Number of tCK cycles for the channel DIMM's CAS
> latency.
> +  UINT16 tCWL;    ///< Number of tCK cycles for the channel DIMM's
> minimum CAS write latency time.
> +  UINT16 tFAW;    ///< Number of tCK cycles for the channel DIMM's minimum
> four activate window delay time.
> +  UINT16 tRAS;    ///< Number of tCK cycles for the channel DIMM's minimum
> active to precharge delay time.
> +  UINT16 tRCDtRP; ///< Number of tCK cycles for the channel DIMM's
> minimum RAS# to CAS# delay time and Row Precharge delay time.
> +  UINT16 tREFI;   ///< Number of tCK cycles for the channel DIMM's minimum
> Average Periodic Refresh Interval.
> +  UINT16 tRFC;    ///< Number of tCK cycles for the channel DIMM's minimum
> refresh recovery delay time.
> +  UINT16 tRFCpb;  ///< Number of tCK cycles for the channel DIMM's
> minimum per bank refresh recovery delay time.
> +  UINT16 tRFC2;   ///< Number of tCK cycles for the channel DIMM's minimum
> refresh recovery delay time.
> +  UINT16 tRFC4;   ///< Number of tCK cycles for the channel DIMM's minimum
> refresh recovery delay time.
> +  UINT16 tRPab;   ///< Number of tCK cycles for the channel DIMM's minimum
> row precharge delay time for all banks.
> +  UINT16 tRRD;    ///< Number of tCK cycles for the channel DIMM's minimum
> row active to row active delay time.
> +  UINT16 tRRD_L;  ///< Number of tCK cycles for the channel DIMM's
> minimum row active to row active delay time for same bank groups.
> +  UINT16 tRRD_S;  ///< Number of tCK cycles for the channel DIMM's
> minimum row active to row active delay time for different bank groups.
> +  UINT16 tRTP;    ///< Number of tCK cycles for the channel DIMM's minimum
> internal read to precharge command delay time.
> +  UINT16 tWR;     ///< Number of tCK cycles for the channel DIMM's minimum
> write recovery time.
> +  UINT16 tWTR;    ///< Number of tCK cycles for the channel DIMM's
> minimum internal write to read command delay time.
> +  UINT16 tWTR_L;  ///< Number of tCK cycles for the channel DIMM's
> minimum internal write to read command delay time for same bank groups.
> +  UINT16 tWTR_S;  ///< Number of tCK cycles for the channel DIMM's
> minimum internal write to read command delay time for different bank
> groups.
> +  UINT16 tCCD_L;  ///< Number of tCK cycles for the channel DIMM's
> minimum CAS-to-CAS delay for same bank group.
> +} MrcTiming;
> +
> +typedef struct {
> +  UINT8 SG;       ///< Number of tCK cycles between transactions in the same
> bank group.
> +  UINT8 DG;       ///< Number of tCK cycles between transactions when
> switching bank groups.
> +  UINT8 DR;       ///< Number of tCK cycles between transactions when
> switching between Ranks (in the same DIMM).
> +  UINT8 DD;       ///< Number of tCK cycles between transactions when
> switching between DIMMs
> +} MrcTurnaroundTimes;
> +
> +typedef struct {
> +  INT32 Mtb;    ///< Medium time base.
> +  INT32 Ftb;    ///< Fine time base.
> +} MrcTimeBase;
> +
> +typedef struct {
> +  UINT8  Left;   ///< The left side of the timing eye.
> +  UINT8  Center; ///< The center of the timing eye.
> +  UINT8  Right;  ///< The right side of the timing eye.
> +} MrcDqTimeMargin;
> +
> +typedef struct {
> +  UINT8  High;   ///< The high side of the Vref eye.
> +  UINT8  Center; ///< The center of the Vref eye.
> +  UINT8  Low;    ///< The low side of the Vref eye.
> +} MrcDqVrefMargin;
> +
> +typedef struct {
> +  UINT8  Left;   ///< The left side of the command eye.
> +  UINT8  Right;  ///< The right side of the command eye.
> +  UINT8  High;   ///< The high side of the command eye.
> +  UINT8  Low;    ///< The low side of the command eye.
> +} MrcCommandMargin;
> +
> +typedef struct {
> +  UINT8  Left;   ///< The left side of the receive enable eye.
> +  UINT8  Right;  ///< The right side of the receive enableeye.
> +} MrcRecvEnMargin;
> +
> +typedef struct {
> +  UINT8  Left;   ///< The left side of the write leveling eye.
> +  UINT8  Right;  ///< The right side of the write leveling eye.
> +} MrcWrLevelMargin;
> +
> +typedef struct {
> +  UINT8     SpdValid[sizeof (MrcSpd) / (CHAR_BITS * sizeof (UINT8))]; ///<
> Each valid bit maps to SPD byte.
> +  UINT8     MrcSpdString[3]; ///< The SPD data start marker. This must be
> located at the start of the SPD data structure. It includes this string plus the
> following flag.
> +  union {
> +    struct {
> +      UINT8   DimmNumber    : 4; ///< SPD zero based DIMM number.
> +      UINT8   ChannelNumber : 3; ///< SPD zero based channel number.
> +      UINT8   MdSocket      : 1; ///< 0 = memory down, 1 = socketed.
> +    } Bit;
> +    UINT8 Data;
> +  } Flag;
> +  MrcSpd Data;            ///< The SPD data for each DIMM. SPDGeneral field =
> 0 when absent.
> +} MrcSpdData;
> +
> +typedef UINT8        (*MRC_IO_READ_8)               (UINT32 IoAddress);
> +typedef UINT16       (*MRC_IO_READ_16)              (UINT32 IoAddress);
> +typedef UINT32       (*MRC_IO_READ_32)              (UINT32 IoAddress);
> +typedef void         (*MRC_IO_WRITE_8)              (UINT32 IoAddress, UINT8
> Value);
> +typedef void         (*MRC_IO_WRITE_16)             (UINT32 IoAddress,
> UINT16 Value);
> +typedef void         (*MRC_IO_WRITE_32)             (UINT32 IoAddress,
> UINT32 Value);
> +typedef UINT8        (*MRC_MMIO_READ_8)             (UINT32 Address);
> +typedef UINT16       (*MRC_MMIO_READ_16)            (UINT32 Address);
> +typedef UINT32       (*MRC_MMIO_READ_32)            (UINT32 Address);
> +typedef UINT64       (*MRC_MMIO_READ_64)            (UINT32 Address);
> +typedef UINT8        (*MRC_MMIO_WRITE_8)            (UINT32 Address,
> UINT8 Value);
> +typedef UINT16       (*MRC_MMIO_WRITE_16)           (UINT32 Address,
> UINT16 Value);
> +typedef UINT32       (*MRC_MMIO_WRITE_32)           (UINT32 Address,
> UINT32 Value);
> +typedef UINT64       (*MRC_MMIO_WRITE_64)           (UINT32 Address,
> UINT64 Value);
> +typedef UINT8        (*MRC_SMBUS_READ_8)            (UINT32 Address,
> UINT32 *Status);
> +typedef UINT16       (*MRC_SMBUS_READ_16)           (UINT32 Address,
> UINT32 *Status);
> +typedef UINT8        (*MRC_SMBUS_WRITE_8)           (UINT32 Address,
> UINT8 Value, UINT32 *Status);
> +typedef UINT16       (*MRC_SMBUS_WRITE_16)          (UINT32 Address,
> UINT16 Value, UINT32 *Status);
> +typedef UINT32       (*MRC_GET_PCI_DEVICE_ADDRESS)  (UINT8 Bus, UINT8
> Device, UINT8 Function, UINT8 Offset);
> +typedef UINT32       (*MRC_GET_PCIE_DEVICE_ADDRESS) (UINT8 Bus, UINT8
> Device, UINT8 Function, UINT8 Offset);
> +typedef void         (*MRC_GET_RTC_TIME)            (UINT8 *Second, UINT8
> *Minute, UINT8 *Hour, UINT8 *Day, UINT8 *Month, UINT16 *Year);
> +typedef UINT64       (*MRC_GET_CPU_TIME)            (void *MrcData);
> +typedef void *       (*MRC_MEMORY_COPY)             (UINT8 *Destination,
> UINT8 *Source, UINT32 NumBytes);
> +typedef void *       (*MRC_MEMORY_SET_BYTE)         (UINT8 *Destination,
> UINT32 NumBytes, UINT8 Value);
> +typedef void *       (*MRC_MEMORY_SET_WORD)         (UINT16
> *Destination, UINT32 NumWords, UINT16 Value);
> +typedef void *       (*MRC_MEMORY_SET_DWORD)        (UINT32
> *Destination, UINT32 NumDwords, UINT32 Value);
> +typedef UINT64       (*MRC_LEFT_SHIFT_64)           (UINT64 Data, UINT32
> NumBits);
> +typedef UINT64       (*MRC_RIGHT_SHIFT_64)          (UINT64 Data, UINT32
> NumBits);
> +typedef UINT64       (*MRC_MULT_U64_U32)            (UINT64 Multiplicand,
> UINT32 Multiplier);
> +typedef UINT64       (*MRC_DIV_U64_U64)             (UINT64 Dividend,
> UINT64 Divisor, UINT64 *Remainder);
> +typedef BOOLEAN      (*MRC_GET_SPD_DATA)            (UINT8 BootMode,
> UINT8 SpdAddress, UINT8 *SpdData, UINT8 *Ddr3Table, UINT32 Ddr3TableSize,
> UINT8 *Ddr4Table, UINT32 Ddr4TableSize, UINT8 *LpddrTable, UINT32
> LpddrTableSize);
> +typedef BOOLEAN      (*MRC_GET_RANDOM_NUMBER)       (UINT32
> *Rand);
> +typedef UINT32       (*MRC_CPU_MAILBOX_READ)        (UINT32 Type,
> UINT32 Command, UINT32 *Value, UINT32 *Status);
> +typedef UINT32       (*MRC_CPU_MAILBOX_WRITE)       (UINT32 Type,
> UINT32 Command, UINT32 Value, UINT32 *Status);
> +typedef UINT32       (*MRC_GET_MEMORY_VDD)          (void *MrcData,
> UINT32 DefaultVdd);
> +typedef UINT32       (*MRC_SET_MEMORY_VDD)          (void *MrcData,
> UINT32 DefaultVdd, UINT32 Value);
> +typedef UINT32       (*MRC_CHECKPOINT)              (void *MrcData, UINT32
> CheckPoint, void *Scratch);
> +typedef void         (*MRC_DEBUG_HOOK)              (void *GlobalData,
> UINT16 DisplayDebugNumber);
> +typedef void         (*MRC_PRINT_STRING)            (void *String);
> +typedef UINT8        (*MRC_GET_RTC_CMOS)            (UINT8 Location);
> +typedef UINT64       (*MRC_MSR_READ_64)             (UINT32 Location);
> +typedef UINT64       (*MRC_MSR_WRITE_64)            (UINT32 Location,
> UINT64 Data);
> +typedef void         (*MRC_RETURN_FROM_SMC)         (void *GlobalData,
> UINT32 MrcStatus);
> +typedef void         (*MRC_DRAM_RESET)              (UINT32
> PciEBaseAddress, UINT32 ResetValue);
> +typedef void         (*MRC_SET_LOCK_PRMRR)          (UINT32 PrmrrBase,
> UINT32 PrmrrSize);
> +typedef void         (*MRC_TXT_ACHECK)              (void);
> +
> +///
> +/// Function calls that are called external to the MRC.
> +///   This structure needs to be aligned with SA_FUNCTION_CALLS.  All
> functions that are
> +///   not apart of SA_FUNCTION_CALLS need to be at the end of the structure.
> +///
> +typedef struct {
> +  MRC_IO_READ_8               MrcIoRead8;
> +  MRC_IO_READ_16              MrcIoRead16;
> +  MRC_IO_READ_32              MrcIoRead32;
> +  MRC_IO_WRITE_8              MrcIoWrite8;
> +  MRC_IO_WRITE_16             MrcIoWrite16;
> +  MRC_IO_WRITE_32             MrcIoWrite32;
> +  MRC_MMIO_READ_8             MrcMmioRead8;
> +  MRC_MMIO_READ_16            MrcMmioRead16;
> +  MRC_MMIO_READ_32            MrcMmioRead32;
> +  MRC_MMIO_READ_64            MrcMmioRead64;
> +  MRC_MMIO_WRITE_8            MrcMmioWrite8;
> +  MRC_MMIO_WRITE_16           MrcMmioWrite16;
> +  MRC_MMIO_WRITE_32           MrcMmioWrite32;
> +  MRC_MMIO_WRITE_64           MrcMmioWrite64;
> +  MRC_SMBUS_READ_8            MrcSmbusRead8;
> +  MRC_SMBUS_READ_16           MrcSmbusRead16;
> +  MRC_SMBUS_WRITE_8           MrcSmbusWrite8;
> +  MRC_SMBUS_WRITE_16          MrcSmbusWrite16;
> +  MRC_GET_PCI_DEVICE_ADDRESS  MrcGetPciDeviceAddress;
> +  MRC_GET_PCIE_DEVICE_ADDRESS MrcGetPcieDeviceAddress;
> +  MRC_GET_RTC_TIME            MrcGetRtcTime;
> +  MRC_GET_CPU_TIME            MrcGetCpuTime;
> +  MRC_MEMORY_COPY             MrcCopyMem;
> +  MRC_MEMORY_SET_BYTE         MrcSetMem;
> +  MRC_MEMORY_SET_WORD         MrcSetMemWord;
> +  MRC_MEMORY_SET_DWORD        MrcSetMemDword;
> +  MRC_LEFT_SHIFT_64           MrcLeftShift64;
> +  MRC_RIGHT_SHIFT_64          MrcRightShift64;
> +  MRC_MULT_U64_U32            MrcMultU64x32;
> +  MRC_DIV_U64_U64             MrcDivU64x64;
> +  MRC_GET_SPD_DATA            MrcGetSpdData;
> +  MRC_GET_RANDOM_NUMBER       MrcGetRandomNumber;
> +  MRC_CPU_MAILBOX_READ        MrcCpuMailboxRead;
> +  MRC_CPU_MAILBOX_WRITE       MrcCpuMailboxWrite;
> +  MRC_GET_MEMORY_VDD          MrcGetMemoryVdd;
> +  MRC_SET_MEMORY_VDD          MrcSetMemoryVdd;
> +  MRC_CHECKPOINT              MrcCheckpoint;
> +  MRC_DEBUG_HOOK              MrcDebugHook;
> +  MRC_PRINT_STRING            MrcPrintString;
> +  MRC_GET_RTC_CMOS            MrcRtcCmos;
> +  MRC_MSR_READ_64             MrcReadMsr64;
> +  MRC_MSR_WRITE_64            MrcWriteMsr64;
> +  MRC_RETURN_FROM_SMC         MrcReturnFromSmc;
> +  MRC_DRAM_RESET              MrcDramReset;
> +  MRC_SET_LOCK_PRMRR          MrcSetLockPrmrr;
> +  MRC_TXT_ACHECK              MrcTxtAcheck;
> +} MRC_FUNCTION;
> +
> +///
> +///*****************************************
> +/// Output related "global data" structures.
> +///*****************************************
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are SDRAM level definitions. All ranks on a rank are set to
> these values.
> +///
> +/* Commented out until needed, in order to save space.
> +typedef struct {
> +} MrcSdramOut;
> +*/
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are rank level definitions. All ranks on a DIMM are set to
> these values.
> +///
> +typedef struct {
> +//MrcSdramOut     Sdram[MAX_SDRAM_IN_DIMM];         ///< The
> following are SDRAM level definitions.
> +  UINT16             MR[MAX_MR_IN_DIMM];            ///< DRAM mode
> register value.
> +  UINT16             MR11;                          ///< LPDDR3 ODT MR
> +  UINT8              Ddr4PdaMr6[MAX_SDRAM_IN_DIMM]; ///< DDR4 MR6[6:0]
> for per-DRAM VrefDQ (PDA)
> +#if (SUPPORT_DDR4 == SUPPORT)
> +  UINT8              Device[MAX_SDRAM_IN_DIMM];     ///< Which Bytes are
> tied to which Device where BIT0 set means Byte 0
> +#endif //SUPPORT_DDR4
> +} MrcRankOut;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are DIMM level definitions. All ranks on a DIMM are set to
> these values.
> +///
> +typedef struct {
> +  MrcDimmSts     Status;                    ///< See MrcDimmSts for the
> definition of this field.
> +  MrcTiming      Timing[MAX_PROFILE];       ///< The DIMMs timing values.
> +  MrcVddSelect   VddVoltage[MAX_PROFILE];   ///< The voltage (VDD) setting
> for this DIMM, per profile.
> +  BOOLEAN        EccSupport;                ///< TRUE if ECC is enabled and
> supported on this DIMM.
> +  BOOLEAN        IgnoreNonEccDimm;          ///< TRUE if a DIMM without
> ECC capability should be ignored.
> +  BOOLEAN        AddressMirrored;           ///< TRUE if the DIMM is address
> mirrored.
> +  BOOLEAN        SelfRefreshTemp;           ///< TRUE if the DIMM supports
> self refresh extended operating temperature range (SRT).
> +  BOOLEAN        AutoSelfRefresh;           ///< TRUE if the DIMM supports
> automatic self refresh (ASR).
> +  BOOLEAN        PartialSelfRefresh;        ///< TRUE if the DIMM supports
> Partial Array Self Refresh (PASR).
> +  BOOLEAN        OnDieThermalSensor;        ///< TRUE if the DIMM supports
> On-die Thermal Sensor (ODTS) Readout.
> +  BOOLEAN        ExtendedTemperRange;       ///< TRUE if the DIMM
> supports Extended Temperature Range (ETR).
> +  BOOLEAN        ExtendedTemperRefresh;     ///< TRUE if the DIMM
> supports 1x Extended Temperature Refresh rate, FALSE = 2x.
> +  MrcDdrType     DdrType;                   ///< DDR type: DDR3 or LPDDR3
> +  MEMORY_PACKAGE ModuleType;                ///< Module type: UDIMM,
> SO-DIMM, etc.
> +  UINT32         SdramCount;                ///< The number of SDRAM
> components on a DIMM.
> +  UINT32         DimmCapacity;              ///< DIMM size in MBytes.
> +  UINT32         RowSize;                   ///< The DIMMs row address size.
> +  UINT16         ColumnSize;                ///< The DIMMs column address size.
> +  UINT16         Crc;                       ///< Calculated CRC16 of the DIMM's
> provided SPD. Can be used to detect DIMM change.
> +  UINT8          RankInDimm;                ///< The number of ranks in this
> DIMM.
> +  UINT8          Banks;                     ///< Number of banks the DIMM
> contains.
> +  UINT8          BankGroups;                ///< Number of bank groups the
> DIMM contains.
> +  UINT8          PrimaryBusWidth;           ///< DIMM primary bus width.
> +  UINT8          SdramWidth;                ///< DIMM SDRAM width.
> +  UINT8          SdramWidthIndex;           ///< DIMM SDRAM width index (0 =
> x4, 1 = x8, 2 = x16, 3 = x32).
> +  UINT8          DensityIndex;              ///< Total SDRAM capacity index (0 =
> 256Mb, 1 = 512Mb, 2 = 1Gb, etc).
> +  UINT8          tMAC;                      ///< Maximum Activate Count for pTRR.
> +  UINT8          ReferenceRawCard;          ///< Indicates which JEDEC
> reference design raw card was used as the basis for the module assembly.
> +  UINT8          ReferenceRawCardRevision;  ///< Indicates which JEDEC
> reference design raw card revision.
> +  UINT8          XmpSupport;                ///< Indicates if XMP profiles are
> supported. 0 = None, 1 = XMP1 only, 2 = XMP2 only, 3 = All.
> +  UINT8          XmpRevision;               ///< Indicates the XMP revision of this
> DIMM. 0 = None, 12h = 1.2, 13h = 1.3.
> +  MrcFrequency   Speed;                     ///< Max DIMM speed in the current
> profile - needed for SMBIOS.
> +  MrcRankOut     Rank[MAX_RANK_IN_DIMM];    ///< The following are rank
> level definitions.
> +} MrcDimmOut;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are channel level definitions. All DIMMs on a memory
> channel are set to these values.
> +///
> +typedef struct {
> +  MrcChannelSts       Status;                                                       ///<
> Indicates whether this channel should be used.
> +  MrcVirtualChannel   VirtualChannel;
> ///< define the virtual channel type A or B.
> +  MrcTiming           Timing[MAX_PROFILE];
> ///< The channel timing values.
> +  MrcTimeBase         TimeBase[MAX_DIMMS_IN_CHANNEL][MAX_PROFILE];
> ///< Medium and fine timebases for each DIMM in the channel and each
> memory profile.
> +  UINT32              Capacity;                                                     ///<
> Amount of memory in this channel, in MBytes.
> +  UINT32              DimmCount;                                                    ///<
> Number of valid DIMMs that exist in the channel.
> +  UINT32              DataOffsetTrain[MAX_SDRAM_IN_DIMM];
> ///< DataOffsetTrain CR
> +  UINT32              DataCompOffset[MAX_SDRAM_IN_DIMM];
> ///< DataCompOffset CR
> +  UINT32              CkeCmdPiCode[MAX_COMMAND_GROUPS];
> ///< CKE  CmdPiCode CR, per group
> +  UINT32              CmdsCmdPiCode[MAX_COMMAND_GROUPS];
> ///< CmdS CmdPiCode CR, per group
> +  UINT32              CmdnCmdPiCode[MAX_COMMAND_GROUPS];
> ///< CmdN CmdPiCode CR, per group
> +  UINT16
> TxDqs[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                ///<
> TxDQS PI Code
> +  UINT16
> TxDq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                 ///<
> TxDQ Pi Code
> +  UINT16
> RcvEn[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                ///<
> RcvEn PI Code
> +  UINT16
> WlDelay[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];              ///<
> WlDelay PI Code
> +  UINT8               ClkPiCode[MAX_RANK_IN_CHANNEL];
> ///< Clk Pi Code
> +  UINT8               CtlPiCode[MAX_RANK_IN_CHANNEL];
> ///< Ctl Pi Code
> +  UINT8               CkePiCode[MAX_RANK_IN_CHANNEL];
> ///< Ctl Pi Code
> +  UINT8               TxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];
> ///< TxEq setting
> +  MrcCommandMargin    Command[MAX_RANK_IN_CHANNEL];
> ///< Cmd setting
> +  MrcDqTimeMargin
> RxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];
> ///< Rx PerBit Pi Code
> +  MrcDqTimeMargin
> TxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];
> ///< Tx PerBit Pi Code
> +  MrcDqVrefMargin
> RxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];
> ///< Rx PerBit Vref
> +  MrcDqVrefMargin
> TxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];
> ///< Rx PerBit Vref
> +  MrcRecvEnMargin     ReceiveEnable[MAX_RANK_IN_CHANNEL];
> ///< Receive enable per rank
> +  MrcWrLevelMargin    WriteLevel[MAX_RANK_IN_CHANNEL];
> ///< Write leveling per rank
> +  UINT8               IoLatency[MAX_RANK_IN_CHANNEL];
> ///< IOLatency
> +  UINT8               RTLatency[MAX_RANK_IN_CHANNEL];
> ///< RoundTripLatency
> +  UINT32              RTIoComp;                                                     ///<
> RoundTrip IO Compensation of the Channel
> +  UINT8               RxVref[MAX_SDRAM_IN_DIMM];
> ///< RX Vref in steps of 7.9 mv
> +  UINT8               RxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];
> ///< RxEQ Setting
> +  UINT8
> RxDqsP[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];               ///<
> RxDQSP PI Code
> +  UINT8
> RxDqsN[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];               ///<
> RxDQSN PI Code
> +  UINT8               ValidRankBitMask;                                             ///<
> Bit map of the populated ranks per channel
> +  UINT8               ValidCkeBitMask;                                              ///< Bit
> map of the used CKE pins per channel
> +  MrcDimmOut          Dimm[MAX_DIMMS_IN_CHANNEL];
> ///< DIMM specific output variables.
> +  MrcTurnaroundTimes  tRd2Rd;
> ///< The system's minimal delay timings for Read  command followed by Read
> command.
> +  MrcTurnaroundTimes  tRd2Wr;
> ///< The system's minimal delay timings for Read  command followed by Write
> command.
> +  MrcTurnaroundTimes  tWr2Rd;
> ///< The system's minimal delay timings for Write command followed by Read
> command.
> +  MrcTurnaroundTimes  tWr2Wr;
> ///< The system's minimal delay timings for Write command followed by Write
> command.
> +} MrcChannelOut;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are memory controller level definitions. All channels on a
> controller are set to these values.
> +///
> +typedef struct {
> +  MrcControllerSts Status;               ///< Indicates whether this controller
> should be used.
> +  UINT16           DeviceId;             ///< The PCI device id of this memory
> controller.
> +  UINT8            RevisionId;           ///< The PCI revision id of this memory
> controller.
> +  UINT8            ChannelCount;         ///< Number of valid channels that
> exist on the controller.
> +  MrcChannelOut    Channel[MAX_CHANNEL]; ///< The following are
> channel level definitions.
> +} MrcControllerOut;
> +
> +///
> +///********************************************
> +/// Saved data related "global data" structures.
> +///********************************************
> +///
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered to be needed
> +/// by the MRC between power state transitions (S0->S3->S0) and also fast
> and warm boot modes.
> +/// The following are DIMM level definitions.
> +///
> +typedef struct {
> +  UINT8 SpdDramDeviceType;       ///< Save SPD DramDeviceType
> information needed for SMBIOS structure creation.
> +  UINT8 SpdModuleType;           ///< Save SPD ModuleType information
> needed for SMBIOS structure creation.
> +  UINT8 SpdModuleMemoryBusWidth; ///< Save SPD
> ModuleMemoryBusWidth information needed for SMBIOS structure creation.
> +  UINT8 SpdSave[MAX_SPD_SAVE];   ///< Save SPD Manufacturing
> information needed for SMBIOS structure creation.
> +} MrcDimmSave;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered to be needed
> +/// by the MRC between power state transitions (S0->S3->S0) and also fast
> and warm boot modes.
> +/// The following are channel level definitions.
> +///
> +typedef struct {
> +  MrcChannelSts Status;                               ///< Indicates whether this
> channel should be used.
> +  UINT32        DimmCount;                            ///< Number of valid DIMMs
> that exist in the channel.
> +  UINT8         ValidRankBitMask;                     ///< Bit map of the
> populated ranks per channel
> +  MrcTiming     Timing[MAX_PROFILE];                  ///< The channel timing
> values.
> +  MrcDimmOut    Dimm[MAX_DIMMS_IN_CHANNEL];           ///< Save the
> DIMM output characteristics.
> +  MrcDimmSave   DimmSave[MAX_DIMMS_IN_CHANNEL];       ///< Save SPD
> information needed for SMBIOS structure creation.
> +} MrcChannelSave;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered to be needed
> +/// by the MRC between power state transitions (S0->S3->S0) and also fast
> and warm boot modes.
> +/// The following are controller level definitions.
> +///
> +typedef struct {
> +  MrcControllerSts  Status;               ///< Indicates whether this controller
> should be used.
> +  UINT8             ChannelCount;         ///< Number of valid channels that
> exist on the controller.
> +  MrcChannelSave    Channel[MAX_CHANNEL]; ///< The following are
> channel level definitions.
> +} MrcContSave;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered to be needed
> +/// by the MRC between power state transitions (S0->S3->S0) and also fast
> and warm boot modes.
> +/// The following are system level definitions.
> +///
> +typedef struct {
> +  UINT32 Crc;                  ///< The CRC-32 of the data in this structure.
> +} MrcSaveHeader;
> +
> +//
> +// ------- IMPORTANT NOTE --------
> +// MRC_MC_REGISTER_COUNT in MrcInterface.h should match the table in
> MrcSaveRestore.c.
> +// Update this define whenever you add/remove registers from this table.
> +//
> +#define MRC_REGISTER_COUNT_COMMON (1376 / sizeof (UINT32)) ///< The
> number of MC registers that need to be saved (common)
> +#define MRC_REGISTER_COUNT_SAGV   (1528 / sizeof (UINT32)) ///< The
> number of MC registers that need to be saved (per SA GV point)
> +
> +typedef struct {
> +  MrcCapabilityId McCapId;                                   ///< The memory
> controller's capabilities.
> +  UINT32          RegSaveCommon[MRC_REGISTER_COUNT_COMMON];
> ///< The MC registers that are common to both SA GV points
> +  UINT32          RegSaveLow[MRC_REGISTER_COUNT_SAGV];       ///< The
> MC registers for the Low SA GV point
> +  UINT32          RegSaveHigh[MRC_REGISTER_COUNT_SAGV];      ///< The
> MC registers for the High SA GV point, or for SA GV Disabled case
> +  UINT32          MeStolenSize;                              ///< The managebility
> engine memory size, in Mbyte units.
> +  MrcCpuStepping  CpuStepping;                               ///< The last cold
> boot happended with this CPU stepping.
> +  MrcCpuModel     CpuModel;                                  ///< The last cold
> boot happended with this CPU model.
> +  MrcCpuFamily    CpuFamily;                                 ///< CPU is Coffeelake
> +  MrcVersion      Version;                                   ///< The last cold boot
> happended with this MRC version.
> +  UINT32          SaMemCfgCrc;                               ///< The CRC32 of the
> system agent memory configuration structure.
> +  MrcContSave     Controller[MAX_CONTROLLERS];               ///< The
> following are controller level definitions.
> +  MrcFrequency    FreqMax;                                   ///< The system's
> requested maximum frequency.
> +  MrcFrequency    Frequency;                                 ///< The system's
> common memory controller frequency.
> +  UINT32          MemoryClock;                               ///< The system's
> common memory controller clock, in femtoseconds.
> +  BOOLEAN         OddRatioModeLow;                           ///< If Odd Ratio
> Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for
> SAGV Low point.
> +  BOOLEAN         OddRatioModeHigh;                          ///< If Odd Ratio
> Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for
> SAGV High point, or SAGV disabled / fixed high / fixed low
> +  MrcRefClkSelect RefClk;                                    ///< The memory
> controller is going to use this reference clock.
> +  MrcClockRatio   Ratio;                                     ///< Request for this
> memory controller to use this clock ratio.
> +  MrcVddSelect    VddVoltage[MAX_PROFILE];                   ///< The voltage
> (VDD) setting for all DIMMs in the system, per profile.
> +  BOOLEAN         EccSupport;                                ///< TRUE if ECC is
> enabled and supported on this controller.
> +  MrcDdrType      DdrType;                                   ///< DDR type: DDR3,
> DDR4, or LPDDR3
> +  UINT32          DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1]; ///< The
> Default XMP tCK values read from SPD.
> +  UINT8           XmpProfileEnable;                          ///< If XMP capable
> DIMMs are detected, this will indicate which XMP Profiles are common among
> all DIMMs.
> +  BOOLEAN         BinnedLpddrDevices;                        ///< Binned LPDDR3
> devices (6Gb/12Gb/etc)
> +  BOOLEAN         TCRSensitiveHynixDDR4;                     ///< TCR sensitive
> Hynix DDR4 in the system
> +  BOOLEAN         TCRSensitiveMicronDDR4;                    ///< TCR sensitive
> Micron DDR4 in the system
> +  BOOLEAN         LpddrEctDone;                       ///< Set to TRUE once Early
> Command Training on LPDDR is done, and we can run JEDEC Init
> +  UINT8           BerEnable;                          ///< BER Enable (and # of
> Addresses)
> +  UINT64          BerAddress[4];                      ///< BER Addresses
> +  BOOLEAN         DmfcLimitedBoard;                   ///< Indicates if the
> system has 2DPC Memory Configuration which should be DMFC limited.
> +  BOOLEAN         DmfcLimited;                        ///< Indicates if the system
> has DMFC limited. Should only be set if DmfcLImitedBoard is TRUE.
> +  BOOLEAN         MixedUDimmConfig2Dpc;               ///< Indicates if the
> system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
> +  BOOLEAN         ExtendedDdrOverclock;               ///< Indicates if MC is
> capable of extended Overclock Memory frequencies.
> +} MrcSaveData;
> +
> +typedef struct {
> +  UINT32              Size;                        ///< The size of this structure, in
> bytes. Must be the first entry in this structure.
> +  MrcDebug            Debug;                       ///< MRC debug related
> variables used for serial output and debugging purposes.
> +  MrcVersion          Version;                     ///< The memory reference code
> version.
> +  MrcFrequency        FreqMax;                     ///< The requested maximum
> valid frequency.
> +  MrcFrequency        Frequency;                   ///< The system's common
> memory controller frequency.
> +  UINT32              MemoryClockMax;              ///< The system's common
> memory controller maximum clock, in femtoseconds.
> +  UINT32              MemoryClock;                 ///< The system's common
> memory controller clock, in femtoseconds.
> +  MrcRefClkSelect     RefClk;                      ///< The memory controller is
> going to use this reference clock.
> +  MrcClockRatio       Ratio;                       ///< Request for this memory
> controller to use this clock ratio.
> +  MrcMemoryMap        MemoryMapData;               ///< The system's
> memory map data.
> +  MrcGfxDataSize      GraphicsStolenSize;          ///< Graphics Data Stolen
> Memory size in MB
> +  MrcGfxGttSize       GraphicsGttSize;             ///< GTT graphics stolen
> memory size in MB
> +  MrcVddSelect        VddVoltage[MAX_PROFILE];     ///< The currently
> running voltage (VDD) setting for all DIMMs in the system, per profile.
> +  MrcGdxc             Gdxc;                        ///< GDXC enable and size.
> +  BOOLEAN             VddVoltageDone;              ///< To determine if
> VddVoltageDone update has been done already
> +  BOOLEAN             EccSupport;                  ///< TRUE if ECC is enabled and
> supported on this controller.
> +  BOOLEAN             EnDumRd;                     ///< Enable/Disable Logic
> Analyzer
> +  BOOLEAN             RestoreMRs;                  ///< Enable/Disable restoring
> +  BOOLEAN             LpddrEctDone;                ///< Set to TRUE once Early
> Command Training on LPDDR is done, and we can run JEDEC Init
> +  BOOLEAN             LpddrWLUpdated;              ///< Set to TRUE once
> LPDDR WL Memory Set has been updated
> +  BOOLEAN             JedecInitDone;               ///< Set to TRUE once JEDEC
> Init on LPDDR/DDR4 is done
> +  UINT32              DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1];
> ///< The Default XMP tCK values read from SPD.
> +  UINT8               XmpProfileEnable;            ///< If XMP capable DIMMs are
> detected, this will indicate which XMP Profiles are common among all DIMMs.
> +  BOOLEAN             Capable100;                  ///< The MC is capable of 100
> reference clock (0 = no, 1 = yes).
> +  BOOLEAN             AutoSelfRefresh;             ///< Indicates ASR is
> supported for all the DIMMS for 2xRefresh
> +  MrcDdrType          DdrType;                     ///< Current memory type:
> DDR3, DDR4, or LPDDR3
> +  MrcSpdStatus        SpdSecurityStatus;           ///< Status variable to
> inform BIOS that memory contains an alias.
> +  UINT32              MrcTotalChannelLimit;        ///< The maximum allowed
> memory size per channel, in MBytes.
> +  UINT8               SdramCount;                  ///< The number of SDRAM
> components on a DIMM.
> +  UINT16              Qclkps;                      ///< Qclk period in pS
> +  UINT8               DQPat;                       ///< Global Variables storing the
> current DQPat REUT Test
> +  INT8                DQPatLC;                     ///< Global Variables storing the
> current DQPat Loopcount
> +  UINT16              NumCL;                       ///< Global Variables storing the
> current number of Cachelines
> +  UINT8               ValidRankMask;               ///< Rank bit map - includes
> both channels
> +  UINT8               ValidChBitMask;              ///< Channel bit map of the
> populated channels
> +  BOOLEAN             UpmPwrRetrainFlag;           ///< A flag that indicates if
> training with higher UPM/PWR limits.
> +  UINT32
> MarginResult[MAX_RESULT_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHANNE
> L][MAX_SDRAM_IN_DIMM][MAX_EDGES]; ///< Stores last margin
> measurement.
> +  BOOLEAN
> MarginSignReversed[MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_SDRA
> M_IN_DIMM][MAX_EDGES]; ///< Indicates if the Margin Sign is Reversed
> +  MrcOdtPowerSaving   OdtPowerSavingData;          ///< ODT power savings
> data.
> +  BOOLEAN             TxDIMMVref[MAX_CHANNEL];     ///< Whether Write
> DIMM Vref is enabled based on Channel
> +  UINT32              MchBarWriteCount;            ///< The number of MMIO
> writes performed during MRC execution.
> +  UINT32              MchBarReadCount;             ///< The number of MMIO
> reads performed during MRC execution.
> +  UINT8               BerEnable;                   ///< BER Enable (and # of
> Addresses)
> +  UINT64              BerAddress[4];               ///< BER Addresses
> +  UINT8               CmdVLoop;                    ///< Keeps track of the # of
> CmdV training step runned
> +  UINT8               CmdVLoopStatus;              ///< Keeps the last status of
> the CmdV training step
> +  UINT8               tMAC;                        ///< Maximum Activate Count for
> pTRR.
> +  UINT8               LpddrMemWriteLatencySet;     ///< 0 = Set A (WL), 1 = Set
> B (WL) if supported
> +  BOOLEAN             Ddr4PdaEnable;               ///< Current status of PDA - if
> true all the Mr6 operations need to use PDA mode.
> +  BOOLEAN             BinnedLpddrDevices;          ///< Binned LPDDR3 devices
> (6Gb/12Gb/etc)
> +  MrcControllerOut    Controller[MAX_CONTROLLERS]; ///< The following
> are controller level definitions.
> +  BOOLEAN             TCRSensitiveHynixDDR4;       ///< TCR sensitive Hynix
> DDR4 in the system
> +  BOOLEAN             TCRSensitiveMicronDDR4;      ///< TCR sensitive Micron
> DDR4 in the system
> +  BOOLEAN             OddRatioMode;                ///< If Odd Ratio Mode is
> enabled, QCLK frequency has an addition of 133/100 MHz
> +  BOOLEAN             LpddrDramOdt;                ///< Indicates if LPDDR
> DRAM ODT is used - Only used for 2133+
> +  BOOLEAN             ExtendedDdrOverclock;        ///< Indicates if MC is
> capable of extended Overclock Memory frequencies.
> +  BOOLEAN             DmfcLimitedBoard;            ///< Indicates if the system
> has 2DPC Memory Configuration which should be DMFC limited.
> +  BOOLEAN             DmfcLimited;                 ///< Indicates if the system has
> DMFC has been limited. Should only be set if DmfcLImitedBoard is TRUE.
> +  BOOLEAN             MixedUDimmConfig2Dpc;        ///< Indicates if the
> system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
> +#ifdef BDAT_SUPPORT
> +  union {
> +    MRC_BDAT_SCHEMA_LIST_HOB *Pointer;             ///< Pointer to the
> BDAT schema list.
> +    UINT64                   Data;
> +  } BdatSchemasHob;
> +  union {
> +    BDAT_MEMORY_DATA_HOB *Pointer;                 ///< Pointer to the BDAT
> memory data HOB.
> +    UINT64               Data;
> +  } BdatMemoryHob[MAX_SCHEMA_LIST_LENGTH];
> +  UINT8
> Margin2DResult[MAX_2D_EYE_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHAN
> NEL][MAX_2D_EYE_OFFSETS][MAX_EDGES]; ///< Stores the 2D Eye Margin
> +#endif
> +
> +#ifdef UP_SERVER_FLAG
> +  UINT8              ThermOffset[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> ///< TSOD Thermal Offset
> +#endif
> +} MrcOutput;
> +
> +///
> +///****************************************
> +/// Input related "global data" structures.
> +///****************************************
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are SDRAM level definitions. All ranks on a rank are set to
> these values.
> +///
> +/* Commented out until needed, in order to save space.
> +typedef struct {
> +  UINT8  Placeholder;  ///< TODO: Is there anything that needs to go in here?
> +} MrcSdramIn;
> +*/
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are rank level definitions. All ranks on a DIMM are set to
> these values.
> +///
> +/* Commented out until needed, in order to save space.
> +typedef struct {
> +  MrcSdramIn  Sdram[MAX_SDRAM_IN_DIMM]; ///< The following are
> SDRAM level definitions.
> +} MrcRankIn;
> +*/
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are DIMM level definitions. All ranks on a DIMM are set to
> these values.
> +///
> +typedef struct {
> +  MrcDimmSts  Status;                 ///< Indicates whether this DIMM should
> be used.
> +  MrcSpdData  Spd;                    ///< The SPD data for each DIMM.
> SPDGeneral field = 0 when absent.
> +  MrcTiming   Timing;                 ///< The DIMMs requested timing
> overrides.
> +  UINT8       SpdAddress;             ///< The SMBus address for the DIMM's
> SPD data.
> +//MrcRankIn   Rank[MAX_RANK_IN_DIMM]; ///< The following are rank level
> definitions.
> +} MrcDimmIn;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are channel level definitions. All DIMMs on a memory
> channel are set to these values.
> +///
> +typedef struct {
> +  MrcChannelSts Status;                        ///< Indicates whether this channel
> should be used.
> +  UINT32        DimmCount;                     ///< The maximum number of
> DIMMs on this channel.
> +  MrcDimmIn     Dimm[MAX_DIMMS_IN_CHANNEL];    ///< The following
> are DIMM level definitions.
> +  UINT8         DqsMapCpu2Dram[8];             ///< Mapping from CPU DQS
> pins to SDRAM DQS pins
> +  UINT8         DqMapCpu2Dram[8][MAX_BITS];    ///< Mapping from CPU
> DQ pins to SDRAM DQ pins
> +  UINT8         DQByteMap[MrcIterationMax][2]; ///< Maps which PI clocks
> are used by what LPDDR DQ Bytes (from CPU side), per group
> +                                               ///< DQByteMap[0] - ClkDQByteMap:
> +                                               ///<   If clock is per rank, program to [0xFF,
> 0xFF]
> +                                               ///<   If clock is shared by 2 ranks, program
> to [0xFF, 0] or [0, 0xFF]
> +                                               ///<   If clock is shared by 2 ranks but does
> not go to all bytes,
> +                                               ///<           Entry[i] defines which DQ
> bytes Group i services
> +                                               ///< DQByteMap[1] - CmdNDQByteMap:
> Entry[0] is CmdN/CAA and Entry[1] is CmdN/CAB
> +                                               ///< DQByteMap[2] - CmdSDQByteMap:
> Entry[0] is CmdS/CAA and Entry[1] is CmdS/CAB
> +                                               ///< DQByteMap[3] - CkeDQByteMap :
> Entry[0] is CKE /CAA and Entry[1] is CKE /CAB
> +                                               ///<                For DDR, DQByteMap[3:1]
> = [0xFF, 0]
> +                                               ///< DQByteMap[4] - CtlDQByteMap :
> Always program to [0xFF, 0] since we have 1 CTL / rank
> +                                               ///<                               Variable only
> exists to make the code easier to use
> +                                               ///< DQByteMap[5] - CmdVDQByteMap:
> Always program to [0xFF, 0] since we have 1 CA Vref
> +                                               ///<                               Variable only
> exists to make the code easier to use
> +} MrcChannelIn;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are memory controller level definitions. All channels on a
> controller are set to these values.
> +///
> +typedef struct {
> +  MrcControllerSts  Status;               ///< Indicates whether this controller
> should be used.
> +  UINT8             ChannelCount;         ///< Number of valid channels that
> are requested on the controller.
> +  MrcChannelIn      Channel[MAX_CHANNEL]; ///< The following are channel
> level definitions.
> +} MrcControllerIn;
> +
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are system level definitions. All memory controllers in the
> system are set to these values.
> +typedef struct {
> +  // Start of synchronization to the SA MEMORY_CONFIGURATION structure.
> +  // Alignment of this block must be maintained and field offsets must match.
> +  UINT8   Header[28];             ///< Offset 0-27 Config Block Header
> +  UINT16  Size;                   ///< Offset 28 The size of this structure, in bytes.
> Must be the first entry in this structure.
> +  UINT8   HobBufferSize;          ///< Offset 30 Size of HOB buffer
> +  UINT8   MemoryProfile;          ///< Offset 31 SPD XMP profile selection - for
> XMP supported DIMM: <b>0=Default DIMM profile</b>, 1=Customized profile,
> 2=XMP profile 1, 3=XMP profile 2.
> +  // The following parameters are used only when MemoryProfile is
> UserDefined (CUSTOM PROFILE)
> +  UINT16  tCL;                    ///< Offset 32 User defined Memory Timing tCL
> value,   valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 31=Maximum.
> +  UINT16  tRCDtRP;                ///< Offset 34 User defined Memory Timing
> tRCD value (same as tRP), valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 63=Maximum.
> +  UINT16  tRAS;                   ///< Offset 36 User defined Memory Timing
> tRAS value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 64=Maximum.
> +  UINT16  tWR;                    ///< Offset 38 User defined Memory Timing
> tWR value,   valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> legal values: 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 24.
> +  UINT16  tRFC;                   ///< Offset 40 User defined Memory Timing
> tRFC value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 1023=Maximum.
> +  UINT16  tRRD;                   ///< Offset 42 User defined Memory Timing
> tRRD value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 15=Maximum.
> +  UINT16  tWTR;                   ///< Offset 44 User defined Memory Timing
> tWTR value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 28=Maximum.
> +  UINT16  tRTP;                   ///< Offset 46 User defined Memory Timing
> tRTP value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 15=Maximum. DDR4 legal values: 5, 6, 7, 8, 9, 10, 12
> +  UINT16  tFAW;                   ///< Offset 48 User defined Memory Timing
> tFAW value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 63=Maximum.
> +  UINT16  tCWL;                   ///< Offset 50 User defined Memory Timing
> tCWL value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 20=Maximum.
> +  UINT16  tREFI;                  ///< Offset 52 User defined Memory Timing
> tREFI value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 65535=Maximum.
> +  UINT16  PciIndex;               ///< Offset 54 Pci index register address:
> <b>0xCF8=Default</b>
> +  UINT16  PciData;                ///< Offset 56 Pci data register address:
> <b>0xCFC=Default</b>
> +  UINT16  VddVoltage;             ///< Offset 58 DRAM voltage (Vdd) in
> millivolts: <b>0=Platform Default (no override)</b>, 1200=1.2V, 1350=1.35V
> etc.
> +  UINT16  Idd3n;                  ///< Offset 60 EPG Active standby current
> (Idd3N) in milliamps from DIMM datasheet.
> +  UINT16  Idd3p;                  ///< Offset 62 EPG Active power-down current
> (Idd3P) in milliamps from DIMM datasheet.
> +
> +  UINT32  EccSupport:1;                   ///< Offset 64 DIMM Ecc Support
> option - for Desktop only: 0=Disable, <b>1=Enable</b>
> +  UINT32  MrcSafeConfig:1;                ///<  - MRC Safe Mode:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  RemapEnable:1;                  ///<  - This option is used to control
> whether to enable/disable memory remap above 4GB: 0=Disable,
> <b>1=Enable</b>.
> +  UINT32  ScramblerEnable:1;              ///<  - Memory scrambler support:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  Vc1ReadMeter:1;                 ///<  - VC1 Read Metering Enable:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  DdrThermalSensor:1;             ///<  - Ddr Thermal Sensor:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  LpddrMemWriteLatencySet:1;      ///<  - LPDDR3 Write Latency Set
> option: 0=Set A, <b>1=Set B</b>
> +  UINT32  Off64Bits7to8Rsvd:2;            ///<  - Bits 7-8 Reserved
> +  UINT32  SimicsFlag:1;                   ///<  - Option to Enable SIMICS:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  Ddr4DdpSharedClock:1;           ///<  - New Select if CLK0 is shared
> between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>,
> 1=Shared
> +  UINT32  Ddr4DdpSharedZq:1;              ///<  - Select if ZQ pin is shared
> between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>,
> 1=Shared
> +  // Thermal Management
> +  UINT32  ThermalManagement:1;            ///<  - Memory Thermal
> Management Support: <b>0=Disable</b>, 1=Enable.
> +  UINT32  PeciInjectedTemp:1;             ///<  - Enable/Disable memory
> temperatures to be injected to the processor via PECI: <b>0=Disable</b>,
> 1=Enable.
> +  UINT32  ExttsViaTsOnBoard:1;            ///<  - Enable/Disable routing
> TS-on-Board's ALERT# and THERM# to EXTTS# pins on the PCH:
> <b>0=Disable</b>, 1=Enable.
> +  UINT32  ExttsViaTsOnDimm:1;             ///<  - Enable/Disable routing
> TS-on-DIMM's ALERT# to EXTTS# pin on the PCH: <b>0=Disable</b>, 1=Enable.
> +  UINT32  VirtualTempSensor:1;            ///<  - Enable/Disable Virtual
> Temperature Sensor (VTS): <b>0=Disable</b>, 1=Enable.
> +  UINT32  Lp4DqsOscEn:1;                  ///<  - DqDqsReTraining support:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  DualDimmPerChannelBoardType:1;  ///<  -
> DualDimmPerChannelBoardType: Option to indicate if the Memory Design for
> the board includes two DIMMs per channel: <b>0=Single DIMM Design</b>,
> 1=Dual DIMM Design
> +  UINT32  ReservedBits1:13;
> +  /**
> +   Disables a DIMM slot in the channel even if a DIMM is present\n
> +   Array index represents the channel number (0 = channel 0, 1 = channel 1)\n
> +     <b>0x0 = DIMM 0 and DIMM 1 enabled</b>\n
> +     0x1 = DIMM 0 disabled, DIMM 1 enabled\n
> +     0x2 = DIMM 0 enabled, DIMM 1 disabled\n
> +     0x3 = DIMM 0 and DIMM 1 disabled (will disable the whole channel)\n
> +  **/
> +  UINT8   DisableDimmChannel[MAX_CHANNEL];  ///< Offset 68
> +  /**
> +   Selects the ratio to multiply the reference clock by for the DDR frequency\n
> +   When RefClk is 133MHz\n
> +   <b>0x00 = Auto</b>, 0x03 through 0x0C are valid values, all others are
> invalid\n
> +   When RefClk is 100MHz\n
> +   <b>0x00 = Auto</b>, 0x06 through 0x10 are valid values, all others are
> invalid\n
> +  **/
> +  UINT8   Ratio;                  ///< Offset 70
> +  UINT8   ProbelessTrace;         ///< Offset 71 Probeless Trace:
> <b>0=Disabled</b>, <b>1=Enabled</b>
> +  UINT32  BClkFrequency;          ///< Offset 72 Base reference clock value, in
> Hertz: <b>100000000 = 100Hz</b>, 125000000=125Hz, 167000000=167Hz,
> 250000000=250Hz
> +  /**
> +     - Channel Hash Enable.\n
> +    NOTE: BIT7 will interleave the channels at a 2 cacheline granularity, BIT8 at
> 4 and BIT9 at 8\n
> +    0=BIT6, <B>1=BIT7</B>, 2=BIT8, 3=BIT9
> +  **/
> +  UINT8   ChHashInterleaveBit;    ///< Offset 76
> +  UINT8   EnergyScaleFact;        ///< Offset 77 - Energy Scale Factor.
> 0=Minimal, 7=Maximum, <b>4=Default</b>
> +  UINT8   Reserved0;              ///< Offset 78 - Reserved for future use.
> +  UINT8   McLock;                 ///< Offset 79 - Enable/Disable memory
> configuration register locking: 0=Disable, <b>1=Enable</b>.
> +  // Training Algorithms
> +  TrainingStepsEn TrainingEnables;    ///< Offset 80 - Options to Enable
> individual training steps
> +  TrainingStepsEn2 TrainingEnables2;  ///< Offset 84 - Options to Enable
> individual training steps
> +
> +  UINT32  OddRatioMode:1;             ///< Offset 88 - If Odd Ratio Mode is
> enabled, QCLK frequency has an addition of 133/100 MHz: <b>0=Disable</b>,
> 1=Enable
> +  UINT32  MrcTimeMeasure:1;           ///< - Enables serial debug level to
> display the MRC execution times only: <b>0=Disable</b>, 1=Enable
> +  UINT32  MrcFastBoot:1;              ///< - Enables the MRC fast boot path for
> faster cold boot execution: 0=Disable, <b>1=Enable</b>
> +  UINT32  DqPinsInterleaved:1;        ///< - Interleaving mode of DQ/DQS pins
> for HSW_ULT which depends on board routing: <b>0=Disable</b>, 1=Enable
> +  UINT32  RankInterleave:1;           ///< - Rank Interleave Mode: 0=Disable,
> <b>1=Enable</b>
> +  UINT32  EnhancedInterleave:1;       ///< - Enhanced Interleave Mode:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  WeaklockEn:1;               ///< - Weak Lock Enable: 0=Disable,
> <b>1=Enable</b>
> +  UINT32  CmdTriStateDis:1;           ///< - CMD Tri-State Support:
> <b>0=Enable</b>, 1=Disable. Note: This should be set to 1 (Disable) if
> Command RTT is not present on the platform.
> +  UINT32  MemoryTrace:1;              ///< - Memory Trace to second DDR
> channel using Stacked Mode: <b>0=Disable</b>, 1=Enable
> +  UINT32  ChHashEnable:1;             ///< - Channel Hash Enable: 0=Disable,
> <b>1=Enable</b>
> +  UINT32  EnableExtts:1;              ///< - Enable Extts: <b>0=Disable</b>,
> 1=Enable
> +  UINT32  EnableCltm:1;               ///< - Enable Closed Loop Thermal
> Management: <b>0=Disable</b>, 1=Enable
> +  UINT32  EnableOltm:1;               ///< - Enable Open Loop Thermal
> Management: <b>0=Disable</b>, 1=Enable
> +  UINT32  EnablePwrDn:1;              ///< - Enable Power Down control for
> DDR: 0=PCODE control, <b>1=BIOS control</b>
> +  UINT32  EnablePwrDnLpddr:1;         ///< - Enable Power Down for LPDDR:
> 0=PCODE control, <b>1=BIOS control</b>
> +  UINT32  LockPTMregs:1;              ///< - Lock PCU Thermal Management
> registers: 0=Disable, <b>1=Enable</b>
> +  UINT32  UserPowerWeightsEn:1;       ///< - Allows user to explicitly set
> power weight, scale factor, and channel power floor values: <b>0=Disable</b>,
> 1=Enable
> +  UINT32  RaplLim2Lock:1;             ///< - Lock DDR_RAPL_LIMIT register:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  RaplLim2Ena:1;              ///< - Enable Power Limit 2:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  RaplLim1Ena:1;              ///< - Enable Power Limit 1:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  SrefCfgEna:1;               ///< - Enable Self Refresh: 0=Disable,
> <b>1=Enable</b>
> +  UINT32  ThrtCkeMinDefeatLpddr:1;    ///< - Throttler CKE min defeature for
> LPDDR: 0=Disable, <b>1=Enable</b>
> +  UINT32  ThrtCkeMinDefeat:1;         ///< - Throttler CKE min defeature:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  AutoSelfRefreshSupport:1;   ///< - FALSE = No auto self refresh
> support, <b>TRUE = auto self refresh support</b>
> +  UINT32  ExtTemperatureSupport:1;    ///< - FALSE = No extended
> temperature support, <b>TRUE = extended temperature support</b>
> +  UINT32  MobilePlatform:1;           ///< - Memory controller device id
> indicates: <b>TRUE if mobile</b>, FALSE if not. Note: This will be
> auto-detected and updated.
> +  UINT32  Force1Dpc:1;                ///< - TRUE means force one DIMM per
> channel, <b>FALSE means no limit</b>
> +  UINT32  ForceSingleRank:1;          ///< - TRUE means use Rank0 only (in
> each DIMM): <b>0=Disable</b>, 1=Enable
> +  UINT32  RhPrevention:1;             ///< - RH Prevention Enable/Disable:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  VttTermination:1;           ///< - Vtt Termination for Data ODT:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  VttCompForVsshi:1;          ///< - Enable/Disable Vtt Comparator
> For Vsshi: <b>0=Disable</b>, 1=Enable
> +  UINT32  ExitOnFailure:1;            ///< - MRC option for exit on failure or
> continue on failure: 0=Disable, <b>1=Enable</b>
> +
> +  UINT32  VddSettleWaitTime;      ///< Offset 92 - Amount of time in
> microseconds to wait for Vdd to settle on top of 200us required by JEDEC spec:
> <b>Default=0</b>
> +  UINT16  FreqSaGvLow;            ///< Offset 96 - SA GV: 0 is Auto/default,
> otherwise holds the frequency value: <b>0=Default</b>, 1067, 1200, 1333,
> 1400, 1600, 1800, 1867.
> +  UINT16  SrefCfgIdleTmr;         ///< Offset 98 - Self Refresh idle timer:
> <b>512=Minimal</b>, 65535=Maximum
> +  UINT8   RhActProbability;       ///< Offset 100 - Activation probability for
> Hardware RHP
> +  UINT8   SmramMask;              ///< Offset 101 - Reserved memory ranges
> for SMRAM
> +  UINT16  Vc1ReadMeterThreshold;  ///< Offset 102 - VC1 Read Meter
> Threshold (within Time Window): 0=Minimal, 0xFFFF=Maximum,
> <b>0x118=Default</b>
> +  UINT32  Vc1ReadMeterTimeWindow; ///< Offset 104 - VC1 Read Meter
> Time Window: 0=Minimal, 0x1FFFF=Maximum, <b>0x320=Default</b>
> +  UINT64  BerAddress[4];          ///< Offset 108 - 139 BER Address(es):
> <b>0=Minimal</b>, 0xFFFFFFFFFFFFFFFF=Maximum (step is 0x40)
> +
> +  UINT16  ChHashMask;             ///< Offset 140 - Channel Hash Mask:
> 0x0001=BIT6 set(Minimal), 0x3FFF=BIT[19:6] set(Maximum), <b>0x30CE=
> BIT[19:18, 13:12 ,9:7] set</b>
> +  UINT16  DdrFreqLimit;           ///< Offset 142 - Memory Frequency Limit:
> <b>0=Auto (limited by SPD/CPU capability)</b>, for valid values see
> MrcFrequency in MrcInterface.h
> +  ThermalMngmtEn  ThermalEnables; ///< Offset 144 - 187
> +
> +  UINT8   MaxRttWr;               ///< Offset 188 - Maximum DIMM RTT_WR to
> use in power training: <b>0=ODT Off</b>, 1 = 120 ohms
> +  UINT8   ThrtCkeMinTmr;          ///< Offset 189 - Throttler CKE min timer:
> 0=Minimal, 0xFF=Maximum, <b>0x30=Default</b>
> +  UINT8   ThrtCkeMinTmrLpddr;     ///< Offset 190 - Throttler CKE min timer
> for LPDDR: 0=Minimal, 0xFF=Maximum, <b>0x40=Default</b>
> +  UINT8   BerEnable;              ///< Offset 191 - BER Enable and # of
> Addresses passed in: <b>0=Minimal</b>, 8=Maximum
> +  UINT8   CkeRankMapping;         ///< Offset 192 - Bits [7:4] - Channel 1, bits
> [3:0] - Channel 0. <b>0xAA=Default</b> Bit [i] specifies which rank CKE[i] goes
> to.
> +  UINT8   StrongWkLeaker;         ///< Offset 193 - Strong Weak Leaker:
> 1=Minimal, <b>7=Maximum</b>
> +  UINT8   CaVrefConfig;           ///< Offset 194 - 0=VREF_CA goes to both
> CH_A and CH_B, 1=VREF_CA to CH_A, VREF_DQ_A to CH_B, <b>2=VREF_CA to
> CH_A, VREF_DQ_B to CH_B</b>
> +  UINT8   SaGv;                   ///< Offset 195 - SA GV: <b>0=Disabled</b>,
> 1=FixedLow, 2=FixedHigh, 3=Enabled
> +  UINT8   RaplPwrFlCh1;           ///< Offset 196 - Power Channel 1 Floor value:
> <b>0=Minimal</b>, 255=Maximum
> +  UINT8   RaplPwrFlCh0;           ///< Offset 197 - Power Channel 0 Floor value:
> <b>0=Minimal</b>, 255=Maximum
> +  UINT8   NModeSupport;           ///< Offset 198 - Memory N Mode Support
> - Enable user to select Auto, 1N or 2N: <b>0=AUTO</b>, 1=1N, 2=2N.
> +  UINT8   RefClk;                 ///< Offset 199 - Selects the DDR base reference
> clock. 0x01 = 100MHz, <b>0x00 = 133MHz</b>
> +  UINT8   EnCmdRate;              ///< Offset 200 - CMD Rate Enable: 0=Disable,
> 1=1 CMD, 2=2 CMDs, <b>3=3 CMDs</b>, 4=4 CMDs, 5=5 CMDs, 6=6 CMDs, 7=7
> CMDs
> +  UINT8   Refresh2X;              ///< Offset 201 - Refresh 2x: <b>0=Disable</b>,
> 1=Enable for WARM or HOT, 2=Enable for HOT only
> +  UINT8   EpgEnable;              ///< Offset 202 - Enable Energy Performance
> Gain.
> +  UINT8   RhSolution;             ///< Offset 203 - Type of solution to be used
> for RHP - 0/1 = HardwareRhp/Refresh2x
> +  UINT8   UserThresholdEnable;    ///< Offset 204 - Flag to manually select
> the DIMM CLTM Thermal Threshold, 0=Disable,  1=Enable, <b>0=Default</b>
> +  UINT8   UserBudgetEnable;       ///< Offset 205 - Flag to manually select the
> Budget Registers for CLTM Memory Dimms , 0=Disable,  1=Enable,
> <b>0=Default</b>
> +  UINT8   TsodTcritMax;           ///< Offset 206 - TSOD Tcrit Maximum Value
> to be Configure , 0=Minimal, 128=Maximum, , <b>105=Default</b>
> +
> +  UINT8   TsodEventMode;          ///< Offset 207 - Flag to Enable Event Mode
> Interruption in TSOD Configuration Register, 0=Disable,  1=Enable,
> <b>1=Default</b>
> +  UINT8   TsodEventPolarity;      ///< Offset 208 - Event Signal Polarity in
> TSOD Configuration Register, 0=Low,  1=High, <b>0=Default</b>
> +  UINT8   TsodCriticalEventOnly;  ///< Offset 209 - Critical Trigger Only in
> TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
> +  UINT8   TsodEventOutputControl; ///< Offset 210 - Event Output Control in
> TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
> +  UINT8   TsodAlarmwindowLockBit; ///< Offset 211 - Alarm Windows Lock Bit
> in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
> +  UINT8   TsodCriticaltripLockBit;///< Offset 212 - Critical Trip Lock Bit in TSOD
> Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
> +  UINT8   TsodShutdownMode;       ///< Offset 213 - Shutdown Mode TSOD
> Configuration Register,0=Enable,  1=Disable, <b>0=Default</b>
> +  UINT8   TsodThigMax;            ///< Offset 214 - Thigh Max Value In the  for
> CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
> +  UINT8   TsodManualEnable;       ///< Offset 215 - Flag to manually select
> the TSOD Register Values , 0=Disable,  1=Enable, <b>0=Default</b>
> +  UINT8   DllBwEn0;               ///< Offset 216 - DllBwEn value for 1067
> +  UINT8   DllBwEn1;               ///< Offset 217 - DllBwEn value for 1333
> +  UINT8   DllBwEn2;               ///< Offset 218 - DllBwEn value for 1600
> +  UINT8   DllBwEn3;               ///< Offset 219 - DllBwEn value for 1867 and
> up
> +  UINT8   RetrainOnFastFail;      ///< Offset 220 - Restart MRC in Cold mode if
> SW MemTest fails during Fast flow. 0 = Disabled, <b>1 = Enabled</b>
> +  UINT8   ForceOltmOrRefresh2x;   ///< Offset 221 - Force OLTM or 2X Refresh
> when needed. <b>0 = Force OLTM</b>, 1 = Force 2x Refresh
> +  UINT8   PowerDownMode;          ///< Offset 222 - CKE Power Down Mode:
> <b>0xFF=AUTO</b>, 0=No Power Down, 1= APD mode, 6=PPD-DLL Off mode
> +  UINT8   PwdwnIdleCounter;       ///< Offset 223 - CKE Power Down Mode
> Idle Counter: 0=Minimal, 255=Maximum, <b>0x80=0x80 DCLK</b>
> +  UINT8   IsvtIoPort;             ///< Offset 224 ISVT IO Port Address: 0=Minimal,
> 0xFF=Maximum, <b>0x99=Default</b>
> +  UINT8   Reserved3;              ///< Offset 225 -  ConfigBlock size must be a
> multiple of DWORDs
> +  MrcGdxc Gdxc;                   ///< Offset 226 - 228 - GDXC enable and size.
> +  UINT8   RMTLoopCount;           ///< Offset 229 - Indicates the Loop Count
> to be used for Rank Margin Tool Testing: 1=Minimal, 32=Maximum, 0=AUTO,
> <b>0=Default</b>
> +  UINT8   Reserved4[2];           ///< Offset 230 - 231 Reserved for DWORD
> alignment.
> +  UINT32  RmtPerTask:1;                 ///< Offset 232 Bit 0: Rank Margin Tool
> Per Task. <b>0 = Disabled</b>, 1 = Enabled
> +  UINT32  Off232Bit1Rsvd:2;             ///< Offset 232 Bit 1-2: Reserved
> +  UINT32  EnBER:1;                      ///< Offset 232 Bit 3: Define if EnBER is
> enabled for Rank Margin Tool
> +  UINT32  Ddr4MixedUDimm2DpcLimit:1;    ///< Offset 232 Bit 4:
> Enable/Disable 2667 Frequency Limitation for DDR4 U-DIMM Mixed Dimm
> 2DPC population. 0 = Disabled, <b>1 = Enabled</b>
> +  UINT32  FastBootRmt:1;                ///< Offset 232 Bit 5: Enable/Disable
> RMT on FastBoot. <b>0 = Disabled</b>, 1 = Enabled
> +  UINT32  MrcTrainOnWarm:1;             ///< Offset 232 Bit 6: Enalbes MRC
> trainin on warm boot : <b>0=Disable</b>, 1 = Enabled
> +  UINT32  LongFlyByModeEnabled:1;       ///< Offset 232 Bit 7: Long FlyBy
> Mode Enabled : <b>0 = Disabled</b>, 1 = Enabled
> +  UINT32  Off232RsvdBits:24;            ///< Offset 232 Bit 8-31: Reserved
> +
> +  //
> +  // TurnAround Timing
> +  //
> +  MrcTurnaroundTimes tRd2Rd;      ///< Offset 236 - User-defined overrides
> for Read-to-Read   Turn Around Timings. <b>0 = AUTO</b>
> +  MrcTurnaroundTimes tRd2Wr;      ///< Offset 240 - User-defined overrides
> for Read-to-Write  Turn Around Timings. <b>0 = AUTO</b>
> +  MrcTurnaroundTimes tWr2Rd;      ///< Offset 244 - User-defined overrides
> for Write-to-Read  Turn Around Timings. <b>0 = AUTO</b>
> +  MrcTurnaroundTimes tWr2Wr;      ///< Offset 248 - User-defined overrides
> for Write-to-Write Turn Around Timings. <b>0 = AUTO</b>
> +  UINT16  tRRD_L;                 ///< Offset 252 - User defined DDR4 Memory
> Timing tRRD_L value,  valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 15=Maximum.
> +  UINT16  tRRD_S;                 ///< Offset 254 - User defined DDR4 Memory
> Timing tRRD_S value,  valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 15=Maximum.
> +  UINT16  tWTR_L;                 ///< Offset 266 - User defined DDR4 Memory
> Timing tWTR_L value,  valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 28=Maximum.
> +  UINT16  tWTR_S;                 ///< Offset 268 - User defined DDR4 Memory
> Timing tWTR_S value,  valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 28=Maximum.
> +
> +  //
> +  // End of synchronization to the SA MEMORY_CONFIGURATION structure.
> +  //
> +  MrcFrequency     FreqMax;                     ///< The requested maximum
> valid frequency.
> +  MrcBoardType     BoardType;                   ///< Define the board type
> (CRBMB,CRBDT,User1,User2). the OEM can add more boards.
> +  MrcCpuStepping   CpuStepping;                 ///< Define the CPU stepping.
> +  MrcCpuModel      CpuModel;                    ///< Define the CPU model.
> +  MrcCpuFamily     CpuFamily;                   ///< CPU is Coffeelake
> +  MrcGfxDataSize   GraphicsStolenSize;          ///< Graphics Data Stolen
> Memory size in MB
> +  MrcGfxGttSize    GraphicsGttSize;             ///< GTT graphics stolen
> memory size in MB
> +  MrcBaseTime      BaseTime;                    ///< RTC base time.
> +  MrcIteration     Iteration;                   ///< Number of iterations thru the
> MRC core call table.
> +  MrcMode          MrcMode;                     ///< The control for full or
> MiniBIOS MRC.
> +  MrcBootMode      BootMode;                    ///< The requested memory
> controller boot mode.
> +  BOOLEAN          TxtFlag;                     ///< Trusted eXecution Technology
> flag.
> +  BOOLEAN          SetRxDqs32;                  ///< Set DQS Delay to 32 control.
> +  BOOLEAN          GfxIsVersatileAcceleration;  ///< iGFX engines are in
> Versatile Acceleration
> +  BOOLEAN          DDR4MAP;                     ///< DDR4 PDA Mapping training
> control.
> +  POINTER_STRUCT   SaMemCfgAddress;             ///< Starting address of
> the input parameters to CRC.
> +  UINT32           SaMemCfgSize;                ///< The size of the input
> parameters to CRC.
> +  UINT32           PciEBaseAddress;             ///< define the PciE base
> address.
> +  UINT32           MchBarBaseAddress;           ///< define the MCH bar base
> address.
> +  UINT32           SmbusBaseAddress;            ///< This field defines the
> smbus base address.
> +  UINT32           GdxcBaseAddress;             ///< This field defines the GDXC
> base address.
> +  UINT32           HpetBaseAddress;             ///< This field defines the hpet
> base address.
> +  UINT32           MeStolenSize;                ///< define the size that the ME
> need in MB.
> +  UINT32           MmioSize;                    ///< define the MMIO size in MB.
> +  UINT32           TsegSize;                    ///< TSEG size that require by the
> system in MB.
> +  UINT32           IedSize;                     ///< IED size that require by the
> system in MB.
> +  UINT32           DprSize;                     ///< DPR size required by system in
> MB.
> +  UINT32           PrmrrSize;                   ///< Prmrr size required by the
> system in MB.
> +  POINTER_STRUCT   SerialBuffer;                ///< Pointer to the start of the
> serial buffer.
> +  UINT32           SerialBufferSize;            ///< The size of the serial buffer, in
> bytes.
> +  UINT32           DebugStream;                 ///< The debug port pointer.
> +  INT32            DebugLevel;                  ///< Indicates the level of debug
> messaging.
> +  UINT16           VccIomV;                     ///< VccIO logic voltage in mV.
> +  MrcControllerIn  Controller[MAX_CONTROLLERS]; ///< The following are
> controller level definitions.
> +  UINT32           HeapBase;                    ///< Starting address of the heap
> space.
> +  UINT32           HeapSize;                    ///< Size of the heap space, in
> bytes.
> +  UINT32           MrcStackTop;                 ///< Top of the stack at the
> beginning of MRC, for stack usage calculations.
> +  BOOLEAN          BdatEnable;                  ///< Option to enable output of
> training results into BDAT.
> +  UINT8            BdatTestType;                ///< When BdatEnable is set to
> TRUE, this option selects the type of training results data which will be
> populated into BDAT: <b>0=RMT</b>, 1=RMT Per Bit, 2=Margin 2D.
> +  BOOLEAN          LpddrDramOdt;                ///< TRUE if LPDDR DRAM ODT
> is used - depends on board design
> +  BOOLEAN          Ddr3DramOdt;                 ///< TRUE if DDR3  DRAM ODT
> is used - depends on board design
> +  BOOLEAN          Ddr4DramOdt;                 ///< TRUE if DDR4  DRAM ODT
> is used - depends on board design
> +  BOOLEAN          EnableVrefPwrDn;             ///< Setting this limits VrefGen
> to be off only during CKEPowerDown
> +  BOOLEAN          TxEqDis;                     ///< Disable TX Equalization
> +  BOOLEAN          EnVttOdt;                    ///< Enable VTT Termination for
> Data ODT
> +  UINT32           CpuidModel;                  ///< Unique CPU identifier.
> +  UINT8            CpuidStepping;               ///< Revision of the CPU.
> +  UINT8            CpuidSku;                    ///< SKU of the CPU.
> +  UINT32           SiPreMemPolicyPpi;
> +  TrainingModeType PowerTrainingMode;           ///< 0 - Power Training. 1 -
> Margin Training.
> +  union {
> +    MRC_FUNCTION  *Func;                        ///< External to MRC function
> pointers
> +    UINT64        Data;
> +  } Call;
> +  UINT16          RcompResistor[MAX_RCOMP];     ///< Reference RCOMP
> resistors on motherboard
> +  UINT16          RcompTarget[MAX_RCOMP_TARGETS]; ///< RCOMP target
> values for DqOdt, DqDrv, CmdDrv, CtlDrv, ClkDrv
> +  UINT32          CleanMemory:1;                ///< TRUE to request a memory
> clean
> +  UINT32          OcSupport:1;                  ///< TRUE if Overclocking is
> enabled in BIOS
> +  UINT32          RsvdBits5:30;
> +  /**
> +   Sets the serial debug message level\n
> +     0x00 = Disabled\n
> +     0x01 = Errors only\n
> +     0x02 = Errors and Warnings\n
> +     <b>0x03 = Errors, Warnings, and Info</b>\n
> +     0x04 = Errors, Warnings, Info, and Events\n
> +     0x05 = Displays Memory Init Execution Time Summary only\n
> +  **/
> +  UINT8           SerialDebugLevel;
> +} MrcInput;
> +
> +typedef struct {
> +  UINT32        Size;   ///< The size of this structure, in bytes. Must be the first
> entry in this structure.
> +  MrcSaveHeader Header; ///< The header portion of the MRC saved data.
> +  MrcSaveData   Data;   ///< The data portion of the MRC saved data.
> +} MrcSave;
> +
> +typedef struct {
> +  // Global variables that will be copied to the HOB follow.
> +  UINT8        MrcDataString[4]; ///< Beginning of global data marker, starts
> with "MRC". Must be the first entry in this structure.
> +  UINT32       MrcDataSize;      ///< The size of the MRC global data area, in
> bytes. Must be the second entry in this structure.
> +  MrcSave      Save;             ///< System specific save variables.
> +  MrcInput     Inputs;           ///< System specific input variables.
> +  MrcOutput    Outputs;          ///< System specific output variables.
> +
> +  // Global variables that will remain internal to the MRC library follow.
> +  union {
> +    void   *Internal; ///< System specific output variables that remain internal
> to the library.
> +    UINT64 Data;
> +  } IntOutputs;
> +} MrcParameters;
> +
> +#pragma pack (pop)
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcRmtData.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcRmtData.h
> new file mode 100644
> index 0000000000..9dd9b096ba
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcRmtData.h
> @@ -0,0 +1,203 @@
> +/** @file
> +  Copies the memory related timing and configuration information into the
> +  Compatible BIOS data (BDAT) table.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MrcRmtData_h_
> +#define _MrcRmtData_h_
> +
> +#include "MrcTypes.h"
> +
> +#define VDD_1_350             1350                      ///< VDD in millivolts
> +#define VDD_1_500             1500                      ///< VDD in millivolts
> +#define PI_STEP_BASE          2048                      ///< Magic number from
> spec
> +#define PI_STEP_INTERVAL      128                       ///< tCK is split into this
> amount of intervals
> +#define PI_STEP               ((PI_STEP_BASE) / (PI_STEP_INTERVAL))
> +#define VREF_STEP_BASE        100                       ///< Magic number from
> spec
> +#define TX_VREF_STEP          7800                      ///< TX Vref step in
> microvolts
> +#define TX_VREF(VDD)          (((TX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD))
> ///< VDD passed in is in millivolts
> +#define RX_VREF_STEP          8000                      ///< TX Vref step in
> microvolts
> +#define RX_VREF(VDD)          (((RX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD))
> ///< VDD passed in is in millivolts
> +#define CA_VREF_STEP          8000                      ///< TX Vref step in
> microvolts
> +#define CA_VREF(VDD)          (((CA_VREF_STEP) * (VREF_STEP_BASE)) / (VDD))
> ///< VDD passed in is in millivolts
> +
> +#define MAX_SPD_RMT           512                       ///< The maximum
> amount of data, in bytes, in an SPD structure.
> +#define RMT_PRIMARY_VERSION   4                         ///< The BDAT
> structure that is currently supported.
> +#define RMT_SECONDARY_VERSION 0                         ///< The BDAT
> structure that is currently supported.
> +#define MAX_MODE_REGISTER     7                         ///< Number of mode
> registers
> +#define MAX_DRAM_DEVICE       9                         ///< Maximum number
> of memory devices
> +#define MAX_2D_EYE_TYPE       2                         ///< Maximum number
> of supported Margin 2D Eye Types
> +#define MAX_2D_EYE_OFFSETS    7                         ///< Number of 2D Eye
> Offsets
> +
> +//
> +// Warning: Bdat4.h has its own copy of this #define
> +// make sure to change it in both places
> +//
> +#define MAX_SCHEMA_LIST_LENGTH (10)
> +
> +
> +#ifdef BDAT_SUPPORT
> +/*
> +  BSSA result Memory Schema GUID
> +  {8F4E928-0F5F-46D4-8410-479FDA279DB6}
> +*/
> +extern EFI_GUID gSsaBiosResultsGuid;
> +/*
> +  RMT Results Metadata GUID
> +  {02CB1552-D659-4232-B51F-CAB1E11FCA87}
> +*/
> +extern EFI_GUID gRmtResultMetadataGuid;
> +/*
> +  RMT Results Columns GUID
> +  {0E60A1EB-331F-42A1-9DE7-453E84761154}
> +*/
> +extern EFI_GUID gRmtResultColumnsGuid;
> +
> +/*
> +Margin2D Results Metadata GUID
> +{48265582-8E49-4AC7-AA06-E1B9A74C9716}
> +*/
> +extern EFI_GUID gMargin2DResultMetadataGuid;
> +/*
> +Margin2D Results Columns GUID
> +{91A449EC-8A4A-4736-AD71-A3F6F6D752D9}
> +*/
> +extern EFI_GUID gMargin2DResultColumnsGuid;
> +
> +#endif
> +/*
> + GUID for Schema List HOB
> + This is private GUID used by MemoryInit internally.
> + {3047C2AC-5E8E-4C55-A1CB-EAAD0A88861B}
> +*/
> +extern EFI_GUID gMrcSchemaListHobGuid;
> +
> +#pragma pack(push, 1)
> +
> +
> +///
> +/// SSA results buffer header.
> +///
> +typedef struct {
> +  UINT32  Revision;
> +  BOOLEAN TransferMode;
> +  struct {
> +    UINT32   Reserved;
> +    UINT32   MetadataSize;
> +    EFI_GUID MetadataType;
> +  } MdBlock;
> +  struct {
> +    UINT32   Reserved;
> +    EFI_GUID ResultType;
> +    UINT32   ResultElementSize;
> +    INT32    ResultCapacity;
> +    INT32    ResultElementCount;
> +  } RsBlock;
> +} RESULTS_DATA_HDR;
> +
> +// start auto-generated by the BSSA CCK sourced from the result xml files.
> +typedef enum {
> +  DisableScrambler = 0,
> +  EnableScrambler = 1,
> +  DontTouchScrambler = 2,
> +  SCRAMBLER_OVERRIDE_MODE_DELIM = MRC_INT32_MAX
> +} SCRAMBLER_OVERRIDE_MODE;
> +
> +typedef struct _RMT_RESULT_METADATA {
> +  BOOLEAN EnableCtlAllMargin;
> +  UINT16 SinglesBurstLength;
> +  UINT32 SinglesLoopCount;
> +  UINT16 TurnaroundsBurstLength;
> +  UINT32 TurnaroundsLoopCount;
> +  SCRAMBLER_OVERRIDE_MODE ScramblerOverrideMode;
> +  UINT8 PiStepUnit[2];
> +  UINT16 RxVrefStepUnit[2];
> +  UINT16 TxVrefStepUnit[2][2];
> +  UINT16 CmdVrefStepUnit[2][2];
> +  UINT8 MajorVer;
> +  UINT8 MinorVer;
> +  UINT8 RevVer;
> +  UINT32 BuildVer;
> +  UINT16 ResultEleCount;
> +} RMT_RESULT_METADATA;
> +
> +
> +typedef struct _RMT_RESULT_ROW_HEADER {
> +  UINT32 ResultType : 5;
> +  UINT32 Socket : 3;
> +  UINT32 Controller : 2;
> +  UINT32 Channel : 3;
> +  UINT32 DimmA : 1;
> +  UINT32 RankA : 3;
> +  UINT32 DimmB : 1;
> +  UINT32 RankB : 3;
> +  UINT32 Lane : 8;
> +  UINT32 IoLevel : 1;
> +  UINT32 Reserved : 2;
> +} RMT_RESULT_ROW_HEADER;
> +
> +typedef struct _RMT_RESULT_COLUMNS {
> +  RMT_RESULT_ROW_HEADER Header;
> +  UINT8 Margin[4][2];
> +} RMT_RESULT_COLUMNS;
> +
> +// end of auto-generated by the BSSA CCK sourced from the result xml files.
> +
> +typedef struct _BASE_RMT_RESULT {
> +  RESULTS_DATA_HDR              ResultsHeader;
> +  RMT_RESULT_METADATA           Metadata;
> +  RMT_RESULT_COLUMNS            Rows[1];
> +} BASE_RMT_RESULT;
> +
> +
> +typedef struct {
> +  UINT32                      Data1;
> +  UINT16                      Data2;
> +  UINT16                      Data3;
> +  UINT8                       Data4[8];
> +} BDAT_EFI_GUID;
> +
> +typedef struct {
> +  UINT16  HobType;
> +  UINT16  HobLength;
> +  UINT32  Reserved;
> +} BDAT_HOB_GENERIC_HEADER;
> +
> +typedef struct {
> +  BDAT_HOB_GENERIC_HEADER  Header;
> +  BDAT_EFI_GUID            Name;
> +  ///
> +  /// Guid specific data goes here
> +  ///
> +} BDAT_HOB_GUID_TYPE;
> +
> +typedef struct {
> +  BDAT_EFI_GUID               SchemaId;                         ///< The GUID
> uniquely identifies the format of the data contained within the structure.
> +  UINT32                      DataSize;                         ///< The total size of the
> memory block, including both the header as well as the schema specific data.
> +  UINT16                      Crc16;                            ///< Crc16 is computed in
> the same manner as the field in the BDAT_HEADER_STRUCTURE.
> +} MRC_BDAT_SCHEMA_HEADER_STRUCTURE;
> +
> +typedef struct {
> +  MRC_BDAT_SCHEMA_HEADER_STRUCTURE SchemaHeader;
> ///< The schema header.
> +  BASE_RMT_RESULT          RMT_RESULTS_WITH_META_COLUMNS;
> +} BDAT_MEMORY_DATA_STRUCTURE;
> +
> +typedef struct {
> +  BDAT_HOB_GUID_TYPE          HobGuidType;
> +  BDAT_MEMORY_DATA_STRUCTURE  MemorySchema;
> +} BDAT_MEMORY_DATA_HOB;
> +
> +#pragma pack (pop)
> +
> +typedef struct {
> +  BDAT_HOB_GUID_TYPE          HobGuidType;
> +  UINT16                      SchemaHobCount;
> +  UINT16                      Reserved;
> +  BDAT_EFI_GUID
> SchemaHobGuids[MAX_SCHEMA_LIST_LENGTH];
> +} MRC_BDAT_SCHEMA_LIST_HOB;
> +
> +#endif //_MrcRmtData_h_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcSpdData.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcSpdData.h
> new file mode 100644
> index 0000000000..45de5084c0
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcSpdData.h
> @@ -0,0 +1,1167 @@
> +/** @file
> +  SPD data format header file.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MrcSpdData_h_
> +#define _MrcSpdData_h_
> +#pragma pack (push, 1)
> +
> +#include "MrcTypes.h"
> +
> +#define MAX_XMP_PROFILES  (2)
> +#define SPD3_MANUF_SIZE   (SPD3_MANUF_END - SPD3_MANUF_START + 1)
> ///< The size of the SPD manufacturing data.
> +#define SPD4_MANUF_SIZE   (SPD4_MANUF_END - SPD4_MANUF_START + 1)
> ///< The size of the SPD manufacturing data.
> +#define SPDLP_MANUF_SIZE  (SPDLP_MANUF_END - SPDLP_MANUF_START +
> 1) ///< The size of the SPD manufacturing data
> +
> +typedef union {
> +  struct {
> +    UINT8  BytesUsed                           :  4; ///< Bits 3:0
> +    UINT8  BytesTotal                          :  3; ///< Bits 6:4
> +    UINT8  CrcCoverage                         :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_DEVICE_DESCRIPTION_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Minor                               :  4; ///< Bits 3:0
> +    UINT8  Major                               :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_REVISION_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Type                                :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_DRAM_DEVICE_TYPE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  ModuleType                          :  4; ///< Bits 3:0
> +    UINT8                                      :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MODULE_TYPE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Density                             :  4; ///< Bits 3:0
> +    UINT8  BankAddress                         :  3; ///< Bits 6:4
> +    UINT8                                      :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_SDRAM_DENSITY_BANKS_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  ColumnAddress                       :  3; ///< Bits 2:0
> +    UINT8  RowAddress                          :  3; ///< Bits 5:3
> +    UINT8                                      :  2; ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD_SDRAM_ADDRESSING_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  OperationAt1_50                     :  1; ///< Bits 0:0
> +    UINT8  OperationAt1_35                     :  1; ///< Bits 1:1
> +    UINT8  OperationAt1_25                     :  1; ///< Bits 2:2
> +    UINT8                                      :  5; ///< Bits 7:3
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MODULE_NOMINAL_VOLTAGE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  SdramDeviceWidth                    :  3; ///< Bits 2:0
> +    UINT8  RankCount                           :  3; ///< Bits 5:3
> +    UINT8                                      :  2; ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MODULE_ORGANIZATION_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  PrimaryBusWidth                     :  3; ///< Bits 2:0
> +    UINT8  BusWidthExtension                   :  2; ///< Bits 4:3
> +    UINT8                                      :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Divisor                             :  4; ///< Bits 3:0
> +    UINT8  Dividend                            :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_FINE_TIMEBASE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Dividend                            :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Divisor                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT;
> +
> +typedef struct {
> +  SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT Dividend; ///< Medium
> Timebase (MTB) Dividend
> +  SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT  Divisor;  ///< Medium
> Timebase (MTB) Divisor
> +} SPD_MEDIUM_TIMEBASE;
> +
> +typedef union {
> +  struct {
> +    UINT8  tCKmin                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TCK_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT16 CL4                                 :  1; ///< Bits 0:0
> +    UINT16 CL5                                 :  1; ///< Bits 1:1
> +    UINT16 CL6                                 :  1; ///< Bits 2:2
> +    UINT16 CL7                                 :  1; ///< Bits 3:3
> +    UINT16 CL8                                 :  1; ///< Bits 4:4
> +    UINT16 CL9                                 :  1; ///< Bits 5:5
> +    UINT16 CL10                                :  1; ///< Bits 6:6
> +    UINT16 CL11                                :  1; ///< Bits 7:7
> +    UINT16 CL12                                :  1; ///< Bits 8:8
> +    UINT16 CL13                                :  1; ///< Bits 9:9
> +    UINT16 CL14                                :  1; ///< Bits 10:10
> +    UINT16 CL15                                :  1; ///< Bits 11:11
> +    UINT16 CL16                                :  1; ///< Bits 12:12
> +    UINT16 CL17                                :  1; ///< Bits 13:13
> +    UINT16 CL18                                :  1; ///< Bits 14:14
> +    UINT16                                     :  1; ///< Bits 15:15
> +  } Bits;
> +  UINT16 Data;
> +  UINT8  Data8[2];
> +} SPD_CAS_LATENCIES_SUPPORTED_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tAAmin                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TAA_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tWRmin                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TWR_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRCDmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRCD_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRRDmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRRD_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRPmin                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRP_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRPab                               :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRP_AB_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tRPabFine                            :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TRP_AB_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRPpb                               :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRP_PB_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tRPpbFine                            :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TRP_PB_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT16  tRFCab                             :  16; ///< Bits 15:0
> +  } Bits;
> +  UINT16 Data;
> +  UINT8  Data8[2];
> +} SPD_TRFC_AB_MTB_STRUCT;
> +
> +typedef union {
> +struct {
> +    UINT16  tRFCpb                             :  16; ///< Bits 15:0
> +  } Bits;
> +  UINT16 Data;
> +  UINT8  Data8[2];
> +} SPD_TRFC_PB_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRASminUpper                        :  4; ///< Bits 3:0
> +    UINT8  tRCminUpper                         :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRAS_TRC_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRASmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRAS_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRCmin                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRC_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT16 tRFCmin                             :  16; ///< Bits 15:0
> +  } Bits;
> +  UINT16 Data;
> +  UINT8  Data8[2];
> +} SPD_TRFC_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tWTRmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TWTR_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRTPmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRTP_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tFAWminUpper                        :  4; ///< Bits 3:0
> +    UINT8                                      :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TFAW_MIN_MTB_UPPER_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tFAWmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TFAW_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tCWLmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TCWL_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  NMode                               :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_SYSTEM_COMMAND_RATE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT16 tREFImin                            :  16; ///< Bits 15:0
> +  } Bits;
> +  UINT16 Data;
> +  UINT8  Data8[2];
> +} SPD_TREFI_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  RZQ6                                :  1; ///< Bits 0:0
> +    UINT8  RZQ7                                :  1; ///< Bits 1:1
> +    UINT8                                      :  5; ///< Bits 6:2
> +    UINT8  DllOff                              :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_SDRAM_OPTIONAL_FEATURES_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  ExtendedTemperatureRange            :  1; ///< Bits 0:0
> +    UINT8  ExtendedTemperatureRefreshRate      :  1; ///< Bits 1:1
> +    UINT8  AutoSelfRefresh                     :  1; ///< Bits 2:2
> +    UINT8  OnDieThermalSensor                  :  1; ///< Bits 3:3
> +    UINT8                                      :  3; ///< Bits 6:4
> +    UINT8  PartialArraySelfRefresh             :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_SDRAM_THERMAL_REFRESH_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  ThermalSensorAccuracy               :  7; ///< Bits 6:0
> +    UINT8  ThermalSensorPresence               :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MODULE_THERMAL_SENSOR_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  NonStandardDeviceDescription        :  7; ///< Bits 6:0
> +    UINT8  SdramDeviceType                     :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_SDRAM_DEVICE_TYPE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8                                      :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_AUTO_SELF_REFRESH_PERF_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tCKminFine                           :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TCK_MIN_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tAAminFine                           :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TAA_MIN_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tRCDminFine                          :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TRCD_MIN_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tRPminFine                           :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TRP_MIN_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tRCminFine                           :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TRC_MIN_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tMACencoding                        :  4; ///< Bits 3:0
> +    UINT8  tMAWencoding                        :  2; ///< Bits 5:4
> +    UINT8  Reserved                            :  2; ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD_PTRR_SUPPORT_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tRRDminFine                          :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TRRD_MIN_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD_UNBUF_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> +  struct {
> +    UINT8  FrontThickness                      :  4; ///< Bits 3:0
> +    UINT8  BackThickness                       :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_UNBUF_MODULE_NOMINAL_THICKNESS;
> +
> +typedef union {
> +  struct {
> +    UINT8  Card                                :  5; ///< Bits 4:0
> +    UINT8  Revision                            :  2; ///< Bits 6:5
> +    UINT8  Extension                           :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_UNBUF_REFERENCE_RAW_CARD;
> +
> +typedef union {
> +  struct {
> +    UINT8  MappingRank1                        :  1; ///< Bits 0:0
> +    UINT8                                      :  7; ///< Bits 7:1
> +  } Bits;
> +  UINT8  Data;
> +} SPD_UNBUF_ADDRESS_MAPPING;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8                                      :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD_RDIMM_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> +  struct {
> +    UINT8  FrontThickness                      :  4; ///< Bits 3:0
> +    UINT8  BackThickness                       :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_RDIMM_MODULE_NOMINAL_THICKNESS;
> +
> +typedef union {
> +  struct {
> +    UINT8  Card                                :  5; ///< Bits 4:0
> +    UINT8  Revision                            :  2; ///< Bits 6:5
> +    UINT8  Extension                           :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_RDIMM_REFERENCE_RAW_CARD;
> +
> +typedef union {
> +  struct {
> +    UINT8  RegisterCount                       :  2; ///< Bits 1:0
> +    UINT8  DramRowCount                        :  2; ///< Bits 3:2
> +    UINT8                                      :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_RDIMM_MODULE_ATTRIBUTES;
> +
> +typedef union {
> +  struct {
> +    UINT16 ContinuationCount                   :  7; ///< Bits 6:0
> +    UINT16 ContinuationParity                  :  1; ///< Bits 7:7
> +    UINT16 LastNonZeroByte                     :  8; ///< Bits 15:8
> +  } Bits;
> +  UINT16 Data;
> +  UINT8  Data8[2];
> +} SPD_MANUFACTURER_ID_CODE;
> +
> +typedef struct {
> +  UINT8  Year;                                 ///< Year represented in BCD (00h =
> 2000)
> +  UINT8  Week;                                 ///< Year represented in BCD (47h =
> week 47)
> +} SPD_MANUFACTURING_DATE;
> +
> +typedef union {
> +  UINT32 Data;
> +  UINT16 SerialNumber16[2];
> +  UINT8  SerialNumber8[4];
> +} SPD_MANUFACTURER_SERIAL_NUMBER;
> +
> +typedef struct {
> +  UINT8 Location;                              ///< Module Manufacturing Location
> +} SPD_MANUFACTURING_LOCATION;
> +
> +typedef struct {
> +  SPD_MANUFACTURER_ID_CODE            IdCode;                   ///< Module
> Manufacturer ID Code
> +  SPD_MANUFACTURING_LOCATION          Location;                 ///<
> Module Manufacturing Location
> +  SPD_MANUFACTURING_DATE              Date;                     ///< Module
> Manufacturing Year, in BCD (range: 2000-2255)
> +  SPD_MANUFACTURER_SERIAL_NUMBER      SerialNumber;             ///<
> Module Serial Number
> +} SPD_UNIQUE_MODULE_ID;
> +
> +typedef union {
> +  UINT16 Crc[1];
> +  UINT8  Data8[2];
> +} SPD_CYCLIC_REDUNDANCY_CODE;
> +
> +typedef union {
> +  struct {
> +    UINT8  ProfileEnable1                :  1;                     ///< Bits 0:0
> +    UINT8  ProfileEnable2                :  1;                     ///< Bits 1:1
> +    UINT8  ProfileConfig1                :  2;                     ///< Bits 3:2
> +    UINT8  ProfileConfig2                :  2;                     ///< Bits 5:4
> +    UINT8                                :  2;                     ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD_XMP_ORG_CONFIG;
> +
> +typedef struct {
> +  UINT16                              XmpId;                    ///< 176-177 XMP
> Identification String
> +  SPD_XMP_ORG_CONFIG                  XmpOrgConf;               ///< 178 XMP
> Organization & Configuration
> +  SPD_REVISION_STRUCT                 XmpRevision;              ///< 179 XMP
> Revision
> +  SPD_MEDIUM_TIMEBASE
> MediumTimeBase[MAX_XMP_PROFILES]; ///< 180-183 Medium Timebase
> (MTB)
> +  SPD_FINE_TIMEBASE_STRUCT            FineTimeBase;             ///< 184
> Fine Timebase (FTB) Dividend / Divisor
> +} SPD_EXTREME_MEMORY_PROFILE_HEADER;
> +
> +typedef union {
> +  struct {
> +    UINT8  Decimal : 5;
> +    UINT8  Integer : 2;
> +    UINT8          : 1;
> +  } Bits;
> +  UINT8 Data;
> +} SPD_VDD_VOLTAGE_LEVEL_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Decimal : 7;
> +    UINT8  Integer : 1;
> +  } Bits;
> +  UINT8 Data;
> +} SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0;
> +
> +typedef union {
> +  struct {
> +    UINT8  Fine                                :  2; ///< Bits 1:0
> +    UINT8  Medium                              :  2; ///< Bits 3:2
> +    UINT8                                      :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_TIMEBASE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT32 CL7                                 :  1; ///< Bits 0:0
> +    UINT32 CL8                                 :  1; ///< Bits 1:1
> +    UINT32 CL9                                 :  1; ///< Bits 2:2
> +    UINT32 CL10                                :  1; ///< Bits 3:3
> +    UINT32 CL11                                :  1; ///< Bits 4:4
> +    UINT32 CL12                                :  1; ///< Bits 5:5
> +    UINT32 CL13                                :  1; ///< Bits 6:6
> +    UINT32 CL14                                :  1; ///< Bits 7:7
> +    UINT32 CL15                                :  1; ///< Bits 8:8
> +    UINT32 CL16                                :  1; ///< Bits 9:9
> +    UINT32 CL17                                :  1; ///< Bits 10:10
> +    UINT32 CL18                                :  1; ///< Bits 11:11
> +    UINT32 CL19                                :  1; ///< Bits 12:12
> +    UINT32 CL20                                :  1; ///< Bits 13:13
> +    UINT32 CL21                                :  1; ///< Bits 14:14
> +    UINT32 CL22                                :  1; ///< Bits 15:15
> +    UINT32 CL23                                :  1; ///< Bits 16:16
> +    UINT32 CL24                                :  1; ///< Bits 17:17
> +    UINT32                                     :  14; ///< Bits 31:18
> +  } Bits;
> +  UINT32 Data;
> +  UINT16 Data16[2];
> +  UINT8  Data8[4];
> +} SPD4_CAS_LATENCIES_SUPPORTED_STRUCT;
> +
> +typedef struct {
> +  SPD_VDD_VOLTAGE_LEVEL_STRUCT        Vdd;                      ///< 185, 220
> XMP Module VDD Voltage Level
> +  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 186, 221
> XMP SDRAM Minimum Cycle Time (tCKmin)
> +  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 187, 222
> XMP Minimum CAS Latency Time (tAAmin)
> +  SPD_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///<
> 188-189, 223-224 XMP CAS Latencies Supported, Least Significant Byte
> +  SPD_TCWL_MIN_MTB_STRUCT             tCWLmin;                  ///< 190,
> 225 XMP Minimum CAS Write Latency Time (tCWLmin)
> +  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 191, 226
> XMP Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 192,
> 227 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TWR_MIN_MTB_STRUCT              tWRmin;                   ///< 193,
> 228 XMP Minimum Write Recovery Time (tWRmin)
> +  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///<
> 194, 229 XMP Upper Nibbles for tRAS and tRC
> +  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 195, 230
> XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
> +  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 196, 231
> XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant
> Byte
> +  SPD_TREFI_MIN_MTB_STRUCT            tREFImin;                 ///< 197-198,
> 232-233 XMP Maximum tREFI Time (Average Periodic Refresh Interval), Least
> Significant Byte
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFCmin;                  ///< 199-200,
> 234-235 XMP Minimum Refresh Recovery Delay Time (tRFCmin), Least
> Significant Byte
> +  SPD_TRTP_MIN_MTB_STRUCT             tRTPmin;                  ///< 201, 236
> XMP Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
> +  SPD_TRRD_MIN_MTB_STRUCT             tRRDmin;                  ///< 202,
> 237 XMP Minimum Row Active to Row Active Delay Time (tRRDmin)
> +  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///<
> 203, 238 XMP Upper Nibble for tFAW
> +  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 204,
> 239 XMP Minimum Four Activate Window Delay Time (tFAWmin)
> +  SPD_TWTR_MIN_MTB_STRUCT             tWTRmin;                  ///< 205,
> 240 XMP Minimum Internal Write to Read Command Delay Time (tWTRmin)
> +  UINT8                               Reserved1[207 - 206 + 1]; ///< 206-207, 241-242
> XMP Reserved
> +  SPD_SYSTEM_COMMAND_RATE_STRUCT      SystemCmdRate;            ///<
> 208, 243 XMP System ADD/CMD Rate (1N or 2N mode)
> +  SPD_AUTO_SELF_REFRESH_PERF_STRUCT   AsrPerf;                  ///< 209,
> 244 XMP SDRAM Auto Self Refresh Performance (Sub 1x Refresh and IDD6
> impact)
> +  UINT8                               VoltageLevel;             ///< 210, 245 XMP
> Memory Controller Voltage Level
> +  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 211, 246
> XMP Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
> +  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 212, 247
> XMP Fine Offset for Minimum CAS Latency Time (tAAmin)
> +  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 213, 248
> XMP Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 214,
> 249 XMP Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 215, 250
> XMP Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
> +  UINT8                               Reserved2[218 - 216 + 1]; ///< 216-218, 251-253
> XMP Reserved
> +  UINT8                               VendorPersonality;        ///< 219, 254 XMP
> Vendor Personality
> +} SPD_EXTREME_MEMORY_PROFILE_DATA;
> +
> +typedef struct {
> +  SPD_EXTREME_MEMORY_PROFILE_HEADER   Header;                   ///<
> 176-184 XMP header
> +  SPD_EXTREME_MEMORY_PROFILE_DATA     Data[MAX_XMP_PROFILES];
> ///< 185-254 XMP profiles
> +} SPD_EXTREME_MEMORY_PROFILE;
> +
> +typedef struct {
> +  UINT16                              XmpId;                        ///< 384-385 XMP
> Identification String
> +  SPD_XMP_ORG_CONFIG                  XmpOrgConf;                   ///< 386
> XMP Organization & Configuration
> +  SPD_REVISION_STRUCT                 XmpRevision;                  ///< 387
> XMP Revision
> +  SPD4_TIMEBASE_STRUCT                TimeBase[MAX_XMP_PROFILES];
> ///< 388-389 Medium and Fine Timebase
> +  UINT8                               Reserved[392 - 390 + 1];     ///< 390-392
> Reserved
> +} SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0;
> +
> +typedef struct {
> +  SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0    Vdd;                      ///< 393,
> 440 XMP Module VDD Voltage Level
> +  UINT8                               Reserved1[395 - 394 + 1]; ///< 394-395, 441-442
> XMP Reserved
> +  SPD_TCK_MIN_MTB_STRUCT              tCKAVGmin;                ///< 396,
> 443 XMP SDRAM Minimum Cycle Time (tCKAVGmin)
> +  SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies;             ///<
> 397-400, 444-447 XMP CAS Latencies Supported
> +  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 401, 448
> XMP Minimum CAS Latency Time (tAAmin)
> +  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 402,
> 449 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 403, 450
> XMP Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///<
> 404, 451 XMP Upper Nibbles for tRAS and tRC
> +  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 405, 452
> XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
> +  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 406, 453
> XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant
> Byte
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFC1min;                 ///< 407-408,
> 454-455 XMP Minimum Refresh Recovery Delay Time (tRFC1min)
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFC2min;                 ///< 409-410,
> 456-457 XMP Minimum Refresh Recovery Delay Time (tRFC2min)
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFC4min;                 ///< 411-412,
> 458-459 XMP Minimum Refresh Recovery Delay Time (tRFC4min)
> +  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///<
> 413, 460 Upper Nibble for tFAW
> +  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 414,
> 461 Minimum Four Activate Window Delay Time (tFAWmin)
> +  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Smin;                ///< 415,
> 462 Minimum Activate to Activate Delay Time (tRRD_Smin), different bank
> group
> +  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Lmin;                ///< 416,
> 463 Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
> +  UINT8                               Reserved2[424 - 417 + 1]; ///< 417-424, 464-471
> XMP Reserved
> +  SPD_TRRD_MIN_FTB_STRUCT             tRRD_LminFine;            ///< 425,
> 472 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin),
> different bank group
> +  SPD_TRRD_MIN_FTB_STRUCT             tRRD_SminFine;            ///< 426,
> 473 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin),
> same bank group
> +  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 427, 474
> Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
> +  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 428, 475
> Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 429,
> 476 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 430, 477
> Fine Offset for Minimum CAS Latency Time (tAAmin)
> +  SPD_TCK_MIN_FTB_STRUCT              tCKAVGminFine;            ///< 431,
> 478 Fine Offset for SDRAM Maximum Cycle Time (tCKAVGmin)
> +  UINT8                               Reserved3[439 - 432 + 1]; ///< 432-439, 479-486
> XMP Reserved
> +} SPD_EXTREME_MEMORY_PROFILE_DATA_2_0;
> +
> +typedef struct {
> +  SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0      Header;
> ///< 384-392 XMP header
> +  SPD_EXTREME_MEMORY_PROFILE_DATA_2_0
> Data[MAX_XMP_PROFILES];   ///< 393-486 XMP profiles
> +} SPD_EXTREME_MEMORY_PROFILE_2_0;
> +
> +typedef struct {
> +  SPD_DEVICE_DESCRIPTION_STRUCT       Description;              ///< 0
> Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
> +  SPD_REVISION_STRUCT                 Revision;                 ///< 1   SPD
> Revision
> +  SPD_DRAM_DEVICE_TYPE_STRUCT         DramDeviceType;           ///< 2
> DRAM Device Type
> +  SPD_MODULE_TYPE_STRUCT              ModuleType;               ///< 3
> Module Type
> +  SPD_SDRAM_DENSITY_BANKS_STRUCT      SdramDensityAndBanks;
> ///< 4   SDRAM Density and Banks
> +  SPD_SDRAM_ADDRESSING_STRUCT         SdramAddressing;          ///< 5
> SDRAM Addressing
> +  SPD_MODULE_NOMINAL_VOLTAGE_STRUCT   ModuleNominalVoltage;
> ///< 6   Module Nominal Voltage, VDD
> +  SPD_MODULE_ORGANIZATION_STRUCT      ModuleOrganization;       ///<
> 7   Module Organization
> +  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT  ModuleMemoryBusWidth;
> ///< 8   Module Memory Bus Width
> +  SPD_FINE_TIMEBASE_STRUCT            FineTimebase;             ///< 9   Fine
> Timebase (FTB) Dividend / Divisor
> +  SPD_MEDIUM_TIMEBASE                 MediumTimebase;           ///< 10-11
> Medium Timebase (MTB) Dividend
> +  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 12
> SDRAM Minimum Cycle Time (tCKmin)
> +  UINT8                               Reserved1;                ///< 13  Reserved
> +  SPD_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///<
> 14-15 CAS Latencies Supported
> +  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 16
> Minimum CAS Latency Time (tAAmin)
> +  SPD_TWR_MIN_MTB_STRUCT              tWRmin;                   ///< 17
> Minimum Write Recovery Time (tWRmin)
> +  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 18
> Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TRRD_MIN_MTB_STRUCT             tRRDmin;                  ///< 19
> Minimum Row Active to Row Active Delay Time (tRRDmin)
> +  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 20
> Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///<
> 21  Upper Nibbles for tRAS and tRC
> +  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 22
> Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
> +  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 23
> Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFCmin;                  ///< 24-25
> Minimum Refresh Recovery Delay Time (tRFCmin)
> +  SPD_TWTR_MIN_MTB_STRUCT             tWTRmin;                  ///< 26
> Minimum Internal Write to Read Command Delay Time (tWTRmin)
> +  SPD_TRTP_MIN_MTB_STRUCT             tRTPmin;                  ///< 27
> Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
> +  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///<
> 28  Upper Nibble for tFAW
> +  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 29
> Minimum Four Activate Window Delay Time (tFAWmin)
> +  SPD_SDRAM_OPTIONAL_FEATURES_STRUCT  SdramOptionalFeatures;
> ///< 30  SDRAM Optional Features
> +  SPD_SDRAM_THERMAL_REFRESH_STRUCT    ThermalAndRefreshOptions;
> ///< 31  SDRAMThermalAndRefreshOptions
> +  SPD_MODULE_THERMAL_SENSOR_STRUCT    ModuleThermalSensor;
> ///< 32  Module Thermal Sensor
> +  SPD_SDRAM_DEVICE_TYPE_STRUCT        SdramDeviceType;          ///< 33
> SDRAM Device Type
> +  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 34  Fine
> Offset for SDRAM Minimum Cycle Time (tCKmin)
> +  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 35  Fine
> Offset for Minimum CAS Latency Time (tAAmin)
> +  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 36
> Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 37
> Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 38  Fine
> Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
> +  SPD_TRP_AB_MTB_STRUCT               tRPab;                    ///< 39
> Minimum Row Precharge Delay Time for all banks (tRPab)
> +  SPD_TRP_AB_FTB_STRUCT               tRPabFine;                ///< 40  Fine
> Offset for Minimum Row Precharge Delay Time for all banks (tRPab)
> +  SPD_PTRR_SUPPORT_STRUCT             pTRRsupport;              ///< 41 -
> pTRR support with TMAC value
> +  UINT8                               Reserved3[59 - 42 + 1];   ///< 42 - 59 Reserved
> +} SPD_GENERAL_SECTION;
> +
> +typedef struct {
> +  SPD_UNBUF_MODULE_NOMINAL_HEIGHT     ModuleNominalHeight;
> ///< 60 Module Nominal Height
> +  SPD_UNBUF_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;
> ///< 61 Module Maximum Thickness
> +  SPD_UNBUF_REFERENCE_RAW_CARD        ReferenceRawCardUsed;
> ///< 62 Reference Raw Card Used
> +  SPD_UNBUF_ADDRESS_MAPPING           AddressMappingEdgeConn;
> ///< 63 Address Mapping from Edge Connector to DRAM
> +  UINT8                               Reserved[116 - 64 + 1];   ///< 64-116 Reserved
> +} SPD_MODULE_UNBUFFERED;
> +
> +typedef struct {
> +  SPD_RDIMM_MODULE_NOMINAL_HEIGHT     ModuleNominalHeight;
> ///< 60 Module Nominal Height
> +  SPD_RDIMM_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;
> ///< 61 Module Maximum Thickness
> +  SPD_RDIMM_REFERENCE_RAW_CARD        ReferenceRawCardUsed;
> ///< 62 Reference Raw Card Used
> +  SPD_RDIMM_MODULE_ATTRIBUTES         DimmModuleAttributes;     ///<
> 63 DIMM Module Attributes
> +  UINT8                               Reserved[116 - 64 + 1];   ///< 64-116 Reserved
> +} SPD_MODULE_REGISTERED;
> +
> +typedef union {
> +  SPD_MODULE_UNBUFFERED               Unbuffered;
> +  SPD_MODULE_REGISTERED               Registered;
> +} SPD_MODULE_SPECIFIC;
> +
> +typedef struct {
> +  UINT8                          ModulePartNumber[145 - 128 + 1];        ///<
> 128-145 Module Part Number
> +} SPD_MODULE_PART_NUMBER;
> +
> +typedef struct {
> +  UINT8                          ModuleRevisionCode[147 - 146 + 1];      ///<
> 146-147 Module Revision Code
> +} SPD_MODULE_REVISION_CODE;
> +
> +typedef struct {
> +  UINT8                          ManufactureSpecificData[175 - 150 + 1]; ///<
> 150-175 Manufacturer's Specific Data
> +} SPD_MANUFACTURE_SPECIFIC;
> +
> +///
> +/// DDR3 Serial Presence Detect structure
> +///
> +typedef struct {
> +  SPD_GENERAL_SECTION         General;                                ///< 0-59
> General Section
> +  SPD_MODULE_SPECIFIC         Module;                                 ///< 60-116
> Module-Specific Section
> +  SPD_UNIQUE_MODULE_ID        ModuleId;                               ///<
> 117-125 Unique Module ID
> +  SPD_CYCLIC_REDUNDANCY_CODE  Crc;                                    ///<
> 126-127 Cyclical Redundancy Code (CRC)
> +  SPD_MODULE_PART_NUMBER      ModulePartNumber;
> ///< 128-145 Module Part Number
> +  SPD_MODULE_REVISION_CODE    ModuleRevisionCode;
> ///< 146-147 Module Revision Code
> +  SPD_MANUFACTURER_ID_CODE    DramIdCode;                             ///<
> 148-149 Dram Manufacturer ID Code
> +  SPD_MANUFACTURE_SPECIFIC    ManufactureSpecificData;                ///<
> 150-175 Manufacturer's Specific Data
> +  SPD_EXTREME_MEMORY_PROFILE  Xmp;                                    ///<
> 176-254 Intel(r) Extreme Memory Profile support
> +  UINT8                       Reserved;                               ///< 255 Reserved
> +} MrcSpdDdr3;
> +
> +typedef union {
> +  struct {
> +    UINT8  Density                             :  4; ///< Bits 3:0
> +    UINT8  BankAddress                         :  2; ///< Bits 5:4
> +    UINT8  BankGroup                           :  2; ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_SDRAM_DENSITY_BANKS_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  SignalLoading                       :  2; ///< Bits 1:0
> +    UINT8                                      :  2; ///< Bits 3:2
> +    UINT8  DieCount                            :  3; ///< Bits 6:4
> +    UINT8  SdramDeviceType                     :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_SDRAM_DEVICE_TYPE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  OperationAt1_20                     :  1; ///< Bits 0:0
> +    UINT8  EndurantAt1_20                      :  1; ///< Bits 1:1
> +    UINT8                                      :  6; ///< Bits 7:2
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tCKmax                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_TCK_MAX_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tCKmaxFine                          :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD4_TCK_MAX_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8                                      :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_SDRAM_THERMAL_REFRESH_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_UNBUF_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_RDIMM_MODULE_NOMINAL_HEIGHT;
> +
> +typedef struct {
> +  SPD_DEVICE_DESCRIPTION_STRUCT       Description;              ///< 0
> Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
> +  SPD_REVISION_STRUCT                 Revision;                 ///< 1       SPD
> Revision
> +  SPD_DRAM_DEVICE_TYPE_STRUCT         DramDeviceType;           ///< 2
> DRAM Device Type
> +  SPD_MODULE_TYPE_STRUCT              ModuleType;               ///< 3
> Module Type
> +  SPD4_SDRAM_DENSITY_BANKS_STRUCT     SdramDensityAndBanks;
> ///< 4       SDRAM Density and Banks
> +  SPD_SDRAM_ADDRESSING_STRUCT         SdramAddressing;          ///< 5
> SDRAM Addressing
> +  SPD4_SDRAM_DEVICE_TYPE_STRUCT       SdramDeviceType;          ///< 6
> SDRAM Device Type
> +  SPD_PTRR_SUPPORT_STRUCT             pTRRsupport;              ///< 7
> pTRR support with TMAC value
> +  SPD4_SDRAM_THERMAL_REFRESH_STRUCT   ThermalAndRefreshOptions;
> ///< 8       SDRAM Thermal and Refresh Options
> +  UINT8                               Reserved0[10 - 9 + 1];    ///< 9-10    Reserved
> +  SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT  ModuleNominalVoltage;
> ///< 11      Module Nominal Voltage, VDD
> +  SPD_MODULE_ORGANIZATION_STRUCT      ModuleOrganization;       ///<
> 12      Module Organization
> +  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT  ModuleMemoryBusWidth;
> ///< 13      Module Memory Bus Width
> +  SPD_MODULE_THERMAL_SENSOR_STRUCT    ModuleThermalSensor;
> ///< 14      Module Thermal Sensor
> +  UINT8                               Reserved1[16 - 15 + 1];   ///< 15-16   Reserved
> +  SPD4_TIMEBASE_STRUCT                Timebase;                 ///< 17
> Timebases
> +  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 18
> SDRAM Minimum Cycle Time (tCKmin)
> +  SPD4_TCK_MAX_MTB_STRUCT             tCKmax;                   ///< 19
> SDRAM Maximum Cycle Time (tCKmax)
> +  SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies;             ///<
> 20-23   CAS Latencies Supported
> +  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 24
> Minimum CAS Latency Time (tAAmin)
> +  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 25
> Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 26
> Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///<
> 27      Upper Nibbles for tRAS and tRC
> +  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 28
> Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
> +  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 29
> Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFC1min;                 ///< 30-31
> Minimum Refresh Recovery Delay Time (tRFC1min)
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFC2min;                 ///< 32-33
> Minimum Refresh Recovery Delay Time (tRFC2min)
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFC4min;                 ///< 34-35
> Minimum Refresh Recovery Delay Time (tRFC4min)
> +  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///<
> 36      Upper Nibble for tFAW
> +  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 37
> Minimum Four Activate Window Delay Time (tFAWmin)
> +  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Smin;                ///< 38
> Minimum Activate to Activate Delay Time (tRRD_Smin), different bank group
> +  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Lmin;                ///< 39
> Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
> +  UINT8                               Reserved2[117 - 40 + 1];  ///< 40-117
> Reserved
> +  SPD_TRRD_MIN_FTB_STRUCT             tRRD_LminFine;            ///< 118
> Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin),
> different bank group
> +  SPD_TRRD_MIN_FTB_STRUCT             tRRD_SminFine;            ///< 119
> Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin), same
> bank group
> +  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 120
> Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
> +  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 121
> Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 122
> Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 123
> Fine Offset for Minimum CAS Latency Time (tAAmin)
> +  SPD4_TCK_MAX_FTB_STRUCT             tCKmaxFine;               ///< 124
> Fine Offset for SDRAM Minimum Cycle Time (tCKmax)
> +  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 125
> Fine Offset for SDRAM Maximum Cycle Time (tCKmin)
> +  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 126-127
> Cyclical Redundancy Code (CRC)
> +} SPD4_BASE_SECTION;
> +
> +typedef struct {
> +  SPD4_UNBUF_MODULE_NOMINAL_HEIGHT    ModuleNominalHeight;
> ///< 128     Module Nominal Height
> +  SPD_UNBUF_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;
> ///< 129     Module Maximum Thickness
> +  SPD_UNBUF_REFERENCE_RAW_CARD        ReferenceRawCardUsed;
> ///< 130     Reference Raw Card Used
> +  SPD_UNBUF_ADDRESS_MAPPING           AddressMappingEdgeConn;
> ///< 131     Address Mapping from Edge Connector to DRAM
> +  UINT8                               Reserved[253 - 132 + 1];  ///< 132-253
> Reserved
> +  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 254-255
> Cyclical Redundancy Code (CRC)
> +} SPD4_MODULE_UNBUFFERED;
> +
> +typedef struct {
> +  SPD4_RDIMM_MODULE_NOMINAL_HEIGHT    ModuleNominalHeight;
> ///< 128     Module Nominal Height
> +  SPD_RDIMM_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;
> ///< 129     Module Maximum Thickness
> +  SPD_RDIMM_REFERENCE_RAW_CARD        ReferenceRawCardUsed;
> ///< 130     Reference Raw Card Used
> +  SPD_RDIMM_MODULE_ATTRIBUTES         DimmModuleAttributes;     ///<
> 131     DIMM Module Attributes
> +  UINT8                               Reserved[253 - 132 + 1];  ///< 253-132
> Reserved
> +  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 254-255
> Cyclical Redundancy Code (CRC)
> +} SPD4_MODULE_REGISTERED;
> +
> +typedef union {
> +  SPD4_MODULE_UNBUFFERED              Unbuffered;               ///<
> 128-255 Unbuffered Memory Module Types
> +  SPD4_MODULE_REGISTERED              Registered;               ///< 128-255
> Registered Memory Module Types
> +} SPD4_MODULE_SPECIFIC;
> +
> +typedef struct {
> +  UINT8                               ModulePartNumber[348 - 329 + 1]; ///<
> 329-348 Module Part Number
> +} SPD4_MODULE_PART_NUMBER;
> +
> +typedef struct {
> +  UINT8                               ManufactureSpecificData[381 - 353 + 1]; ///<
> 353-381 Manufacturer's Specific Data
> +} SPD4_MANUFACTURE_SPECIFIC;
> +
> +typedef UINT8                         SPD4_MODULE_REVISION_CODE;///< 349
> Module Revision Code
> +typedef UINT8                         SPD4_DRAM_STEPPING;       ///< 352
> Dram Stepping
> +
> +typedef struct {
> +  SPD_UNIQUE_MODULE_ID                ModuleId;                 ///< 320-328
> Unique Module ID
> +  SPD4_MODULE_PART_NUMBER             ModulePartNumber;         ///<
> 329-348 Module Part Number
> +  SPD4_MODULE_REVISION_CODE           ModuleRevisionCode;       ///<
> 349     Module Revision Code
> +  SPD_MANUFACTURER_ID_CODE            DramIdCode;               ///<
> 350-351 Dram Manufacturer ID Code
> +  SPD4_DRAM_STEPPING                  DramStepping;             ///< 352
> Dram Stepping
> +  SPD4_MANUFACTURE_SPECIFIC           ManufactureSpecificData;  ///<
> 353-381 Manufacturer's Specific Data
> +  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 382-383
> Cyclical Redundancy Code (CRC)
> +} SPD4_MANUFACTURING_DATA;
> +
> +typedef union {
> +  SPD_EXTREME_MEMORY_PROFILE_2_0      Xmp;                      ///<
> 384-463 Intel(r) Extreme Memory Profile support
> +  UINT8                               Reserved0[511 - 384 + 1]; ///< 384-511
> Unbuffered Memory Module Types
> +} SPD4_END_USER_SECTION;
> +
> +///
> +/// DDR4 Serial Presence Detect structure
> +///
> +typedef struct {
> +  SPD4_BASE_SECTION                   Base;                     ///< 0-127   Base
> Configuration and DRAM Parameters
> +  SPD4_MODULE_SPECIFIC                Module;                   ///< 128-255
> Module-Specific Section
> +  UINT8                               Reserved0[319 - 256 + 1]; ///< 256-319
> Reserved
> +  SPD4_MANUFACTURING_DATA             ManufactureInfo;          ///<
> 320-383 Manufacturing Information
> +  SPD4_END_USER_SECTION               EndUser;                  ///< 384-511
> End User Programmable
> +} MrcSpdDdr4;
> +
> +typedef union {
> +  struct {
> +    UINT8  Fine                                :  2; ///< Bits 1:0
> +    UINT8  Medium                              :  2; ///< Bits 3:2
> +    UINT8                                      :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_TIMEBASE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT32 CL3                                 :  1;  ///< Bits 0:0
> +    UINT32 CL6                                 :  1;  ///< Bits 1:1
> +    UINT32 CL8                                 :  1;  ///< Bits 2:2
> +    UINT32 CL9                                 :  1;  ///< Bits 3:3
> +    UINT32 CL10                                :  1;  ///< Bits 4:4
> +    UINT32 CL11                                :  1;  ///< Bits 5:5
> +    UINT32 CL12                                :  1;  ///< Bits 6:6
> +    UINT32 CL14                                :  1;  ///< Bits 7:7
> +    UINT32 CL16                                :  1;  ///< Bits 8:8
> +    UINT32                                     :  1;  ///< Bits 9:9
> +    UINT32 CL20                                :  1;  ///< Bits 10:10
> +    UINT32 CL22                                :  1;  ///< Bits 11:11
> +    UINT32 CL24                                :  1;  ///< Bits 12:12
> +    UINT32                                     :  1;  ///< Bits 13:13
> +    UINT32 CL28                                :  1;  ///< Bits 14:14
> +    UINT32                                     :  1;  ///< Bits 15:15
> +    UINT32 CL32                                :  1;  ///< Bits 16:16
> +    UINT32                                     :  1;  ///< Bits 17:17
> +    UINT32 CL36                                :  1;  ///< Bits 18:18
> +    UINT32                                     :  1;  ///< Bits 19:19
> +    UINT32 CL40                                :  1;  ///< Bits 20:20
> +    UINT32                                     :  11; ///< Bits 31:21
> +  } Bits;
> +  UINT32 Data;
> +  UINT16 Data16[2];
> +  UINT8  Data8[4];
> +} SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Density                             :  4; ///< Bits 3:0
> +    UINT8  BankAddress                         :  2; ///< Bits 5:4
> +    UINT8  BankGroup                           :  2; ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  SignalLoading                       :  2; ///< Bits 1:0
> +    UINT8  ChannelsPerDie                      :  2; ///< Bits 3:2
> +    UINT8  DieCount                            :  3; ///< Bits 6:4
> +    UINT8  SdramPackageType                    :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  OperationAt1_20                     :  1; ///< Bits 0:0
> +    UINT8  EndurantAt1_20                      :  1; ///< Bits 1:1
> +    UINT8  OperationAt1_10                     :  1; ///< Bits 2:2
> +    UINT8  EndurantAt1_10                      :  1; ///< Bits 3:3
> +    UINT8  OperationAtTBD2V                    :  1; ///< Bits 4:4
> +    UINT8  EndurantAtTBD2V                     :  1; ///< Bits 5:5
> +    UINT8                                      :  2; ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tCKmax                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_TCK_MAX_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  ReadLatencyMode                     :  2; ///< Bits 1:0
> +    UINT8  WriteLatencySet                     :  2; ///< Bits 3:2
> +    UINT8                                      :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_RW_LATENCY_OPTION_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tCKmaxFine                           :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_LPDDR_TCK_MAX_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8                                      :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_UNBUF_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_RDIMM_MODULE_NOMINAL_HEIGHT;
> +
> +typedef struct {
> +  SPD_DEVICE_DESCRIPTION_STRUCT             Description;              ///< 0
> Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
> +  SPD_REVISION_STRUCT                       Revision;                 ///< 1
> SPD Revision
> +  SPD_DRAM_DEVICE_TYPE_STRUCT               DramDeviceType;           ///<
> 2       DRAM Device Type
> +  SPD_MODULE_TYPE_STRUCT                    ModuleType;               ///< 3
> Module Type
> +  SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT      SdramDensityAndBanks;
> ///< 4       SDRAM Density and Banks
> +  SPD_SDRAM_ADDRESSING_STRUCT               SdramAddressing;
> ///< 5       SDRAM Addressing
> +  SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT       SdramPackageType;
> ///< 6       SDRAM Package Type
> +  SPD_PTRR_SUPPORT_STRUCT                   pTRRsupport;              ///< 7
> pTRR support with TMAC value - SDRAM Optional Features
> +  SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT
> ThermalAndRefreshOptions; ///< 8       SDRAM Thermal and Refresh Options
> +  UINT8                                     Reserved0[10 - 9 + 1];    ///< 9-10
> Reserved
> +  SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT
> ModuleNominalVoltage;     ///< 11      Module Nominal Voltage, VDD
> +  SPD_MODULE_ORGANIZATION_STRUCT            ModuleOrganization;
> ///< 12      Module Organization
> +  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT
> ModuleMemoryBusWidth;     ///< 13      Module Memory Bus Width
> +  SPD_MODULE_THERMAL_SENSOR_STRUCT          ModuleThermalSensor;
> ///< 14      Module Thermal Sensor
> +  UINT8                                     Reserved1[16 - 15 + 1];   ///< 15-16
> Reserved
> +  SPD_LPDDR_TIMEBASE_STRUCT                 Timebase;                 ///< 17
> Timebases
> +  SPD_TCK_MIN_MTB_STRUCT                    tCKmin;                   ///< 18
> SDRAM Minimum Cycle Time (tCKmin)
> +  SPD_LPDDR_TCK_MAX_MTB_STRUCT              tCKmax;                   ///<
> 19      SDRAM Maximum Cycle Time (tCKmax)
> +  SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;
> ///< 20-23   CAS Latencies Supported
> +  SPD_TAA_MIN_MTB_STRUCT                    tAAmin;                   ///< 24
> Minimum CAS Latency Time (tAAmin)
> +  SPD_LPDDR_RW_LATENCY_OPTION_STRUCT        LatencySetOptions;
> ///< 25      Read and Write Latency Set Options
> +  SPD_TRCD_MIN_MTB_STRUCT                   tRCDmin;                  ///< 26
> Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TRP_AB_MTB_STRUCT                     tRPab;                    ///< 27
> Minimum Row Precharge Delay Time (tRPab), all banks
> +  SPD_TRP_PB_MTB_STRUCT                     tRPpb;                    ///< 28
> Minimum Row Precharge Delay Time (tRPpb), per bank
> +  SPD_TRFC_AB_MTB_STRUCT                    tRFCab;                   ///< 29-30
> Minimum Refresh Recovery Delay Time (tRFCab), all banks
> +  SPD_TRFC_PB_MTB_STRUCT                    tRFCpb;                   ///< 31-32
> Minimum Refresh Recovery Delay Time (tRFCpb), per bank
> +  UINT8                                     Reserved2[119 - 33 + 1];  ///< 33-119
> Reserved
> +  SPD_TRP_PB_FTB_STRUCT                     tRPpbFine;                ///< 120
> Fine Offset for Minimum Row Precharge Delay Time (tRPpbFine), per bank
> +  SPD_TRP_AB_FTB_STRUCT                     tRPabFine;                ///< 121
> Fine Offset for Minimum Row Precharge Delay Time (tRPabFine), all ranks
> +  SPD_TRCD_MIN_FTB_STRUCT                   tRCDminFine;              ///<
> 122     Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TAA_MIN_FTB_STRUCT                    tAAminFine;               ///< 123
> Fine Offset for Minimum CAS Latency Time (tAAmin)
> +  SPD_LPDDR_TCK_MAX_FTB_STRUCT              tCKmaxFine;               ///<
> 124     Fine Offset for SDRAM Maximum Cycle Time (tCKmax)
> +  SPD_TCK_MIN_FTB_STRUCT                    tCKminFine;               ///< 125
> Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
> +  SPD_CYCLIC_REDUNDANCY_CODE                Crc;                      ///<
> 126-127 Cyclical Redundancy Code (CRC)
> +} SPD_LPDDR_BASE_SECTION;
> +
> +typedef union {
> +  struct {
> +    UINT8  FrontThickness                      :  4; ///< Bits 3:0
> +    UINT8  BackThickness                       :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8 Data;
> +} SPD_LPDDR_MODULE_MAXIMUM_THICKNESS;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Card                                :  5; ///< Bits 4:0
> +    UINT8  Revision                            :  2; ///< Bits 6:5
> +    UINT8  Extension                           :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_REFERENCE_RAW_CARD;
> +
> +typedef struct {
> +  SPD_LPDDR_MODULE_NOMINAL_HEIGHT         ModuleNominalHeight;
> ///< 128     Module Nominal Height
> +  SPD_LPDDR_MODULE_MAXIMUM_THICKNESS
> ModuleMaximumThickness;   ///< 129     Module Maximum Thickness
> +  SPD_LPDDR_REFERENCE_RAW_CARD            ReferenceRawCardUsed;
> ///< 130     Reference Raw Card Used
> +  UINT8                                   Reserved[253 - 131 + 1];  ///< 131-253
> Reserved
> +  SPD_CYCLIC_REDUNDANCY_CODE              Crc;                      ///<
> 254-255 Cyclical Redundancy Code (CRC)
> +} SPD_LPDDR_MODULE_LPDIMM;
> +
> +typedef union {
> +  SPD_LPDDR_MODULE_LPDIMM                 LpDimm;                   ///<
> 128-255 Unbuffered Memory Module Types
> +} SPD_LPDDR_MODULE_SPECIFIC;
> +
> +typedef struct {
> +  UINT8                                   ModulePartNumber[348 - 329 + 1]; ///<
> 329-348 Module Part Number
> +} SPD_LPDDR_MODULE_PART_NUMBER;
> +
> +typedef struct {
> +  UINT8                                   ManufactureSpecificData[381 - 353 + 1];
> ///< 353-381 Manufacturer's Specific Data
> +} SPD_LPDDR_MANUFACTURE_SPECIFIC;
> +
> +typedef UINT8
> SPD_LPDDR_MODULE_REVISION_CODE;///< 349     Module Revision Code
> +typedef UINT8                             SPD_LPDDR_DRAM_STEPPING;       ///<
> 352     Dram Stepping
> +
> +typedef struct {
> +  SPD_UNIQUE_MODULE_ID                    ModuleId;                 ///<
> 320-328 Unique Module ID
> +  SPD_LPDDR_MODULE_PART_NUMBER            ModulePartNumber;
> ///< 329-348 Module Part Number
> +  SPD_LPDDR_MODULE_REVISION_CODE          ModuleRevisionCode;
> ///< 349     Module Revision Code
> +  SPD_MANUFACTURER_ID_CODE                DramIdCode;               ///<
> 350-351 Dram Manufacturer ID Code
> +  SPD_LPDDR_DRAM_STEPPING                 DramStepping;             ///< 352
> Dram Stepping
> +  SPD_LPDDR_MANUFACTURE_SPECIFIC          ManufactureSpecificData;
> ///< 353-381 Manufacturer's Specific Data
> +  UINT8                                   Reserved[383 - 382 + 1];  ///< 382-383
> Reserved
> +} SPD_LPDDR_MANUFACTURING_DATA;
> +
> +typedef union {
> +  UINT8                                   Reserved0[511 - 384 + 1]; ///< 384-511 End
> User Programmable
> +} SPD_LPDDR_END_USER_SECTION;
> +
> +typedef struct {
> +  SPD_LPDDR_BASE_SECTION                  Base;                     ///< 0-127
> Base Configuration and DRAM Parameters
> +  SPD_LPDDR_MODULE_SPECIFIC               Module;                   ///<
> 128-255 Module-Specific Section
> +  UINT8                                   Reserved0[319 - 256 + 1]; ///< 256-319
> Reserved
> +  SPD_LPDDR_MANUFACTURING_DATA            ManufactureInfo;          ///<
> 320-383 Manufacturing Information
> +  SPD_LPDDR_END_USER_SECTION              EndUser;                  ///<
> 384-511 End User Programmable
> +} MrcSpdLpDdr;
> +
> +typedef union {
> +  MrcSpdDdr3  Ddr3;
> +  MrcSpdDdr4  Ddr4;
> +  MrcSpdLpDdr Lpddr;
> +} MrcSpd;
> +
> +#ifndef MAX_SPD_SAVE
> +#define MAX_SPD_SAVE (sizeof (SPD_MANUFACTURER_ID_CODE) + \
> +                      sizeof (SPD_MANUFACTURING_LOCATION) + \
> +                      sizeof (SPD_MANUFACTURING_DATE) + \
> +                      sizeof (SPD_MANUFACTURER_SERIAL_NUMBER) + \
> +                      sizeof (SPD4_MODULE_PART_NUMBER))
> +#endif
> +
> +#pragma pack (pop)
> +#endif // _MrcSpdData_h_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcTypes.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcTypes.h
> new file mode 100644
> index 0000000000..b267315f36
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcTypes.h
> @@ -0,0 +1,237 @@
> +/** @file
> +  Include the the general MRC types
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MRC_TYPES_H
> +#define _MRC_TYPES_H
> +
> +#ifdef MRC_MINIBIOS_BUILD
> +#include "MrcMiniBiosEfiDefs.h"
> +#else
> +#include <Base.h>
> +#endif // MRC_MINIBIOS_BUILD
> +
> +//
> +// Data Types
> +//
> +typedef union {
> +  struct {
> +    UINT32  Low;
> +    UINT32  High;
> +  } Data32;
> +  UINT64 Data;
> +} UINT64_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT32  Low;
> +    INT32  High;
> +  } Data32;
> +  INT64 Data;
> +} INT64_STRUCT;
> +
> +typedef union {
> +  VOID    *Ptr;
> +  UINTN   DataN;
> +  UINT64  Data64;
> +} POINTER_STRUCT;
> +
> +#define UNSUPPORT 0
> +#define SUPPORT   1
> +
> +typedef enum {
> +  mrcSuccess,
> +  mrcFail,
> +  mrcWrongInputParameter,
> +  mrcCasError,
> +  mrcTimingError,
> +  mrcSenseAmpErr,
> +  mrcReadMPRErr,
> +  mrcReadLevelingError,
> +  mrcWriteLevelingError,
> +  mrcDataTimeCentering1DErr,
> +  mrcWriteVoltage2DError,
> +  mrcReadVoltage2DError,
> +  mrcMiscTrainingError,
> +  mrcWrError,
> +  mrcDimmNotSupport,
> +  mrcChannelNotSupport,
> +  mrcPiSettingError,
> +  mrcDqsPiSettingError,
> +  mrcDeviceBusy,
> +  mrcFrequencyChange,
> +  mrcReutSequenceError,
> +  mrcCrcError,
> +  mrcFrequencyError,
> +  mrcDimmNotExist,
> +  mrcColdBootRequired,
> +  mrcRoundTripLatencyError,
> +  mrcMixedDimmSystem,
> +  mrcAliasDetected,
> +  mrcRetrain,
> +  mrcRtpError,
> +  mrcUnsupportedTechnology,
> +  mrcMappingError,
> +  mrcSocketNotSupported,
> +  mrcControllerNotSupported,
> +  mrcRankNotSupported,
> +  mrcTurnAroundTripError
> +} MrcStatus;
> +
> +//
> +// general  macros
> +//
> +#ifndef MIN
> +#define MIN(a, b) (((a) < (b)) ? (a) : (b))
> +#endif
> +
> +#ifndef MAX
> +#define MAX(a, b) (((a) > (b)) ? (a) : (b))
> +#endif
> +
> +#ifndef ABS
> +#define ABS(x)  (((x) < 0) ? (-(x)) : (x))
> +#endif
> +
> +//
> +// Make sure x is inside the range of [a..b]
> +//
> +#ifndef RANGE
> +#define RANGE(x, a, b) (MIN ((b), MAX ((x), (a))))
> +#endif
> +
> +#ifndef DIVIDECEIL
> +#define DIVIDECEIL(a, b)   (((a) + (b) - 1) / (b))
> +#endif
> +
> +#ifndef DIVIDEROUND
> +#define DIVIDEROUND(a, b)  (((a) * (b) > 0) ? ((a) + (b) / 2) / (b) : ((a) - (b) / 2)
> / (b))
> +#endif
> +
> +#ifndef DIVIDEFLOOR
> +#define DIVIDEFLOOR(a, b)  ((a) / (b))
> +#endif
> +
> +//
> +// Number of elements in a 1D array
> +//
> +#ifndef ARRAY_COUNT
> +#define ARRAY_COUNT(a) (sizeof (a) / sizeof (a[0]))
> +#endif
> +
> +//
> +//  use for ignore parames
> +//
> +// #define MRC_IGNORE_PARAM(x) ((x) = (x))
> +//
> +#if _MSC_EXTENSIONS
> +//
> +// Disable warning that make it impossible to compile at /W4
> +// This only works for Microsoft* tools
> +//
> +//
> +// Disabling bitfield type checking warnings.
> +//
> +#pragma warning (disable : 4214)
> +//
> +// Unreferenced formal parameter - We are object oriented, so we pass
> parameters even
> +//  if we don't need them.
> +//
> +#pragma warning (disable : 4100)
> +//
> +// ASSERT(FALSE) or while (TRUE) are legal constructs so supress this warning
> +//
> +#pragma warning(disable : 4127)
> +//
> +// The given function was selected for inline expansion, but the compiler did
> not perform the inlining.
> +//
> +#pragma warning(disable : 4710)
> +
> +#endif // _MSC_EXTENSIONS
> +#define MRC_BIT0          0x00000001
> +#define MRC_BIT1          0x00000002
> +#define MRC_BIT2          0x00000004
> +#define MRC_BIT3          0x00000008
> +#define MRC_BIT4          0x00000010
> +#define MRC_BIT5          0x00000020
> +#define MRC_BIT6          0x00000040
> +#define MRC_BIT7          0x00000080
> +#define MRC_BIT8          0x00000100
> +#define MRC_BIT9          0x00000200
> +#define MRC_BIT10         0x00000400
> +#define MRC_BIT11         0x00000800
> +#define MRC_BIT12         0x00001000
> +#define MRC_BIT13         0x00002000
> +#define MRC_BIT14         0x00004000
> +#define MRC_BIT15         0x00008000
> +#define MRC_BIT16         0x00010000
> +#define MRC_BIT17         0x00020000
> +#define MRC_BIT18         0x00040000
> +#define MRC_BIT19         0x00080000
> +#define MRC_BIT20         0x00100000
> +#define MRC_BIT21         0x00200000
> +#define MRC_BIT22         0x00400000
> +#define MRC_BIT23         0x00800000
> +#define MRC_BIT24         0x01000000
> +#define MRC_BIT25         0x02000000
> +#define MRC_BIT26         0x04000000
> +#define MRC_BIT27         0x08000000
> +#define MRC_BIT28         0x10000000
> +#define MRC_BIT29         0x20000000
> +#define MRC_BIT30         0x40000000
> +#define MRC_BIT31         0x80000000
> +#define MRC_BIT32        0x100000000ULL
> +#define MRC_BIT33        0x200000000ULL
> +#define MRC_BIT34        0x400000000ULL
> +#define MRC_BIT35        0x800000000ULL
> +#define MRC_BIT36       0x1000000000ULL
> +#define MRC_BIT37       0x2000000000ULL
> +#define MRC_BIT38       0x4000000000ULL
> +#define MRC_BIT39       0x8000000000ULL
> +#define MRC_BIT40      0x10000000000ULL
> +#define MRC_BIT41      0x20000000000ULL
> +#define MRC_BIT42      0x40000000000ULL
> +#define MRC_BIT43      0x80000000000ULL
> +#define MRC_BIT44     0x100000000000ULL
> +#define MRC_BIT45     0x200000000000ULL
> +#define MRC_BIT46     0x400000000000ULL
> +#define MRC_BIT47     0x800000000000ULL
> +#define MRC_BIT48    0x1000000000000ULL
> +#define MRC_BIT49    0x2000000000000ULL
> +#define MRC_BIT50    0x4000000000000ULL
> +#define MRC_BIT51    0x8000000000000ULL
> +#define MRC_BIT52   0x10000000000000ULL
> +#define MRC_BIT53   0x20000000000000ULL
> +#define MRC_BIT54   0x40000000000000ULL
> +#define MRC_BIT55   0x80000000000000ULL
> +#define MRC_BIT56  0x100000000000000ULL
> +#define MRC_BIT57  0x200000000000000ULL
> +#define MRC_BIT58  0x400000000000000ULL
> +#define MRC_BIT59  0x800000000000000ULL
> +#define MRC_BIT60 0x1000000000000000ULL
> +#define MRC_BIT61 0x2000000000000000ULL
> +#define MRC_BIT62 0x4000000000000000ULL
> +#define MRC_BIT63 0x8000000000000000ULL
> +
> +#define MRC_DEADLOOP() { volatile int __iii; __iii = 1; while (__iii); }
> +
> +#ifndef ASM
> +#define ASM __asm
> +#endif
> +
> +///
> +/// Type Max/Min Values
> +///
> +#define MRC_INT32_MAX   (0x7FFFFFFF)
> +#define MRC_INT32_MIN   (0x80000000)
> +#define MRC_INT64_MAX   (0x7FFFFFFFFFFFFFFFLL)
> +#define MRC_INT64_MIN   (0x8000000000000000LL)
> +#define MRC_UINT32_MAX  (0xFFFFFFFF)
> +#define MRC_UINT64_MAX  (0xFFFFFFFFFFFFFFFFULL)
> +#define MRC_UINT_MIN    (0x0)
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcI
> nterface.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcI
> nterface.h
> new file mode 100644
> index 0000000000..d444e937d6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcI
> nterface.h
> @@ -0,0 +1,15 @@
> +/** @file
> +  This file includes all the data structures that the MRC considers "global
> data".
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _UNIFIED_MrcInterface_h_
> +#define _UNIFIED_MrcInterface_h_
> +
> +#include "Coffeelake/MrcInterface.h"
> +
> +#endif
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
> new file mode 100644
> index 0000000000..82d798b783
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
> @@ -0,0 +1,50 @@
> +/** @file
> +  Header file for initialization of GT PowerManagement
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GRAPHICS_INIT_H_
> +#define _GRAPHICS_INIT_H_
> +
> +#include <Library/DxeServicesTableLib.h>
> +#include <Guid/DxeServices.h>
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Library/PciSegmentLib.h>
> +#include <SaAccess.h>
> +#include <Protocol/SaPolicy.h>
> +#include "SaInitDxe.h"
> +#include "SaInit.h"
> +#include <PchAccess.h>
> +#include <CpuRegs.h>
> +#include <Library/CpuPlatformLib.h>
> +
> +
> +/**
> +  Initialize GT ACPI tables
> +
> +  @param[in] ImageHandle - Handle for the image of this driver
> +  @param[in] SaPolicy    - SA DXE Policy protocol
> +
> +  @retval EFI_SUCCESS          - GT ACPI initialization complete
> +  @retval EFI_NOT_FOUND        - Dxe System Table not found.
> +  @retval EFI_OUT_OF_RESOURCES - Mmio not allocated successfully.
> +**/
> +EFI_STATUS
> +GraphicsInit (
> +  IN EFI_HANDLE             ImageHandle,
> +  IN SA_POLICY_PROTOCOL     *SaPolicy
> +  );
> +
> +/**
> +  Do Post GT PM Init Steps after VBIOS Initialization.
> +
> +  @retval EFI_SUCCESS          Succeed.
> +**/
> +EFI_STATUS
> +PostPmInitEndOfDxe (
> +  VOID
> +  );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.h
> new file mode 100644
> index 0000000000..0e95db3d02
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.h
> @@ -0,0 +1,193 @@
> +/** @file
> +  This is part of the implementation of an Intel Graphics drivers OpRegion /
> +  Software SCI interface between system BIOS, ASL code, and Graphics drivers.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _IGD_OPREGION_INIT_H_
> +#define _IGD_OPREGION_INIT_H_
> +
> +///
> +/// Statements that include other header files.
> +///
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <PchAccess.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PmcLib.h>
> +#include <SaAccess.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <CpuRegs.h>
> +#include <SaInit.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <SiConfigHob.h>
> +
> +///
> +/// Driver Consumed Protocol Prototypes
> +///
> +#include <Protocol/PciIo.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/LegacyBios.h>
> +#include <Protocol/SaPolicy.h>
> +
> +
> +#include <Private/Protocol/SaNvsArea.h>
> +
> +///
> +/// Driver Produced Protocol Prototypes
> +///
> +#include <Protocol/IgdOpRegion.h>
> +
> +///
> +///
> +/// OpRegion (Miscellaneous) defines.
> +///
> +/// OpRegion Header defines.
> +///
> +typedef UINT16  STRING_REF;
> +#define HEADER_SIGNATURE            "IntelGraphicsMem"
> +#define HEADER_SIZE                 0x2000
> +#define HEADER_OPREGION_VER         0x0200
> +#define HEADER_OPREGION_REV         0x00
> +#define HEADER_MBOX_SUPPORT         (HD_MBOX5 + HD_MBOX4 +
> HD_MBOX3 + HD_MBOX2 + HD_MBOX1)
> +#define HD_MBOX1                    BIT0
> +#define HD_MBOX2                    BIT1
> +#define HD_MBOX3                    BIT2
> +#define HD_MBOX4                    BIT3
> +#define HD_MBOX5                    BIT4
> +#define SVER_SIZE                   32
> +
> +///
> +/// OpRegion Mailbox 1 EQUates.
> +///
> +/// OpRegion Mailbox 3 EQUates.
> +///
> +#define ALS_ENABLE            BIT0
> +#define BLC_ENABLE            BIT1
> +#define BACKLIGHT_BRIGHTNESS  0xFF
> +#define FIELD_VALID_BIT       BIT31
> +#define PFIT_ENABLE           BIT2
> +#define PFIT_OPRN_AUTO        0x00000000
> +#define PFIT_OPRN_SCALING     0x00000007
> +#define PFIT_OPRN_OFF         0x00000000
> +#define PFIT_SETUP_AUTO       0
> +#define PFIT_SETUP_SCALING    1
> +#define PFIT_SETUP_OFF        2
> +#define INIT_BRIGHT_LEVEL     0x64
> +#define PFIT_STRETCH          6
> +
> +///
> +/// Video BIOS / VBT defines
> +///
> +#define OPTION_ROM_SIGNATURE    0xAA55
> +#define VBIOS_LOCATION_PRIMARY  0xC0000
> +
> +#define VBT_SIGNATURE           SIGNATURE_32 ('$', 'V', 'B', 'T')
> +///
> +/// Typedef stuctures
> +///
> +#pragma pack(1)
> +typedef struct {
> +  UINT16  Signature;  /// 0xAA55
> +  UINT8   Size512;
> +  UINT8   Reserved[21];
> +  UINT16  PcirOffset;
> +  UINT16  VbtOffset;
> +} INTEL_VBIOS_OPTION_ROM_HEADER;
> +#pragma pack()
> +
> +#pragma pack(1)
> +typedef struct {
> +  UINT32  Signature;  /// "PCIR"
> +  UINT16  VendorId;   /// 0x8086
> +  UINT16  DeviceId;
> +  UINT16  Reserved0;
> +  UINT16  Length;
> +  UINT8   Revision;
> +  UINT8   ClassCode[3];
> +  UINT16  ImageLength;
> +  UINT16  CodeRevision;
> +  UINT8   CodeType;
> +  UINT8   Indicator;
> +  UINT16  Reserved1;
> +} INTEL_VBIOS_PCIR_STRUCTURE;
> +#pragma pack()
> +
> +#pragma pack(1)
> +typedef struct {
> +  UINT8   HeaderSignature[20];
> +  UINT16  HeaderVersion;
> +  UINT16  HeaderSize;
> +  UINT16  HeaderVbtSize;
> +  UINT8   HeaderVbtCheckSum;
> +  UINT8   HeaderReserved;
> +  UINT32  HeaderOffsetVbtDataBlock;
> +  UINT32  HeaderOffsetAim1;
> +  UINT32  HeaderOffsetAim2;
> +  UINT32  HeaderOffsetAim3;
> +  UINT32  HeaderOffsetAim4;
> +  UINT8   DataHeaderSignature[16];
> +  UINT16  DataHeaderVersion;
> +  UINT16  DataHeaderSize;
> +  UINT16  DataHeaderDataBlockSize;
> +  UINT8   CoreBlockId;
> +  UINT16  CoreBlockSize;
> +  UINT16  CoreBlockBiosSize;
> +  UINT8   CoreBlockBiosType;
> +  UINT8   CoreBlockReleaseStatus;
> +  UINT8   CoreBlockHWSupported;
> +  UINT8   CoreBlockIntegratedHW;
> +  UINT8   CoreBlockBiosBuild[4];
> +  UINT8   CoreBlockBiosSignOn[155];
> +} VBIOS_VBT_STRUCTURE;
> +#pragma pack()
> +///
> +/// Driver Private Function definitions
> +///
> +
> +/**
> +  Graphics OpRegion / Software SCI driver installation function.
> +
> +  @retval EFI_SUCCESS     - The driver installed without error.
> +  @retval EFI_ABORTED     - The driver encountered an error and could not
> complete
> +                            installation of the ACPI tables.
> +**/
> +EFI_STATUS
> +IgdOpRegionInit (
> +  VOID
> +  );
> +
> +/**
> +  Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
> +  The VBT (Video BIOS Table) is a block of customizable data that is built
> +  within the video BIOS and edited by customers.
> +
> +  @retval EFI_SUCCESS            - Video BIOS VBT information returned.
> +  @exception EFI_UNSUPPORTED     - Could not find VBT information
> (*VBiosVbtPtr = NULL).
> +**/
> +EFI_STATUS
> +GetVBiosVbtEndOfDxe (
> +  VOID
> +  );
> +
> +/**
> +  Update Graphics OpRegion after PCI enumeration.
> +
> +  @retval EFI_SUCCESS     - The function completed successfully.
> +**/
> +EFI_STATUS
> +UpdateIgdOpRegionEndOfDxe (
> +  VOID
> +  );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.
> h
> new file mode 100644
> index 0000000000..34a2809f80
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.
> h
> @@ -0,0 +1,91 @@
> +/** @file
> +  Header file for PciExpress Initialization Driver.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCIEXPRESS_INITIALIZATION_DRIVER_H_
> +#define _PCIEXPRESS_INITIALIZATION_DRIVER_H_
> +
> +#include <Library/HobLib.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Register/Msr.h>
> +#include <SaAccess.h>
> +#include <PchAccess.h>
> +#include <Private/SaConfigHob.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Private/Protocol/SaNvsArea.h>
> +
> +#define GEN1      1
> +#define GEN2      2
> +
> +///
> +/// Function prototypes
> +///
> +/**
> +  PCI Express Dxe Initialization.
> +  Run before PCI Bus Init, where assignment of Bus, Memory,
> +    and I/O Resources are assigned.
> +
> +  @param[in] SaPolicy    -     SA DXE Policy protocol
> +
> +  @retval EFI_SUCCESS        - Pci Express successfully started and ready to be
> used
> +  @exception EFI_UNSUPPORTED - Pci Express can't be initialized
> +**/
> +EFI_STATUS
> +PciExpressInit (
> +  IN SA_POLICY_PROTOCOL *SaPolicy
> +  );
> +
> +/**
> +  Find the Offset to a given Capabilities ID
> +
> +  @param[in] Segment   -   Pci Segment Number
> +  @param[in] Bus       -   Pci Bus Number
> +  @param[in] Device    -   Pci Device Number
> +  @param[in] Function  -   Pci Function Number
> +  @param[in] CapId     -   CAPID to search fo
> +
> +  @retval 0       - CAPID not found
> +  @retval Other   - CAPID found, Offset of desired CAPID
> +**/
> +UINT32
> +PcieFindCapId (
> +  IN UINT8   Segment,
> +  IN UINT8   Bus,
> +  IN UINT8   Device,
> +  IN UINT8   Function,
> +  IN UINT8   CapId
> +  );
> +
> +/**
> +  Search and return the offset of desired Pci Express Capability ID
> +
> +  @param[in] Segment   -   Pci Segment Number
> +  @param[in] Bus       -   Pci Bus Number
> +  @param[in] Device    -   Pci Device Number
> +  @param[in] Function  -   Pci Function Number
> +  @param[in] CapId     -   Extended CAPID to search for
> +
> +  @retval 0       - CAPID not found
> +  @retval Other   - CAPID found, Offset of desired CAPID
> +**/
> +UINT32
> +PcieFindExtendedCapId (
> +  IN UINT8   Segment,
> +  IN UINT8   Bus,
> +  IN UINT8   Device,
> +  IN UINT8   Function,
> +  IN UINT16  CapId
> +  );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
> new file mode 100644
> index 0000000000..73af27e9d7
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
> @@ -0,0 +1,23 @@
> +/** @file
> +  This is header file for SA PCIE Root Complex initialization.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +EFI_STATUS
> +PegInitBeforeEndOfDxe (
> +  VOID
> +  );
> +
> +/**
> +  This function performs SA registers Saving/Restoring in EndOfDxe callback
> +
> +  @retval EFI_SUCCESS     - Save/restore has done
> +  @retval EFI_UNSUPPORTED - Save/restore not done successfully
> +**/
> +EFI_STATUS
> +SaSaveRestore (
> +  VOID
> +  );
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
> new file mode 100644
> index 0000000000..d7e2423ffd
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
> @@ -0,0 +1,71 @@
> +/** @file
> +  Header file for SA Common Initialization Driver.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_INITIALIZATION_DRIVER_H_
> +#define _SA_INITIALIZATION_DRIVER_H_
> +
> +#include <Uefi.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Pci.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciCf8Lib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/SaPlatformLib.h>
> +#include <Guid/EventGroup.h>
> +#include <CpuRegs.h>
> +#include <SaAccess.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Private/SaConfigHob.h>
> +
> +extern SA_POLICY_PROTOCOL              *mSaPolicy;
> +extern SA_CONFIG_HOB                   *SaConfigHob;
> +
> +typedef struct {
> +  UINT64  BaseAddr;
> +  UINT32  Offset;
> +  UINT32  AndMask;
> +  UINT32  OrMask;
> +} BOOT_SCRIPT_REGISTER_SETTING;
> +
> +/**
> +  SystemAgent Initialization Common Function.
> +
> +  @retval EFI_SUCCESS   - Always.
> +**/
> +VOID
> +SaInitEntryPoint (
> +  VOID
> +  );
> +
> +/**
> +  Common function locks the PAM register as part of the SA Security
> requirements.
> +
> +  @retval EFI_SUCCESS   - Always.
> +**/
> +VOID
> +SaPamLock (
> +  VOID
> +  );
> +/**
> +  This function performs SA Security locking in EndOfDxe callback
> +
> +  @retval EFI_SUCCESS     - Security lock has done
> +  @retval EFI_UNSUPPORTED - Security lock not done successfully
> +**/
> +EFI_STATUS
> +SaSecurityInit (
> +  VOID
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
> new file mode 100644
> index 0000000000..1991fd82c4
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
> @@ -0,0 +1,139 @@
> +/** @file
> +  Header file for SA Initialization Driver.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_INITIALIZATION_DXE_DRIVER_H_
> +#define _SA_INITIALIZATION_DXE_DRIVER_H_
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/AcpiTable.h>
> +#include "VTd.h"
> +#include "PcieComplex.h"
> +#include "IgdOpRegionInit.h"
> +#include <Private/Library/LegacyRegion.h>
> +#include "GraphicsInit.h"
> +#include "PciExpressInit.h"
> +#include "SwitchableGraphicsInit.h"
> +#include <Library/CpuPlatformLib.h>
> +
> +///
> +/// Driver Consumed Protocol Prototypes
> +///
> +#include <Protocol/SaPolicy.h>
> +
> +extern EFI_GUID gSaAcpiTableStorageGuid;
> +extern EFI_GUID gSaSsdtAcpiTableStorageGuid;
> +extern EFI_GUID gPegSsdtAcpiTableStorageGuid;
> +
> +typedef struct {
> +  UINT64                Address;
> +  EFI_BOOT_SCRIPT_WIDTH Width;
> +  UINT32                Value;
> +} BOOT_SCRIPT_PCI_REGISTER_SAVE;
> +
> +///
> +/// Function Prototype
> +///
> +/**
> +  This function gets registered as a callback to perform SA initialization before
> ExitPmAuth
> +
> +  @param[in] Event     - A pointer to the Event that triggered the callback.
> +  @param[in] Context   - A pointer to private data registered with the
> callback function.
> +
> +  @retval EFI_SUCCESS   - Always.
> +
> +**/
> +VOID
> +EFIAPI
> +SaPciEnumCompleteCallback (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  );
> +
> +/**
> +  <b>System Agent Initialization DXE Driver Entry Point</b>
> +  - <b>Introduction</b> \n
> +    Based on the information/data in SA_POLICY_PROTOCOL, this module
> performs further SA initialization in DXE phase,
> +    e.g. internal devices enable/disable, SSVID/SID programming, graphic
> power-management, VT-d, IGD OpRegion initialization.
> +    From the perspective of a PCI Express hierarchy, the Broadwell System
> Agent and PCH together appear as a Root Complex with root ports the number
> of which depends on how the 8 PCH ports and 4 System Agent PCIe ports are
> configured [4x1, 2x8, 1x16].
> +    There is an internal link (DMI or OPI) that connects the System Agent to the
> PCH component. This driver includes initialization of SA DMI, PCI Express, SA &
> PCH Root Complex Topology.
> +    For iGFX, this module implements the initialization of the Graphics
> Technology Power Management from the Broadwell System Agent BIOS
> Specification and the initialization of the IGD OpRegion/Software SCI - BIOS
> Specification.
> +    The ASL files that go along with the driver define the IGD OpRegion
> mailboxes in ACPI space and implement the software SCI interrupt mechanism.
> +    The IGD OpRegion/Software SCI code serves as a communication interface
> between system BIOS, ASL, and Intel graphics driver including making a block of
> customizable data (VBT) from the Intel video BIOS available.
> +    Reference Code for the SCI service functions "Get BIOS Data" and "System
> BIOS Callback" can be found in the ASL files, those functions can be platform
> specific, the sample provided in the reference code are implemented for Intel
> CRB.
> +    This module implements the VT-d functionality described in the Broadwell
> System Agent BIOS Specification.
> +    This module publishes the LegacyRegion protocol to control the read and
> write accesses to the Legacy BIOS ranges.
> +    E000 and F000 segments are the legacy BIOS ranges and contain pointers
> to the ACPI regions, SMBIOS tables and so on. This is a private protocol used by
> Intel Framework.
> +    This module registers CallBack function that performs SA security registers
> lockdown at end of post as required from Broadwell Bios Spec.
> +    In addition, this module publishes the SaInfo Protocol with information
> such as current System Agent reference code version#.
> +
> +  - @pre
> +    - EFI_FIRMWARE_VOLUME_PROTOCOL: Documented in Firmware Volume
> Specification, available at the URL:
> http://www.intel.com/technology/framework/spec.htm
> +    - SA_POLICY_PROTOCOL: A protocol published by a platform DXE module
> executed earlier; this is documented in this document as well.
> +    - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL: Documented in the Unified
> Extensible Firmware Interface Specification, version 2.0, available at the URL:
> http://www.uefi.org/specs/
> +    - EFI_BOOT_SCRIPT_SAVE_PROTOCOL: A protocol published by a platform
> DXE module executed earlier; refer to the Sample Code section of the
> Framework PCH Reference Code.
> +    - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL:
> Documented in the Unified Extensible Firmware Interface Specification,
> version 2.0, available at the URL: http://www.uefi.org/specs/
> +    - EFI_ACPI_TABLE_PROTOCOL : Documented in PI Specification 1.2
> +    - EFI_CPU_IO_PROTOCOL: Documented in CPU I/O Protocol Specification,
> available at the URL: http://www.intel.com/technology/framework/spec.htm
> +    - EFI_DATA_HUB_PROTOCOL: Documented in EFI Data Hub Infrastructure
> Specification, available at the URL:
> http://www.intel.com/technology/framework/spec.htm
> +    - EFI_HII_PROTOCOL (or EFI_HII_DATABASE_PROTOCOL for UEFI 2.1):
> Documented in Human Interface Infrastructure Specification, available at the
> URL: http://www.intel.com/technology/framework/spec.htm
> +    (For EFI_HII_DATABASE_PROTOCOL, refer to UEFI Specification Version 2.1
> available at the URL: http://www.uefi.org/)
> +
> +  - @result
> +    IGD power-management functionality is initialized;  VT-d is initialized
> (meanwhile, the DMAR table is updated); IGD OpRegion is initialized -
> IGD_OPREGION_PROTOCOL installed, IGD OpRegion allocated and mailboxes
> initialized, chipset initialized and ready to generate Software SCI for Internal
> graphics events. Publishes the SA_INFO_PROTOCOL with current SA reference
> code version #. Publishes the EFI_LEGACY_REGION_PROTOCOL documented in
> the Compatibility Support Module Specification, version 0.9, available at the
> URL: http://www.intel.com/technology/framework/spec.htm
> +
> +  - <b>References</b> \n
> +    IGD OpRegion/Software SCI for Broadwell
> +    Advanced Configuration and Power Interface Specification Revision 4.0a.
> +
> +  - <b>Porting Recommendations</b> \n
> +    No modification of the DXE driver should be typically necessary.
> +    This driver should be executed after all related devices (audio, video, ME,
> etc.) are initialized to ensure correct data in DMAR table and DMA-remapping
> registers.
> +
> +  @param[in] ImageHandle             Handle for the image of this driver
> +  @param[in] SystemTable             Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
> +**/
> +EFI_STATUS
> +EFIAPI
> +SaInitEntryPointDxe (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  );
> +
> +/**
> +  SystemAgent Acpi Initialization.
> +
> +  @param[in] ImageHandle             Handle for the image of this driver
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
> +**/
> +EFI_STATUS
> +EFIAPI
> +SaAcpiInit (
> +  IN EFI_HANDLE         ImageHandle
> +  );
> +
> +/**
> +  This function locks the PAM register as part of the SA Security requirements.
> +
> +  @param[in] Event     - A pointer to the Event that triggered the callback.
> +  @param[in] Context   - A pointer to private data registered with the
> callback function.
> +
> +  @retval EFI_SUCCESS   - Always.
> +**/
> +VOID
> +EFIAPI
> +SaPamLockDxe (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGra
> phicsInit.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGra
> phicsInit.h
> new file mode 100644
> index 0000000000..2b1b4c5880
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGra
> phicsInit.h
> @@ -0,0 +1,17 @@
> +/** @file
> +  Header file for the SwitchableGraphics Dxe driver.
> +  This driver loads SwitchableGraphics ACPI tables.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SWITCHABLE_GRAPHICS_DXE_H_
> +#define _SWITCHABLE_GRAPHICS_DXE_H_
> +
> +
> +#include <Protocol/FirmwareVolume2.h>
> +
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
> new file mode 100644
> index 0000000000..c4bc47f7fe
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
> @@ -0,0 +1,53 @@
> +/** @file
> +  This code provides a initialization of intel VT-d (Virtualization Technology
> for Directed I/O).
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _VT_D_H_
> +#define _VT_D_H_
> +
> +///
> +/// Include files
> +///
> +#include <DmaRemappingTable.h>
> +#include <SaAccess.h>
> +#include <PchAccess.h>
> +#include <Uefi.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> +#include <Protocol/AcpiTable.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Private/PchConfigHob.h>
> +#include <CpuRegs.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +
> +#define VTD_ECAP_REG  0x10
> +#define IR            BIT3
> +
> +/**
> +  Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
> +  Publish the appropriate SSDT based on current configuration and
> capabilities.
> +
> +  @param[in] SaPolicy            SA DXE Policy protocol
> +
> +  @retval EFI_SUCCESS - Vtd initialization complete
> +  @retval Other       - No Vtd function initiated
> +**/
> +EFI_STATUS
> +VtdInit (
> +  IN  SA_POLICY_PROTOCOL    *SaPolicy
> +  );
> +
> +/**
> +  PciEnumerationComplete routine for update DMAR
> +**/
> +VOID
> +UpdateDmarPciEnumCompleteCallback (
> +  VOID
> +  );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.h
> new file mode 100644
> index 0000000000..02c74c0672
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.h
> @@ -0,0 +1,162 @@
> +/** @file
> +  Header file for SMM Access Driver.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SMM_ACCESS_DRIVER_H_
> +#define _SMM_ACCESS_DRIVER_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Uefi/UefiBaseType.h>
> +
> +#include <Guid/SmramMemoryReserve.h>
> +#include <Protocol/SmmAccess2.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <SaAccess.h>
> +
> +#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5', 's',
> 'a')
> +
> +///
> +/// Private data
> +///
> +typedef struct {
> +  UINTN                           Signature;
> +  EFI_HANDLE                      Handle;
> +  EFI_SMM_ACCESS2_PROTOCOL        SmmAccess;
> +
> +  ///
> +  /// Local Data for SMM Access interface goes here
> +  ///
> +  UINTN                           NumberRegions;
> +  EFI_SMRAM_DESCRIPTOR            *SmramDesc;
> +} SMM_ACCESS_PRIVATE_DATA;
> +
> +#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
> +  CR (a, \
> +      SMM_ACCESS_PRIVATE_DATA, \
> +      SmmAccess, \
> +      SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
> +      )
> +
> +//
> +// Prototypes
> +// Driver model protocol interface
> +//
> +/**
> +  <b>SMM Access Driver Entry Point</b>
> +  This driver installs an SMM Access Protocol
> +  - <b>Introduction</b> \n
> +    This module publishes the SMM access protocol.  The protocol is used by
> the SMM Base driver to access the SMRAM region when the processor is not in
> SMM.
> +    The SMM Base driver uses the services provided by the SMM access
> protocol to open SMRAM during post and copy the SMM handler.
> +    SMM access protocol is also used to close the SMRAM region once the
> copying is done.
> +    Finally, the SMM access protocol provides services to "Lock" the SMRAM
> region.
> +    Please refer the SMM Protocols section in the attached SMM CIS
> Specification version 0.9 for further details.
> +    This driver is required if SMM is supported. Proper configuration of SMM
> registers is recommended even if SMM is not supported.
> +
> +  - @result
> +    Publishes the _EFI_SMM_ACCESS_PROTOCOL: Documented in the System
> Management Mode Core Interface Specification, available at the URL:
> http://www.intel.com/technology/framework/spec.htm
> +
> +  - <b>Porting Recommendations</b> \n
> +    No modification of this module is recommended.  Any modification
> should be done in compliance with the _EFI_SMM_ACCESS_PROTOCOL
> protocol definition.
> +
> +  @param[in] ImageHandle     - Handle for the image of this driver
> +  @param[in] SystemTable     - Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS     - Protocol was installed successfully
> +  @exception EFI_UNSUPPORTED - Protocol was not installed
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmAccessDriverEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  );
> +
> +/**
> +  This routine accepts a request to "open" a region of SMRAM.  The
> +  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> +  The use of "open" means that the memory is visible from all boot-service
> +  and SMM agents.
> +
> +  @param[in] This                  - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR      - The region could not be opened because
> locked by
> +                          chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Open (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  );
> +
> +/**
> +  This routine accepts a request to "close" a region of SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "close" means that the memory is only visible from SMM agents,
> +  not from BS or RT code.
> +
> +  @param[in] This                  - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR      - The region could not be closed because
> locked by
> +                            chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Close (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  );
> +
> +/**
> +  This routine accepts a request to "lock" SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "lock" means that the memory can no longer be opened
> +  to BS state..
> +
> +  @param[in] This                  - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR      - The region could not be locked because at
> least
> +                          one range is still open.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Lock (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  );
> +
> +/**
> +  This routine services a user request to discover the SMRAM
> +  capabilities of this platform.  This will report the possible
> +  ranges that are possible for SMRAM access, based upon the
> +  memory controller capabilities.
> +
> +  @param[in] This                  - Pointer to the SMRAM Access Interface.
> +  @param[in] SmramMapSize          - Pointer to the variable containing size
> of the
> +                            buffer to contain the description information.
> +  @param[in] SmramMap              - Buffer containing the data describing
> the Smram
> +                            region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetCapabilities (
> +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> +  IN OUT UINTN                   *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR    *SmramMap
> +  );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
> new file mode 100644
> index 0000000000..5daa2367e6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
> @@ -0,0 +1,157 @@
> +/** @file
> +  DXE driver for Initializing SystemAgent Graphics ACPI table initialization.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "GraphicsInit.h"
> +#include "SaInit.h"
> +#include <Protocol/LegacyBios.h>
> +#include <Protocol/GopComponentName2.h>
> +#include <SiConfigHob.h>
> +
> +typedef union {
> +  struct {
> +    UINT32  Low;
> +    UINT32  High;
> +  } Data32;
> +  UINT64 Data;
> +} UINT64_STRUCT;
> +
> +extern SYSTEM_AGENT_NVS_AREA_PROTOCOL  mSaNvsAreaProtocol;
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT64
> mGttMmAdr;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT64_STRUCT
> mMchBarBase;
> +GLOBAL_REMOVE_IF_UNREFERENCED
> GOP_COMPONENT_NAME2_PROTOCOL  *GopComponentName2Protocol =
> NULL;
> +
> +/**
> +    Do Post GT PM Init Steps after VBIOS Initialization.
> +
> +  @retval EFI_SUCCESS          Succeed.
> +**/
> +EFI_STATUS
> +PostPmInitEndOfDxe (
> +  VOID
> +  )
> +{
> +  CHAR16                    *DriverVersion;
> +  UINTN                     Index;
> +  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
> +  EFI_STATUS                Status;
> +  GRAPHICS_DXE_CONFIG       *GraphicsDxeConfig;
> +  EFI_PEI_HOB_POINTERS      HobPtr;
> +  SI_CONFIG_HOB_DATA        *SiConfigHobData;
> +
> +  ///
> +  /// Get the platform setup policy.
> +  ///
> +  DriverVersion = NULL;
> +  LegacyBios = NULL;
> +  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **)
> &mSaPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Get Silicon Config data HOB
> +  //
> +  HobPtr.Guid   = GetFirstGuidHob (&gSiConfigHobGuid);
> +  SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA
> (HobPtr.Guid);
> +
> +  if (SiConfigHobData->CsmFlag == 1) {
> +    Status = gBS->LocateProtocol (
> +                    &gEfiLegacyBiosProtocolGuid,
> +                    NULL,
> +                    (VOID **) &LegacyBios
> +                    );
> +  }
> +
> +  if (LegacyBios == NULL) {
> +    Status = gBS->LocateProtocol (&gGopComponentName2ProtocolGuid,
> NULL, (VOID **)&GopComponentName2Protocol);
> +    if (!EFI_ERROR (Status)) {
> +      Status = GopComponentName2Protocol->GetDriverVersion (
> +                                            GopComponentName2Protocol,
> +                                            "en-US",
> +                                            &DriverVersion
> +                                            );
> +      if (!EFI_ERROR (Status)) {
> +        for (Index = 0; (DriverVersion[Index] != '\0'); Index++) {
> +        }
> +        Index = (Index+1)*2;
> +        CopyMem (GraphicsDxeConfig->GopVersion, DriverVersion, Index);
> +      }
> +    }
> +  }
> +
> +  ///
> +  /// Return final status
> +  ///
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +Initialize GT ACPI tables
> +
> +  @param[in] ImageHandle -     Handle for the image of this driver
> +  @param[in] SaPolicy -        SA DXE Policy protocol
> +
> +  @retval EFI_SUCCESS          - GT ACPI initialization complete
> +  @retval EFI_NOT_FOUND        - Dxe System Table not found.
> +  @retval EFI_OUT_OF_RESOURCES - Mmio not allocated successfully.
> +**/
> +EFI_STATUS
> +GraphicsInit (
> +  IN EFI_HANDLE              ImageHandle,
> +  IN SA_POLICY_PROTOCOL      *SaPolicy
> +  )
> +{
> +  EFI_STATUS            Status;
> +  GRAPHICS_DXE_CONFIG   *GraphicsDxeConfig;
> +
> +  mGttMmAdr               = 0;
> +  Status                  = EFI_SUCCESS;
> +  mMchBarBase.Data32.High = PciSegmentRead32
> (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0,
> R_SA_MCHBAR + 4));
> +  mMchBarBase.Data32.Low  = PciSegmentRead32
> (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0,
> R_SA_MCHBAR));
> +  mMchBarBase.Data       &= (UINT64) ~BIT0;
> +
> +  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  /// Update IGD SA Global NVS
> +  ///
> +  DEBUG ((DEBUG_INFO, " Update Igd SA Global NVS Area.\n"));
> +
> +  mSaNvsAreaProtocol.Area->AlsEnable                    =
> GraphicsDxeConfig->AlsEnable;
> +  ///
> +  /// Initialize IGD state by checking if IGD Device 2 Function 0 is enabled in the
> chipset
> +  ///
> +  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 0, 0, R_SA_DEVEN)) & B_SA_DEVEN_D2EN_MASK) {
> +    mSaNvsAreaProtocol.Area->IgdState = 1;
> +  } else {
> +    mSaNvsAreaProtocol.Area->IgdState = 0;
> +  }
> +
> +  mSaNvsAreaProtocol.Area->BrightnessPercentage         = 100;
> +  mSaNvsAreaProtocol.Area->IgdBootType                  =
> GraphicsDxeConfig->IgdBootType;
> +  mSaNvsAreaProtocol.Area->IgdPanelType                 =
> GraphicsDxeConfig->IgdPanelType;
> +  mSaNvsAreaProtocol.Area->IgdPanelScaling              =
> GraphicsDxeConfig->IgdPanelScaling;
> +  ///
> +  /// Get SFF power mode platform data for the IGD driver.  Flip the bit
> (bitwise xor)
> +  /// since Setup value is opposite of NVS and IGD OpRegion value.
> +  ///
> +  mSaNvsAreaProtocol.Area->IgdDvmtMemSize               =
> GraphicsDxeConfig->IgdDvmtMemSize;
> +  mSaNvsAreaProtocol.Area->IgdFunc1Enable               = 0;
> +  mSaNvsAreaProtocol.Area->IgdHpllVco                   = MmioRead8
> (mMchBarBase.Data + 0xC0F) & 0x07;
> +  mSaNvsAreaProtocol.Area->IgdSciSmiMode                = 0;
> +  mSaNvsAreaProtocol.Area->GfxTurboIMON                 =
> GraphicsDxeConfig->GfxTurboIMON;
> +
> +  mSaNvsAreaProtocol.Area->EdpValid                     = 0;
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.c
> new file mode 100644
> index 0000000000..6ec0691074
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.c
> @@ -0,0 +1,570 @@
> +/** @file
> +  This is part of the implementation of an Intel Graphics drivers OpRegion /
> +  Software SCI interface between system BIOS, ASL code, and Graphics drivers.
> +  The code in this file will load the driver and initialize the interface
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "IgdOpRegionInit.h"
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED IGD_OPREGION_PROTOCOL
> mIgdOpRegion;
> +
> +/**
> +  Get VBT data using SaPlaformPolicy
> +
> +  @param[out] VbtFileBuffer    Pointer to VBT data buffer.
> +
> +  @retval EFI_SUCCESS      VBT data was returned.
> +  @retval EFI_NOT_FOUND    VBT data not found.
> +  @exception EFI_UNSUPPORTED  Invalid signature in VBT data.
> +**/
> +EFI_STATUS
> +GetIntegratedIntelVbtPtr (
> +  OUT VBIOS_VBT_STRUCTURE **VbtFileBuffer
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_PHYSICAL_ADDRESS          VbtAddress;
> +  UINT32                        Size;
> +  GRAPHICS_DXE_CONFIG           *GraphicsDxeConfig;
> +
> +  ///
> +  /// Get the SA policy.
> +  ///
> +  Status = gBS->LocateProtocol (
> +                  &gSaPolicyProtocolGuid,
> +                  NULL,
> +                  (VOID **) &mSaPolicy
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  VbtAddress = GraphicsDxeConfig->VbtAddress;
> +  Size       = GraphicsDxeConfig->Size;
> +
> +  if (VbtAddress == 0x00000000) {
> +    return EFI_NOT_FOUND;
> +  } else {
> +    ///
> +    /// Check VBT signature
> +    ///
> +    *VbtFileBuffer  = NULL;
> +    *VbtFileBuffer = (VBIOS_VBT_STRUCTURE *) (UINTN) VbtAddress;
> +    if ((*((UINT32 *) ((*VbtFileBuffer)->HeaderSignature))) != VBT_SIGNATURE)
> {
> +      FreePool (*VbtFileBuffer);
> +      *VbtFileBuffer = NULL;
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  if (Size == 0) {
> +    return EFI_NOT_FOUND;
> +  } else {
> +    ///
> +    /// Check VBT size
> +    ///
> +    if ((*VbtFileBuffer)->HeaderVbtSize > Size) {
> +      (*VbtFileBuffer)->HeaderVbtSize = (UINT16) Size;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Get a pointer to an uncompressed image of the Intel video BIOS.
> +
> +  @Note: This function would only be called if the video BIOS at 0xC000 is
> +         missing or not an Intel video BIOS.  It may not be an Intel video BIOS
> +         if the Intel graphic contoller is considered a secondary adapter.
> +
> +  @param[out] VBiosImage     - Pointer to an uncompressed Intel video BIOS.
> This pointer must
> +                               be set to NULL if an uncompressed image of the Intel
> Video BIOS
> +                               is not obtainable.
> +
> +  @retval EFI_SUCCESS        - VBiosPtr is updated.
> +  @exception EFI_UNSUPPORTED - No Intel video BIOS found.
> +**/
> +EFI_STATUS
> +GetIntegratedIntelVBiosPtr (
> +  OUT INTEL_VBIOS_OPTION_ROM_HEADER **VBiosImage
> +  )
> +{
> +  EFI_HANDLE                    *HandleBuffer;
> +  UINTN                         HandleCount;
> +  UINTN                         Index;
> +  INTEL_VBIOS_PCIR_STRUCTURE    *PcirBlockPtr;
> +  EFI_STATUS                    Status;
> +  EFI_PCI_IO_PROTOCOL           *PciIo;
> +  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosRomImage;
> +
> +  ///
> +  /// Set as if an umcompressed Intel video BIOS image was not obtainable.
> +  ///
> +  VBiosRomImage = NULL;
> +
> +  ///
> +  /// Get all PCI IO protocols
> +  ///
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiPciIoProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  /// Find the video BIOS by checking each PCI IO handle for an Intel video
> +  /// BIOS OPROM.
> +  ///
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[Index],
> +                    &gEfiPciIoProtocolGuid,
> +                    (VOID **) &PciIo
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    VBiosRomImage = PciIo->RomImage;
> +
> +    ///
> +    /// If this PCI device doesn't have a ROM image, skip to the next device.
> +    ///
> +    if (!VBiosRomImage) {
> +      continue;
> +    }
> +    ///
> +    /// Get pointer to PCIR structure
> +    ///
> +    PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *)
> VBiosRomImage + VBiosRomImage->PcirOffset);
> +
> +    ///
> +    /// Check if we have an Intel video BIOS OPROM.
> +    ///
> +    if ((VBiosRomImage->Signature == OPTION_ROM_SIGNATURE) &&
> +        (PcirBlockPtr->VendorId == V_SA_MC_VID) &&
> +        (PcirBlockPtr->ClassCode[0] == 0x00) &&
> +        (PcirBlockPtr->ClassCode[1] == 0x00) &&
> +        (PcirBlockPtr->ClassCode[2] == 0x03)
> +        ) {
> +      ///
> +      /// Found Intel video BIOS.
> +      ///
> +      *VBiosImage = VBiosRomImage;
> +      return EFI_SUCCESS;
> +    }
> +  }
> +  ///
> +  /// No Intel video BIOS found.
> +  ///
> +  ///
> +  /// Free any allocated buffers
> +  ///
> +  FreePool (HandleBuffer);
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
> +  The VBT (Video BIOS Table) is a block of customizable data that is built
> +  within the video BIOS and edited by customers.
> +
> +  @retval EFI_SUCCESS            - Video BIOS VBT information returned.
> +  @exception EFI_UNSUPPORTED     - Could not find VBT information
> (*VBiosVbtPtr = NULL).
> +**/
> +EFI_STATUS
> +GetVBiosVbtEndOfDxe (
> +  VOID
> +  )
> +{
> +  INTEL_VBIOS_PCIR_STRUCTURE    *PcirBlockPtr;
> +  UINT32                        PcirBlockAddress;
> +  UINT16                        PciVenderId;
> +  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosPtr;
> +  VBIOS_VBT_STRUCTURE           *VBiosVbtPtr;
> +  EFI_LEGACY_BIOS_PROTOCOL      *LegacyBios;
> +  EFI_STATUS                    Status;
> +  VBIOS_VBT_STRUCTURE           *VbtFileBuffer;
> +  UINTN                         Index;
> +  UINT8                         LegacyVbtFound;
> +  GRAPHICS_DXE_CONFIG           *GraphicsDxeConfig;
> +  EFI_PEI_HOB_POINTERS          HobPtr;
> +  SI_CONFIG_HOB_DATA            *SiConfigHobData;
> +
> +  VbtFileBuffer = NULL;
> +  LegacyVbtFound = 1;
> +
> +  ///
> +  /// Get the SA policy.
> +  ///
> +  Status = gBS->LocateProtocol (
> +                  &gSaPolicyProtocolGuid,
> +                  NULL,
> +                  (VOID **) &mSaPolicy
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  LegacyBios = NULL;
> +  VBiosPtr = NULL;
> +  //
> +  // Get Silicon Config data HOB
> +  //
> +  HobPtr.Guid = GetFirstGuidHob (&gSiConfigHobGuid);
> +  SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA
> (HobPtr.Guid);
> +  if (SiConfigHobData->CsmFlag == 1) {
> +    Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID
> **) &LegacyBios);
> +
> +    if (LegacyBios) {
> +      VBiosPtr      = (INTEL_VBIOS_OPTION_ROM_HEADER *) (UINTN)
> (VBIOS_LOCATION_PRIMARY);
> +      PcirBlockAddress = VBIOS_LOCATION_PRIMARY + VBiosPtr->PcirOffset;
> +      PcirBlockPtr  = (INTEL_VBIOS_PCIR_STRUCTURE *) (UINTN)
> (PcirBlockAddress);
> +      PciVenderId   = PcirBlockPtr->VendorId;
> +      ///
> +      /// If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get
> +      /// the integrated Intel video BIOS (must be uncompressed).
> +      ///
> +      if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId !=
> V_SA_MC_VID)) {
> +        GetIntegratedIntelVBiosPtr (&VBiosPtr);
> +        if (VBiosPtr != NULL) {
> +          ///
> +          /// Video BIOS found.
> +          ///
> +          PcirBlockPtr  = (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *) VBiosPtr
> + VBiosPtr->PcirOffset);
> +          PciVenderId   = PcirBlockPtr->VendorId;
> +
> +          if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) ||
> (PciVenderId != V_SA_MC_VID)) {
> +            ///
> +            /// Intel video BIOS not found.
> +            ///
> +            VBiosVbtPtr = NULL;
> +            LegacyVbtFound = 0;
> +          }
> +        }
> +      }
> +    }
> +  }
> +  if ((LegacyBios == NULL) || (LegacyVbtFound == 0)) {
> +    ///
> +    /// No Video BIOS found, try to get VBT from FV.
> +    ///
> +    GetIntegratedIntelVbtPtr (&VbtFileBuffer);
> +    if (VbtFileBuffer != NULL) {
> +      ///
> +      /// Video BIOS not found, use VBT from SaPolicy
> +      ///
> +      DEBUG ((DEBUG_INFO, "VBT data found\n"));
> +      for (Index = 0; (GraphicsDxeConfig->GopVersion[Index] != '\0'); Index++) {
> +      }
> +      Index = (Index+1)*2;
> +      CopyMem (mIgdOpRegion.OpRegion->Header.DVER,
> GraphicsDxeConfig->GopVersion, Index);
> +      CopyMem (mIgdOpRegion.OpRegion->MBox4.RVBT, VbtFileBuffer,
> VbtFileBuffer->HeaderVbtSize);
> +      return EFI_SUCCESS;
> +    }
> +  }
> +
> +  if (VBiosPtr == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "VBIOS found at 0x%X\n", VBiosPtr));
> +  VBiosVbtPtr = (VBIOS_VBT_STRUCTURE *) ((UINT8 *) VBiosPtr +
> VBiosPtr->VbtOffset);
> +
> +  if ((*((UINT32 *) (VBiosVbtPtr->HeaderSignature))) != VBT_SIGNATURE) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  ///
> +  /// Initialize Video BIOS version with its build number.
> +  ///
> +  mIgdOpRegion.OpRegion->Header.VVER[0] =
> VBiosVbtPtr->CoreBlockBiosBuild[0];
> +  mIgdOpRegion.OpRegion->Header.VVER[1] =
> VBiosVbtPtr->CoreBlockBiosBuild[1];
> +  mIgdOpRegion.OpRegion->Header.VVER[2] =
> VBiosVbtPtr->CoreBlockBiosBuild[2];
> +  mIgdOpRegion.OpRegion->Header.VVER[3] =
> VBiosVbtPtr->CoreBlockBiosBuild[3];
> +  CopyMem (mIgdOpRegion.OpRegion->MBox4.RVBT, VBiosVbtPtr,
> VBiosVbtPtr->HeaderVbtSize);
> +
> +  ///
> +  /// Return final status
> +  ///
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Graphics OpRegion / Software SCI driver installation function.
> +
> +  @param[in] void         - None
> +  @retval EFI_SUCCESS     - The driver installed without error.
> +  @retval EFI_ABORTED     - The driver encountered an error and could not
> complete
> +                            installation of the ACPI tables.
> +**/
> +EFI_STATUS
> +IgdOpRegionInit (
> +  VOID
> +  )
> +{
> +  EFI_HANDLE                      Handle;
> +  EFI_STATUS                      Status;
> +  UINT32                          DwordData;
> +  UINT64                          IgdBaseAddress;
> +  SA_POLICY_PROTOCOL              *SaPolicy;
> +  GRAPHICS_DXE_CONFIG             *GraphicsDxeConfig;
> +  UINT8                           Index;
> +  SYSTEM_AGENT_NVS_AREA_PROTOCOL  *SaNvsAreaProtocol;
> +
> +  ///
> +  /// Get the SA policy.
> +  ///
> +  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID
> **)&SaPolicy);
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  ///
> +  ///  Locate the SA Global NVS Protocol.
> +  ///
> +  Status = gBS->LocateProtocol (
> +                  &gSaNvsAreaProtocolGuid,
> +                  NULL,
> +                  (VOID **) &SaNvsAreaProtocol
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  /// Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize
> +  /// the first 1K, and set the IGD OpRegion pointer in the Global NVS
> +  /// area structure.
> +  ///
> +  Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof
> (IGD_OPREGION_STRUCTURE), (VOID **) &mIgdOpRegion.OpRegion);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  SetMem (mIgdOpRegion.OpRegion, sizeof (IGD_OPREGION_STRUCTURE),
> 0);
> +  SaNvsAreaProtocol->Area->IgdOpRegionAddress = (UINT32) (UINTN)
> (mIgdOpRegion.OpRegion);
> +
> +  ///
> +  /// If IGD is disabled return
> +  ///
> +  IgdBaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0);
> +  if (PciSegmentRead32 (IgdBaseAddress + 0) == 0xFFFFFFFF) {
> +    return EFI_SUCCESS;
> +  }
> +  ///
> +  /// Initialize OpRegion Header
> +  ///
> +  CopyMem (mIgdOpRegion.OpRegion->Header.SIGN, HEADER_SIGNATURE,
> sizeof (HEADER_SIGNATURE));
> +  ///
> +  /// Set OpRegion Size in KBs
> +  ///
> +  mIgdOpRegion.OpRegion->Header.SIZE = HEADER_SIZE / 1024;
> +  mIgdOpRegion.OpRegion->Header.OVER = (UINT32) (LShiftU64
> (HEADER_OPREGION_VER, 16) + LShiftU64 (HEADER_OPREGION_REV, 8));
> +
> +  ///
> +  /// All Mailboxes are supported.
> +  ///
> +  mIgdOpRegion.OpRegion->Header.MBOX = HEADER_MBOX_SUPPORT;
> +
> +  ///
> +  /// Initialize OpRegion Mailbox 1 (Public ACPI Methods).
> +  ///
> +  /// Note - The initial setting of mailbox 1 fields is implementation specific.
> +  /// Adjust them as needed many even coming from user setting in setup.
> +  ///
> +  ///
> +  /// Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservation).
> +  ///
> +  /// Note - The initial setting of mailbox 3 fields is implementation specific.
> +  /// Adjust them as needed many even coming from user setting in setup.
> +  ///
> +  ///
> +  /// Do not initialize TCHE. This field is written by the graphics driver only.
> +  ///
> +  ///
> +  /// The ALSI field is generally initialized by ASL code by reading the
> embedded controller.
> +  ///
> +  mIgdOpRegion.OpRegion->Header.PCON =
> GraphicsDxeConfig->PlatformConfig;
> +  mIgdOpRegion.OpRegion->Header.PCON =
> mIgdOpRegion.OpRegion->Header.PCON | 0x2;
> +
> +  mIgdOpRegion.OpRegion->MBox3.BCLP = BACKLIGHT_BRIGHTNESS;
> +
> +  mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT |
> PFIT_STRETCH);
> +
> +  ///
> +  /// Reporting to driver for VR IMON Calibration. Bits [5-1] values supported
> 14A to 31A.
> +  ///
> +  mIgdOpRegion.OpRegion->MBox3.PCFT =
> (SaNvsAreaProtocol->Area->GfxTurboIMON << 1) & 0x003E;
> +
> +  ///
> +  /// Set Initial current Brightness
> +  ///
> +  mIgdOpRegion.OpRegion->MBox3.CBLV = (INIT_BRIGHT_LEVEL |
> FIELD_VALID_BIT);
> +
> +  ///
> +  /// Static Backlight Brightness Level Duty cycle Mapping Table
> +  ///
> +  for (Index = 0; Index < MAX_BCLM_ENTRIES; Index++) {
> +    mIgdOpRegion.OpRegion->MBox3.BCLM[Index] =
> GraphicsDxeConfig->BCLM[Index];
> +  }
> +
> +  mIgdOpRegion.OpRegion->MBox3.IUER = 0x00;
> +
> +  if (!EFI_ERROR (Status)) {
> +    mIgdOpRegion.OpRegion->MBox3.IUER =
> GraphicsDxeConfig->IuerStatusVal;
> +  }
> +
> +  ///
> +  /// Initialize hardware state:
> +  ///   Set ASLS Register to the OpRegion physical memory address.
> +  ///   Set SWSCI register bit 15 to a "1" to activate SCI interrupts.
> +  ///
> +  PciSegmentWrite32 (IgdBaseAddress + R_SA_IGD_ASLS_OFFSET, (UINT32)
> (UINTN) (mIgdOpRegion.OpRegion));
> +  PciSegmentAndThenOr16 (IgdBaseAddress + R_SA_IGD_SWSCI_OFFSET,
> (UINT16) ~(BIT0), BIT15);
> +
> +  DwordData = PciSegmentRead32 (IgdBaseAddress +
> R_SA_IGD_ASLS_OFFSET);
> +  S3BootScriptSaveMemWrite (
> +    S3BootScriptWidthUint32,
> +    (UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (IgdBaseAddress +
> R_SA_IGD_ASLS_OFFSET),
> +    1,
> +    &DwordData
> +    );
> +  DwordData = PciSegmentRead32 (IgdBaseAddress +
> R_SA_IGD_SWSCI_OFFSET);
> +  S3BootScriptSaveMemWrite (
> +    S3BootScriptWidthUint32,
> +    (UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (IgdBaseAddress +
> R_SA_IGD_SWSCI_OFFSET),
> +    1,
> +    &DwordData
> +    );
> +
> +  ///
> +  /// Install OpRegion / Software SCI protocol
> +  ///
> +  Handle = NULL;
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &Handle,
> +                  &gIgdOpRegionProtocolGuid,
> +                  &mIgdOpRegion,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  /// Return final status
> +  ///
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Update Graphics OpRegion after PCI enumeration.
> +
> +  @param[in] void         - None
> +  @retval EFI_SUCCESS     - The function completed successfully.
> +**/
> +EFI_STATUS
> +UpdateIgdOpRegionEndOfDxe (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  UINTN                         HandleCount;
> +  EFI_HANDLE                    *HandleBuffer;
> +  UINTN                         Index;
> +  EFI_PCI_IO_PROTOCOL           *PciIo;
> +  PCI_TYPE00                    Pci;
> +  UINTN                         Segment;
> +  UINTN                         Bus;
> +  UINTN                         Device;
> +  UINTN                         Function;
> +
> +  Bus      = 0;
> +  Device   = 0;
> +  Function = 0;
> +
> +  DEBUG ((DEBUG_INFO, "UpdateIgdOpRegionEndOfDxe\n"));
> +
> +  mIgdOpRegion.OpRegion->Header.PCON |= BIT8; //Set External Gfx
> Adapter field is valid
> +  mIgdOpRegion.OpRegion->Header.PCON &= (UINT32) (~BIT7); //Assume No
> External Gfx Adapter
> +
> +  ///
> +  /// Get all PCI IO protocols handles
> +  ///
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiPciIoProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer
> +                  );
> +
> +  if (!EFI_ERROR (Status)) {
> +    for (Index = 0; Index < HandleCount; Index++) {
> +      ///
> +      /// Get the PCI IO Protocol Interface corresponding to each handle
> +      ///
> +      Status = gBS->HandleProtocol (
> +                      HandleBuffer[Index],
> +                      &gEfiPciIoProtocolGuid,
> +                      (VOID **) &PciIo
> +                      );
> +
> +      if (!EFI_ERROR (Status)) {
> +        ///
> +        /// Read the PCI configuration space
> +        ///
> +        Status = PciIo->Pci.Read (
> +                              PciIo,
> +                              EfiPciIoWidthUint32,
> +                              0,
> +                              sizeof (Pci) / sizeof (UINT32),
> +                              &Pci
> +                              );
> +
> +        ///
> +        /// Find the display controllers devices
> +        ///
> +        if (!EFI_ERROR (Status) && IS_PCI_DISPLAY (&Pci)) {
> +          Status = PciIo->GetLocation (
> +                            PciIo,
> +                            &Segment,
> +                            &Bus,
> +                            &Device,
> +                            &Function
> +                            );
> +
> +          //
> +          // Assumption: Onboard devices will be sits on Bus no 0, while
> external devices will be sits on Bus no > 0
> +          //
> +          if (!EFI_ERROR (Status) && (Bus > 0)) {
> +            //External Gfx Adapter Detected and Available
> +            DEBUG ((DEBUG_INFO, "PCON - External Gfx Adapter Detected and
> Available\n"));
> +            mIgdOpRegion.OpRegion->Header.PCON |= BIT7;
> +            break;
> +          }
> +        }
> +      }
> +    }
> +  }
> +
> +  ///
> +  /// Free any allocated buffers
> +  ///
> +  if (HandleBuffer != NULL) {
> +    FreePool (HandleBuffer);
> +  }
> +
> +  ///
> +  /// Return final status
> +  ///
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
> new file mode 100644
> index 0000000000..bbdf0d0fab
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
> @@ -0,0 +1,171 @@
> +/** @file
> +  This driver does SA PCI Express ACPI table initialization.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PciExpressInit.h"
> +
> +extern SYSTEM_AGENT_NVS_AREA_PROTOCOL   mSaNvsAreaProtocol;
> +extern SA_CONFIG_HOB                    *mSaConfigHob;
> +
> +/**
> +  PCI Express Dxe Initialization.
> +  Run before PCI Bus Init, where assignment of Bus, Memory,
> +    and I/O Resources are assigned.
> +
> +  @param[in] SaPolicy     -     SA DXE Policy protocol
> +
> +  @retval EFI_SUCCESS     - Pci Express successfully started and ready to be
> used
> +**/
> +EFI_STATUS
> +PciExpressInit (
> +  IN SA_POLICY_PROTOCOL *SaPolicy
> +  )
> +{
> +  EFI_STATUS                                    Status;
> +  PCIE_DXE_CONFIG                               *PcieDxeConfig;
> +  MSR_BROADWELL_PKG_CST_CONFIG_CONTROL_REGISTER Msr;
> +
> +  Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID
> *)&PcieDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +
> +  Msr.Uint64 = AsmReadMsr64
> (MSR_BROADWELL_PKG_CST_CONFIG_CONTROL);
> +  mSaNvsAreaProtocol.Area->PackageCstateLimit  = (UINT8) Msr.Bits.Limit;
> +
> +  mSaNvsAreaProtocol.Area->PwrDnBundlesGlobalEnable  = 0;
> +
> +  if (mSaConfigHob != NULL) {
> +    mSaNvsAreaProtocol.Area->Peg0PowerDownUnusedBundles  =
> mSaConfigHob->PowerDownUnusedBundles[0];
> +    mSaNvsAreaProtocol.Area->Peg1PowerDownUnusedBundles  =
> mSaConfigHob->PowerDownUnusedBundles[1];
> +    mSaNvsAreaProtocol.Area->Peg2PowerDownUnusedBundles  =
> mSaConfigHob->PowerDownUnusedBundles[2];
> +    if (SA_PEG_MAX_FUN > 3) {
> +      mSaNvsAreaProtocol.Area->Peg3PowerDownUnusedBundles  =
> mSaConfigHob->PowerDownUnusedBundles[3];
> +    }
> +  }
> +  ///
> +  /// LTR/OBFF
> +  ///
> +  mSaNvsAreaProtocol.Area->Peg0LtrEnable                =
> PcieDxeConfig->PegPwrOpt[0].LtrEnable;
> +  mSaNvsAreaProtocol.Area->Peg0ObffEnable               =
> PcieDxeConfig->PegPwrOpt[0].ObffEnable;
> +  mSaNvsAreaProtocol.Area->Peg1LtrEnable                =
> PcieDxeConfig->PegPwrOpt[1].LtrEnable;
> +  mSaNvsAreaProtocol.Area->Peg1ObffEnable               =
> PcieDxeConfig->PegPwrOpt[1].ObffEnable;
> +  mSaNvsAreaProtocol.Area->Peg2LtrEnable                =
> PcieDxeConfig->PegPwrOpt[2].LtrEnable;
> +  mSaNvsAreaProtocol.Area->Peg2ObffEnable               =
> PcieDxeConfig->PegPwrOpt[2].ObffEnable;
> +  mSaNvsAreaProtocol.Area->PegLtrMaxSnoopLatency        =
> LTR_MAX_SNOOP_LATENCY_VALUE;
> +  mSaNvsAreaProtocol.Area->PegLtrMaxNoSnoopLatency      =
> LTR_MAX_NON_SNOOP_LATENCY_VALUE;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Find the Offset to a given Capabilities ID
> +  CAPID list:
> +    0x01 = PCI Power Management Interface
> +    0x04 = Slot Identification
> +    0x05 = MSI Capability
> +    0x10 = PCI Express Capability
> +
> +  @param[in] Segment   -   Pci Segment Number
> +  @param[in] Bus       -   Pci Bus Number
> +  @param[in] Device    -   Pci Device Number
> +  @param[in] Function  -   Pci Function Number
> +  @param[in] CapId     -   CAPID to search for
> +
> +  @retval 0       - CAPID not found
> +  @retval Other   - CAPID found, Offset of desired CAPID
> +**/
> +UINT32
> +PcieFindCapId (
> +  IN UINT8   Segment,
> +  IN UINT8   Bus,
> +  IN UINT8   Device,
> +  IN UINT8   Function,
> +  IN UINT8   CapId
> +  )
> +{
> +  UINT64 DeviceBaseAddress;
> +  UINT8  CapHeader;
> +
> +  ///
> +  /// Always start at Offset 0x34
> +  ///
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device,
> Function, 0);
> +  CapHeader         = PciSegmentRead8 (DeviceBaseAddress +
> PCI_CAPBILITY_POINTER_OFFSET);
> +  if (CapHeader == 0xFF) {
> +    return 0;
> +  }
> +
> +  while (CapHeader != 0) {
> +    ///
> +    /// Bottom 2 bits of the pointers are reserved per PCI Local Bus Spec 2.2
> +    ///
> +    CapHeader &= ~(BIT1 + BIT0);
> +    ///
> +    /// Search for desired CapID
> +    ///
> +    if (PciSegmentRead8 (DeviceBaseAddress + CapHeader) == CapId) {
> +      return CapHeader;
> +    }
> +
> +    CapHeader = PciSegmentRead8 (DeviceBaseAddress + CapHeader + 1);
> +  }
> +
> +  return 0;
> +}
> +
> +/**
> +  Search and return the offset of desired Pci Express Capability ID
> +  CAPID list:
> +    0x0001 = Advanced Error Rreporting Capability
> +    0x0002 = Virtual Channel Capability
> +    0x0003 = Device Serial Number Capability
> +    0x0004 = Power Budgeting Capability
> +
> +  @param[in] Segment   -   Pci Segment Number
> +  @param[in] Bus       -   Pci Bus Number
> +  @param[in] Device    -   Pci Device Number
> +  @param[in] Function  -   Pci Function Number
> +  @param[in] CapId     -   Extended CAPID to search for
> +
> +  @retval 0       - CAPID not found
> +  @retval Other   - CAPID found, Offset of desired CAPID
> +**/
> +UINT32
> +PcieFindExtendedCapId (
> +  IN UINT8   Segment,
> +  IN UINT8   Bus,
> +  IN UINT8   Device,
> +  IN UINT8   Function,
> +  IN UINT16  CapId
> +  )
> +{
> +  UINT64  DeviceBaseAddress;
> +  UINT16  CapHeaderOffset;
> +  UINT16  CapHeaderId;
> +
> +  ///
> +  /// Start to search at Offset 0x100
> +  /// Get Capability Header
> +  ///
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device,
> Function, 0);
> +  CapHeaderId     = 0;
> +  CapHeaderOffset = 0x100;
> +
> +  while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
> +    ///
> +    /// Search for desired CapID
> +    ///
> +    CapHeaderId = PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffset);
> +    if (CapHeaderId == CapId) {
> +      return CapHeaderOffset;
> +    }
> +
> +    CapHeaderOffset = (PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffset + 2) >> 4);
> +  }
> +
> +  return 0;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
> new file mode 100644
> index 0000000000..1dc37334ae
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
> @@ -0,0 +1,171 @@
> +/** @file
> +  This file will perform SA PCIE Root Complex initialization.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PciExpressInit.h"
> +#include <Private/Library/SaPcieLib.h>
> +#include "PcieComplex.h"
> +#include <Private/Protocol/SaIotrapSmi.h>
> +#include "SaInit.h"
> +
> +///
> +/// Global variables
> +///
> +UINT16                                 mSaIotrapSmiAddress;
> +extern SA_CONFIG_HOB                   *mSaConfigHob;
> +
> +///
> +/// Functions
> +///
> +/**
> +    This function gets registered as a callback to perform all SA late
> initialization
> +
> +    @param[in] Event     - A pointer to the Event that triggered the callback.
> +    @param[in] Context   - A pointer to private data registered with the
> callback function.
> +**/
> +VOID
> +EFIAPI
> +SaLateInitSmiCallback (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  )
> +{
> +  EFI_STATUS                 Status;
> +  SA_IOTRAP_SMI_PROTOCOL     *SaIotrapSmiProtocol;
> +
> +  if (mSaIotrapSmiAddress == 0) {
> +    //
> +    // Use global variable instead of protocol data since it maybe tampered in
> unsecure environment
> +    // Get IOTrap address when first time this routine calling
> (gEfiPciEnumerationCompleteProtocolGuid callback)
> +    //
> +    SaIotrapSmiProtocol = NULL;
> +    Status = gBS->LocateProtocol (&gSaIotrapSmiProtocolGuid, NULL, (VOID **)
> &SaIotrapSmiProtocol);
> +    ASSERT_EFI_ERROR (Status);
> +    if (SaIotrapSmiProtocol != NULL) {
> +      mSaIotrapSmiAddress = SaIotrapSmiProtocol->SaIotrapSmiAddress;
> +    }
> +  }
> +
> +  ASSERT (mSaIotrapSmiAddress != 0);
> +  if (mSaIotrapSmiAddress != 0) {
> +    //
> +    // Generate IOTRAP SMI immediately
> +    //
> +    DEBUG ((DEBUG_INFO, "[SA] Issue IOTRAP SMI %X\n",
> mSaIotrapSmiAddress));
> +    IoWrite8 (mSaIotrapSmiAddress, 0);
> +  }
> +  if (Event != NULL) {
> +    gBS->CloseEvent (Event);
> +  }
> +  return;
> +}
> +
> +/**
> +  This function performs Peg initialization before EndOfDxe.
> +  @note This function will be executed as
> gEfiPciEnumerationCompleteProtocolGuid protocol callback and assumed SA
> DXE/SMM drivers have been dispatched.
> +
> +  @retval EFI_SUCCESS   - Always.
> +**/
> +EFI_STATUS
> +PegInitBeforeEndOfDxe (
> +  VOID
> +  )
> +{
> +  EFI_EVENT                       ReadyToBoot;
> +  EFI_STATUS                      Status;
> +  BOOLEAN                         AspmHasBeenHandled;
> +
> +  DEBUG ((DEBUG_INFO, "[SA] Pcie before EndOfDxe callback.\n"));
> +  AspmHasBeenHandled = FALSE;
> +  ///
> +  /// SMM mode ASPM handling
> +  /// Check if supported and enabled
> +  ///
> +  if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom
> == TRUE)) {
> +    ///
> +    /// Do the Phase 1 SMI callback
> +    /// This will enumerate PCIe downstream devices
> +    ///
> +    SaLateInitSmiCallback (NULL, NULL);
> +
> +    if (mSaIotrapSmiAddress != 0) {
> +      ///
> +      /// Create an ReadyToBoot call back event to do the Phase 3 SMI callback
> +      /// This will handle PEG ASPM programming after OROM execution
> +      /// Note: Phase 2 SMI callback will be triggered in EndOfDxe callback
> +      ///       to initialize rest of PCIe settings prior to OPROM
> +      ///
> +      Status = EfiCreateEventReadyToBootEx (
> +                 TPL_NOTIFY,
> +                 (EFI_EVENT_NOTIFY) SaLateInitSmiCallback,
> +                 NULL,
> +                 &ReadyToBoot
> +                 );
> +      ASSERT_EFI_ERROR (Status);
> +      AspmHasBeenHandled = TRUE;
> +    }
> +  }
> +
> +  ///
> +  /// DXE mode ASPM handling
> +  /// Check if SMM mode already taken care all things
> +  /// TRUE to skip DXE mode task. Otherwise do DXE mode ASPM initialization
> +  ///
> +  if (AspmHasBeenHandled == FALSE) {
> +
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function performs SA registers Saving/Restoring in EndOfDxe callback
> +
> +  @retval EFI_SUCCESS     - Save/restore has done
> +  @retval EFI_UNSUPPORTED - Save/restore not done successfully
> +**/
> +EFI_STATUS
> +SaSaveRestore (
> +  VOID
> +  )
> +{
> +  BOOLEAN                         SaveRestoreHasBeenHandled;
> +  UINT8                           SmiData;
> +
> +  SaveRestoreHasBeenHandled = FALSE;
> +
> +  if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom
> == TRUE)) {
> +    ///
> +    /// Generate the Phase 2 of SA SMI to do SA chipset save/restore and
> security lock
> +    ///
> +    SaLateInitSmiCallback (NULL, NULL);
> +
> +    if (mSaIotrapSmiAddress != 0) {
> +      ///
> +      /// Store IOTRAP SMI address into Boot Script save table
> +      /// This is required to trigger this IOTRAP during S3 resume to restore all
> settings
> +      ///
> +      SmiData = 0;
> +      S3BootScriptSaveIoWrite (
> +        S3BootScriptWidthUint8,
> +        (UINTN) mSaIotrapSmiAddress,
> +        1,
> +        &SmiData
> +        );
> +      SaveRestoreHasBeenHandled = TRUE;
> +    }
> +  }
> +
> +  ///
> +  /// Check if SMM mode already taken care this task
> +  ///
> +  if (SaveRestoreHasBeenHandled == TRUE) {
> +    return EFI_SUCCESS;
> +  } else {
> +    return EFI_UNSUPPORTED;
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
> new file mode 100644
> index 0000000000..d5a63785b4
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
> @@ -0,0 +1,496 @@
> +/** @file
> +  This is the driver that initializes the Intel System Agent.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaInitDxe.h"
> +#include "SaInit.h"
> +#include <Private/SaConfigHob.h>
> +#include <Private/Protocol/SaNvsArea.h>
> +#include <Library/PchInfoLib.h>
> +
> +///
> +/// Global Variables
> +///
> +GLOBAL_REMOVE_IF_UNREFERENCED
> SYSTEM_AGENT_NVS_AREA_PROTOCOL  mSaNvsAreaProtocol;
> +GLOBAL_REMOVE_IF_UNREFERENCED SA_POLICY_PROTOCOL
> *mSaPolicy;
> +extern SA_CONFIG_HOB                                          *mSaConfigHob;
> +
> +/**
> +  Initialize System Agent SSDT ACPI tables
> +
> +  @retval EFI_SUCCESS    ACPI tables are initialized successfully
> +  @retval EFI_NOT_FOUND  ACPI tables not found
> +**/
> +EFI_STATUS
> +InitializeSaSsdtAcpiTables (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_HANDLE                    *HandleBuffer;
> +  UINTN                         NumberOfHandles;
> +  EFI_FV_FILETYPE               FileType;
> +  UINT32                        FvStatus;
> +  EFI_FV_FILE_ATTRIBUTES        Attributes;
> +  UINTN                         Size;
> +  UINTN                         i;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
> +  INTN                          Instance;
> +  EFI_ACPI_COMMON_HEADER        *CurrentTable;
> +  UINTN                         AcpiTableKey;
> +  UINT8                         *CurrPtr;
> +  UINT8                         *EndPtr;
> +  UINT32                        *Signature;
> +  EFI_ACPI_DESCRIPTION_HEADER   *SaAcpiTable;
> +  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
> +
> +  FwVol       = NULL;
> +  SaAcpiTable = NULL;
> +
> +  ///
> +  /// Locate ACPI Table protocol
> +  ///
> +  DEBUG ((DEBUG_INFO, "Init SA SSDT table\n"));
> +  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)
> &AcpiTable);
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG ((DEBUG_WARN, "Fail to locate EfiAcpiTableProtocol.\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  ///
> +  /// Locate protocol.
> +  /// There is little chance we can't find an FV protocol
> +  ///
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiFirmwareVolume2ProtocolGuid,
> +                  NULL,
> +                  &NumberOfHandles,
> +                  &HandleBuffer
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +  ///
> +  /// Looking for FV with ACPI storage file
> +  ///
> +  for (i = 0; i < NumberOfHandles; i++) {
> +    ///
> +    /// Get the protocol on this handle
> +    /// This should not fail because of LocateHandleBuffer
> +    ///
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[i],
> +                    &gEfiFirmwareVolume2ProtocolGuid,
> +                    (VOID **) &FwVol
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    ///
> +    /// See if it has the ACPI storage file
> +    ///
> +    Size      = 0;
> +    FvStatus  = 0;
> +    Status = FwVol->ReadFile (
> +                      FwVol,
> +                      &gSaSsdtAcpiTableStorageGuid,
> +                      NULL,
> +                      &Size,
> +                      &FileType,
> +                      &Attributes,
> +                      &FvStatus
> +                      );
> +
> +    ///
> +    /// If we found it, then we are done
> +    ///
> +    if (Status == EFI_SUCCESS) {
> +      break;
> +    }
> +  }
> +  ///
> +  /// Free any allocated buffers
> +  ///
> +  FreePool (HandleBuffer);
> +
> +  ///
> +  /// Sanity check that we found our data file
> +  ///
> +  ASSERT (FwVol != NULL);
> +  if (FwVol == NULL) {
> +    DEBUG ((DEBUG_INFO, "SA Global NVS table not found\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +  ///
> +  /// Our exit status is determined by the success of the previous operations
> +  /// If the protocol was found, Instance already points to it.
> +  /// Read tables from the storage file.
> +  ///
> +  Instance      = 0;
> +  CurrentTable  = NULL;
> +  while (Status == EFI_SUCCESS) {
> +    Status = FwVol->ReadSection (
> +                      FwVol,
> +                      &gSaSsdtAcpiTableStorageGuid,
> +                      EFI_SECTION_RAW,
> +                      Instance,
> +                      (VOID **) &CurrentTable,
> +                      &Size,
> +                      &FvStatus
> +                      );
> +
> +    if (!EFI_ERROR (Status)) {
> +      ///
> +      /// Check the table ID to modify the table
> +      ///
> +      if (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->OemTableId ==
> SIGNATURE_64 ('S', 'a', 'S', 's', 'd', 't', ' ', 0)) {
> +        SaAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
> +        ///
> +        /// Locate the SSDT package
> +        ///
> +        CurrPtr = (UINT8 *) SaAcpiTable;
> +        EndPtr  = CurrPtr + SaAcpiTable->Length;
> +
> +        for (; CurrPtr <= EndPtr; CurrPtr++) {
> +          Signature = (UINT32 *) (CurrPtr + 3);
> +          if (*Signature == SIGNATURE_32 ('S', 'A', 'N', 'V')) {
> +            ASSERT (*(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) ==
> 0xFFFF0000);
> +            ASSERT (*(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof
> (UINT32) + 1) == 0xAA55);
> +            ///
> +            /// SA Global NVS Area address
> +            ///
> +            *(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) = (UINT32) (UINTN)
> mSaNvsAreaProtocol.Area;
> +            ///
> +            /// SA Global NVS Area size
> +            ///
> +            *(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) +
> 1) =
> +              sizeof (SYSTEM_AGENT_NVS_AREA);
> +
> +            AcpiTableKey = 0;
> +            Status = AcpiTable->InstallAcpiTable (
> +                                  AcpiTable,
> +                                  SaAcpiTable,
> +                                  SaAcpiTable->Length,
> +                                  &AcpiTableKey
> +                                  );
> +            ASSERT_EFI_ERROR (Status);
> +            return EFI_SUCCESS;
> +          }
> +        }
> +      }
> +      ///
> +      /// Increment the instance
> +      ///
> +      Instance++;
> +      CurrentTable = NULL;
> +    }
> +  }
> +
> +  return Status;
> +
> +}
> +
> +/**
> +  Install SSDT Table
> +
> +  @retval EFI_SUCCESS - SSDT Table load successful.
> +**/
> +EFI_STATUS
> +InstallSsdtAcpiTable (
> +  IN GUID   SsdtTableGuid,
> +  IN UINT64 Signature
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_HANDLE                    *HandleBuffer;
> +  BOOLEAN                       LoadTable;
> +  UINTN                         NumberOfHandles;
> +  UINTN                         Index;
> +  INTN                          Instance;
> +  UINTN                         Size;
> +  UINT32                        FvStatus;
> +  UINTN                         TableHandle;
> +  EFI_FV_FILETYPE               FileType;
> +  EFI_FV_FILE_ATTRIBUTES        Attributes;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
> +  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
> +  EFI_ACPI_DESCRIPTION_HEADER   *TableHeader;
> +  EFI_ACPI_COMMON_HEADER        *Table;
> +
> +  FwVol         = NULL;
> +  Table         = NULL;
> +
> +  DEBUG ((DEBUG_INFO, "Loading SSDT Table GUID: %g\n", SsdtTableGuid));
> +
> +  ///
> +  /// Locate FV protocol.
> +  ///
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiFirmwareVolume2ProtocolGuid,
> +                  NULL,
> +                  &NumberOfHandles,
> +                  &HandleBuffer
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  /// Look for FV with ACPI storage file
> +  ///
> +  for (Index = 0; Index < NumberOfHandles; Index++) {
> +    ///
> +    /// Get the protocol on this handle
> +    /// This should not fail because of LocateHandleBuffer
> +    ///
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[Index],
> +                    &gEfiFirmwareVolume2ProtocolGuid,
> +                    (VOID **) &FwVol
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +    if (FwVol == NULL) {
> +      return EFI_NOT_FOUND;
> +    }
> +    ///
> +    /// See if it has the ACPI storage file
> +    ///
> +    Size      = 0;
> +    FvStatus  = 0;
> +    Status = FwVol->ReadFile (
> +                      FwVol,
> +                      &SsdtTableGuid,
> +                      NULL,
> +                      &Size,
> +                      &FileType,
> +                      &Attributes,
> +                      &FvStatus
> +                      );
> +
> +    ///
> +    /// If we found it, then we are done
> +    ///
> +    if (!EFI_ERROR (Status)) {
> +      break;
> +    }
> +  }
> +  ///
> +  /// Our exit status is determined by the success of the previous operations
> +  /// If the protocol was found, Instance already points to it.
> +  ///
> +  ///
> +  /// Free any allocated buffers
> +  ///
> +  FreePool (HandleBuffer);
> +
> +  ///
> +  /// Sanity check that we found our data file
> +  ///
> +  ASSERT (FwVol);
> +
> +  ///
> +  /// Locate ACPI tables
> +  ///
> +  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)
> &AcpiTable);
> +
> +  ///
> +  /// Read tables from the storage file.
> +  ///
> +  if (FwVol == NULL) {
> +    ASSERT_EFI_ERROR (EFI_NOT_FOUND);
> +    return EFI_NOT_FOUND;
> +  }
> +  Instance = 0;
> +
> +  while (Status == EFI_SUCCESS) {
> +    ///
> +    /// Read the ACPI tables
> +    ///
> +    Status = FwVol->ReadSection (
> +                      FwVol,
> +                      &SsdtTableGuid,
> +                      EFI_SECTION_RAW,
> +                      Instance,
> +                      (VOID **) &Table,
> +                      &Size,
> +                      &FvStatus
> +                      );
> +    if (!EFI_ERROR (Status)) {
> +      ///
> +      /// check and load SwitchableGraphics SSDT table
> +      ///
> +      LoadTable   = FALSE;
> +      TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
> +
> +      if (((EFI_ACPI_DESCRIPTION_HEADER *) TableHeader)->OemTableId ==
> Signature) {
> +        ///
> +        /// This is the SSDT table that match the Signature
> +        ///
> +        DEBUG ((DEBUG_INFO, "Found out SSDT Table GUID: %g\n",
> SsdtTableGuid));
> +        LoadTable = TRUE;
> +      }
> +
> +      ///
> +      /// Add the table
> +      ///
> +      if (LoadTable) {
> +        TableHandle = 0;
> +        Status = AcpiTable->InstallAcpiTable (
> +                              AcpiTable,
> +                              TableHeader,
> +                              TableHeader->Length,
> +                              &TableHandle
> +                              );
> +      }
> +      ///
> +      /// Increment the instance
> +      ///
> +      Instance++;
> +      Table = NULL;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function gets registered as a callback to perform Dmar Igd
> +
> +  @param[in] Event     - A pointer to the Event that triggered the callback.
> +  @param[in] Context   - A pointer to private data registered with the
> callback function.
> +**/
> +VOID
> +EFIAPI
> +SaAcpiEndOfDxeCallback (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  )
> +{
> +  EFI_STATUS          Status;
> +
> +  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 0xFFFF) {
> +    Status = PostPmInitEndOfDxe ();
> +    if (EFI_SUCCESS != Status) {
> +      DEBUG ((DEBUG_WARN, "[SA] EndOfDxe GraphicsInit Error, Status = %r
> \n", Status));
> +      ASSERT_EFI_ERROR (Status);
> +    }
> +  }
> +
> +  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 0xFFFF) {
> +    Status = GetVBiosVbtEndOfDxe ();
> +    if (EFI_SUCCESS != Status) {
> +      DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Op Region Error, Status = %r \n",
> Status));
> +    }
> +
> +    Status = UpdateIgdOpRegionEndOfDxe ();
> +    if (EFI_SUCCESS != Status) {
> +      DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Update Op Region Error, Status
> = %r \n", Status));
> +    }
> +  }
> +
> +  return;
> +}
> +
> +/**
> +  SystemAgent Acpi Initialization.
> +
> +  @param[in] ImageHandle             Handle for the image of this driver
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
> +**/
> +EFI_STATUS
> +EFIAPI
> +SaAcpiInit (
> +  IN EFI_HANDLE         ImageHandle
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_CPUID_REGISTER        CpuidRegs;
> +  CPU_FAMILY                CpuFamilyId;
> +  EFI_EVENT                 EndOfDxeEvent;
> +
> +  CpuFamilyId = GetCpuFamily();
> +  AsmCpuid (1, &CpuidRegs.RegEax, 0, 0, 0);
> +  ///
> +  /// Get the platform setup policy.
> +  ///
> +  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **)
> &mSaPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  /// Install System Agent Global NVS protocol
> +  ///
> +  DEBUG ((DEBUG_INFO, "Install SA GNVS protocol\n"));
> +  Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof
> (SYSTEM_AGENT_NVS_AREA), (VOID **) &mSaNvsAreaProtocol.Area);
> +  ASSERT_EFI_ERROR (Status);
> +  ZeroMem ((VOID *) mSaNvsAreaProtocol.Area, sizeof
> (SYSTEM_AGENT_NVS_AREA));
> +  mSaNvsAreaProtocol.Area->XPcieCfgBaseAddress  = (UINT32) (PcdGet64
> (PcdPciExpressBaseAddress));
> +  mSaNvsAreaProtocol.Area->CpuIdInfo            = CpuidRegs.RegEax;
> +  if (mSaConfigHob != NULL) {
> +    mSaNvsAreaProtocol.Area->IpuAcpiMode =
> mSaConfigHob->IpuAcpiMode;
> +  }
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &ImageHandle,
> +                  &gSaNvsAreaProtocolGuid,
> +                  &mSaNvsAreaProtocol,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  /// PciExpress Dxe Initialization
> +  ///
> +  DEBUG ((DEBUG_INFO, "Initializing PciExpress (Dxe)\n"));
> +  PciExpressInit (mSaPolicy);
> +
> +  ///
> +  /// GtPostInit Initialization
> +  ///
> +  DEBUG ((DEBUG_INFO, "Initializing GT ACPI tables\n"));
> +
> +  GraphicsInit (ImageHandle, mSaPolicy);
> +
> +  /// Vtd Initialization
> +  ///
> +  DEBUG ((DEBUG_INFO, "Initializing VT-d ACPI tables\n"));
> +  VtdInit (mSaPolicy);
> +
> +  ///
> +  /// IgdOpRegion Install Initialization
> +  ///
> +  DEBUG ((DEBUG_INFO, "Initializing IGD OpRegion\n"));
> +  IgdOpRegionInit ();
> +
> +  ///
> +  /// Register an end of DXE event for SA ACPI to do tasks before invoking any
> UEFI drivers,
> +  /// applications, or connecting consoles,...
> +  ///
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  SaAcpiEndOfDxeCallback,
> +                  NULL,
> +                  &gEfiEndOfDxeEventGroupGuid,
> +                  &EndOfDxeEvent
> +                  );
> +
> +  ///
> +  /// Install System Agent Global NVS ACPI table
> +  ///
> +  Status = InitializeSaSsdtAcpiTables ();
> +
> +  ///
> +  /// Install PEG SSDT table only if PEG port is present
> +  ///
> +  if (IsPchLinkDmi (CpuFamilyId)) {
> +    if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, SA_PEG0_FUN_NUM,
> R_SA_PEG_DID_OFFSET)) != V_SA_DEVICE_ID_INVALID) {
> +      Status = InstallSsdtAcpiTable (gPegSsdtAcpiTableStorageGuid,
> SIGNATURE_64 ('P','e','g','S','s','d','t',0));
> +      ASSERT_EFI_ERROR (Status);
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
> new file mode 100644
> index 0000000000..40bb107ad0
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
> @@ -0,0 +1,179 @@
> +/** @file
> +  This is the Common driver that initializes the Intel System Agent.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaInit.h"
> +#include <Library/PciSegmentLib.h>
> +#include <Private/SaConfigHob.h>
> +#include <Protocol/PciEnumerationComplete.h>
> +
> +//
> +// Declare I/O Ports used to perform PCI Confguration Cycles
> +//
> +#define PCI_CONFIGURATION_ADDRESS_PORT  0xCF8
> +#define PCI_CONFIGURATION_DATA_PORT     0xCFC
> +
> +/**
> +  Convert a PCI Library address to PCI CF8 formatted address.
> +
> +  Declare macro to convert PCI Library address to PCI CF8 formatted address.
> +  Bit fields of PCI Library and CF8 formatted address is as follows:
> +  PCI Library formatted address    CF8 Formatted Address
> + =============================    ======================
> +    Bits 00..11  Register           Bits 00..07  Register
> +    Bits 12..14  Function           Bits 08..10  Function
> +    Bits 15..19  Device             Bits 11..15  Device
> +    Bits 20..27  Bus                Bits 16..23  Bus
> +    Bits 28..31  Reserved(MBZ)      Bits 24..30  Reserved(MBZ)
> +                                    Bits 31..31  Must be 1
> +
> +  @param  A The address to convert.
> +
> +  @retval The coverted address.
> +
> +**/
> +#define PCI_TO_CF8_ADDRESS(A) \
> +  ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
> +
> +///
> +/// Global Variables
> +///
> +GLOBAL_REMOVE_IF_UNREFERENCED SA_CONFIG_HOB
> *mSaConfigHob;
> +BOOLEAN                                                              mSkipPamLock =
> FALSE;
> +
> +/*
> +  Intel(R) Core Processor Skylake BWG version 0.4.0
> +
> +  18.6 System Agent Configuration Locking
> +   For reliable operation and security, System BIOS must set the following bits:
> +   1. For all modern Intel processors, Intel strongly recommends that BIOS
> should set
> +       the D_LCK bit. Set B0:D0:F0.R088h [4] = 1b to lock down SMRAM space.
> +  BaseAddr values for mSaSecurityRegisters that uses PciExpressBaseAddress
> will be initialized at
> +  Runtime inside function SaPcieInitPolicy().
> +*/
> +GLOBAL_REMOVE_IF_UNREFERENCED BOOT_SCRIPT_REGISTER_SETTING
> mSaSecurityRegisters[] = {
> +  {0,  R_SA_SMRAMC,  0xFFFFFFFF,  BIT4}
> +};
> +
> +/**
> +  SystemAgent Initialization Common Function.
> +
> +  @retval EFI_SUCCESS   - Always.
> +**/
> +
> +VOID
> +SaInitEntryPoint (
> +  VOID
> +  )
> +{
> +  ///
> +  /// Get SaConfigHob HOB
> +  ///
> +  mSaConfigHob              = NULL;
> +  mSaConfigHob              = (SA_CONFIG_HOB *) GetFirstGuidHob
> (&gSaConfigHobGuid);
> +  if (mSaConfigHob != NULL) {
> +    mSkipPamLock = mSaConfigHob->SkipPamLock;
> +  }
> +
> +  return;
> +}
> +
> +
> +
> +/**
> +  Common function locks the PAM register as part of the SA Security
> requirements.
> +
> +  @retval EFI_SUCCESS   - Always.
> +**/
> +
> +VOID
> +SaPamLock (
> +  VOID
> +  )
> +{
> +  UINT64 BaseAddress;
> +  UINT32 Data32Or;
> +
> +  if (mSkipPamLock == FALSE) {
> +    //
> +    // Lock PAM by PAM Lock Bit
> +    //
> +    BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, 0, 0, 0);
> +    Data32Or    = BIT0;
> +    DEBUG ((DEBUG_INFO, "PAM_LOCK!!\n"));
> +    PciSegmentOr32 (BaseAddress + R_SA_PAM0, Data32Or);
> +  }
> +}
> +
> +/**
> +  This function does SA security lock
> +**/
> +VOID
> +SaSecurityLock (
> +  VOID
> +  )
> +{
> +  UINT8           Index;
> +  UINT32          RegOffset;
> +  UINT32          Data32Or;
> +  UINT32          Data32;
> +  UINT8           Data8;
> +
> +  ///
> +  /// 17.2 System Agent Security Lock configuration
> +  ///
> +  DEBUG ((DEBUG_INFO, "DXE SaSecurityLock\n"));
> +  for (Index = 0; Index < (sizeof (mSaSecurityRegisters) / sizeof
> (BOOT_SCRIPT_REGISTER_SETTING)); Index++) {
> +    RegOffset   = mSaSecurityRegisters[Index].Offset;
> +    Data32Or    = mSaSecurityRegisters[Index].OrMask;
> +
> +    if (RegOffset == R_SA_SMRAMC) {
> +      ///
> +      /// SMRAMC LOCK must use CF8/CFC access
> +      ///
> +      PciCf8Or8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV,
> SA_MC_FUN, R_SA_SMRAMC), (UINT8) Data32Or);
> +      Data8 = PciCf8Read8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV,
> SA_MC_FUN, R_SA_SMRAMC));
> +      Data32 = PCI_TO_CF8_ADDRESS (PCI_CF8_LIB_ADDRESS (SA_MC_BUS,
> SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC));
> +      S3BootScriptSaveIoWrite (
> +        S3BootScriptWidthUint32,
> +        (UINTN) (PCI_CONFIGURATION_ADDRESS_PORT),
> +        1,
> +        &Data32
> +        );
> +      S3BootScriptSaveIoWrite (
> +        S3BootScriptWidthUint8,
> +        (UINTN) (PCI_CONFIGURATION_DATA_PORT),
> +        1,
> +        &Data8
> +        );
> +    }
> +  }
> +}
> +
> +/**
> +  This function performs SA Security locking in EndOfDxe callback
> +
> +  @retval EFI_SUCCESS     - Security lock has done
> +  @retval EFI_UNSUPPORTED - Security lock not done successfully
> +**/
> +EFI_STATUS
> +SaSecurityInit (
> +  VOID
> +  )
> +{
> +
> +  UINT8                     Index;
> +
> +  for (Index = 0; Index < (sizeof (mSaSecurityRegisters) / sizeof
> (BOOT_SCRIPT_REGISTER_SETTING)); Index++) {
> +    if (mSaSecurityRegisters[Index].BaseAddr != PcdGet64
> (PcdMchBaseAddress)) {
> +      mSaSecurityRegisters[Index].BaseAddr = PcdGet64
> (PcdPciExpressBaseAddress);
> +    }
> +  }
> +  SaSecurityLock ();
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
> new file mode 100644
> index 0000000000..d646e60618
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
> @@ -0,0 +1,122 @@
> +/** @file
> +  This is the driver that initializes the Intel System Agent.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaInitDxe.h"
> +#include "SaInit.h"
> +#include <Private/SaConfigHob.h>
> +#include <Protocol/PciEnumerationComplete.h>
> +#include <MemInfoHob.h>
> +
> +///
> +/// Global Variables
> +///
> +extern SA_CONFIG_HOB         *mSaConfigHob;
> +
> +/**
> +  SystemAgent Dxe Initialization.
> +
> +  @param[in] ImageHandle             Handle for the image of this driver
> +  @param[in] SystemTable             Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
> +**/
> +EFI_STATUS
> +EFIAPI
> +SaInitEntryPointDxe (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS                Status;
> +  VOID                      *Registration;
> +
> +  DEBUG ((DEBUG_INFO, "SaInitDxe Start\n"));
> +
> +  SaInitEntryPoint ();
> +
> +  Status = SaAcpiInit (ImageHandle);
> +
> +  ///
> +  /// Create PCI Enumeration Completed callback for SA
> +  ///
> +  EfiCreateProtocolNotifyEvent (
> +    &gEfiPciEnumerationCompleteProtocolGuid,
> +    TPL_CALLBACK,
> +    SaPciEnumCompleteCallback,
> +    NULL,
> +    &Registration
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "SaInitDxe End\n"));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function gets registered as a callback to perform SA initialization before
> EndOfDxe
> +
> +  @param[in] Event     - A pointer to the Event that triggered the callback.
> +  @param[in] Context   - A pointer to private data registered with the
> callback function.
> +**/
> +VOID
> +EFIAPI
> +SaPciEnumCompleteCallback (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  )
> +{
> +  EFI_STATUS          Status;
> +  VOID                *ProtocolPointer;
> +
> +  DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback Start\n"));
> +  ///
> +  /// Check if this is first time called by EfiCreateProtocolNotifyEvent() or not,
> +  /// if it is, we will skip it until real event is triggered
> +  ///
> +  Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid,
> NULL, (VOID **) &ProtocolPointer);
> +  if (EFI_SUCCESS != Status) {
> +    return;
> +  }
> +
> +  gBS->CloseEvent (Event);
> +
> +  Status = PegInitBeforeEndOfDxe ();
> +  if (EFI_SUCCESS != Status) {
> +    DEBUG ((DEBUG_WARN, "[SA] Pcie initialization before EndOfDxe Error,
> Status = %r \n", Status));
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  SaSaveRestore ();
> +  SaSecurityInit ();
> +  UpdateDmarPciEnumCompleteCallback ();
> +
> +  DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback End\n"));
> +  return;
> +}
> +
> +/**
> +  This function locks the PAM register as part of the SA Security requirements.
> +
> +  @param[in] Event     - A pointer to the Event that triggered the callback.
> +  @param[in] Context   - A pointer to private data registered with the
> callback function.
> +
> +**/
> +VOID
> +EFIAPI
> +SaPamLockDxe (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "SaPamLockDxe Start\n"));
> +
> +  SaPamLock ();
> +
> +  DEBUG ((DEBUG_INFO, "SaPamLockDxe End\n"));
> +}
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
> new file mode 100644
> index 0000000000..acbf6b7aab
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
> @@ -0,0 +1,717 @@
> +/** @file
> +  This code provides a initialization of intel VT-d (Virtualization Technology
> for Directed I/O).
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaInitDxe.h"
> +#include "SaInit.h"
> +#include "VTd.h"
> +#include <CpuRegs.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PchSerialIoLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <PchInfoHob.h>
> +#include <PchAccess.h>
> +
> +
> +extern SA_CONFIG_HOB                                          *mSaConfigHob;
> +
> +/**
> +  For device that specified by Device Num and Function Num,
> +  mDevEnMap is used to check device presence.
> +  0x80 means use Device ID to detemine presence
> +  0x8F means force to update
> +
> +  The structure is used to check if device scope is valid when update DMAR
> table
> +**/
> +UINT16  mDevEnMap[][2] = {{0x0200, 0x80}, {0x1400, 0x80}, {0x1401, 0x80},
> {0x1607, 0x8F}};
> +
> +BOOLEAN mInterruptRemappingSupport;
> +
> +/**
> +  Get the corresponding device Enable/Disable bit according DevNum and
> FunNum
> +
> +  @param[in] DevNum  - Device Number
> +  @param[in] FunNum  - Function Number
> +
> +  @retval If the device is found, return disable/Enable bit in FD/Deven
> reigster
> +  @retval If not found return 0xFF
> +**/
> +UINT16
> +GetFunDisableBit (
> +  UINT8 DevNum,
> +  UINT8 FunNum
> +  )
> +{
> +  UINTN Index;
> +
> +  for (Index = 0; Index < sizeof (mDevEnMap) / 4; Index++) {
> +    if (mDevEnMap[Index][0] == ((DevNum << 0x08) | FunNum)) {
> +      return mDevEnMap[Index][1];
> +    }
> +  }
> +
> +  return 0xFF;
> +}
> +
> +/**
> +  Update the DRHD structure
> +
> +  @param[in, out] DrhdEnginePtr       - A pointer to DRHD structure
> +**/
> +VOID
> +UpdateDrhd (
> +  IN OUT VOID *DrhdEnginePtr
> +  )
> +{
> +  UINT16                        Length;
> +  UINT16                        DisableBit;
> +  BOOLEAN                       NeedRemove;
> +  EFI_ACPI_DRHD_ENGINE1_STRUCT  *DrhdEngine;
> +
> +  //
> +  // Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE1_STRUCT Pointer
> +  //
> +  DrhdEngine      = (EFI_ACPI_DRHD_ENGINE1_STRUCT *) DrhdEnginePtr;
> +  Length          = DrhdEngine->DrhdHeader.Header.Length;
> +  DisableBit = GetFunDisableBit (
> +                 DrhdEngine->DeviceScope[0].PciPath.Device,
> +                 DrhdEngine->DeviceScope[0].PciPath.Function
> +                 );
> +  NeedRemove = FALSE;
> +
> +  if ((DisableBit == 0xFF) ||
> +      (DrhdEngine->DrhdHeader.RegisterBaseAddress == 0) ||
> +      ((DisableBit == 0x80) &&
> +       (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0,
> DrhdEngine->DeviceScope[0].PciPath.Device,
> DrhdEngine->DeviceScope[0].PciPath.Function, 0x00)) == 0xFFFFFFFF))
> +      ) {
> +    NeedRemove = TRUE;
> +  }
> +  if (NeedRemove) {
> +    Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> +  }
> +  ///
> +  /// If no devicescope is left, we set the structure length as 0x00
> +  ///
> +  if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) ||
> (DrhdEngine->DrhdHeader.Flags == 0x01)) {
> +    DrhdEngine->DrhdHeader.Header.Length = Length;
> +  } else {
> +    DrhdEngine->DrhdHeader.Header.Length = 0;
> +  }
> +}
> +
> +/**
> +  Get IOAPIC ID from LPC
> +
> +  @retval APIC ID
> +**/
> +UINT8
> +GetIoApicId (
> +  VOID
> +  )
> +{
> +  UINT32                IoApicAddress;
> +  UINT32                IoApicId;
> +
> +  IoApicAddress = PcdGet32 (PcdIoApicBaseAddress);
> +  ///
> +  /// Get current IO APIC ID
> +  ///
> +  MmioWrite8 ((UINTN) (IoApicAddress + R_IO_APIC_INDEX_OFFSET), 0);
> +  IoApicId = MmioRead32 ((UINTN) (IoApicAddress +
> R_IO_APIC_DATA_OFFSET)) >> 24;
> +
> +  return (UINT8) IoApicId;
> +}
> +
> +/**
> +  Update the second DRHD structure
> +
> +  @param[in, out] DrhdEnginePtr       - A pointer to DRHD structure
> +**/
> +VOID
> +UpdateDrhd2 (
> +  IN OUT VOID *DrhdEnginePtr
> +  )
> +{
> +  UINT16                        Length;
> +  UINTN                         DeviceScopeNum;
> +  UINTN                         ValidDeviceScopeNum;
> +  UINT16                        Index;
> +  UINT8                         Bus;
> +  UINT8                         Path[2];
> +  BOOLEAN                       NeedRemove;
> +  EFI_ACPI_DRHD_ENGINE3_STRUCT  *DrhdEngine;
> +  VOID                          *HobPtr;
> +  PCH_INFO_HOB                  *PchInfoHob;
> +
> +  ///
> +  /// Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE3_STRUCT Pointer
> +  ///
> +  DrhdEngine      = (EFI_ACPI_DRHD_ENGINE3_STRUCT *) DrhdEnginePtr;
> +
> +  Length          = DrhdEngine->DrhdHeader.Header.Length;
> +  DeviceScopeNum  = (DrhdEngine->DrhdHeader.Header.Length -
> EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) / sizeof
> (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> +  Bus             = 0;
> +  ValidDeviceScopeNum = 0;
> +  Path[0]         = 0;
> +  Path[1]         = 0;
> +
> +  HobPtr = GetFirstGuidHob (&gPchInfoHobGuid);
> +  ASSERT (HobPtr != NULL);
> +  if (HobPtr == NULL) {
> +    return;
> +  }
> +  PchInfoHob = (PCH_INFO_HOB *) GET_GUID_HOB_DATA (HobPtr);
> +  ASSERT (PchInfoHob != NULL);
> +  if (PchInfoHob == NULL) {
> +    return;
> +  }
> +
> +  for (Index = 0; Index < DeviceScopeNum; Index++) {
> +    NeedRemove = FALSE;
> +    /**
> +      For HPET and APIC, update device scope if Interrupt remapping is
> supported. remove device scope
> +      if interrupt remapping is not supported.
> +      - Index = 0 - IOAPIC
> +      - Index = 1 - HPET
> +    **/
> +    if (mInterruptRemappingSupport) {
> +      if (Index == 0) {
> +        ///
> +        /// Update source id for IoApic's device scope entry
> +        ///
> +        Bus = (UINT8) PchInfoHob->IoApicBusNum;
> +        Path[0] = (UINT8) PchInfoHob->IoApicDevNum;
> +        Path[1] = (UINT8) PchInfoHob->IoApicFuncNum;
> +
> DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNum
> ber = Bus;
> +        DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
> +        DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
> +        //
> +        // Update APIC ID
> +        //
> +
> DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.EnumerationI
> d = GetIoApicId ();
> +      }
> +      if (Index == 1) {
> +        ///
> +        /// Update source id for HPET's device scope entry
> +        ///
> +        Bus     = (UINT8) PchInfoHob->HpetBusNum;
> +        Path[0] = (UINT8) PchInfoHob->HpetDevNum;
> +        Path[1] = (UINT8) PchInfoHob->HpetFuncNum;
> +
> DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNum
> ber = Bus;
> +        DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
> +        DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
> +      }
> +    } else {
> +      if ((Index == 0) || (Index == 1)) {
> +        NeedRemove = TRUE;
> +      }
> +    }
> +
> +    CopyMem (
> +      &DrhdEngine->DeviceScope[ValidDeviceScopeNum],
> +      &DrhdEngine->DeviceScope[Index],
> +      sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
> +      );
> +    if (NeedRemove) {
> +      Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> +    } else {
> +      ValidDeviceScopeNum++;
> +    }
> +  }
> +  ///
> +  /// If no devicescope is left, we set the structure length as 0x00
> +  ///
> +  if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) ||
> (DrhdEngine->DrhdHeader.Flags == 0x01)) {
> +    DrhdEngine->DrhdHeader.Header.Length = Length;
> +  } else {
> +    DrhdEngine->DrhdHeader.Header.Length = 0;
> +  }
> +}
> +
> +/**
> +  Update the RMRR structure
> +
> +  @param[in, out] RmrrPtr             - A pointer to RMRR structure
> +**/
> +VOID
> +UpdateRmrr (
> +  IN OUT VOID *RmrrPtr
> +  )
> +{
> +  UINT16                  Length;
> +  UINT16                  DisableBit;
> +  UINTN                   DeviceScopeNum;
> +  UINTN                   ValidDeviceScopeNum;
> +  UINTN                   Index;
> +  BOOLEAN                 NeedRemove;
> +  EFI_ACPI_RMRR_USB_STRUC *Rmrr;
> +
> +  ///
> +  /// To make sure all devicescope can be checked,
> +  /// we convert the RmrrPtr to EFI_ACPI_RMRR_USB_STRUC pointer
> +  ///
> +  Rmrr                = (EFI_ACPI_RMRR_USB_STRUC *) RmrrPtr;
> +
> +  Length              = Rmrr->RmrrHeader.Header.Length;
> +  ValidDeviceScopeNum = 0;
> +  DeviceScopeNum      = (Rmrr->RmrrHeader.Header.Length -
> EFI_ACPI_RMRR_HEADER_LENGTH) / sizeof
> (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> +  for (Index = 0; Index < DeviceScopeNum; Index++) {
> +    DisableBit = GetFunDisableBit (
> +                   Rmrr->DeviceScope[Index].PciPath.Device,
> +                   Rmrr->DeviceScope[Index].PciPath.Function
> +                   );
> +    NeedRemove = FALSE;
> +    if ((DisableBit == 0xFF) ||
> +        ((DisableBit == 0x80) &&
> +         (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0,
> Rmrr->DeviceScope[Index].PciPath.Device,
> Rmrr->DeviceScope[Index].PciPath.Function, 0x00)) == 0xFFFFFFFF))
> +        ) {
> +      NeedRemove = TRUE;
> +    } else if (DisableBit == 0x8F) {
> +      NeedRemove = FALSE;
> +    }
> +    CopyMem (
> +      &Rmrr->DeviceScope[ValidDeviceScopeNum],
> +      &Rmrr->DeviceScope[Index],
> +      sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
> +      );
> +
> +    if (Rmrr->RmrrHeader.ReservedMemoryRegionLimitAddress == 0x0) {
> +      NeedRemove = TRUE;
> +    }
> +
> +    if (NeedRemove) {
> +      Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> +    } else {
> +      ValidDeviceScopeNum++;
> +    }
> +  }
> +  ///
> +  /// If No deviceScope is left, set length as 0x00
> +  ///
> +  if (Length > EFI_ACPI_RMRR_HEADER_LENGTH) {
> +    Rmrr->RmrrHeader.Header.Length = Length;
> +  } else {
> +    Rmrr->RmrrHeader.Header.Length = 0;
> +  }
> +}
> +
> +/**
> +  Update the DMAR table
> +
> +  @param[in, out] TableHeader         - The table to be set
> +  @param[in, out] Version             - Version to publish
> +**/
> +VOID
> +DmarTableUpdate (
> +  IN OUT   EFI_ACPI_DESCRIPTION_HEADER       *TableHeader,
> +  IN OUT   EFI_ACPI_TABLE_VERSION            *Version
> +  )
> +{
> +  EFI_ACPI_DMAR_TABLE *DmarTable;
> +  EFI_ACPI_DMAR_TABLE TempDmarTable;
> +  UINTN               Offset;
> +  UINTN               StructureLen;
> +  UINT64              McD0BaseAddress;
> +  UINTN               MchBar;
> +  UINT16              IgdMode;
> +  UINT16              GttMode;
> +  UINT32              IgdMemSize;
> +  UINT32              GttMemSize;
> +  EFI_STATUS          Status;
> +  MISC_DXE_CONFIG     *MiscDxeConfig;
> +
> +  IgdMemSize  = 0;
> +  GttMemSize  = 0;
> +  DmarTable   = (EFI_ACPI_DMAR_TABLE *) TableHeader;
> +
> +  Status = GetConfigBlock ((VOID *) mSaPolicy, &gMiscDxeConfigGuid, (VOID
> *)&MiscDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  /// Set INTR_REMAP bit (BIT 0) if interrupt remapping is supported
> +  ///
> +  if (mInterruptRemappingSupport) {
> +    DmarTable->DmarHeader.Flags |= BIT0;
> +  }
> +
> +  if (mSaConfigHob->VtdData.X2ApicOptOut == 1) {
> +    DmarTable->DmarHeader.Flags |= BIT1;
> +  } else {
> +    DmarTable->DmarHeader.Flags &= 0xFD;
> +  }
> +
> +  ///
> +  /// Get OemId
> +  ///
> +  CopyMem (DmarTable->DmarHeader.Header.OemId, PcdGetPtr
> (PcdAcpiDefaultOemId), sizeof (DmarTable->DmarHeader.Header.OemId));
> +  DmarTable->DmarHeader.Header.OemTableId      = PcdGet64
> (PcdAcpiDefaultOemTableId);
> +  DmarTable->DmarHeader.Header.OemRevision     = PcdGet32
> (PcdAcpiDefaultOemRevision);
> +  DmarTable->DmarHeader.Header.CreatorId       = PcdGet32
> (PcdAcpiDefaultCreatorId);
> +  DmarTable->DmarHeader.Header.CreatorRevision = PcdGet32
> (PcdAcpiDefaultCreatorRevision);
> +
> +  ///
> +  /// Calculate IGD memsize
> +  ///
> +  McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 0, 0, 0);
> +  MchBar          = PciSegmentRead32 (McD0BaseAddress + R_SA_MCHBAR)
> & ~BIT0;
> +  IgdMode = ((PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) &
> B_SA_GGC_GMS_MASK) >> N_SA_GGC_GMS_OFFSET) & 0xFF;
> +  if (IgdMode < 0xF0) {
> +    IgdMemSize = IgdMode * 32 * (1024) * (1024);
> +  } else {
> +    IgdMemSize = 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024);
> +  }
> +  ///
> +  /// Calculate GTT mem size
> +  ///
> +  GttMemSize = 0;
> +  GttMode = (PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) &
> B_SA_GGC_GGMS_MASK) >> N_SA_GGC_GGMS_OFFSET;
> +  if (GttMode <= V_SA_GGC_GGMS_8MB) {
> +    GttMemSize = (1 << GttMode) * (1024) * (1024);
> +  }
> +
> +  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress   =
> (PciSegmentRead32 (McD0BaseAddress + R_SA_TOLUD) & ~(0x01)) -
> IgdMemSize - GttMemSize;
> +  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress  =
> DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress +
> IgdMemSize + GttMemSize - 1;
> +  DEBUG ((DEBUG_INFO, "RMRR Base  address IGD %016lX\n",
> DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress));
> +  DEBUG ((DEBUG_INFO, "RMRR Limit address IGD %016lX\n",
> DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress));
> +
> +  DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress
> = MiscDxeConfig->RmrrUsbBaseAddress[0];
> +  DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress
> = MiscDxeConfig->RmrrUsbBaseAddress[1];
> +
> +  ///
> +  /// Convert to 4KB alignment.
> +  ///
> +  if
> (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress !=
> 0x0) {
> +    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress
> &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
> +    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress
> &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
> +    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress
> += 0x1000-1;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "RMRR Base  address USB %016lX\n",
> DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress));
> +  DEBUG ((DEBUG_INFO, "RMRR Limit address USB %016lX\n",
> DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress));
> +
> +  if (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress
> == 0) {
> +    DEBUG ((DEBUG_WARN, "WARNING:
> RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress is 0.\n"));
> +  }
> +
> +  DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress
> = MiscDxeConfig->RmrrCsmeBaseAddress[0];
> +  DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress
> = MiscDxeConfig->RmrrCsmeBaseAddress[1];
> +  DEBUG ((DEBUG_INFO, "RMRR Base  address CSME %016lX\n",
> DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress));
> +  DEBUG ((DEBUG_INFO, "RMRR Limit address CSME %016lX\n",
> DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress));
> +  ///
> +  /// Update DRHD structures of DmarTable
> +  ///
> +  DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress =
> (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
> +  DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress =
> (MmioRead32 (MchBar + R_SA_MCHBAR_VTD3_OFFSET) &~1);
> +
> +  DEBUG ((DEBUG_INFO, "VTD base address1 %x\n",
> DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress));
> +  DEBUG ((DEBUG_INFO, "VTD base address3 %x\n",
> DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress));
> +  ///
> +  /// copy DmarTable to TempDmarTable to be processed
> +  ///
> +  CopyMem (&TempDmarTable, DmarTable, sizeof (EFI_ACPI_DMAR_TABLE));
> +
> +  ///
> +  /// Update DRHD structures of temp DMAR table
> +  ///
> +  UpdateDrhd (&TempDmarTable.DrhdEngine1);
> +  UpdateDrhd2 (&TempDmarTable.DrhdEngine3);
> +
> +  ///
> +  /// Update RMRR structures of temp DMAR table
> +  ///
> +  UpdateRmrr ((VOID *) &TempDmarTable.RmrrUsb);
> +  UpdateRmrr ((VOID *) &TempDmarTable.RmrrIgd);
> +  UpdateRmrr ((VOID *) &TempDmarTable.RmrrCsme);
> +
> +  ///
> +  /// Remove unused device scope or entire DRHD structures
> +  ///
> +  Offset = (UINTN) (&TempDmarTable.DrhdEngine1);
> +  if (TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length != 0) {
> +    Offset += TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length;
> +  }
> +  if (TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length != 0) {
> +    StructureLen = TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length;
> +    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.DrhdEngine3,
> TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length);
> +    Offset += StructureLen;
> +  }
> +  ///
> +  /// Remove unused device scope or entire RMRR structures
> +  ///
> +  if (TempDmarTable.RmrrUsb.RmrrHeader.Header.Length != 0) {
> +    StructureLen = TempDmarTable.RmrrUsb.RmrrHeader.Header.Length;
> +    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrUsb,
> TempDmarTable.RmrrUsb.RmrrHeader.Header.Length);
> +    Offset += StructureLen;
> +  }
> +  if (TempDmarTable.RmrrIgd.RmrrHeader.Header.Length != 0) {
> +    StructureLen = TempDmarTable.RmrrIgd.RmrrHeader.Header.Length;
> +    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrIgd,
> TempDmarTable.RmrrIgd.RmrrHeader.Header.Length);
> +    Offset += StructureLen;
> +  }
> +  if (TempDmarTable.RmrrCsme.RmrrHeader.Header.Length != 0) {
> +    StructureLen = TempDmarTable.RmrrCsme.RmrrHeader.Header.Length;
> +    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrCsme,
> TempDmarTable.RmrrCsme.RmrrHeader.Header.Length);
> +    Offset += StructureLen;
> +  }
> +
> +  Offset = Offset - (UINTN) &TempDmarTable;
> +  ///
> +  /// Re-calculate DMAR table check sum
> +  ///
> +  TempDmarTable.DmarHeader.Header.Checksum = (UINT8)
> (TempDmarTable.DmarHeader.Header.Checksum +
> TempDmarTable.DmarHeader.Header.Length - Offset);
> +  ///
> +  /// Set DMAR table length
> +  ///
> +  TempDmarTable.DmarHeader.Header.Length = (UINT32) Offset;
> +  ///
> +  /// Replace DMAR table with rebuilt table TempDmarTable
> +  ///
> +  CopyMem ((VOID *) DmarTable, (VOID *) &TempDmarTable,
> TempDmarTable.DmarHeader.Header.Length);
> +}
> +
> +/**
> +  PciEnumerationComplete routine for update DMAR
> +**/
> +VOID
> +UpdateDmarPciEnumCompleteCallback (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_HANDLE                      *HandleBuffer;
> +  UINTN                           NumberOfHandles;
> +  EFI_FV_FILETYPE                 FileType;
> +  UINT32                          FvStatus;
> +  EFI_FV_FILE_ATTRIBUTES          Attributes;
> +  UINTN                           Size;
> +  UINTN                           i;
> +  INTN                            Instance;
> +  EFI_ACPI_TABLE_VERSION          Version;
> +  EFI_ACPI_COMMON_HEADER          *CurrentTable;
> +  UINTN                           AcpiTableHandle;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL   *FwVol;
> +  EFI_ACPI_TABLE_PROTOCOL         *AcpiTable;
> +  EFI_ACPI_DESCRIPTION_HEADER     *VtdAcpiTable;
> +  STATIC BOOLEAN                  Triggered = FALSE;
> +
> +
> +  if (Triggered) {
> +    return;
> +  }
> +
> +  Triggered     = TRUE;
> +
> +  FwVol         = NULL;
> +  AcpiTable     = NULL;
> +  VtdAcpiTable  = NULL;
> +
> +  DEBUG ((DEBUG_INFO, "UpdateDmarPciEnumCompleteCallback \n"));
> +
> +
> +  ///
> +  /// Fix DMAR Table always created, skip install when disabled
> +  ///
> +  if ((mSaConfigHob->VtdData.VtdDisable == TRUE) || (PciSegmentRead32
> (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0,
> R_SA_MC_CAPID0_A_OFFSET)) & BIT23)) {
> +    DEBUG ((DEBUG_INFO, "Vtd Disabled, skip DMAR Table install\n"));
> +    return;
> +  }
> +
> +
> +  ///
> +  /// Locate ACPI support protocol
> +  ///
> +  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)
> &AcpiTable);
> +
> +  ///
> +  /// Locate protocol.
> +  /// There is little chance we can't find an FV protocol
> +  ///
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiFirmwareVolume2ProtocolGuid,
> +                  NULL,
> +                  &NumberOfHandles,
> +                  &HandleBuffer
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  /// Looking for FV with ACPI storage file
> +  ///
> +  for (i = 0; i < NumberOfHandles; i++) {
> +    ///
> +    /// Get the protocol on this handle
> +    /// This should not fail because of LocateHandleBuffer
> +    ///
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[i],
> +                    &gEfiFirmwareVolume2ProtocolGuid,
> +                    (VOID **) &FwVol
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    ///
> +    /// See if it has the ACPI storage file
> +    ///
> +    Size      = 0;
> +    FvStatus  = 0;
> +    Status = FwVol->ReadFile (
> +                      FwVol,
> +                      &gSaAcpiTableStorageGuid,
> +                      NULL,
> +                      &Size,
> +                      &FileType,
> +                      &Attributes,
> +                      &FvStatus
> +                      );
> +
> +    ///
> +    /// If we found it, then we are done
> +    ///
> +    if (Status == EFI_SUCCESS) {
> +      break;
> +    }
> +  }
> +  ///
> +  /// Our exit status is determined by the success of the previous operations
> +  /// If the protocol was found, Instance already points to it.
> +  ///
> +  ///
> +  /// Free any allocated buffers
> +  ///
> +  FreePool (HandleBuffer);
> +
> +  ///
> +  /// Sanity check that we found our data file
> +  ///
> +  ASSERT (FwVol);
> +  if (FwVol == NULL) {
> +    return;
> +  }
> +  ///
> +  /// By default, a table belongs in all ACPI table versions published.
> +  ///
> +  Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0
> | EFI_ACPI_TABLE_VERSION_3_0;
> +
> +  ///
> +  /// Read tables from the storage file.
> +  ///
> +  Instance      = 0;
> +  CurrentTable  = NULL;
> +
> +  while (Status == EFI_SUCCESS) {
> +    Status = FwVol->ReadSection (
> +                      FwVol,
> +                      &gSaAcpiTableStorageGuid,
> +                      EFI_SECTION_RAW,
> +                      Instance,
> +                      (VOID **) &CurrentTable,
> +                      &Size,
> +                      &FvStatus
> +                      );
> +
> +    if (!EFI_ERROR (Status)) {
> +      ///
> +      /// Check the Signature ID to modify the table
> +      ///
> +      switch (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Signature) {
> +
> +        case EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE:
> +          VtdAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
> +          DmarTableUpdate (VtdAcpiTable, &Version);
> +          break;
> +
> +        default:
> +          break;
> +      }
> +      ///
> +      /// Increment the instance
> +      ///
> +      Instance++;
> +      CurrentTable = NULL;
> +    }
> +  }
> +  ///
> +  /// Update the VTD table in the ACPI tables.
> +  ///
> +  AcpiTableHandle = 0;
> +  if (VtdAcpiTable != NULL) {
> +    Status = AcpiTable->InstallAcpiTable (
> +                          AcpiTable,
> +                          VtdAcpiTable,
> +                          VtdAcpiTable->Length,
> +                          &AcpiTableHandle
> +                          );
> +    FreePool (VtdAcpiTable);
> +  }
> +}
> +
> +/**
> +  Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
> +  Publish the appropriate SSDT based on current configuration and
> capabilities.
> +
> +  @param[in] SaPolicy     -  SA DXE Policy protocol
> +
> +  @retval EFI_SUCCESS     - Vtd initialization complete
> +  @exception EFI_UNSUPPORTED - Vtd is not enabled by policy
> +**/
> +EFI_STATUS
> +VtdInit (
> +  IN  SA_POLICY_PROTOCOL    *SaPolicy
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINT64                          McD0BaseAddress;
> +  UINT64                          McD2BaseAddress;
> +  UINTN                           MchBar;
> +  SYSTEM_AGENT_NVS_AREA_PROTOCOL  *SaNvsAreaProtocol;
> +
> +  mInterruptRemappingSupport  = FALSE;
> +  mSaConfigHob       = NULL;
> +  mSaConfigHob = GetFirstGuidHob (&gSaConfigHobGuid);
> +  if (mSaConfigHob != NULL) {
> +    mInterruptRemappingSupport  =
> mSaConfigHob->VtdData.InterruptRemappingSupport;
> +  }
> +
> +  ///
> +  ///  Locate the SA Global NVS Protocol.
> +  ///
> +  Status = gBS->LocateProtocol (
> +                  &gSaNvsAreaProtocolGuid,
> +                  NULL,
> +                  (VOID **) &SaNvsAreaProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  McD0BaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 0, 0, 0);
> +  McD2BaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0);
> +  mSaPolicy        = SaPolicy;
> +  MchBar           = PciSegmentRead32(McD0BaseAddress + R_SA_MCHBAR)
> & ~BIT0;
> +
> +  if (mSaConfigHob != NULL) {
> +    SaNvsAreaProtocol->Area->VtdDisable =
> mSaConfigHob->VtdData.VtdDisable;
> +  }
> +  SaNvsAreaProtocol->Area->VtdBaseAddress1 = (MmioRead32(MchBar +
> R_SA_MCHBAR_VTD1_OFFSET) &~1);
> +  SaNvsAreaProtocol->Area->VtdBaseAddress3 = (MmioRead32(MchBar +
> R_SA_MCHBAR_VTD3_OFFSET) &~1);
> +  SaNvsAreaProtocol->Area->VtdEngine1Vid =
> PciSegmentRead16(McD2BaseAddress + PCI_VENDOR_ID_OFFSET);
> +
> +  if (mSaConfigHob != NULL) {
> +    if ((mSaConfigHob->VtdData.VtdDisable) || (PciSegmentRead32
> (McD0BaseAddress + R_SA_MC_CAPID0_A_OFFSET) & BIT23)) {
> +      DEBUG ((DEBUG_WARN, "VTd disabled or no capability!\n"));
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  ///
> +  /// Check SA supports VTD and VTD is enabled in setup menu
> +  ///
> +  DEBUG ((DEBUG_INFO, "VTd enabled\n"));
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.c
> new file mode 100644
> index 0000000000..08fd9266c6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.c
> @@ -0,0 +1,356 @@
> +/** @file
> +  This is the driver that publishes the SMM Access Protocol
> +  instance for System Agent.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SmmAccessDriver.h"
> +
> +static SMM_ACCESS_PRIVATE_DATA  mSmmAccess;
> +
> +
> +/**
> +  This is the standard EFI driver point that
> +  installs an SMM Access Protocol
> +
> +  @param[in] ImageHandle     - Handle for the image of this driver
> +  @param[in] SystemTable     - Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS           - Protocol was installed successfully
> +  @exception EFI_UNSUPPORTED    - Protocol was not installed
> +  @retval EFI_NOT_FOUND         - Protocol can't be found.
> +  @retval EFI_OUT_OF_RESOURCES  - Protocol does not have enough
> resources to initialize the driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmAccessDriverEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           Index;
> +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
> +  EFI_PEI_HOB_POINTERS            *Hob;
> +
> +  ///
> +  /// --cr-- INITIALIZE_SCRIPT (ImageHandle, SystemTable);
> +  ///
> +  /// Initialize Global variables
> +  ///
> +  ZeroMem (&mSmmAccess, sizeof (mSmmAccess));
> +
> +  mSmmAccess.Signature        = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
> +  mSmmAccess.Handle           = NULL;
> +
> +  ///
> +  /// Get Hob list
> +  ///
> +  Hob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
> +  if (Hob == NULL) {
> +    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  DescriptorBlock = (VOID *) ((UINT8 *) Hob + sizeof (EFI_HOB_GUID_TYPE));
> +
> +  ///
> +  /// Alloc space for mSmmAccess.SmramDesc
> +  ///
> +  mSmmAccess.SmramDesc = AllocateZeroPool
> ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof
> (EFI_SMRAM_DESCRIPTOR));
> +  if (mSmmAccess.SmramDesc == NULL) {
> +    DEBUG ((DEBUG_WARN, "Alloc mSmmAccess.SmramDesc fail.\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "Alloc mSmmAccess.SmramDesc success.\n"));
> +
> +  ///
> +  /// Use the HOB to publish SMRAM capabilities
> +  ///
> +  for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions;
> Index++) {
> +    mSmmAccess.SmramDesc[Index].PhysicalStart =
> DescriptorBlock->Descriptor[Index].PhysicalStart;
> +    mSmmAccess.SmramDesc[Index].CpuStart      =
> DescriptorBlock->Descriptor[Index].CpuStart;
> +    mSmmAccess.SmramDesc[Index].PhysicalSize  =
> DescriptorBlock->Descriptor[Index].PhysicalSize;
> +    mSmmAccess.SmramDesc[Index].RegionState   =
> DescriptorBlock->Descriptor[Index].RegionState;
> +  }
> +
> +  mSmmAccess.NumberRegions              = Index;
> +  mSmmAccess.SmmAccess.Open             = Open;
> +  mSmmAccess.SmmAccess.Close            = Close;
> +  mSmmAccess.SmmAccess.Lock             = Lock;
> +  mSmmAccess.SmmAccess.GetCapabilities  = GetCapabilities;
> +  mSmmAccess.SmmAccess.LockState        = FALSE;
> +  mSmmAccess.SmmAccess.OpenState        = FALSE;
> +
> +  ///
> +  /// Install our protocol interfaces on the device's handle
> +  ///
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &mSmmAccess.Handle,
> +                  &gEfiSmmAccess2ProtocolGuid,
> +                  &mSmmAccess.SmmAccess,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_WARN, "InstallMultipleProtocolInterfaces returned
> %r\n", Status));
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "open" a region of SMRAM.  The
> +  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> +  The use of "open" means that the memory is visible from all boot-service
> +  and SMM agents.
> +
> +  @param[in] This               - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR      - The region could not be opened because
> locked by
> +                          chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Open (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINT64                  Address;
> +  UINT8                   SmramControl;
> +  UINTN                   DescriptorIndex;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> +      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
> +      return EFI_DEVICE_ERROR;
> +    }
> +  }
> +
> +  ///
> +  /// BEGIN CHIPSET SPECIFIC CODE
> +  ///
> +  ///
> +  /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
> +  ///
> +  Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN,
> R_SA_SMRAMC);
> +
> +  SmramControl = PciRead8 (Address);
> +  ///
> +  ///  Is SMRAM locked?
> +  ///
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
> +      ///
> +      /// Cannot Open a locked region
> +      ///
> +      SmmAccess->SmramDesc[DescriptorIndex].RegionState |=
> EFI_SMRAM_LOCKED;
> +      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
> +      return EFI_DEVICE_ERROR;
> +    }
> +  }
> +  ///
> +  /// Open SMRAM region
> +  ///
> +  SmramControl |= B_SA_SMRAMC_D_OPEN_MASK;
> +  SmramControl &= ~(B_SA_SMRAMC_D_CLS_MASK);
> +
> +  PciWrite8 (Address, SmramControl);
> +  ///
> +  /// END CHIPSET SPECIFIC CODE
> +  ///
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> EFI_SMRAM_OPEN;
> +  }
> +  SmmAccess->SmmAccess.OpenState = TRUE;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "close" a region of SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "close" means that the memory is only visible from SMM agents,
> +  not from BS or RT code.
> +
> +  @param[in] This               - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR      - The region could not be closed because
> locked by chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Close (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINT64                  Address;
> +  UINT8                   SmramControl;
> +  BOOLEAN                 OpenState;
> +  UINT8                   Index;
> +  UINTN                   DescriptorIndex;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> +      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
> +      continue;
> +    }
> +
> +    ///
> +    /// BEGIN CHIPSET SPECIFIC CODE
> +    ///
> +    ///
> +    /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
> +    ///
> +    Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN,
> R_SA_SMRAMC);
> +
> +    SmramControl = PciRead8 (Address);
> +    ///
> +    ///  Is SMRAM locked?
> +    ///
> +    if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
> +      ///
> +      /// Cannot Close a locked region
> +      ///
> +      SmmAccess->SmramDesc[DescriptorIndex].RegionState |=
> EFI_SMRAM_LOCKED;
> +      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
> +      return EFI_DEVICE_ERROR;
> +    }
> +    ///
> +    /// Close SMRAM region
> +    ///
> +    SmramControl &= ~(B_SA_SMRAMC_D_OPEN_MASK);
> +
> +    PciWrite8 (Address, SmramControl);
> +    ///
> +    /// END CHIPSET SPECIFIC CODE
> +    ///
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> ~EFI_SMRAM_OPEN;
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> +  }
> +
> +  ///
> +  /// Find out if any regions are still open
> +  ///
> +  OpenState = FALSE;
> +  for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
> +    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) ==
> EFI_SMRAM_OPEN) {
> +      OpenState = TRUE;
> +    }
> +  }
> +
> +  SmmAccess->SmmAccess.OpenState = OpenState;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "lock" SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "lock" means that the memory can no longer be opened
> +  to BS state..
> +
> +  @param[in] This               - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR      - The region could not be locked because at
> least
> +                                  one range is still open.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Lock (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINT64                  Address;
> +  UINT8                   SmramControl;
> +  UINTN                   DescriptorIndex;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> +  if (SmmAccess->SmmAccess.OpenState) {
> +    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are
> still open\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |=
> EFI_SMRAM_LOCKED;
> +  }
> +  SmmAccess->SmmAccess.LockState = TRUE;
> +
> +  ///
> +  /// BEGIN CHIPSET SPECIFIC CODE
> +  ///
> +  ///
> +  /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
> +  ///
> +  Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN,
> R_SA_SMRAMC);
> +
> +  SmramControl = PciRead8 (Address);
> +  ///
> +  /// Lock the SMRAM
> +  ///
> +  SmramControl |= B_SA_SMRAMC_D_LCK_MASK;
> +
> +  PciWrite8 (Address, SmramControl);
> +  ///
> +  /// END CHIPSET SPECIFIC CODE
> +  ///
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine services a user request to discover the SMRAM
> +  capabilities of this platform.  This will report the possible
> +  ranges that are possible for SMRAM access, based upon the
> +  memory controller capabilities.
> +
> +  @param[in] This                  - Pointer to the SMRAM Access Interface.
> +  @param[in] SmramMapSize          - Pointer to the variable containing size
> of the
> +                                     buffer to contain the description information.
> +  @param[in] SmramMap              - Buffer containing the data describing
> the Smram
> +                                     region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetCapabilities (
> +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> +  IN OUT UINTN                       *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> +  )
> +{
> +  EFI_STATUS              Status;
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINTN                   NecessaryBufferSize;
> +
> +  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> +  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof
> (EFI_SMRAM_DESCRIPTOR);
> +
> +  if (*SmramMapSize < NecessaryBufferSize) {
> +    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
> +    Status = EFI_BUFFER_TOO_SMALL;
> +  } else {
> +    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  *SmramMapSize = NecessaryBufferSize;
> +
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.asl
> c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.asl
> c
> new file mode 100644
> index 0000000000..c864a0ca8f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.asl
> c
> @@ -0,0 +1,250 @@
> +/** @file
> +  This file describes the contents of the ACPI DMA address Remapping
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "Dmar.h"
> +#include <Register/PchRegsP2sb.h>
> +
> +EFI_ACPI_DMAR_TABLE DmarTable = {
> +  //
> +  // EFI_ACPI_DMAR_HEADER
> +  //
> +  {
> +    //
> +    // EFI_ACPI_DESCRIPTION_HEADER
> +    //
> +    {
> +      EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE,
> +      sizeof (EFI_ACPI_DMAR_TABLE),
> +      EFI_ACPI_DMAR_TABLE_REVISION,
> +
> +      //
> +      // Checksum will be updated at runtime
> +      //
> +      0x00,
> +
> +      //
> +      // It is expected that these values will be programmed at runtime
> +      //
> +      { 'I', 'N', 'T', 'E', 'L', ' ' },
> +      EFI_ACPI_DMAR_OEM_TABLE_ID,
> +      0x1,
> +      EFI_ACPI_DMAR_OEM_CREATOR_ID,
> +      1
> +    },
> +
> +    //
> +    // DMAR table specific entries below:
> +    //
> +
> +    //
> +    // 39-bit addressing Host Address Width
> +    //
> +    38,
> +
> +    //
> +    // Flags
> +    //
> +    0,
> +
> +    //
> +    // Reserved fields
> +    //
> +    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
> +  },
> +
> +  //
> +  // First DRHD structure, VT-d Engine #1
> +  //
> +  {
> +    //
> +    // EFI_ACPI_DMAR_DRHD_HEADER
> +    //
> +    {
> +      {0,                                         // Type = 0 (DRHD)
> +      sizeof (EFI_ACPI_DRHD_ENGINE1_STRUCT)},     // Length of structure
> +      0,                                          // Flag - Do not include all
> +      0,                                          // Reserved fields
> +      0,                                          // Segment
> +      0                                           // Base address of DMA-remapping
> hardware - Updated at boot time
> +    },
> +    //
> +    // Device Scopes
> +    //
> +    {
> +      {
> +        {1,                                     // Type
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),  // Length
> +        0,                                      // Segment number
> +        0,                                      // Reserved
> +        0},                                     // Start bus number
> +        {2, 0}                                  // PCI path
> +      }
> +    }
> +  },
> +
> +  //
> +  //Third DRHD structure VT-d Engine# 3
> +  //
> +  {
> +    //
> +    // EFI_ACPI_DMAR_DRHD_HEADER
> +    //
> +    {
> +      {0,                                        // Type = 0 (DRHD)
> +      sizeof (EFI_ACPI_DRHD_ENGINE3_STRUCT)},    // Length of strucure.
> +      1,                                         // Flag - Include all
> +      0,                                         // Reserved
> +      0,                                         // Segment Number
> +      0                                          // Base address of DMA-remapping
> hardware.
> +    },
> +    {
> +      //
> +      // Device Scopes
> +      //
> +      {
> +        {3,                                          // Type=IO APIC
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),       // Length
> +        0,                                           // Reserved
> +        2,                                           // Enumeration ID
> +        V_P2SB_CFG_IBDF_BUS},                        // Start bus number
> +        {V_P2SB_CFG_IBDF_DEV, V_P2SB_CFG_IBDF_FUNC}  // PCI path
> +      },
> +      //
> +      // Device Scopes
> +      //
> +      {
> +        {4,                                          // Type=HPET
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),       // Length
> +        0,                                           // Reserved
> +        0,                                           // Enumeration ID
> +        V_P2SB_CFG_HBDF_BUS},                        // Start bus number
> +        {V_P2SB_CFG_HBDF_DEV, V_P2SB_CFG_HBDF_FUNC}  // PCI path
> +      }
> +    }
> +  },
> +  //RMRR structure for USB devices.
> +  {
> +    //
> +    // EFI_ACPI_DMAR_RMRR_HEADER
> +    //
> +    {
> +      {
> +        0x1,                                     // Type 1 - RMRR structure
> +        sizeof(EFI_ACPI_RMRR_USB_STRUC)          // Length
> +      },
> +      { 0x00, 0x00 },                            // Reserved
> +      0x0000,                                    // Segment Num
> +      0x00000000000E0000,                        // RMRR Base address - Updated
> in runtime.
> +      0x00000000000EFFFF                         // RMRR Limit address - Updated
> in runtime.
> +    },
> +    //
> +    // Device Scopes
> +    //
> +    {
> +      {
> +        {1,                                    // Type
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> +        0,                                     // Reserved
> +        0,                                     // Enum ID
> +        0},                                    // Start bus number
> +        {20, 0}                                // PCI path
> +      },
> +      {
> +        {1,                                    // Type
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> +        0,                                     // Reserved
> +        0,                                     // Enum ID
> +        0},                                    // Start bus number
> +        {20, 1}                                // PCI path
> +      }
> +    }
> +  },
> +
> +  //RMRR structure for IGD device.
> +  {
> +    //
> +    // EFI_ACPI_DMAR_RMRR_HEADER
> +    //
> +    {
> +      {1,                                       // Type 1 - RMRR structure
> +      sizeof (EFI_ACPI_RMRR_IGD_STRUC)},        // Length
> +      {0x0000},                                 // Reserved
> +      0x0000,                                   // Segment Num
> +      0x0000000000000000,                       // RMRR Base address - Updated
> in runtime.
> +      0x0000000000000000                        // RMRR Limit address - Updated
> in runtime.
> +    },
> +    //
> +    // Device Scopes
> +    //
> +    {
> +      {
> +        {1,                                   // Type
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> +        0,                                    // Reserved
> +        0,                                    // Enum ID
> +        0},                                   // Start bus number
> +        {2, 0}                                // PCI path
> +      }
> +    }
> +  },
> +
> +  // RMRR structure for WiAMT DMA access.
> +  // Keep this device in end of RMRR queue.
> +  {
> +    //
> +    // EFI_ACPI_DMAR_RMRR_HEADER
> +    //
> +    {
> +      {1,                                       // Type 1 - RMRR structure
> +      sizeof (EFI_ACPI_RMRR_CSME_STRUC)},       // Length
> +      {0x0000},                                 // Reserved
> +      0x0000,                                   // Segment Num
> +      0x0000000000000000,                       // RMRR Base address - Updated
> in runtime.
> +      0x0000000000000000                        // RMRR Limit address - Updated
> in runtime.
> +    },
> +    //
> +    // Device Scopes
> +    //
> +    {
> +      {
> +        {1,                                   // Type
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> +        0,                                    // Reserved
> +        0,                                    // Enum ID
> +        0},                                   // Start bus number
> +        {22, 7}                               // PCI path
> +      }
> +    }
> +  }
> +};
> +
> +//
> +// Dummy function required for build tools
> +//
> +#if defined (__GNUC__)
> +VOID*
> +ReferenceAcpiTable (
> +  VOID
> +  )
> +
> +{
> +  //
> +  // Reference the table being generated to prevent the optimizer from
> removing the
> +  // data structure from the exeutable
> +  //
> +  return (VOID*)&DmarTable;
> +}
> +#else
> +int
> +main (
> +  VOID
> +  )
> +{
> +  return 0;
> +}
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
> new file mode 100644
> index 0000000000..b431a77f05
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
> @@ -0,0 +1,794 @@
> +/** @file
> +  This file contains the SystemAgent PCI Configuration space
> +  definition.
> +  It defines various System Agent PCI Configuration Space registers
> +  which will be used to dynamically produce all resources in the Host Bus.
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +External(M64B)
> +External(M64L)
> +External(M32B)
> +External(M32L)
> +
> +//
> +// Define various System Agent (SA) PCI Configuration Space
> +// registers which will be used to dynamically produce all
> +// resources in the Host Bus _CRS.
> +//
> +OperationRegion (HBUS, PCI_Config, 0x00, 0x100)
> +Field (HBUS, DWordAcc, NoLock, Preserve)
> +{
> +  Offset(0x40),   // EPBAR (0:0:0:40)
> +  EPEN, 1,        // Enable
> +      , 11,
> +  EPBR, 20,       // EPBAR [31:12]
> +
> +  Offset(0x48),   // MCHBAR (0:0:0:48)
> +  MHEN, 1,        // Enable
> +      , 14,
> +  MHBR, 17,       // MCHBAR [31:15]
> +
> +  Offset(0x50),   // GGC (0:0:0:50)
> +  GCLK, 1,        // GGCLCK
> +
> +  Offset(0x54),   // DEVEN (0:0:0:54)
> +  D0EN, 1,        // DEV0 Enable
> +  D1F2, 1,        // DEV1 FUN2 Enable
> +  D1F1, 1,        // DEV1 FUN1 Enable
> +  D1F0, 1,        // DEV1 FUN0 Enable
> +
> +  Offset(0x60),   // PCIEXBAR (0:0:0:60)
> +  PXEN, 1,        // Enable
> +  PXSZ, 2,        // PCI Express Size
> +      , 23,
> +  PXBR, 6,        // PCI Express BAR [31:26]
> +
> +  Offset(0x68),   // DMIBAR (0:0:0:68)
> +  DIEN, 1,        // Enable
> +      , 11,
> +  DIBR, 20,       // DMIBAR [31:12]
> +
> +  Offset(0x70),   // MESEG_BASE (0:0:0:70)
> +      , 20,
> +  MEBR, 12,       // MESEG_BASE [31:20]
> +
> +  Offset(0x80),   // PAM0 Register (0:0:0:80)
> +  PMLK, 1,        // PAM Lock bit.
> +      , 3,
> +  PM0H, 2,        // PAM 0, High Nibble
> +      , 2,
> +
> +  Offset(0x81),   // PAM1 Register (0:0:0:81)
> +  PM1L, 2,        // PAM1, Low  Nibble
> +      , 2,
> +  PM1H, 2,        // PAM1, High Nibble
> +      , 2,
> +
> +  Offset(0x82),   // PAM2 Register (0:0:0:82)
> +  PM2L, 2,        // PAM2, Low  Nibble
> +      , 2,
> +  PM2H, 2,        // PAM2, High Nibble
> +      , 2,
> +
> +  Offset(0x83),   // PAM3 Register (0:0:0:83)
> +  PM3L, 2,        // PAM3, Low  Nibble
> +      , 2,
> +  PM3H, 2,        // PAM3, High Nibble
> +      , 2,
> +
> +  Offset(0x84),   // PAM4 Register (0:0:0:84)
> +  PM4L, 2,        // PAM4, Low  Nibble
> +      , 2,
> +  PM4H, 2,        // PAM4, High Nibble
> +      , 2,
> +
> +  Offset(0x85),   // PAM5 Register (0:0:0:85)
> +  PM5L, 2,        // PAM5, Low  Nibble
> +      , 2,
> +  PM5H, 2,        // PAM5, High Nibble
> +      , 2,
> +
> +  Offset(0x86),   // PAM6 Register (0:0:0:86)
> +  PM6L, 2,        // PAM6, Low  Nibble
> +      , 2,
> +  PM6H, 2,        // PAM6, High Nibble
> +      , 2,
> +
> +  Offset(0xA8),   // Top of Upper Usable DRAM Register (0:0:0:A8)
> +      , 20,
> +  TUUD, 19,       // TOUUD [38:20]
> +
> +  Offset(0xBC),   // Top of Lower Usable DRAM Register (0:0:0:BC)
> +      , 20,
> +  TLUD, 12,       // TOLUD [31:20]
> +
> +  Offset(0xC8),   // ERRSTS register (0:0:0:C8)
> +      , 7,
> +  HTSE, 1         // Host Thermal Sensor Event for SMI/SCI/SERR
> +}
> +//
> +// Define a buffer that will store all the bus, memory, and IO information
> +// relating to the Host Bus.  This buffer will be dynamically altered in
> +// the _CRS and passed back to the OS.
> +//
> +Name(BUF0,ResourceTemplate()
> +{
> +  //
> +  // Bus Number Allocation: Bus 0 to 0xFF
> +  //
> +  WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00,
> +    0x0000,0x00FF,0x00,0x0100,,,PB00)
> +
> +  //
> +  // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 )
> +  //
> +  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
> +    0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00)
> +
> +  //
> +  // PCI Configuration Registers ( 0x0CF8 - 0x0CFF )
> +  //
> +  Io(Decode16,0x0CF8,0x0CF8,1,0x08)
> +
> +  //
> +  // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF )
> +  //
> +  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
> +    0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01)
> +
> +  //
> +  // Video Buffer Area ( 0xA0000 - 0xBFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00)
> +
> +  //
> +  // BIOS Extension Area ( 0xE0000 - 0xE3FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000)
> +
> +  //
> +  // BIOS Extension Area ( 0xE4000 - 0xE7FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400)
> +
> +  //
> +  // BIOS Extension Area ( 0xE8000 - 0xEBFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800)
> +
> +  //
> +  // BIOS Extension Area ( 0xEC000 - 0xEFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00)
> +
> +  //
> +  // BIOS Area ( 0xF0000 - 0xFFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000)
> +
> +//  //
> +//  // Memory Hole Region ( 0xF00000 - 0xFFFFFF )
> +//  //
> +//
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +//    ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE)
> +
> +  //
> +  // PCI Memory Region ( TOLUD - 0xDFFFFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> +    ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01)
> +
> +  //
> +  // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) )
> +  // (This is dummy range for OS compatibility, will patch it in _CRS)
> +  //
> +
> QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> +    ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
> +
> +  //
> +  // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> +    ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03)
> +})
> +
> +  //
> +  // SA reserved resources
> +  //
> +  Device(SRRE) {
> +    Name(_HID,EISAID("PNP0C02")) // motherboard resource
> +    Name(_UID,"SARESV")
> +    Method(_STA,0,Serialized) // device present and decodes its resources,
> but not to be displayed in OSPM
> +    {
> +      If(LGreaterEqual(TLUD, 0x404)) {
> +        Return (3)
> +      } Else {
> +        Return (0)
> +      }
> +    }
> +
> +    Method(_CRS,0,Serialized)
> +    {
> +      Name(BUF0,ResourceTemplate(){
> +        //
> +        // Reserve the 0x40000000 ~ 0x403FFFFF to prevent other driver use this
> memory range
> +        //
> +        Memory32Fixed(ReadOnly,0x40000000,0x400000)
> +      })
> +      If(LGreaterEqual(TLUD, 0x404)) {
> +        Return (BUF0)
> +      } Else {
> +        Return (Buffer(){})
> +      }
> +    }
> +  }
> +
> +Name(EP_B, 0) // to store EP BAR
> +Name(MH_B, 0) // to store MCH BAR
> +Name(PC_B, 0) // to store PCIe BAR
> +Name(PC_L, 0) // to store PCIe BAR Length
> +Name(DM_B, 0) // to store DMI BAR
> +
> +//
> +// Get EP BAR
> +//
> +Method(GEPB,0,Serialized)
> +{
> +  if(LEqual(EP_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.EPBR,12,EP_B)
> +  }
> +  Return(EP_B)
> +}
> +
> +//
> +// Get MCH BAR
> +//
> +Method(GMHB,0,Serialized)
> +{
> +  if(LEqual(MH_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.MHBR,15,MH_B)
> +  }
> +  Return(MH_B)
> +}
> +
> +//
> +// Get PCIe BAR
> +//
> +Method(GPCB,0,Serialized)
> +{
> +  if(LEqual(PC_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.PXBR,26,PC_B)
> +  }
> +  Return(PC_B)
> +}
> +
> +//
> +// Get PCIe Length
> +//
> +Method(GPCL,0,Serialized)
> +{
> +  if(LEqual(PC_L,0)) {
> +    ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L)
> +  }
> +  Return(PC_L)
> +}
> +
> +//
> +// Get DMI BAR
> +//
> +Method(GDMB,0,Serialized)
> +{
> +  if(LEqual(DM_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.DIBR,12,DM_B)
> +  }
> +  Return(DM_B)
> +}
> +
> +
> +Method(_CRS,0,Serialized)
> +{
> +  //
> +  // Fix up Max Bus Number and Length
> +  //
> +  Store(\_SB.PCI0.GPCL(),Local0)
> +  CreateWordField(BUF0, ^PB00._MAX, PBMX)
> +  Store(Subtract(ShiftRight(Local0,20),2), PBMX)
> +  CreateWordField(BUF0, ^PB00._LEN, PBLN)
> +  Store(Subtract(ShiftRight(Local0,20),1), PBLN)
> +  //
> +  // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF.
> +  //
> +  If(PM1L)  // \_SB.PCI0
> +  {
> +    // PAMx != 0.  Set length = 0.
> +
> +    CreateDwordField(BUF0, ^C000._LEN,C0LN)
> +    Store(Zero,C0LN)
> +  }
> +
> +  If(LEqual(PM1L,1))
> +  {
> +    CreateBitField(BUF0, ^C000._RW,C0RW)
> +    Store(Zero,C0RW)
> +  }
> +
> +  If(PM1H)
> +  {
> +    CreateDwordField(BUF0, ^C400._LEN,C4LN)
> +    Store(Zero,C4LN)
> +  }
> +
> +  If(LEqual(PM1H,1))
> +  {
> +    CreateBitField(BUF0, ^C400._RW,C4RW)
> +    Store(Zero,C4RW)
> +  }
> +
> +  If(PM2L)
> +  {
> +    CreateDwordField(BUF0, ^C800._LEN,C8LN)
> +    Store(Zero,C8LN)
> +  }
> +
> +  If(LEqual(PM2L,1))
> +  {
> +    CreateBitField(BUF0, ^C800._RW,C8RW)
> +    Store(Zero,C8RW)
> +  }
> +
> +  If(PM2H)
> +  {
> +    CreateDwordField(BUF0, ^CC00._LEN,CCLN)
> +    Store(Zero,CCLN)
> +  }
> +
> +  If(LEqual(PM2H,1))
> +  {
> +    CreateBitField(BUF0, ^CC00._RW,CCRW)
> +    Store(Zero,CCRW)
> +  }
> +
> +  If(PM3L)
> +  {
> +    CreateDwordField(BUF0, ^D000._LEN,D0LN)
> +    Store(Zero,D0LN)
> +  }
> +
> +  If(LEqual(PM3L,1))
> +  {
> +    CreateBitField(BUF0, ^D000._RW,D0RW)
> +    Store(Zero,D0RW)
> +  }
> +
> +  If(PM3H)
> +  {
> +    CreateDwordField(BUF0, ^D400._LEN,D4LN)
> +    Store(Zero,D4LN)
> +  }
> +
> +  If(LEqual(PM3H,1))
> +  {
> +    CreateBitField(BUF0, ^D400._RW,D4RW)
> +    Store(Zero,D4RW)
> +  }
> +
> +  If(PM4L)
> +  {
> +    CreateDwordField(BUF0, ^D800._LEN,D8LN)
> +    Store(Zero,D8LN)
> +  }
> +
> +  If(LEqual(PM4L,1))
> +  {
> +    CreateBitField(BUF0, ^D800._RW,D8RW)
> +    Store(Zero,D8RW)
> +  }
> +
> +  If(PM4H)
> +  {
> +    CreateDwordField(BUF0, ^DC00._LEN,DCLN)
> +    Store(Zero,DCLN)
> +  }
> +
> +  If(LEqual(PM4H,1))
> +  {
> +    CreateBitField(BUF0, ^DC00._RW,DCRW)
> +    Store(Zero,DCRW)
> +  }
> +
> +  If(PM5L)
> +  {
> +    CreateDwordField(BUF0, ^E000._LEN,E0LN)
> +    Store(Zero,E0LN)
> +  }
> +
> +  If(LEqual(PM5L,1))
> +  {
> +    CreateBitField(BUF0, ^E000._RW,E0RW)
> +    Store(Zero,E0RW)
> +  }
> +
> +  If(PM5H)
> +  {
> +    CreateDwordField(BUF0, ^E400._LEN,E4LN)
> +    Store(Zero,E4LN)
> +  }
> +
> +  If(LEqual(PM5H,1))
> +  {
> +    CreateBitField(BUF0, ^E400._RW,E4RW)
> +    Store(Zero,E4RW)
> +  }
> +
> +  If(PM6L)
> +  {
> +    CreateDwordField(BUF0, ^E800._LEN,E8LN)
> +    Store(Zero,E8LN)
> +  }
> +
> +  If(LEqual(PM6L,1))
> +  {
> +    CreateBitField(BUF0, ^E800._RW,E8RW)
> +    Store(Zero,E8RW)
> +  }
> +
> +  If(PM6H)
> +  {
> +    CreateDwordField(BUF0, ^EC00._LEN,ECLN)
> +    Store(Zero,ECLN)
> +  }
> +
> +  If(LEqual(PM6H,1))
> +  {
> +    CreateBitField(BUF0, ^EC00._RW,ECRW)
> +    Store(Zero,ECRW)
> +  }
> +
> +  If(PM0H)
> +  {
> +    CreateDwordField(BUF0, ^F000._LEN,F0LN)
> +    Store(Zero,F0LN)
> +  }
> +
> +  If(LEqual(PM0H,1))
> +  {
> +    CreateBitField(BUF0, ^F000._RW,F0RW)
> +    Store(Zero,F0RW)
> +  }
> +
> +  // Enable the 1MB region between 15-16MB if HENA = 1.
> +  //
> +  // If( MCHC.HENA)
> +  // {
> +  // CreateDwordField(BUF0, HOLE._LEN,H0LN)
> +  // Store(0x100000,H0LN)
> +  // }
> +
> +  //
> +  // Create pointers to Memory Sizing values.
> +  //
> +  CreateDwordField(BUF0, ^PM01._MIN,M1MN)
> +  CreateDwordField(BUF0, ^PM01._MAX,M1MX)
> +  CreateDwordField(BUF0, ^PM01._LEN,M1LN)
> +
> +  //
> +  // Set Memory Size Values. TLUD represents bits 31:20 of phyical
> +  // TOM, so shift these bits into the correct position and fix up
> +  // the Memory Region available to PCI.
> +  //
> +  Store (M32L, M1LN)
> +  Store (M32B, M1MN)
> +  Subtract (Add (M1MN, M1LN), 1, M1MX)
> +
> +  //
> +  // Create pointers to Memory Sizing values.
> +  // Patch PM02 range basing on memory size and OS type
> +  //
> +  If (LEqual(M64L, 0)) {
> +    CreateQwordField(BUF0, ^PM02._LEN,MSLN)
> +    //
> +    // Set resource length to 0
> +    //
> +    Store (0, MSLN)
> +  }
> +  Else {
> +    CreateQwordField(BUF0, ^PM02._LEN,M2LN)
> +    CreateQwordField(BUF0, ^PM02._MIN,M2MN)
> +    CreateQwordField(BUF0, ^PM02._MAX,M2MX)
> +    //
> +    // Set 64bit MMIO resource Base and Length
> +    //
> +    Store (M64L, M2LN)
> +    Store (M64B, M2MN)
> +    Subtract (Add (M2MN, M2LN), 1, M2MX)
> +  }
> +  Return(BUF0)
> +}
> +
> +//
> +//Name(GUID,UUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))
> +//
> +Name(GUID,Buffer(){0x5b, 0x4d, 0xdb, 0x33,
> +          0xf7, 0x1f,
> +          0x1c, 0x40,
> +          0x96, 0x57,
> +          0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66})
> +
> +
> +Name(SUPP,0)  // PCI _OSC Support Field value
> +Name(CTRL,0)  // PCI _OSC Control Field value
> +Name(XCNT, 0) // Variable used in _OSC for counting
> +
> +Method(_OSC,4,Serialized)
> +{
> +  //
> +  // Check for proper UUID
> +  // Save the capabilities buffer
> +  //
> +  Store(Arg3,Local0)
> +
> +  //
> +  // Create DWord-adressable fields from the Capabilties Buffer
> +  //
> +  CreateDWordField(Local0,0,CDW1)
> +  CreateDWordField(Local0,4,CDW2)
> +  CreateDWordField(Local0,8,CDW3)
> +
> +
> +  //
> +  // Check for proper UUID
> +  //
> +  If(LEqual(Arg0,GUID))
> +  {
> +    // Save Capabilities DWord2 & 3
> +    Store(CDW2,SUPP)
> +    Store(CDW3,CTRL)
> +
> +    //
> +    // You can clear bits in CTRL here if you don't want OS to take
> +    // control
> +    //
> +    If(LNot(NEXP))
> +    {
> +      And(CTRL, 0xFFFFFFF8, CTRL)       // disable Native hot plug, PME
> +    }
> +
> +    If(LEqual(TBTS, 1)) {
> +      // \_OSC disallow only Advanced Error Reporting control
> +      And(CTRL, 0xFFFFFFF7, CTRL)
> +    }
> +
> +    If(Not(And(CDW1,1)))  // Query flag clear?
> +    { // Disable GPEs for features granted native control.
> +      If(And(CTRL,0x01))
> +      {
> +        NHPG()
> +      }
> +      If(And(CTRL,0x04))  // PME control granted?
> +      {
> +        NPME()
> +      }
> +    }
> +
> +    If(LNotEqual(Arg1,One))
> +    {
> +      //
> +      // Unknown revision
> +      //
> +      Or(CDW1,0x08,CDW1)
> +    }
> +
> +    If(LNotEqual(CDW3,CTRL))
> +    {
> +      //
> +      // Capabilities bits were masked
> +      //
> +      Or(CDW1,0x10,CDW1)
> +    }
> +    //
> +    // Update DWORD3 in the buffer
> +    //
> +    Store(CTRL,CDW3)
> +    Store(CTRL,OSCC)
> +    Return(Local0)
> +  } Else {
> +    Or(CDW1,4,CDW1)   // Unrecognized UUID
> +    Return(Local0)
> +  }
> +} // End _OSC
> +
> +//
> +// Added code for Dual IRQ support. Two set of ACPI IRQ tables were
> generated.
> +// Code has been added to select the appropriate IRQ table by checking the
> CPUID.
> +//
> +Scope(\_SB.PCI0)
> +{
> +  Method(AR00) {
> +    Return(\_SB.AR00)
> +  }
> +
> +  Method(PD00) {
> +    Return(\_SB.PD00)
> +  }
> +
> +  Method(AR02) {
> +    Return(\_SB.AR02)
> +  }
> +
> +  Method(PD02) {
> +    Return(\_SB.PD02)
> +  }
> +
> +  Method(AR04) {
> +    Return(\_SB.AR04)
> +  }
> +
> +  Method(PD04) {
> +    Return(\_SB.PD04)
> +  }
> +
> +  Method(AR05) {
> +    Return(\_SB.AR05)
> +  }
> +
> +  Method(PD05) {
> +    Return(\_SB.PD05)
> +  }
> +
> +  Method(AR06) {
> +    Return(\_SB.AR06)
> +  }
> +
> +  Method(PD06) {
> +    Return(\_SB.PD06)
> +  }
> +
> +  Method(AR07) {
> +    Return(\_SB.AR07)
> +  }
> +
> +  Method(PD07) {
> +    Return(\_SB.PD07)
> +  }
> +
> +  Method(AR08) {
> +    Return(\_SB.AR08)
> +  }
> +
> +  Method(PD08) {
> +    Return(\_SB.PD08)
> +  }
> +
> +  Method(AR09) {
> +    Return(\_SB.AR09)
> +  }
> +
> +  Method(PD09) {
> +    Return(\_SB.PD09)
> +  }
> +
> +  Method(AR0A) {
> +    Return(\_SB.AR0A)
> +  }
> +
> +  Method(PD0A) {
> +    Return(\_SB.PD0A)
> +  }
> +
> +  Method(AR0B) {
> +    Return(\_SB.AR0B)
> +  }
> +
> +  Method(PD0B) {
> +    Return(\_SB.PD0B)
> +  }
> +
> +  //
> +  // Add device scope definition for System Agent
> +  // P.E.G. Root Port D1F0
> +  //
> +  Device(PEG0) {
> +    Name(_ADR, 0x00010000)
> +    Device(PEGP) { // P.E.G. Port Slot x16
> +      Name(_ADR, 0x00000000)
> +    }
> +  }
> +  //
> +  // P.E.G. Root Port D1F1
> +  //
> +  Device(PEG1) {
> +    Name(_ADR, 0x00010001)
> +    Device(PEGP) { // P.E.G. Port Slot x8
> +      Name(_ADR, 0x00000000)
> +    }
> +  }
> +  //
> +  // P.E.G. Root Port D1F2
> +  //
> +  Device(PEG2) {
> +    Name(_ADR, 0x00010002)
> +    Device(PEGP) { // P.E.G. Port Slot x4
> +      Name(_ADR, 0x00000000)
> +    }
> +  }
> +  //
> +  // I.G.D
> +  //
> +  Device(GFX0) {
> +    Name(_ADR, 0x00020000)
> +  }
> +  //
> +  // SA Thermal Device
> +  //
> +  Device(B0D4) {
> +    Method(_DSM,4,serialized){if(PCIC(Arg0))
> { return(PCID(Arg0,Arg1,Arg2,Arg3)) }; Return(Buffer() {0})}
> +    Name(_ADR, 0x00040000)
> +  }
> +  //
> +  // Device IPU0 is the IPU PCI device
> +  //
> +  Device(IPU0) {
> +    Name(_ADR, 0x00050000)
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
> new file mode 100644
> index 0000000000..e7a797c973
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
> @@ -0,0 +1,1666 @@
> +/** @file
> +  This file contains the IGD OpRegion/Software ACPI Reference
> +  Code.
> +  It defines the methods to enable/disable output switching,
> +  store display switching and LCD brightness BIOS control
> +  and return valid addresses for all display device encoders
> +  present in the system, etc.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +External(\ECST, MethodObj)
> +External(\PBCL, MethodObj)
> +External(HDOS, MethodObj)
> +External(\ECON, IntObj)
> +External(\PNHM, IntObj)
> +External(OSYS, IntObj)
> +External(CPSC)
> +External(\GUAM, MethodObj)
> +External(DSEN)
> +External(S0ID)
> +
> +Name(TMP1,Package() {0xFFFFFFFF})
> +Name(TMP2,Package() {0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP3,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP4,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP5,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF})
> +Name(TMP6,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP7,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP8,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF})
> +Name(TMP9,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMPA,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF })
> +Name(TMPB,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMPC,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMPD,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF})
> +Name(TMPE,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMPF,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF})
> +Name(TMPG,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF})
> +
> +// Enable/Disable Output Switching.  In WIN2K/WINXP, _DOS = 0 will
> +// get called during initialization to prepare for an ACPI Display
> +// Switch Event.  During an ACPI Display Switch, the OS will call
> +// _DOS = 2 immediately after a Notify=0x80 to temporarily disable
> +// all Display Switching.  After ACPI Display Switching is complete,
> +// the OS will call _DOS = 0 to re-enable ACPI Display Switching.
> +Method(_DOS,1)
> +{
> +  //
> +  // Store Display Switching and LCD brightness BIOS control bit
> +  //
> +  Store(And(Arg0,7),DSEN)
> +
> +  If(LEqual(And(Arg0,  0x3), 0))     // If _DOS[1:0]=0
> +  {
> +    If(CondRefOf(HDOS))
> +    {
> +      HDOS()
> +    }
> +  }
> +}
> +
> +//
> +// Enumerate the Display Environment.  This method will return
> +// valid addresses for all display device encoders present in the
> +// system.  The Miniport Driver will reject the addresses for every
> +// encoder that does not have an attached display device.  After
> +// enumeration is complete, the OS will call the _DGS methods
> +// during a display switch only for the addresses accepted by the
> +// Miniport Driver.  For hot-insertion and removal of display
> +// devices, a re-enumeration notification will be required so the
> +// address of the newly present display device will be accepted by
> +// the Miniport Driver.
> +//
> +Method(_DOD,0)
> +{
> +  If (LEqual(IPTP,1)) {
> +    //
> +    // Increment number of devices if IPU is enabled
> +    //
> +    Store(1, NDID)
> +  } Else {
> +    Store(0, NDID)
> +  }
> +
> +  If(LNotEqual(DIDL, Zero))
> +  {
> +    Store(SDDL(DIDL),DID1)
> +  }
> +  If(LNotEqual(DDL2, Zero))
> +  {
> +    Store(SDDL(DDL2),DID2)
> +  }
> +  If(LNotEqual(DDL3, Zero))
> +  {
> +    Store(SDDL(DDL3),DID3)
> +  }
> +  If(LNotEqual(DDL4, Zero))
> +  {
> +    Store(SDDL(DDL4),DID4)
> +  }
> +  If(LNotEqual(DDL5, Zero))
> +  {
> +    Store(SDDL(DDL5),DID5)
> +  }
> +  If(LNotEqual(DDL6, Zero))
> +  {
> +    Store(SDDL(DDL6),DID6)
> +  }
> +  If(LNotEqual(DDL7, Zero))
> +  {
> +    Store(SDDL(DDL7),DID7)
> +  }
> +  If(LNotEqual(DDL8, Zero))
> +  {
> +    Store(SDDL(DDL8),DID8)
> +  }
> +  If(LNotEqual(DDL9, Zero))
> +  {
> +    Store(SDDL(DDL9),DID9)
> +  }
> +  If(LNotEqual(DD10, Zero))
> +  {
> +    Store(SDDL(DD10),DIDA)
> +  }
> +  If(LNotEqual(DD11, Zero))
> +  {
> +    Store(SDDL(DD11),DIDB)
> +  }
> +  If(LNotEqual(DD12, Zero))
> +  {
> +    Store(SDDL(DD12),DIDC)
> +  }
> +  If(LNotEqual(DD13, Zero))
> +  {
> +    Store(SDDL(DD13),DIDD)
> +  }
> +  If(LNotEqual(DD14, Zero))
> +  {
> +    Store(SDDL(DD14),DIDE)
> +  }
> +  If(LNotEqual(DD15, Zero))
> +  {
> +    Store(SDDL(DD15),DIDF)
> +  }
> +
> +  //
> +  // Enumerate the encoders. Note that for
> +  // current silicon, the maximum number of encoders
> +  // possible is 15.
> +  //
> +  If(LEqual(NDID,1))
> +  {
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMP1,0))
> +    } Else {
> +      Store(Or(0x10000,DID1),Index(TMP1,0))
> +    }
> +    Return(TMP1)
> +  }
> +
> +  If(LEqual(NDID,2))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMP2,0))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMP2,1))
> +    } Else {
> +      Store(Or(0x10000,DID2),Index(TMP2,1))
> +    }
> +    Return(TMP2)
> +  }
> +
> +  If(LEqual(NDID,3))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMP3,0))
> +    Store(Or(0x10000,DID2),Index(TMP3,1))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMP3,2))
> +    } Else {
> +      Store(Or(0x10000,DID3),Index(TMP3,2))
> +    }
> +    Return(TMP3)
> +  }
> +
> +  If(LEqual(NDID,4))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMP4,0))
> +    Store(Or(0x10000,DID2),Index(TMP4,1))
> +    Store(Or(0x10000,DID3),Index(TMP4,2))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMP4,3))
> +    } Else {
> +      Store(Or(0x10000,DID4),Index(TMP4,3))
> +    }
> +    Return(TMP4)
> +  }
> +
> +  If(LEqual(NDID,5))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMP5,0))
> +    Store(Or(0x10000,DID2),Index(TMP5,1))
> +    Store(Or(0x10000,DID3),Index(TMP5,2))
> +    Store(Or(0x10000,DID4),Index(TMP5,3))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMP5,4))
> +    } Else {
> +      Store(Or(0x10000,DID5),Index(TMP5,4))
> +    }
> +    Return(TMP5)
> +  }
> +
> +  If(LEqual(NDID,6))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMP6,0))
> +    Store(Or(0x10000,DID2),Index(TMP6,1))
> +    Store(Or(0x10000,DID3),Index(TMP6,2))
> +    Store(Or(0x10000,DID4),Index(TMP6,3))
> +    Store(Or(0x10000,DID5),Index(TMP6,4))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMP6,5))
> +    } Else {
> +      Store(Or(0x10000,DID6),Index(TMP6,5))
> +    }
> +    Return(TMP6)
> +  }
> +
> +  If(LEqual(NDID,7))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMP7,0))
> +    Store(Or(0x10000,DID2),Index(TMP7,1))
> +    Store(Or(0x10000,DID3),Index(TMP7,2))
> +    Store(Or(0x10000,DID4),Index(TMP7,3))
> +    Store(Or(0x10000,DID5),Index(TMP7,4))
> +    Store(Or(0x10000,DID6),Index(TMP7,5))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMP7,6))
> +    } Else {
> +      Store(Or(0x10000,DID7),Index(TMP7,6))
> +    }
> +    Return(TMP7)
> +  }
> +
> +  If(LEqual(NDID,8))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMP8,0))
> +    Store(Or(0x10000,DID2),Index(TMP8,1))
> +    Store(Or(0x10000,DID3),Index(TMP8,2))
> +    Store(Or(0x10000,DID4),Index(TMP8,3))
> +    Store(Or(0x10000,DID5),Index(TMP8,4))
> +    Store(Or(0x10000,DID6),Index(TMP8,5))
> +    Store(Or(0x10000,DID7),Index(TMP8,6))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMP8,7))
> +    } Else {
> +      Store(Or(0x10000,DID8),Index(TMP8,7))
> +    }
> +    Return(TMP8)
> +  }
> +
> +  If(LEqual(NDID,9))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMP9,0))
> +    Store(Or(0x10000,DID2),Index(TMP9,1))
> +    Store(Or(0x10000,DID3),Index(TMP9,2))
> +    Store(Or(0x10000,DID4),Index(TMP9,3))
> +    Store(Or(0x10000,DID5),Index(TMP9,4))
> +    Store(Or(0x10000,DID6),Index(TMP9,5))
> +    Store(Or(0x10000,DID7),Index(TMP9,6))
> +    Store(Or(0x10000,DID8),Index(TMP9,7))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMP9,8))
> +    } Else {
> +      Store(Or(0x10000,DID9),Index(TMP9,8))
> +    }
> +    Return(TMP9)
> +  }
> +
> +  If(LEqual(NDID,0x0A))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMPA,0))
> +    Store(Or(0x10000,DID2),Index(TMPA,1))
> +    Store(Or(0x10000,DID3),Index(TMPA,2))
> +    Store(Or(0x10000,DID4),Index(TMPA,3))
> +    Store(Or(0x10000,DID5),Index(TMPA,4))
> +    Store(Or(0x10000,DID6),Index(TMPA,5))
> +    Store(Or(0x10000,DID7),Index(TMPA,6))
> +    Store(Or(0x10000,DID8),Index(TMPA,7))
> +    Store(Or(0x10000,DID9),Index(TMPA,8))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMPA,9))
> +    } Else {
> +      Store(Or(0x10000,DIDA),Index(TMPA,9))
> +    }
> +    Return(TMPA)
> +  }
> +
> +  If(LEqual(NDID,0x0B))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMPB,0))
> +    Store(Or(0x10000,DID2),Index(TMPB,1))
> +    Store(Or(0x10000,DID3),Index(TMPB,2))
> +    Store(Or(0x10000,DID4),Index(TMPB,3))
> +    Store(Or(0x10000,DID5),Index(TMPB,4))
> +    Store(Or(0x10000,DID6),Index(TMPB,5))
> +    Store(Or(0x10000,DID7),Index(TMPB,6))
> +    Store(Or(0x10000,DID8),Index(TMPB,7))
> +    Store(Or(0x10000,DID9),Index(TMPB,8))
> +    Store(Or(0x10000,DIDA),Index(TMPB,9))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMPB,10))
> +    } Else {
> +      Store(Or(0x10000,DIDB),Index(TMPB,10))
> +    }
> +    Return(TMPB)
> +  }
> +
> +  If(LEqual(NDID,0x0C))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMPC,0))
> +    Store(Or(0x10000,DID2),Index(TMPC,1))
> +    Store(Or(0x10000,DID3),Index(TMPC,2))
> +    Store(Or(0x10000,DID4),Index(TMPC,3))
> +    Store(Or(0x10000,DID5),Index(TMPC,4))
> +    Store(Or(0x10000,DID6),Index(TMPC,5))
> +    Store(Or(0x10000,DID7),Index(TMPC,6))
> +    Store(Or(0x10000,DID8),Index(TMPC,7))
> +    Store(Or(0x10000,DID9),Index(TMPC,8))
> +    Store(Or(0x10000,DIDA),Index(TMPC,9))
> +    Store(Or(0x10000,DIDB),Index(TMPC,10))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMPC,11))
> +    } Else {
> +      Store(Or(0x10000,DIDC),Index(TMPC,11))
> +    }
> +    Return(TMPC)
> +  }
> +
> +  If(LEqual(NDID,0x0D))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMPD,0))
> +    Store(Or(0x10000,DID2),Index(TMPD,1))
> +    Store(Or(0x10000,DID3),Index(TMPD,2))
> +    Store(Or(0x10000,DID4),Index(TMPD,3))
> +    Store(Or(0x10000,DID5),Index(TMPD,4))
> +    Store(Or(0x10000,DID6),Index(TMPD,5))
> +    Store(Or(0x10000,DID7),Index(TMPD,6))
> +    Store(Or(0x10000,DID8),Index(TMPD,7))
> +    Store(Or(0x10000,DID9),Index(TMPD,8))
> +    Store(Or(0x10000,DIDA),Index(TMPD,9))
> +    Store(Or(0x10000,DIDB),Index(TMPD,10))
> +    Store(Or(0x10000,DIDC),Index(TMPD,11))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMPD,12))
> +    } Else {
> +      Store(Or(0x10000,DIDD),Index(TMPD,12))
> +    }
> +    Return(TMPD)
> +  }
> +
> +  If(LEqual(NDID,0x0E))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMPE,0))
> +    Store(Or(0x10000,DID2),Index(TMPE,1))
> +    Store(Or(0x10000,DID3),Index(TMPE,2))
> +    Store(Or(0x10000,DID4),Index(TMPE,3))
> +    Store(Or(0x10000,DID5),Index(TMPE,4))
> +    Store(Or(0x10000,DID6),Index(TMPE,5))
> +    Store(Or(0x10000,DID7),Index(TMPE,6))
> +    Store(Or(0x10000,DID8),Index(TMPE,7))
> +    Store(Or(0x10000,DID9),Index(TMPE,8))
> +    Store(Or(0x10000,DIDA),Index(TMPE,9))
> +    Store(Or(0x10000,DIDB),Index(TMPE,10))
> +    Store(Or(0x10000,DIDC),Index(TMPE,11))
> +    Store(Or(0x10000,DIDD),Index(TMPE,12))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMPE,13))
> +    } Else {
> +      Store(Or(0x10000,DIDE),Index(TMPE,13))
> +    }
> +    Return(TMPE)
> +  }
> +
> +  If(LEqual(NDID,0x0F))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMPF,0))
> +    Store(Or(0x10000,DID2),Index(TMPF,1))
> +    Store(Or(0x10000,DID3),Index(TMPF,2))
> +    Store(Or(0x10000,DID4),Index(TMPF,3))
> +    Store(Or(0x10000,DID5),Index(TMPF,4))
> +    Store(Or(0x10000,DID6),Index(TMPF,5))
> +    Store(Or(0x10000,DID7),Index(TMPF,6))
> +    Store(Or(0x10000,DID8),Index(TMPF,7))
> +    Store(Or(0x10000,DID9),Index(TMPF,8))
> +    Store(Or(0x10000,DIDA),Index(TMPF,9))
> +    Store(Or(0x10000,DIDB),Index(TMPF,10))
> +    Store(Or(0x10000,DIDC),Index(TMPF,11))
> +    Store(Or(0x10000,DIDD),Index(TMPF,12))
> +    Store(Or(0x10000,DIDE),Index(TMPF,13))
> +    If (LEqual(IPTP,1)) {
> +      //
> +      // IGFX need report IPUA as GFX0 child
> +      //
> +      Store(0x00023480,Index(TMPF,14))
> +    } Else {
> +      Store(Or(0x10000,DIDF),Index(TMPF,14))
> +    }
> +    Return(TMPF)
> +  }
> +
> +  If(LEqual(NDID,0x10))
> +  {
> +    Store(Or(0x10000,DID1),Index(TMPG,0))
> +    Store(Or(0x10000,DID2),Index(TMPG,1))
> +    Store(Or(0x10000,DID3),Index(TMPG,2))
> +    Store(Or(0x10000,DID4),Index(TMPG,3))
> +    Store(Or(0x10000,DID5),Index(TMPG,4))
> +    Store(Or(0x10000,DID6),Index(TMPG,5))
> +    Store(Or(0x10000,DID7),Index(TMPG,6))
> +    Store(Or(0x10000,DID8),Index(TMPG,7))
> +    Store(Or(0x10000,DID9),Index(TMPG,8))
> +    Store(Or(0x10000,DIDA),Index(TMPG,9))
> +    Store(Or(0x10000,DIDB),Index(TMPG,10))
> +    Store(Or(0x10000,DIDC),Index(TMPG,11))
> +    Store(Or(0x10000,DIDD),Index(TMPG,12))
> +    Store(Or(0x10000,DIDE),Index(TMPG,13))
> +    Store(Or(0x10000,DIDF),Index(TMPG,14))
> +    //
> +    // IGFX need report IPUA as GFX0 child
> +    // NDID can only be 0x10 if IPU is enabled
> +    //
> +    Store(0x00023480,Index(TMPG,15))
> +    Return(TMPG)
> +  }
> +
> +  //
> +  // If nothing else, return Unknown LFP.
> +  // (Prevents compiler warning.)
> +  //
> +  Return(Package() {0x00000400})
> +}
> +
> +Device(DD01)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID1),0x400))
> +    {
> +      Store(0x1, EDPV)
> +      Store(NXD1, NXDX)
> +      Store(DID1, DIDX)
> +      Return(1)
> +    }
> +    If(LEqual(DID1,0))
> +    {
> +      Return(1)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID1))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    Return(CDDS(DID1))
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD1)
> +    }
> +    Return(NDDS(DID1))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD02)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID2),0x400))
> +    {
> +      Store(0x2, EDPV)
> +      Store(NXD2, NXDX)
> +      Store(DID2, DIDX)
> +      Return(2)
> +    }
> +    If(LEqual(DID2,0))
> +    {
> +      Return(2)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID2))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(LIDS,0))
> +    {
> +      Return(0x0)
> +    }
> +    Return(CDDS(DID2))
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    //
> +    // Return the Next State.
> +    //
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD2)
> +    }
> +    Return(NDDS(DID2))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD03)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID3),0x400))
> +    {
> +      Store(0x3, EDPV)
> +      Store(NXD3, NXDX)
> +      Store(DID3, DIDX)
> +      Return(3)
> +    }
> +    If(LEqual(DID3,0))
> +    {
> +      Return(3)
> +    }
> +    Else
> +    {
> +    Return(And(0xFFFF,DID3))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID3,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID3))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD3)
> +    }
> +    Return(NDDS(DID3))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD04)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID4),0x400))
> +    {
> +      Store(0x4, EDPV)
> +      Store(NXD4, NXDX)
> +      Store(DID4, DIDX)
> +      Return(4)
> +    }
> +    If(LEqual(DID4,0))
> +    {
> +      Return(4)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID4))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID4,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID4))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD4)
> +    }
> +    Return(NDDS(DID4))
> +  }
> +
> +  //
> +  // Device Set State. (See table above.)
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD05)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID5),0x400))
> +    {
> +      Store(0x5, EDPV)
> +      Store(NXD5, NXDX)
> +      Store(DID5, DIDX)
> +      Return(5)
> +    }
> +    If(LEqual(DID5,0))
> +    {
> +      Return(5)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID5))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID5,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID5))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD5)
> +    }
> +    Return(NDDS(DID5))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD06)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID6),0x400))
> +    {
> +      Store(0x6, EDPV)
> +      Store(NXD6, NXDX)
> +      Store(DID6, DIDX)
> +      Return(6)
> +    }
> +    If(LEqual(DID6,0))
> +    {
> +      Return(6)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID6))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID6,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID6))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD6)
> +    }
> +    Return(NDDS(DID6))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD07)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID7),0x400))
> +    {
> +      Store(0x7, EDPV)
> +      Store(NXD7, NXDX)
> +      Store(DID7, DIDX)
> +      Return(7)
> +    }
> +    If(LEqual(DID7,0))
> +    {
> +      Return(7)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID7))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID7,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID7))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD7)
> +    }
> +    Return(NDDS(DID7))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD08)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID8),0x400))
> +    {
> +      Store(0x8, EDPV)
> +      Store(NXD8, NXDX)
> +      Store(DID8, DIDX)
> +      Return(8)
> +    }
> +    If(LEqual(DID8,0))
> +    {
> +      Return(8)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID8))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID8,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID8))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD8)
> +    }
> +    Return(NDDS(DID8))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD09)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID9),0x400))
> +    {
> +      Store(0x9, EDPV)
> +      Store(NXD8, NXDX)
> +      Store(DID9, DIDX)
> +      Return(9)
> +    }
> +    If(LEqual(DID9,0))
> +    {
> +      Return(9)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID9))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID9,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID9))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD8)
> +    }
> +    Return(NDDS(DID9))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD0A)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DIDA),0x400))
> +    {
> +      Store(0xA, EDPV)
> +      Store(NXD8, NXDX)
> +      Store(DIDA, DIDX)
> +      Return(0x0A)
> +    }
> +    If(LEqual(DIDA,0))
> +    {
> +      Return(0x0A)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DIDA))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DIDA,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DIDA))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD8)
> +    }
> +    Return(NDDS(DIDA))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD0B)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DIDB),0x400))
> +    {
> +      Store(0xB, EDPV)
> +      Store(NXD8, NXDX)
> +      Store(DIDB, DIDX)
> +      Return(0X0B)
> +    }
> +    If(LEqual(DIDB,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DIDB))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DIDB,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DIDB))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD8)
> +    }
> +    Return(NDDS(DIDB))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD0C)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DIDC),0x400))
> +    {
> +      Store(0xC, EDPV)
> +      Store(NXD8, NXDX)
> +      Store(DIDC, DIDX)
> +      Return(0X0C)
> +    }
> +    If(LEqual(DIDC,0))
> +    {
> +      Return(0x0C)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DIDC))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DIDC,0))
> +    {
> +      Return(0x0C)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DIDC))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD8)
> +    }
> +    Return(NDDS(DIDC))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD0D)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DIDD),0x400))
> +    {
> +      Store(0xD, EDPV)
> +      Store(NXD8, NXDX)
> +      Store(DIDD, DIDX)
> +      Return(0X0D)
> +    }
> +    If(LEqual(DIDD,0))
> +    {
> +      Return(0x0D)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DIDD))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DIDD,0))
> +    {
> +      Return(0x0D)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DIDD))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD8)
> +    }
> +    Return(NDDS(DIDD))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD0E)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DIDE),0x400))
> +    {
> +      Store(0xE, EDPV)
> +      Store(NXD8, NXDX)
> +      Store(DIDE, DIDX)
> +      Return(0X0E)
> +    }
> +    If(LEqual(DIDE,0))
> +    {
> +      Return(0x0E)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DIDE))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DIDE,0))
> +    {
> +      Return(0x0E)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DIDE))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD8)
> +    }
> +    Return(NDDS(DIDE))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +Device(DD0F)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DIDF),0x400))
> +    {
> +      Store(0xF, EDPV)
> +      Store(NXD8, NXDX)
> +      Store(DIDF, DIDX)
> +      Return(0X0F)
> +    }
> +    If(LEqual(DIDF,0))
> +    {
> +      Return(0x0F)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DIDF))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DIDC,0))
> +    {
> +      Return(0x0F)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DIDF))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXD8)
> +    }
> +    Return(NDDS(DIDF))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +}
> +
> +//
> +//Device for eDP
> +//
> +Device(DD1F)
> +{
> +  //
> +  // Return Unique ID.
> +  //
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(EDPV, 0x0))
> +    {
> +      Return(0x1F)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DIDX))
> +    }
> +  }
> +
> +  //
> +  // Return the Current Status.
> +  //
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(EDPV, 0x0))
> +    {
> +      Return(0x00)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DIDX))
> +    }
> +  }
> +
> +  //
> +  // Query Graphics State (active or inactive).
> +  //
> +  Method(_DGS,0)
> +  {
> +    If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> +    {
> +      Return (NXDX)
> +    }
> +    Return(NDDS(DIDX))
> +  }
> +
> +  //
> +  // Device Set State.
> +  //
> +  Method(_DSS,1)
> +  {
> +    DSST(Arg0)
> +  }
> +
> +  //
> +  // Query List of Brightness Control Levels Supported.
> +  //
> +  Method(_BCL,0)
> +  {
> +    //
> +    // List of supported brightness levels in the following sequence.
> +    // Level when machine has full power.
> +    // Level when machine is on batteries.
> +    // Other supported levels.
> +    //
> +    If(CondRefOf(\PBCL)) {
> +      Return (PBCL())
> +    } Else {
> +      Return(Package(){80, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
> 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
> 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
> 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
> 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100})
> +    }
> +  }
> +
> +  //
> +  // Set the Brightness Level.
> +  //
> +  Method (_BCM,1)
> +  {
> +    //
> +    // Set the requested level if it is between 0 and 100%.
> +    //
> +    If(LAnd(LGreaterEqual(Arg0,0),LLessEqual(Arg0,100)))
> +    {
> +      \_SB.PCI0.GFX0.AINT(1, Arg0)
> +      Store(Arg0,BRTL)  // Store Brightness Level.
> +    }
> +  }
> +
> +  //
> +  // Brightness Query Current level.
> +  //
> +  Method (_BQC,0)
> +  {
> +    Return(BRTL)
> +  }
> +}
> +
> +Method(SDDL,1)
> +{
> +  Increment(NDID)
> +  Store(And(Arg0,0xF0F),Local0)
> +  Or(0x80000000,Local0, Local1)
> +  If(LEqual(DIDL,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL2,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL3,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL4,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL5,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL6,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL7,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL8,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL9,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DD10,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DD11,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DD12,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DD13,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DD14,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DD15,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  Return(0)
> +}
> +
> +Method(CDDS,1)
> +{
> +  Store(And(Arg0,0xF0F),Local0)
> +
> +  If(LEqual(0, Local0))
> +  {
> +    Return(0x1D)
> +  }
> +  If(LEqual(CADL, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL2, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL3, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL4, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL5, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL6, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL7, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL8, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  Return(0x1D)
> +}
> +
> +Method(NDDS,1)
> +{
> +  Store(And(Arg0,0xF0F),Local0)
> +
> +  If(LEqual(0, Local0))
> +  {
> +    Return(0)
> +  }
> +  If(LEqual(NADL, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL2, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL3, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL4, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL5, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL6, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL7, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL8, Local0))
> +  {
> +    Return(1)
> +  }
> +  Return(0)
> +}
> +
> +//
> +// Device Set State Table
> +//  BIT31  BIT30  Execution
> +//  0  0  Don't implement.
> +//  0  1  Cache change.  Nothing to Implement.
> +//  1  0  Don't Implement.
> +//  1  1  Display Switch Complete.  Implement.
> +//
> +Method(DSST,1)
> +{
> +  If(LEqual(And(Arg0,0xC0000000),0xC0000000))
> +  {
> +    //
> +    // State change was performed by the
> +    // Video Drivers.  Simply update the
> +    // New State.
> +    //
> +    Store(NSTE,CSTE)
> +  }
> +}
> +
> +//
> +// Include IGD OpRegion/Software SCI interrupt handler/DSM which is used
> by
> +// the graphics drivers to request data from system BIOS.
> +//
> +include ("IgfxOpRn.asl")
> +include ("IgfxDsm.asl")
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCo
> mmon.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCo
> mmon.asl
> new file mode 100644
> index 0000000000..7edbe45e2e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCo
> mmon.asl
> @@ -0,0 +1,472 @@
> +/** @file
> +  IGD OpRegion/Software SCI Reference Code.
> +  This file contains ASL code with the purpose of handling events
> +  i.e. hotkeys and other system interrupts.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +/**************************************************************
> **********;
> +;* ACPI Notification Methods
> +;**************************************************************
> **********/
> +
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name:        PDRD
> +;*
> +;* Description: Check if the graphics driver is ready to process
> +;*              notifications and video extensions.
> +;*
> +;* Usage:       This method is to be called prior to performing any
> +;*              notifications or handling video extensions.
> +;*              Ex: If (PDRD()) {Return (FAIL)}
> +;*
> +;* Input:       None
> +;*
> +;* Output:      None
> +;*
> +;* References:  DRDY (Driver ready status), ASLP (Driver recommended
> +;*              sleep timeout value).
> +;*
> +;**************************************************************
> **********/
> +
> +External(HNOT, MethodObj)
> +
> +Method(PDRD)
> +{
> +  //
> +  // If DRDY is clear, the driver is not ready.  If the return value is
> +  // !=0, do not perform any notifications or video extension handling.
> +  //
> +  Return(LNot(DRDY))
> +}
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name:        PSTS
> +;*
> +;* Description: Check if the graphics driver has completed the previous
> +;*              "notify" command.
> +;*
> +;* Usage:       This method is called before every "notify" command.  A
> +;*              "notify" should only be set if the driver has completed the
> +;*              previous command.  Else, ignore the event and exit the parent
> +;*              method.
> +;*              Ex: If (PSTS()) {Return (FAIL)}
> +;*
> +;* Input:       None
> +;*
> +;* Output:      None
> +;*
> +;* References:  CSTS (Notification status), ASLP (Driver recommended sleep
> +;*              timeout value).
> +;*
> +;**************************************************************
> **********/
> +
> +Method(PSTS)
> +{
> +  If(LGreater(CSTS, 2))
> +  {
> +    //
> +    // Sleep for ASLP milliseconds if the status is not "success,
> +    // failure, or pending"
> +    //
> +    Sleep(ASLP)
> +  }
> +
> +  Return(LEqual(CSTS, 3)) // Return True if still Dispatched
> +}
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name:  GNOT
> +;*
> +;* Description: Call the appropriate methods to query the graphics driver
> +;*              status.  If all methods return success, do a notification of
> +;*              the graphics device.
> +;*
> +;* Usage:       This method is to be called when a graphics device
> +;*              notification is required (display switch hotkey, etc).
> +;*
> +;* Input:       Arg0 = Current event type:
> +;*                1 = display switch
> +;*                2 = lid
> +;*                3 = dock
> +;*              Arg1 = Notification type:
> +;*                0 = Re-enumeration
> +;*                0x80 = Display switch
> +;*
> +;* Output:      Returns 0 = success, 1 = failure
> +;*
> +;* References:  PDRD and PSTS methods.  OSYS (OS version)
> +;*
> +;**************************************************************
> **********/
> +
> +Method(GNOT, 2)
> +{
> +  //
> +  // Check for 1. Driver loaded, 2. Driver ready.
> +  // If any of these cases is not met, skip this event and return failure.
> +  //
> +  If(PDRD())
> +  {
> +    Return(0x1) // Return failure if driver not loaded.
> +  }
> +
> +  Store(Arg0, CEVT) // Set up the current event value
> +  Store(3, CSTS) // CSTS=BIOS dispatched an event
> +
> +  If(LAnd(LEqual(CHPD, 0), LEqual(Arg1, 0))) // Do not re-enum if driver
> supports hotplug
> +  {
> +    //
> +    // Re-enumerate the Graphics Device for non-XP operating systems.
> +    //
> +    Notify(\_SB.PCI0.GFX0, Arg1)
> +  }
> +
> +  If(CondRefOf(HNOT))
> +  {
> +    HNOT(Arg0)  //Notification handler for Switchable graphics
> +  }
> +  Else
> +  {
> +    Notify(\_SB.PCI0.GFX0,0x80)
> +  }
> +
> +  Return(0x0) // Return success
> +}
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name:        GHDS
> +;*
> +;* Description: Handle a hotkey display switching event (performs a
> +;*              Notify(GFX0, 0).
> +;*
> +;* Usage:       This method must be called when a hotkey event occurs and
> the
> +;*              purpose of that hotkey is to do a display switch.
> +;*
> +;* Input:       Arg0 = Toggle table number.
> +;*
> +;* Output:      Returns 0 = success, 1 = failure.
> +;*              CEVT and TIDX are indirect outputs.
> +;*
> +;* References:  TIDX, GNOT
> +;*
> +;**************************************************************
> **********/
> +
> +Method(GHDS, 1)
> +{
> +  Store(Arg0, TIDX) // Store the table number
> +  //
> +  // Call GNOT for CEVT = 1 = hotkey, notify value = 0
> +  //
> +  Return(GNOT(1, 0)) // Return stats from GNOT
> +}
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name:        GLID
> +;*
> +;* Description: Handle a lid event (performs the Notify(GFX0, 0), but not the
> +;*              lid notify).
> +;*
> +;* Usage:       This method must be called when a lid event occurs.  A
> +;*              Notify(LID0, 0x80) must follow the call to this method.
> +;*
> +;* Input:       Arg0 = Lid state:
> +;*                0 = All closed
> +;*                1 = internal LFP lid open
> +;*                2 = external lid open
> +;*                3 = both external and internal open
> +;*
> +;* Output:      Returns 0=success, 1=failure.
> +;*              CLID and CEVT are indirect outputs.
> +;*
> +;* References:  CLID, GNOT
> +;*
> +;**************************************************************
> **********/
> +
> +Method(GLID, 1)
> +{
> +
> +  If (LEqual(Arg0,1))
> +  {
> +    Store(3,CLID)
> +  }
> +  Else
> +  {
> +    Store(Arg0, CLID)
> +  }
> +  //
> +  //Store(Arg0, CLID) // Store the current lid state
> +  // Call GNOT for CEVT=2=Lid, notify value = 0
> +  //
> +  if (GNOT(2, 0)) {
> +    Or (CLID, 0x80000000, CLID)
> +    Return (1) // Return Fail
> +  }
> +
> +  Return (0) // Return Pass
> +}
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name:  GDCK
> +;*
> +;* Description: Handle a docking event by updating the current docking status
> +;*              and doing a notification.
> +;*
> +;* Usage:       This method must be called when a docking event occurs.
> +;*
> +;* Input:       Arg0 = Docking state:
> +;*                0 = Undocked
> +;*                1 = Docked
> +;*
> +;* Output:      Returns 0=success, 1=failure.
> +;*              CDCK and CEVT are indirect outputs.
> +;*
> +;* References:  CDCK, GNOT
> +;*
> +;**************************************************************
> **********/
> +
> +Method(GDCK, 1)
> +{
> +  Store(Arg0, CDCK) // Store the current dock state
> +  //
> +  // Call GNOT for CEVT=4=Dock, notify value = 0
> +  //
> +  Return(GNOT(4, 0)) // Return stats from GNOT
> +}
> +
> +/**************************************************************
> **********;
> +;* ASLE Interrupt Methods
> +;**************************************************************
> **********/
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name:        PARD
> +;*
> +;* Description: Check if the driver is ready to handle ASLE interrupts
> +;*              generate by the system BIOS.
> +;*
> +;* Usage:       This method must be called before generating each ASLE
> +;*              interrupt.
> +;*
> +;* Input:       None
> +;*
> +;* Output:      Returns 0 = success, 1 = failure.
> +;*
> +;* References:  ARDY (Driver readiness), ASLP (Driver recommended sleep
> +;*              timeout value)
> +;*
> +;**************************************************************
> **********/
> +
> +Method(PARD)
> +{
> +  If(LNot(ARDY))
> +  {
> +    //
> +    // Sleep for ASLP milliseconds if the driver is not ready.
> +    //
> +    Sleep(ASLP)
> +  }
> +  //
> +  // If ARDY is clear, the driver is not ready.  If the return value is
> +  // !=0, do not generate the ASLE interrupt.
> +  //
> +  Return(LNot(ARDY))
> +}
> +
> +//
> +// Intel Ultrabook Event Handler.  Arg0 represents the Ultrabook Event Bit #
> to pass
> +// to the Intel Graphics Driver.  Note that this is a serialized method, meaning
> +// sumultaneous events are not allowed.
> +//
> +Method(IUEH,1,Serialized)
> +{
> +  And(IUER,0xC0,IUER) // Clear all button events on entry.
> +  XOr(IUER,Shiftleft(1,Arg0),IUER) // Toggle status.
> +
> +  If(LLessEqual(Arg0,4)) // Button Event?
> +  {
> +    Return(AINT(5,0)) // Generate event and return status.
> +
> +  }
> +  Else // Indicator Event.
> +  {
> +    Return(AINT(Arg0,0)) // Generate event and return status.
> +  }
> +}
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name:        AINT
> +;*
> +;* Description: Call the appropriate methods to generate an ASLE interrupt.
> +;*              This process includes ensuring the graphics driver is ready
> +;*              to process the interrupt, ensuring the driver supports the
> +;*              interrupt of interest, and passing information about the event
> +;*              to the graphics driver.
> +;*
> +;* Usage:       This method must called to generate an ASLE interrupt.
> +;*
> +;* Input:       Arg0 = ASLE command function code:
> +;*                0 = Set ALS illuminance
> +;*                1 = Set backlight brightness
> +;*                2 = Do Panel Fitting
> +;*                4 = Reserved
> +;*                5 = Button Indicator Event
> +;*                6 = Convertible Indicator Event
> +;*                7 = Docking Indicator Event
> +;*              Arg1 = If Arg0 = 0, current ALS reading:
> +;*                0 = Reading below sensor range
> +;*                1-0xFFFE = Current sensor reading
> +;*                0xFFFF = Reading above sensor range
> +;*              Arg1 = If Arg0 = 1, requested backlight percentage
> +;*
> +;* Output:      Returns 0 = success, 1 = failure
> +;*
> +;* References:  PARD method.
> +;*
> +;**************************************************************
> **********/
> +
> +Method(AINT, 2)
> +{
> +  //
> +  // Return failure if the requested feature is not supported by the
> +  // driver.
> +  //
> +  If(LNot(And(TCHE, ShiftLeft(1, Arg0))))
> +  {
> +    Return(0x1)
> +  }
> +  //
> +  // Return failure if the driver is not ready to handle an ASLE
> +  // interrupt.
> +  //
> +  If(PARD())
> +  {
> +    Return(0x1)
> +  }
> +  //
> +  // Handle Intel Ultrabook Events.
> +  //
> +  If(LAnd(LGreaterEqual(Arg0,5),LLessEqual(Arg0,7)))
> +  {
> +    Store(ShiftLeft(1,Arg0), ASLC) // Set Ultrbook Event [6:4].
> +    Store(0x01, ASLE) // Generate ASLE interrupt
> +
> +    Store(0,Local2) // Use Local2 as a timeout counter.  Intialize to zero.
> +
> +    While(LAnd(LLess(Local2,250),LNotEqual(ASLC,0))) // Wait 1 second or
> until Driver ACKs a success.
> +    {
> +      Sleep(4) // Delay 4 ms.
> +      Increment(Local2) // Increment Timeout.
> +    }
> +
> +    Return(0) // Return success
> +  }
> +  //
> +  // Evaluate the first argument (Panel fitting, backlight brightness, or ALS).
> +  //
> +  If(LEqual(Arg0, 2))         // Arg0 = 2, so request a panel fitting mode change.
> +  {
> +    If(CPFM)                  // If current mode field is non-zero use it.
> +    {
> +      And(CPFM, 0x0F, Local0) // Create variables without reserved
> +      And(EPFM, 0x0F, Local1) // or valid bits.
> +
> +      If(LEqual(Local0, 1))   // If current mode is centered,
> +      {
> +        If(And(Local1, 6))    // and if stretched is enabled,
> +        {
> +          Store(6, PFIT)      // request stretched.
> +        }
> +        Else                  // Otherwise,
> +        {
> +          If(And(Local1, 8))  // if aspect ratio is enabled,
> +          {
> +            Store(8, PFIT)    // request aspect ratio.
> +          }
> +          Else                // Only centered mode is enabled
> +          {
> +            Store(1, PFIT)    // so request centered. (No change.)
> +          }
> +        }
> +      }
> +      If(LEqual(Local0, 6))   // If current mode is stretched,
> +      {
> +        If(And(Local1, 8))    // and if aspect ratio is enabled,
> +        {
> +          Store(8, PFIT)      // request aspect ratio.
> +        }
> +        Else                  // Otherwise,
> +        {
> +          If(And(Local1, 1))  // if centered is enabled,
> +          {
> +            Store(1, PFIT)    // request centered.
> +          }
> +          Else                // Only stretched mode is enabled
> +          {
> +            Store(6, PFIT)    // so request stretched. (No change.)
> +          }
> +        }
> +      }
> +      If(LEqual(Local0, 8))   // If current mode is aspect ratio,
> +      {
> +        If(And(Local1, 1))    // and if centered is enabled,
> +        {
> +          Store(1, PFIT)      // request centered.
> +        }
> +        Else                  // Otherwise,
> +        {
> +          If(And(Local1, 6))  // if stretched is enabled,
> +          {
> +            Store(6, PFIT)    // request stretched.
> +          }
> +          Else                // Only aspect ratio mode is enabled
> +          {
> +            Store(8, PFIT)    // so request aspect ratio. (No change.)
> +          }
> +        }
> +      }
> +    }
> +    //
> +    // The following code for panel fitting (within the Else condition) is
> retained for backward compatiblity.
> +    //
> +    Else                      // If CFPM field is zero use PFIT and toggle the
> +    {
> +      Xor(PFIT,7,PFIT)        // mode setting between stretched and centered
> only.
> +    }
> +    Or(PFIT,0x80000000,PFIT)  // Set the valid bit for all cases.
> +    Store(4, ASLC)            // Store "Panel fitting event" to ASLC[31:1]
> +  }
> +  Else
> +  {
> +    If(LEqual(Arg0, 1)) // Arg0=1, so set the backlight brightness.
> +    {
> +      Store(Divide(Multiply(Arg1, 255), 100), BCLP) // Convert from percent to
> 0-255.
> +      Or(BCLP, 0x80000000, BCLP) // Set the valid bit.
> +      Store(2, ASLC) // Store "Backlight control event" to ASLC[31:1]
> +    }
> +    Else
> +    {
> +      If(LEqual(Arg0, 0)) // Arg0=0, so set the ALS illuminace
> +      {
> +        Store(Arg1, ALSI)
> +        Store(1, ASLC) // Store "ALS event" to ASLC[31:1]
> +      }
> +      Else
> +      {
> +        Return(0x1) // Unsupported function
> +      }
> +    }
> +  }
> +
> +  Store(0x01, ASLE) // Generate ASLE interrupt
> +  Return(0x0) // Return success
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDs
> m.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDs
> m.asl
> new file mode 100644
> index 0000000000..e7b3c92cda
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDs
> m.asl
> @@ -0,0 +1,369 @@
> +/** @file
> +  IGD OpRegion/_DSM Reference Code.
> +  This file contains Get BIOS Data and Callback functions for
> +  the Integrated Graphics Device (IGD) OpRegion/DSM mechanism
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// _DSM Device Specific Method
> +//
> +// Arg0: UUID Unique function identifier
> +// Arg1: Integer Revision Level
> +// Arg2: Integer Function Index (1 = Return Supported Functions)
> +// Arg3: Additional Inputs/Package Parameters Bits [31:0] input as {Byte0,
> Byte1, Byte2, Byte3} to BIOS which is passed as 32 bit DWORD by Driver
> +//
> +Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj,
> PkgObj}) {
> +
> +  If (LEqual(Arg0, ToUUID ("3E5B41C6-EB1D-4260-9D15-C71FBADAE414"))) {
> +    //
> +    // _DSM Definition for Igd functions
> +    // Arguments:
> +    // Arg0: UUID: 3E5B41C6-EB1D-4260-9D15-C71FBADAE414
> +    // Arg1: Revision ID: 1
> +    // Arg2: Function Index: 16
> +    // Arg3: Additional Inputs Bits[31:0] Arg3 {Byte0, Byte1, Byte2, Byte3}
> +    //
> +    // Return:
> +    // Success for simple notification, Opregion update for some routines and
> a Package for AKSV
> +    //
> +    //
> +    // Switch by function index
> +    //
> +    Switch(ToInteger(Arg2)) {
> +      //
> +      // Function Index: 0
> +      // Standard query - A bitmask of functions supported
> +      //
> +      // Return: A bitmask of functions supported
> +      //
> +      Case (0)
> +      {
> +        If (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
> +          Store("iGfx Supported Functions Bitmap ", Debug)
> +          Return (0x1E7FF)   // bit 11 and 12 is not supported
> +        }
> +      }
> +
> +      //
> +      // Function Index: 1
> +      // Adapter Power State Notification
> +      // Arg3 Bits [7:0]: Adapter Power State bits [7:0] from Driver 00h = D0; 01h
> = D1; 02h = D2; 04h = D3 (Cold/Hot); 08h = D4 (Hibernate Notification)
> +      // Return: Success
> +      //
> +      Case(1) {
> +        If (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
> +          Store(" Adapter Power State Notification ", Debug)
> +
> +          //
> +          // Handle Low Power S0 Idle Capability if enabled
> +          //
> +          If(LAnd(LEqual(S0ID, 1),LLess(OSYS, 2015))) {
> +            //
> +            // Call GUAM to trigger CS Entry
> +            //   If Adapter Power State Notification = D1 (Arg3[0]=0x01)
> +            //
> +            If (LEqual (And(DerefOf (Index (Arg3,0)), 0xFF), 0x01)) {
> +              // GUAM - Global User Absent Mode Notification Method
> +              \GUAM(One) // 0x01 - Power State Standby (CS Entry)
> +            }
> +            Store(And(DerefOf (Index (Arg3,1)), 0xFF), Local0)
> +            //
> +            // Call GUAM
> +            // If Display Turn ON Notification (Arg3 [1] == 0) for CS Exit
> +            //
> +            If (LEqual (Local0, 0)) {
> +              // GUAM - Global User Absent Mode Notification Method
> +              \GUAM(0)
> +            }
> +          }
> +
> +          // Upon notification from driver that the Adapter Power State = D0,
> +          // check if previous lid event failed.  If it did, retry the lid
> +          // event here.
> +          If(LEqual(DerefOf (Index (Arg3,0)), 0)) {
> +            Store(CLID, Local0)
> +            If(And(0x80000000,Local0)) {
> +              And(CLID, 0x0000000F, CLID)
> +              GLID(CLID)
> +            }
> +          }
> +          Return(0x01)
> +        }
> +      }
> +      //
> +      // Function Index: 2
> +      // Display Power State Notification
> +      // Arg3: Display Power State Bits [15:8]
> +      // 00h = On
> +      // 01h = Standby
> +      // 02h = Suspend
> +      // 04h = Off
> +      // 08h = Reduced On
> +      // Return: Success
> +      //
> +     Case(2) {
> +        if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
> +
> +          Store("Display Power State Notification ", Debug)
> +          Return(0x01)
> +        }
> +      }
> +
> +      //
> +      // Function Index: 3
> +      // BIOS POST Completion Notification
> +      // Return: Success
> +      //
> +      Case(3) {
> +        if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
> +          Store("BIOS POST Completion Notification ", Debug)
> +          Return(0x01)      // Not supported, but no failure
> +        }
> +      }
> +
> +      //
> +      // Function Index: 4
> +      // Pre-Hires Set Mode
> +      // Return: Success
> +      //
> +      Case(4) {
> +        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> +          Store("Pre-Hires Set Mode ", Debug)
> +          Return(0x01)      // Not supported, but no failure
> +        }
> +      }
> +
> +      //
> +      // Function Index: 5
> +      // Post-Hires Set Mode
> +      // Return: Success
> +      //
> +      Case(5) {
> +        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> +          Store("Post-Hires Set Mode ", Debug)
> +          Return(0x01)      // Not supported, but no failure
> +        }
> +      }
> +
> +      //
> +      // Function Index: 6
> +      // SetDisplayDeviceNotification (Display Switch)
> +      // Return: Success
> +      //
> +      Case(6) {
> +        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> +          Store("SetDisplayDeviceNotification", Debug)
> +          Return(0x01)      // Not supported, but no failure
> +        }
> +      }
> +
> +      //
> +      // Function Index: 7
> +      // SetBootDevicePreference
> +      // Return: Success
> +      //
> +      Case(7) {
> +        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> +          //<TODO> An OEM may elect to implement this method.  In that case,
> +          // the input values must be saved into non-volatile storage for
> +          // parsing during the next boot.  The following Sample code is Intel
> +          // validated implementation.
> +
> +          Store("SetBootDevicePreference ", Debug)
> +          And(DerefOf (Index (Arg3,0)), 0xFF, IBTT) // Save the boot display to
> NVS
> +          Return(0x01)
> +        }
> +      }
> +
> +      //
> +      // Function Index: 8
> +      // SetPanelPreference
> +      // Return: Success
> +      //
> +      Case(8) {
> +        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> +          // An OEM may elect to implement this method.  In that case,
> +          // the input values must be saved into non-volatile storage for
> +          // parsing during the next boot.  The following Sample code is Intel
> +          // validated implementation.
> +
> +          Store("SetPanelPreference ", Debug)
> +
> +          // Set the panel-related NVRAM variables based the input from the
> driver.
> +          And(DerefOf (Index (Arg3,0)), 0xFF, IPSC)
> +
> +          // Change panel type if a change is requested by the driver (Change if
> +          // panel type input is non-zero).  Zero=No change requested.
> +          If(And(DerefOf (Index (Arg3,1)), 0xFF)) {
> +            And(DerefOf (Index (Arg3,1)), 0xFF, IPAT)
> +            Decrement(IPAT)    // 0 = no change, so fit to CMOS map
> +          }
> +          And(ShiftRight(DerefOf (Index (Arg3,2)), 4), 0x7, IBIA)
> +          Return(0x01)         // Success
> +        }
> +      }
> +
> +      //
> +      // Function Index: 9
> +      // FullScreenDOS
> +      // Return: Success
> +      //
> +      Case(9) {
> +        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> +          Store("FullScreenDOS ", Debug)
> +          Return(0x01)      // Not supported, but no failure
> +        }
> +      }
> +
> +      //
> +      // Function Index: 10
> +      // APM Complete
> +      // Return: Adjusted Lid State
> +      //
> +     Case(10) {
> +        if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
> +
> +          Store("APM Complete ", Debug)
> +          Store(ShiftLeft(LIDS, 8), Local0) // Report the lid state
> +          Add(Local0, 0x100, Local0)        // Adjust the lid state, 0 = Unknown
> +          Return(Local0)
> +        }
> +      }
> +
> +      //
> +      //
> +      // Function Index: 13
> +      // GetBootDisplayPreference
> +      // Arg3 Bits [30:16] : Boot Device Ports
> +      // Arg3 Bits [7:0] : Boot Device Type
> +      // Return: Boot device port and Boot device type from saved
> configuration
> +      //
> +     Case(13) {
> +        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> +
> +          Store("GetBootDisplayPreference ", Debug)
> +          Or(ShiftLeft(DerefOf (Index (Arg3,3)), 24), ShiftLeft(DerefOf (Index
> (Arg3,2)), 16), Local0) // Combine Arg3 Bits [31:16]
> +          And(Local0, 0xEFFF0000, Local0)
> +          And(Local0, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), Local0)
> +          Or(IBTT, Local0, Local0) // Arg3 Bits [7:0] = Boot device type
> +          Return(Local0)
> +        }
> +      }
> +
> +      //
> +      // Function Index: 14
> +      // GetPanelDetails
> +      // Return: Different Panel Settings
> +      //
> +      Case(14) {
> +        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> +          Store("GetPanelDetails ", Debug)
> +
> +          // Report the scaling setting
> +          // Bits [7:0] - Panel Scaling
> +          // Bits contain the panel scaling user setting from CMOS
> +          // 00h = On: Auto
> +          // 01h = On: Force Scaling
> +          // 02h = Off
> +          // 03h = Maintain Aspect Ratio
> +
> +          Store(IPSC, Local0)
> +          Or(Local0, ShiftLeft(IPAT, 8), Local0)
> +
> +          // Adjust panel type, 0 = VBT default
> +          // Bits [15:8] - Panel Type
> +          // Bits contain the panel type user setting from CMOS
> +          // 00h = Not Valid, use default Panel Type & Timings from VBT
> +          // 01h - 0Fh = Panel Number
> +
> +          Add(Local0, 0x100, Local0)
> +
> +          // Report the lid state and Adjust it
> +          // Bits [16] - Lid State
> +          // Bits contain the current panel lid state
> +          // 0 = Lid Open
> +          // 1 = Lid Closed
> +
> +          Or(Local0, ShiftLeft(LIDS, 16), Local0)
> +          Add(Local0, 0x10000, Local0)
> +
> +         // Report the BIA setting
> +         // Bits [22:20] - Backlight Image Adaptation (BIA) Control
> +         // Bits contain the backlight image adaptation control user setting
> from CMOS
> +         // 000 = VBT Default
> +         // 001 = BIA Disabled (BLC may still be enabled)
> +         // 010 - 110 = BIA Enabled at Aggressiveness Level [1 - 5]
> +
> +          Or(Local0, ShiftLeft(IBIA, 20), Local0)
> +          Return(Local0)
> +        }
> +      }
> +
> +      //
> +      // Function Index: 15
> +      // GetInternalGraphics
> +      // Return: Different Internal Grahics Settings
> +      //
> +
> +      Case(15) {
> +        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> +          Store("GetInternalGraphics ", Debug)
> +
> +          Store(GIVD, Local0)                    // Local0[0]      - VGA mode(1=VGA)
> +          Xor(Local0, 1, Local0)                 // Invert the VGA mode polarity
> +
> +          Or(Local0, ShiftLeft(GMFN, 1), Local0) // Local0[1]      - # IGD PCI
> functions-1
> +                                                 // Local0[3:2]    - Reserved
> +                                                 // Local0[4]      - IGD D3 support(0=cold)
> +                                                 // Local0[10:5]   - Reserved
> +          Or(Local0, ShiftLeft(3, 11), Local0)   // Local0[12:11]  - DVMT version
> (11b = 5.0)
> +
> +          //
> +          // Report DVMT 5.0 Total Graphics memory size.
> +          //
> +          Or(Local0, ShiftLeft(IDMS, 17), Local0) // Bits 20:17 are for Gfx total
> memory size
> +
> +          // If the "Set Internal Graphics" call is supported, the modified
> +          // settings flag must be programmed per the specification.  This
> means
> +          // that the flag must be set to indicate that system BIOS requests
> +          // these settings.  Once "Set Internal Graphics" is called, the
> +          //  modified settings flag must be cleared on all subsequent calls to
> +          // this function.
> +
> +          // Report the graphics frequency based on B0:D2:F0:RF0h[12].  Must
> +          // take into account the current VCO.
> +
> +          Or(ShiftLeft(DeRefOf(Index(DeRefOf(Index(CDCT, HVCO)), CDVL)),
> 21),Local0, Local0)
> +          Return(Local0)
> +        }
> +      }
> +
> +      //
> +      // Function Index: 16
> +      // GetAKSV
> +      // Retrun: 5 bytes of AKSV
> +      //
> +      Case(16) {
> +        if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
> +
> +          Store("GetAKSV ", Debug)
> +          Name (KSVP, Package()
> +          {
> +             0x80000000,
> +             0x8000
> +          })
> +          Store(KSV0, Index(KSVP,0)) // First four bytes of AKSV
> +          Store(KSV1, Index(KSVP,1)) // Fifth byte of AKSV
> +          Return(KSVP) // Success
> +        }
> +      }
> +    } // End of switch(Arg2)
> +
> +  } // End of if (ToUUID("3E5B41C6-EB1D-4260-9D15-C71FBADAE414D"))
> +
> +  Return (Buffer () {0x00})
> +} // End of _DSM
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Gbda.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Gbda.asl
> new file mode 100644
> index 0000000000..26e560a358
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Gbda.asl
> @@ -0,0 +1,129 @@
> +/** @file
> +  IGD OpRegion/Software SCI Reference Code.
> +  This file contains Get BIOS Data Area funciton support for
> +  the Integrated Graphics Device (IGD) OpRegion/Software SCI mechanism
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +Method (GBDA, 0, Serialized)
> +{
> +  //
> +  // Supported calls: Sub-function 0
> +  //
> +  If (LEqual(GESF, 0))
> +  {
> +    //
> +    //<NOTE> Reference code is set to Intel's validated implementation.
> +    //
> +    Store(0x0000659, PARM)
> +    Store(Zero, GESF) // Clear the exit parameter
> +    Return(SUCC) // Success
> +  }
> +  //
> +  // Requested callbacks: Sub-function 1
> +  //
> +  If (LEqual(GESF, 1))
> +  {
> +    //
> +    //<NOTE> Call back functions are where the driver calls the
> +    // system BIOS at function indicated event.
> +    //
> +    Store(0x300482, PARM)
> +    If(LEqual(S0ID, One)){
> +      Or(PARM, 0x100, PARM) //Request Fn 8 callback in CS systems
> +    }
> +    Store(Zero, GESF) // Clear the exit parameter
> +    Return(SUCC) // Success
> +  }
> +  //
> +  // Get Boot display Preferences: Sub-function 4
> +  //
> +  If (LEqual(GESF, 4))
> +  {
> +    //
> +    //<NOTE> Get Boot Display Preferences function.
> +    //
> +    And(PARM, 0xEFFF0000, PARM) // PARM[30:16] = Boot device ports
> +    And(PARM, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), PARM)
> +    Or(IBTT, PARM, PARM) // PARM[7:0] = Boot device type
> +    Store(Zero, GESF) // Clear the exit parameter
> +    Return(SUCC) // Success
> +  }
> +  //
> +  // Panel details: Sub-function 5
> +  //
> +  If (LEqual(GESF, 5))
> +  {
> +    //
> +    //<NOTE> Get Panel Details function.
> +    //
> +    Store(IPSC, PARM) // Report the scaling setting
> +    Or(PARM, ShiftLeft(IPAT, 8), PARM)
> +    Add(PARM, 0x100, PARM) // Adjust panel type, 0 = VBT default
> +    Or(PARM, ShiftLeft(LIDS, 16), PARM) // Report the lid state
> +    Add(PARM, 0x10000, PARM) // Adjust the lid state, 0 = Unknown
> +    Or(PARM, ShiftLeft(IBIA, 20), PARM) // Report the BIA setting
> +    Store(Zero, GESF)
> +    Return(SUCC)
> +  }
> +  //
> +  // Internal graphics: Sub-function 7
> +  //
> +  If (LEqual(GESF, 7))
> +  {
> +    Store(GIVD, PARM) // PARM[0]      - VGA mode(1=VGA)
> +    Xor(PARM, 1, PARM) // Invert the VGA mode polarity
> +    Or(PARM, ShiftLeft(GMFN, 1), PARM) // PARM[1]   - # IGD PCI functions-1
> +                                       // PARM[3:2]    - Reserved
> +                                       // PARM[4]      - IGD D3 support(0=cold)
> +                                       // PARM[10:5]   - Reserved
> +    Or(PARM, ShiftLeft(3, 11), PARM) // PARM[12:11] - DVMT mode(11b = 5.0)
> +
> +    //
> +    // Report DVMT 5.0 Total Graphics memory size.
> +    //
> +    Or(PARM, ShiftLeft(IDMS, 17), PARM) // Bits 20:17 are for Gfx total memory
> size
> +    //
> +    // If the "Set Internal Graphics" call is supported, the modified
> +    // settings flag must be programmed per the specification.  This means
> +    // that the flag must be set to indicate that system BIOS requests
> +    // these settings.  Once "Set Internal Graphics" is called, the
> +    //  modified settings flag must be cleared on all subsequent calls to
> +    // this function.
> +    // Report the graphics frequency based on B0:D2:F0:RF0h[12].  Must
> +    // take into account the current VCO.
> +    //
> +    Or(ShiftLeft(Derefof(Index(Derefof(Index(CDCT, HVCO)), CDVL)), 21),PARM,
> PARM)
> +    Store(1, GESF) // Set the modified settings flag
> +    Return(SUCC)
> +  }
> +  //
> +  // Spread spectrum clocks: Sub-function 10
> +  //
> +  If (LEqual(GESF, 10))
> +  {
> +    Store(0, PARM) // Assume SSC is disabled
> +    If(ISSC)
> +    {
> +      Or(PARM, 3, PARM) // If SSC enabled, return SSC1+Enabled
> +    }
> +    Store(0, GESF) // Set the modified settings flag
> +    Return(SUCC) // Success
> +  }
> +
> +  If (LEqual(GESF, 11))
> +  {
> +    Store(KSV0, PARM) // First four bytes of AKSV
> +    Store(KSV1, GESF) // Fifth byte of AKSV
> +
> +    Return(SUCC) // Success
> +  }
> +  //
> +  // A call to a reserved "Get BIOS data" function was received.
> +  //
> +  Store(Zero, GESF) // Clear the exit parameter
> +  Return(CRIT) // Reserved, "Critical failure"
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpR
> n.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Rn.asl
> new file mode 100644
> index 0000000000..a26cbdb00c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Rn.asl
> @@ -0,0 +1,296 @@
> +/** @file
> +  IGD OpRegion/Software SCI Reference Code.
> +  This file contains the interrupt handler code for the Integrated
> +  Graphics Device (IGD) OpRegion/Software SCI mechanism.
> +  It defines OperationRegions to cover the IGD PCI configuration space
> +  as described in the IGD OpRegion specification.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//  Define an OperationRegion to cover the GMCH PCI configuration space as
> +//  described in the IGD OpRegion specificiation.
> +//
> +Scope(\_SB.PCI0)
> +{
> +  OperationRegion(MCHP, PCI_Config, 0x40, 0xC0)
> +  Field(MCHP, AnyAcc, NoLock, Preserve)
> +  {
> +    Offset(0x14),
> +    AUDE, 8,
> +
> +    Offset(0x60), // Top of Memory register
> +    TASM, 10,     // Total system memory (64MB gran)
> +        , 6,
> +  }
> +}
> +
> +//
> +//  Define an OperationRegion to cover the IGD PCI configuration space as
> +//  described in the IGD OpRegion specificiation.
> +//
> +OperationRegion(IGDP, PCI_Config, 0x40, 0xC0)
> +Field(IGDP, AnyAcc, NoLock, Preserve)
> +{
> +  Offset(0x10), // Mirror of gfx control reg
> +      , 1,
> +  GIVD, 1,      // IGD VGA disable bit
> +      , 2,
> +  GUMA, 3,      // Stolen memory size
> +      , 9,
> +  Offset(0x14),
> +      , 4,
> +  GMFN, 1,      // Gfx function 1 enable
> +      , 27,
> +  Offset(0xA4),
> +  ASLE, 8,      // Reg 0xE4, ASLE interrupt register
> +      , 24,     // Only use first byte of ASLE reg
> +  Offset(0xA8), // Reg 0xE8, SWSCI control register
> +  GSSE, 1,      // Graphics SCI event (1=event pending)
> +  GSSB, 14,     // Graphics SCI scratchpad bits
> +  GSES, 1,      // Graphics event select (1=SCI)
> +  Offset(0xB0), // Gfx Clk Frequency and Gating Control
> +      , 12,
> +  CDVL, 1,      // Core display clock value
> +      , 3,      // Graphics Core Display Clock Select
> +  Offset(0xB5),
> +  LBPC, 8,      // Legacy brightness control
> +  Offset(0xBC),
> +  ASLS, 32,     // Reg 0xFC, Address of the IGD OpRegion
> +}
> +
> +//
> +//  Define an OperationRegion to cover the IGD OpRegion layout.
> +//
> +OperationRegion(IGDM, SystemMemory, ASLB, 0x2000)
> +Field(IGDM, AnyAcc, NoLock, Preserve)
> +{
> +  //
> +  // OpRegion Header
> +  //
> +  SIGN, 128,     // Signature-"IntelGraphicsMem"
> +  SIZE, 32,      // OpRegion Size
> +  OVER, 32,      // OpRegion Version
> +  SVER, 256,     // System BIOS Version
> +  VVER, 128,     // VBIOS Version
> +  GVER, 128,     // Driver version
> +  MBOX, 32,      // Mailboxes supported
> +  DMOD, 32,      // Driver Model
> +  PCON, 32,      // Platform Configuration
> +  DVER, 64,      // GOP Version
> +  //
> +  // OpRegion Mailbox 1 (Public ACPI Methods)
> +  // Note: Mailbox 1 is normally reserved for desktop platforms.
> +  //
> +  Offset(0x100),
> +  DRDY, 32,      // Driver readiness (ACPI notification)
> +  CSTS, 32,      // Notification status
> +  CEVT, 32,      // Current event
> +  Offset(0x120),
> +  DIDL, 32,      // Supported display device ID list
> +  DDL2, 32,      // Allows for 8 devices
> +  DDL3, 32,
> +  DDL4, 32,
> +  DDL5, 32,
> +  DDL6, 32,
> +  DDL7, 32,
> +  DDL8, 32,
> +  CPDL, 32,      // Currently present display list
> +  CPL2, 32,      // Allows for 8 devices
> +  CPL3, 32,
> +  CPL4, 32,
> +  CPL5, 32,
> +  CPL6, 32,
> +  CPL7, 32,
> +  CPL8, 32,
> +  CADL, 32,      // Currently active display list
> +  CAL2, 32,      // Allows for 8 devices
> +  CAL3, 32,
> +  CAL4, 32,
> +  CAL5, 32,
> +  CAL6, 32,
> +  CAL7, 32,
> +  CAL8, 32,
> +  NADL, 32,      // Next active display list
> +  NDL2, 32,      // Allows for 8 devices
> +  NDL3, 32,
> +  NDL4, 32,
> +  NDL5, 32,
> +  NDL6, 32,
> +  NDL7, 32,
> +  NDL8, 32,
> +  ASLP, 32,      // ASL sleep timeout
> +  TIDX, 32,      // Toggle table index
> +  CHPD, 32,      // Current hot plug enable indicator
> +  CLID, 32,      // Current lid state indicator
> +  CDCK, 32,      // Current docking state indicator
> +  SXSW, 32,      // Display switch notify on resume
> +  EVTS, 32,      // Events supported by ASL (diag only)
> +  CNOT, 32,      // Current OS notifications (diag only)
> +  NRDY, 32,
> +  //
> +  //Extended DIDL list
> +  //
> +  DDL9, 32,
> +  DD10, 32,
> +  DD11, 32,
> +  DD12, 32,
> +  DD13, 32,
> +  DD14, 32,
> +  DD15, 32,
> +  //
> +  //Extended Currently attached Display Device List  CPD2
> +  //
> +  CPL9, 32,
> +  CP10, 32,
> +  CP11, 32,
> +  CP12, 32,
> +  CP13, 32,
> +  CP14, 32,
> +  CP15, 32,
> +  //
> +  // OpRegion Mailbox 2 (Software SCI Interface)
> +  //
> +  Offset(0x200), // SCIC
> +  SCIE, 1,       // SCI entry bit (1=call unserviced)
> +  GEFC, 4,       // Entry function code
> +  GXFC, 3,       // Exit result
> +  GESF, 8,       // Entry/exit sub-function/parameter
> +      , 16,      // SCIC[31:16] reserved
> +  Offset(0x204), // PARM
> +  PARM, 32,      // PARM register (extra parameters)
> +  DSLP,  32,     // Driver sleep time out
> +  //
> +  // OpRegion Mailbox 3 (BIOS to Driver Notification)
> +  // Note: Mailbox 3 is normally reserved for desktop platforms.
> +  //
> +  Offset(0x300),
> +  ARDY, 32,      // Driver readiness (power conservation)
> +  ASLC, 32,      // ASLE interrupt command/status
> +  TCHE, 32,      // Technology enabled indicator
> +  ALSI, 32,      // Current ALS illuminance reading
> +  BCLP, 32,      // Backlight brightness
> +  PFIT, 32,      // Panel fitting state or request
> +  CBLV, 32,      // Current brightness level
> +  BCLM, 320,     // Backlight brightness level duty cycle mapping table
> +  CPFM, 32,      // Current panel fitting mode
> +  EPFM, 32,      // Enabled panel fitting modes
> +  PLUT, 592,     // Optional. 74-byte Panel LUT Table
> +  PFMB, 32,      // Optional. PWM Frequency and Minimum Brightness
> +  CCDV, 32,      // Optional. Gamma, Brightness, Contrast values.
> +  PCFT, 32,      // Optional. Power Conservation Features
> +  SROT, 32,      // Supported rotation angle.
> +  IUER, 32,      // Optional. Intel Ultrabook Event Register.
> +  FDSS, 64,      // Optional. FFS Display Physical address
> +  FDSP, 32,      // Optional. FFS Display Size
> +  STAT, 32,      // State Indicator
> +  //
> +  // OpRegion Mailbox 4 (VBT)
> +  //
> +  Offset(0x400),
> +  RVBT, 0xC000,  // 6K bytes maximum VBT image
> +  //
> +  // OpRegion Mailbox 5 (BIOS to Driver Notification Extension)
> +  //
> +  Offset(0x1C00),
> +  PHED, 32,      // Panel Header
> +  BDDC, 2048,    // Panel EDID (Max 256 bytes)
> +
> +}
> +
> +//
> +// Convert boot display type into a port mask.
> +//
> +Name (DBTB, Package()
> +{
> +  0x0000,        // Automatic
> +  0x0007,        // Port-0 : Integrated CRT
> +  0x0038,        // Port-1 : DVO-A, or Integrated LVDS
> +  0x01C0,        // Port-2 : SDVO-B, or SDVO-B/C
> +  0x0E00,        // Port-3 : SDVO-C
> +  0x003F,        // [CRT + DVO-A / Integrated LVDS]
> +  0x01C7,        // [CRT + SDVO-B] or [CRT + SDVO-B/C]
> +  0x0E07,        // [CRT + SDVO-C]
> +  0x01F8,        // [DVO-A / Integrated LVDS + SDVO-B]
> +  0x0E38,        // [DVO-A / Integrated LVDS + SDVO-C]
> +  0x0FC0,        // [SDVO-B + SDVO-C]
> +  0x0000,        // Reserved
> +  0x0000,        // Reserved
> +  0x0000,        // Reserved
> +  0x0000,        // Reserved
> +  0x0000,        // Reserved
> +  0x7000,        // Port-4: Integrated TV
> +  0x7007,        // [Integrated TV + CRT]
> +  0x7038,        // [Integrated TV + LVDS]
> +  0x71C0,        // [Integrated TV + DVOB]
> +  0x7E00         // [Integrated TV + DVOC]
> +})
> +
> +//
> +// Core display clock value table.
> +//
> +Name (CDCT, Package()
> +{
> +  Package() {228, 320},
> +  Package() {222, 333},
> +  Package() {222, 333},
> +  Package() {  0,   0},
> +  Package() {222, 333},
> +})
> +
> +//
> +// Defined exit result values:
> +//
> +Name (SUCC, 1)   // Exit result: Success
> +Name (NVLD, 2)   // Exit result: Invalid parameter
> +Name (CRIT, 4)   // Exit result: Critical failure
> +Name (NCRT, 6)   // Exit result: Non-critical failure
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name: GSCI
> +;*
> +;* Description: Handles an SCI generated by the graphics driver.  The
> +;*              PARM and SCIC input fields are parsed to determine the
> +;*              functionality requested by the driver.  GBDA or SBCB
> +;*              is called based on the input data in SCIC.
> +;*
> +;* Usage:       The method must be called in response to a GPE 06 event
> +;*              which will be generated by the graphics driver.
> +;*              Ex: Method(\_GPE._L06) {Return(\_SB.PCI0.GFX0.GSCI())}
> +;*
> +;* Input:       PARM and SCIC are indirect inputs
> +;*
> +;* Output:      PARM and SIC are indirect outputs
> +;*
> +;* References:  GBDA (Get BIOS Data method), SBCB (System BIOS Callback
> +;*              method)
> +;*
> +;**************************************************************
> **********/
> +
> +Method (GSCI, 0, Serialized)
> +{
> +  Include("IgfxOpGbda.asl")  // "Get BIOS Data" Functions
> +  Include("IgfxOpSbcb.asl")  // "System BIOS CallBacks"
> +
> +  If (LEqual(GEFC, 4))
> +  {
> +    Store(GBDA(), GXFC)    // Process Get BIOS Data functions
> +  }
> +
> +  If (LEqual(GEFC, 6))
> +  {
> +    Store(SBCB(), GXFC)    // Process BIOS Callback functions
> +  }
> +
> +  Store(0, GEFC)           // Wipe out the entry function code
> +  Store(1, CPSC)           // Clear CPUSCI_STS to clear the PCH TCO SCI status
> +  Store(0, GSSE)           // Clear the SCI generation bit in PCI space.
> +  Store(0, SCIE)           // Clr SCI serviced bit to signal completion
> +
> +  Return(Zero)
> +}
> +
> +Include("IgfxCommon.asl")    // IGD SCI mobile features
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpS
> bcb.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpS
> bcb.asl
> new file mode 100644
> index 0000000000..0167d922ff
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpS
> bcb.asl
> @@ -0,0 +1,262 @@
> +/** @file
> +  This file contains the system BIOS call back functionality for the
> +  OpRegion/Software SCI mechanism.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +Method (SBCB, 0, Serialized)
> +{
> +  //
> +  // Supported Callbacks: Sub-function 0
> +  //
> +  If (LEqual(GESF, 0x0))
> +  {
> +    //
> +    //<NOTE> An OEM may support the driver->SBIOS status callbacks, but
> +    // the supported callbacks value must be modified.  The code that is
> +    // executed upon reception of the callbacks must be also be updated
> +    // to perform the desired functionality.
> +    //
> +    Store(0x00000000, PARM)   // No callbacks supported
> +    //Store(0x000787FD, PARM) // Used for Intel test implementaion
> +    Store(0x000F87DD, PARM)
> +    Store(Zero, GESF)         // Clear the exit parameter
> +    Return(SUCC)              // "Success"
> +  }
> +  //
> +  // BIOS POST Completion: Sub-function 1
> +  //
> +  If (LEqual(GESF, 1))
> +  {
> +    Store(Zero, GESF) // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)      // Not supported, but no failure
> +  }
> +  //
> +  // Pre-Hires Set Mode: Sub-function 3
> +  //
> +  If (LEqual(GESF, 3))
> +  {
> +    Store(Zero, GESF) // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)      // Not supported, but no failure
> +  }
> +  //
> +  // Post-Hires Set Mode: Sub-function 4
> +  //
> +  If (LEqual(GESF, 4))
> +  {
> +    Store(Zero, GESF) // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)      // Not supported, but no failure
> +  }
> +  //
> +  // Display Switch: Sub-function 5
> +  //
> +  If (LEqual(GESF, 5))
> +  {
> +    Store(Zero, GESF) // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)      // Not supported, but no failure
> +  }
> +  //
> +  // Adapter Power State: Sub-function 7
> +  //
> +  If (LEqual(GESF, 7))
> +  {
> +    //
> +    // Handle Low Power S0 Idle Capability if enabled
> +    //
> +    If(LAnd(LEqual(S0ID, 1),LLess(OSYS, 2015))) {
> +      //
> +      // Call GUAM to trigger CS Entry
> +      //   If Adapter Power State Notification = D1 (PARM[7:0]=0x01)
> +      //
> +      If (LEqual (And(PARM,0xFF), 0x01)) {
> +        // GUAM - Global User Absent Mode Notification Method
> +        \GUAM(One) // 0x01 - Power State Standby (CS Entry)
> +      }
> +      If (LEqual (And(PARM,0xFF), 0x00)) {
> +        // GUAM - Global User Absent Mode Notification Method
> +        \GUAM(0)
> +      }
> +    }
> +    //
> +    // Upon notification from driver that the Adapter Power State = D0,
> +    // check if previous lid event failed.  If it did, retry the lid
> +    // event here.
> +    //
> +    If(LEqual(PARM, 0))
> +    {
> +      Store(CLID, Local0)
> +      If(And(0x80000000,Local0))
> +      {
> +        And(CLID, 0x0000000F, CLID)
> +        GLID(CLID)
> +      }
> +    }
> +    Store(Zero, GESF) // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)      // Not supported, but no failure
> +  }
> +  //
> +  // Display Power State: Sub-function 8
> +  //
> +  If (LEqual(GESF, 8))
> +  {
> +    Store(Zero, GESF) // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)      // Not supported, but no failure
> +  }
> +  //
> +  // Set Boot Display: Sub-function 9
> +  //
> +  If (LEqual(GESF, 9))
> +  {
> +    //
> +    //<NOTE> An OEM may elect to implement this method.  In that case,
> +    // the input values must be saved into non-volatile storage for
> +    // parsing during the next boot.  The following Sample code is Intel
> +    // validated implementation.
> +    //
> +    And(PARM, 0xFF, IBTT) // Save the boot display to NVS
> +    Store(Zero, GESF)     // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)          // Reserved, "Critical failure"
> +  }
> +  //
> +  // Set Panel Details: Sub-function 10 (0Ah)
> +  //
> +  If (LEqual(GESF, 10))
> +  {
> +    //
> +    //<NOTE> An OEM may elect to implement this method.  In that case,
> +    // the input values must be saved into non-volatile storage for
> +    // parsing during the next boot.  The following Sample code is Intel
> +    // validated implementation.
> +    // Set the panel-related NVRAM variables based the input from the driver.
> +    //
> +    And(PARM, 0xFF, IPSC)
> +    //
> +    // Change panel type if a change is requested by the driver (Change if
> +    // panel type input is non-zero).  Zero=No change requested.
> +    //
> +    If(And(ShiftRight(PARM, 8), 0xFF))
> +    {
> +      And(ShiftRight(PARM, 8), 0xFF, IPAT)
> +      Decrement(IPAT)    // 0 = no change, so fit to CMOS map
> +    }
> +    And(ShiftRight(PARM, 20), 0x7, IBIA)
> +    Store(Zero, GESF)    // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)         // Success
> +  }
> +  //
> +  // Set Internal Graphics: Sub-function 11 (0Bh)
> +  //
> +  If (LEqual(GESF, 11))
> +  {
> +    //
> +    //<NOTE> An OEM may elect to implement this method.  In that case,
> +    // the input values must be saved into non-volatile storage for
> +    // parsing during the next boot.  The following Sample code is Intel
> +    // validated implementation.
> +    //
> +    And(ShiftRight(PARM, 1), 1, IF1E)      // Program the function 1 option
> +    If(And(PARM, ShiftLeft(0xF, 13)))      // Use fixed memory if fixed size != 0
> +    {
> +      //
> +      // Fixed memory
> +      //
> +      And(ShiftRight(PARM, 13), 0xF, IDMS) // Program fixed memory size
> +    }
> +    Else
> +    {
> +      //
> +      // DVMT memory
> +      //
> +      And(ShiftRight(PARM, 17), 0xF, IDMS) // Program fixed memory size
> +    }
> +    Store(Zero, GESF)                      // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                           // Success
> +  }
> +  //
> +  // Post-Hires to DOS FS: Sub-function 16 (10h)
> +  //
> +  If (LEqual(GESF, 16))
> +  {
> +    Store(Zero, GESF) // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)      // Not supported, but no failure
> +  }
> +  //
> +  // APM Complete:  Sub-function 17 (11h)
> +  //
> +  If (LEqual(GESF, 17))
> +  {
> +    Store(ShiftLeft(LIDS, 8), PARM) // Report the lid state
> +    Add(PARM, 0x100, PARM)          // Adjust the lid state, 0 = Unknown
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Return(SUCC)                    // Not supported, but no failure
> +  }
> +  //
> +  // Set Spread Spectrum Clocks: Sub-function 18 (12h)
> +  //
> +  If (LEqual(GESF, 18))
> +  {
> +    //
> +    //<NOTE> An OEM may elect to implement this method.  In that case,
> +    // the input values must be saved into non-volatile storage for
> +    // parsing during the next boot.  The following Sample code is Intel
> +    // validated implementation.
> +    //
> +    If(And(PARM, 1))
> +    {
> +      If(LEqual(ShiftRight(PARM, 1), 1))
> +      {
> +        Store(1, ISSC)  // Enable HW SSC, only for clock 1
> +      }
> +      Else
> +      {
> +        Store(Zero, GESF)
> +        Return(CRIT)    // Failure, as the SSC clock must be 1
> +      }
> +    }
> +    Else
> +    {
> +      Store(0, ISSC)    // Disable SSC
> +    }
> +    Store(Zero, GESF)   // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)        // Success
> +  }
> +  //
> +  // Post VBE/PM Callback: Sub-function 19 (13h)
> +  //
> +  If (LEqual(GESF, 19))
> +  {
> +    Store(Zero, GESF)  // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)       // Not supported, but no failure
> +  }
> +  //
> +  // Set PAVP Data: Sub-function 20 (14h)
> +  //
> +  If (LEqual(GESF, 20))
> +  {
> +    And(PARM, 0xF, PAVP) // Store PAVP info
> +    Store(Zero, GESF)    // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)         // Success
> +  }
> +
> +  //
> +  // A call to a reserved "System BIOS callbacks" function was received
> +  //
> +  Store(Zero, GESF) // Clear the exit parameter
> +  Return(SUCC)      // Reserved, "Critical failure"
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
> new file mode 100644
> index 0000000000..e4e47ddf1e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
> @@ -0,0 +1,87 @@
> +/** @file
> +  This file contains the device definition of the System Agent
> +  ACPI reference code.
> +  Currently defines the device objects for the
> +  System Agent IPU device
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Device IPUA is the IPU AVStream virtual device and it appears under GFX0
> +//
> +Scope (\_SB.PCI0.GFX0)
> +{
> +  Device(IPUA) // IPU AVStream virtual device name
> +  {
> +    /*
> +      The identifier for this device (Same as in
> +      _DOD above). This is required so GFX driver can
> +      associate a matching device ID for the AVStream
> +      driver and provide it to PnP (this device ID
> +      should appear in the INF file of the AVStream
> +      driver).
> +    */
> +    Name(_ADR, 0x00003480)
> +    /*
> +      The following is a technique that may be used (per OEM needs) to
> prevent
> +      the load of the camera device in one of the following cases:
> +      - Camera device is fused out
> +      - If the platform setup requires that in a secured boot the camera device
> +      should not be enabled
> +    */
> +    Method (_STA, 0, NotSerialized) {
> +      If(LEqual(IPTP,1)){ // IGFX need report IPU AVStream virtual device as
> GFX0 child
> +        Return (0xF)
> +      } Else { // IGFX should NOT report IPU AVStream virtual device as GFX0
> child
> +        Return (0x0)
> +      }
> +    }
> +  } // End SKC0
> +} // end I.G.D
> +
> +Scope(\_SB.PCI0.IPU0)
> +{
> +//----------------------------------------------------------------------------------------
> +//  Intel Proprietary Passing LTR information from BIOS to IPU Driver. DSM
> Method
> +//
> +//  Method(_DSM, 0x4, Serialized, 0, {IntObj, BuffObj}, {BuffObj, IntObj,
> IntObj, PkgObj})
> +//  Arguments:
> +//  Arg0: GUID: "9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90"
> +//  Arg1: Integer Revision Level (Current revision is 0)
> +//  Arg2: Integer Function Index
> +//                0x1 - return UINT 32bit LTR values
> +//                0x2 - return UINT 32bit Fill Time
> +//
> +//-----------------------------------------------------------------------------------------
> +Method (_DSM, 4, NotSerialized) { // _DSM: Device-Specific Method
> +    If (LEqual(Arg0, ToUUID("9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90")))
> +    {
> +      // Function 0 : Query Function
> +      If (LEqual(Arg2, 0))
> +      {
> +        // Revision 0
> +        If (LEqual(Arg1, 0)) // The current revision is 0
> +        {
> +          Return(Buffer() { 0x07 }) // There are 2 function defined other than
> Query.
> +        } Else {
> +          Return(0) // Revision mismatch
> +        }
> +      }
> +      // Function 1 : Return UINT 32bit LTR values
> +      If(LEqual(Arg2, 1))
> +      {
> +        Return(0x64503C19)
> +      }
> +      // Function 2 : Return UINT 32bit Fill Time
> +      If(LEqual(Arg2, 2))
> +      {
> +        Return(0xFFF0783C)
> +      }
> +    }
> +
> +    Return(0) // Function number or GUID mismatch but normal return.
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
> new file mode 100644
> index 0000000000..4817968240
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
> @@ -0,0 +1,31 @@
> +/** @file
> +  This file contains the device definition of the System Agent
> +  ACPI reference code.
> +  Currently defines the device objects for the
> +  System Agent PCI Express* ports (PEG), iGfx and other devices.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +External(\_SB.PCI0, DeviceObj)
> +External(\_SB.PCI0.GFX0, DeviceObj)
> +External(\_SB.PCI0.IPU0, DeviceObj)
> +External(\_SB.PCI0.B0D3, DeviceObj)
> +External(\_SB.PCI0.PCIC, MethodObj)
> +External(\_SB.PCI0.PCID, MethodObj)
> +
> +
> +///
> +/// I.G.D
> +///
> +Scope (\_SB.PCI0.GFX0)
> +{
> +  include("Igfx.asl")
> +} // end I.G.D
> +
> +///
> +/// IPU Device
> +///
> +include("Ipu.asl")
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.a
> sl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.
> asl
> new file mode 100644
> index 0000000000..09d36ade53
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.
> asl
> @@ -0,0 +1,147 @@
> +/** @file
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +  //
> +  // Define SA NVS Area operatino region.
> +  //
> +
> +
> +
> +  OperationRegion(SANV,SystemMemory, 0xFFFF0000,0xAA55)
> +  Field(SANV,AnyAcc,Lock,Preserve)
> +  {  Offset(0),      ASLB, 32, // Offset(0),     IGD OpRegion base address
> +  Offset(4),      IMON, 8,  // Offset(4),     IMON Current Value
> +  Offset(5),      IGDS, 8,  // Offset(5),     IGD State (Primary Display = 1)
> +  Offset(6),      IBTT, 8,  // Offset(6),     IGD Boot Display Device
> +  Offset(7),      IPAT, 8,  // Offset(7),     IGD Panel Type CMOS option
> +  Offset(8),      IPSC, 8,  // Offset(8),     IGD Panel Scaling
> +  Offset(9),      IBIA, 8,  // Offset(9),     IGD BIA Configuration
> +  Offset(10),     ISSC, 8,  // Offset(10),    IGD SSC Configuration
> +  Offset(11),     IDMS, 8,  // Offset(11),    IGD DVMT Memory Size
> +  Offset(12),     IF1E, 8,  // Offset(12),    IGD Function 1 Enable
> +  Offset(13),     HVCO, 8,  // Offset(13),    HPLL VCO
> +  Offset(14),     GSMI, 8,  // Offset(14),    GMCH SMI/SCI mode (0=SCI)
> +  Offset(15),     PAVP, 8,  // Offset(15),    IGD PAVP data
> +  Offset(16),     CADL, 8,  // Offset(16),    Current Attached Device List
> +  Offset(17),     CSTE, 16, // Offset(17),    Current Display State
> +  Offset(19),     NSTE, 16, // Offset(19),    Next Display State
> +  Offset(21),     NDID, 8,  // Offset(21),    Number of Valid Device IDs
> +  Offset(22),     DID1, 32, // Offset(22),    Device ID 1
> +  Offset(26),     DID2, 32, // Offset(26),    Device ID 2
> +  Offset(30),     DID3, 32, // Offset(30),    Device ID 3
> +  Offset(34),     DID4, 32, // Offset(34),    Device ID 4
> +  Offset(38),     DID5, 32, // Offset(38),    Device ID 5
> +  Offset(42),     DID6, 32, // Offset(42),    Device ID 6
> +  Offset(46),     DID7, 32, // Offset(46),    Device ID 7
> +  Offset(50),     DID8, 32, // Offset(50),    Device ID 8
> +  Offset(54),     DID9, 32, // Offset(54),    Device ID 9
> +  Offset(58),     DIDA, 32, // Offset(58),    Device ID 10
> +  Offset(62),     DIDB, 32, // Offset(62),    Device ID 11
> +  Offset(66),     DIDC, 32, // Offset(66),    Device ID 12
> +  Offset(70),     DIDD, 32, // Offset(70),    Device ID 13
> +  Offset(74),     DIDE, 32, // Offset(74),    Device ID 14
> +  Offset(78),     DIDF, 32, // Offset(78),    Device ID 15
> +  Offset(82),     DIDX, 32, // Offset(82),    Device ID for eDP device
> +  Offset(86),     NXD1, 32, // Offset(86),    Next state DID1 for _DGS
> +  Offset(90),     NXD2, 32, // Offset(90),    Next state DID2 for _DGS
> +  Offset(94),     NXD3, 32, // Offset(94),    Next state DID3 for _DGS
> +  Offset(98),     NXD4, 32, // Offset(98),    Next state DID4 for _DGS
> +  Offset(102),    NXD5, 32, // Offset(102),   Next state DID5 for _DGS
> +  Offset(106),    NXD6, 32, // Offset(106),   Next state DID6 for _DGS
> +  Offset(110),    NXD7, 32, // Offset(110),   Next state DID7 for _DGS
> +  Offset(114),    NXD8, 32, // Offset(114),   Next state DID8 for _DGS
> +  Offset(118),    NXDX, 32, // Offset(118),   Next state DID for eDP
> +  Offset(122),    LIDS, 8,  // Offset(122),   Lid State (Lid Open = 1)
> +  Offset(123),    KSV0, 32, // Offset(123),   First four bytes of AKSV
> (manufacturing mode)
> +  Offset(127),    KSV1, 8,  // Offset(127),   Fifth byte of AKSV (manufacturing
> mode)
> +  Offset(128),    BRTL, 8,  // Offset(128),   Brightness Level Percentage
> +  Offset(129),    ALSE, 8,  // Offset(129),   Ambient Light Sensor Enable
> +  Offset(130),    ALAF, 8,  // Offset(130),   Ambient Light Adjusment Factor
> +  Offset(131),    LLOW, 8,  // Offset(131),   LUX Low Value
> +  Offset(132),    LHIH, 8,  // Offset(132),   LUX High Value
> +  Offset(133),    ALFP, 8,  // Offset(133),   Active LFP
> +  Offset(134),    IPTP, 8,  // Offset(134),   IPU ACPI device type (0=Disabled,
> 1=AVStream virtual device as child of GFX)
> +  Offset(135),    EDPV, 8,  // Offset(135),   Check for eDP display device
> +  Offset(136),    SGMD, 8,  // Offset(136),   SG Mode (0=Disabled, 1=SG
> Muxed, 2=SG Muxless, 3=DGPU Only)
> +  Offset(137),    SGFL, 8,  // Offset(137),   SG Feature List
> +  Offset(138),    SGGP, 8,  // Offset(138),   PCIe0 GPIO Support (0=Disabled,
> 1=PCH Based, 2=I2C Based)
> +  Offset(139),    HRE0, 8,  // Offset(139),   PCIe0 HLD RST IO Expander
> Number
> +  Offset(140),    HRG0, 32, // Offset(140),   PCIe0 HLD RST GPIO Number
> +  Offset(144),    HRA0, 8,  // Offset(144),   PCIe0 HLD RST GPIO Active
> Information
> +  Offset(145),    PWE0, 8,  // Offset(145),   PCIe0 PWR Enable IO Expander
> Number
> +  Offset(146),    PWG0, 32, // Offset(146),   PCIe0 PWR Enable GPIO Number
> +  Offset(150),    PWA0, 8,  // Offset(150),   PCIe0 PWR Enable GPIO Active
> Information
> +  Offset(151),    P1GP, 8,  // Offset(151),   PCIe1 GPIO Support (0=Disabled,
> 1=PCH Based, 2=I2C Based)
> +  Offset(152),    HRE1, 8,  // Offset(152),   PCIe1 HLD RST IO Expander
> Number
> +  Offset(153),    HRG1, 32, // Offset(153),   PCIe1 HLD RST GPIO Number
> +  Offset(157),    HRA1, 8,  // Offset(157),   PCIe1 HLD RST GPIO Active
> Information
> +  Offset(158),    PWE1, 8,  // Offset(158),   PCIe1 PWR Enable IO Expander
> Number
> +  Offset(159),    PWG1, 32, // Offset(159),   PCIe1 PWR Enable GPIO Number
> +  Offset(163),    PWA1, 8,  // Offset(163),   PCIe1 PWR Enable GPIO Active
> Information
> +  Offset(164),    P2GP, 8,  // Offset(164),   PCIe2 GPIO Support (0=Disabled,
> 1=PCH Based, 2=I2C Based)
> +  Offset(165),    HRE2, 8,  // Offset(165),   PCIe2 HLD RST IO Expander
> Number
> +  Offset(166),    HRG2, 32, // Offset(166),   PCIe2 HLD RST GPIO Number
> +  Offset(170),    HRA2, 8,  // Offset(170),   PCIe2 HLD RST GPIO Active
> Information
> +  Offset(171),    PWE2, 8,  // Offset(171),   PCIe2 PWR Enable IO Expander
> Number
> +  Offset(172),    PWG2, 32, // Offset(172),   PCIe2 PWR Enable GPIO Number
> +  Offset(176),    PWA2, 8,  // Offset(176),   PCIe2 PWR Enable GPIO Active
> Information
> +  Offset(177),    DLPW, 16, // Offset(177),   Delay after power enable for PCIe
> +  Offset(179),    DLHR, 16, // Offset(179),   Delay after Hold Reset for PCIe
> +  Offset(181),    EECP, 8,  // Offset(181),   PCIe0 Endpoint Capability
> Structure Offset
> +  Offset(182),    XBAS, 32, // Offset(182),   Any Device's PCIe Config Space
> Base Address
> +  Offset(186),    GBAS, 16, // Offset(186),   GPIO Base Address
> +  Offset(188),    NVGA, 32, // Offset(188),   NVIG opregion address
> +  Offset(192),    NVHA, 32, // Offset(192),   NVHM opregion address
> +  Offset(196),    AMDA, 32, // Offset(196),   AMDA opregion address
> +  Offset(200),    LTRX, 8,  // Offset(200),   Latency Tolerance Reporting Enable
> +  Offset(201),    OBFX, 8,  // Offset(201),   Optimized Buffer Flush and Fill
> +  Offset(202),    LTRY, 8,  // Offset(202),   Latency Tolerance Reporting Enable
> +  Offset(203),    OBFY, 8,  // Offset(203),   Optimized Buffer Flush and Fill
> +  Offset(204),    LTRZ, 8,  // Offset(204),   Latency Tolerance Reporting Enable
> +  Offset(205),    OBFZ, 8,  // Offset(205),   Optimized Buffer Flush and Fill
> +  Offset(206),    LTRW, 8,  // Offset(206),   Latency Tolerance Reporting
> Enable
> +  Offset(207),    OBFA, 8,  // Offset(207),   Optimized Buffer Flush and Fill
> +  Offset(208),    SMSL, 16, // Offset(208),   SA Peg Latency Tolerance
> Reporting Max Snoop Latency
> +  Offset(210),    SNSL, 16, // Offset(210),   SA Peg Latency Tolerance Reporting
> Max No Snoop Latency
> +  Offset(212),    P0UB, 8,  // Offset(212),   Peg0 Unused Bundle Control
> +  Offset(213),    P1UB, 8,  // Offset(213),   Peg1 Unused Bundle Control
> +  Offset(214),    P2UB, 8,  // Offset(214),   Peg2 Unused Bundle Control
> +  Offset(215),    P3UB, 8,  // Offset(215),   Peg3 Unused Bundle Control
> +  Offset(216),    PCSL, 8,  // Offset(216),   The lowest C-state for the package
> +  Offset(217),    PBGE, 8,  // Offset(217),   Pegx Unused Bundle Control
> Global Enable (0=Disabled, 1=Enabled)
> +  Offset(218),    M64B, 64, // Offset(218),   Base of above 4GB MMIO resource
> +  Offset(226),    M64L, 64, // Offset(226),   Length of above 4GB MMIO
> resource
> +  Offset(234),    CPEX, 32, // Offset(234),   CPU ID info to get Family Id or
> Stepping
> +  Offset(238),    EEC1, 8,  // Offset(238),   PCIe1 Endpoint Capability
> Structure Offset
> +  Offset(239),    EEC2, 8,  // Offset(239),   PCIe2 Endpoint Capability
> Structure Offset
> +  Offset(240),    SBN0, 8,  // Offset(240),   PCIe0 Secondary Bus Number
> (PCIe0 Endpoint Bus Number)
> +  Offset(241),    SBN1, 8,  // Offset(241),   PCIe1 Secondary Bus Number
> (PCIe0 Endpoint Bus Number)
> +  Offset(242),    SBN2, 8,  // Offset(242),   PCIe2 Secondary Bus Number
> (PCIe0 Endpoint Bus Number)
> +  Offset(243),    M32B, 32, // Offset(243),   Base of below 4GB MMIO resource
> +  Offset(247),    M32L, 32, // Offset(247),   Length of below 4GB MMIO
> resource
> +  Offset(251),    P0WK, 32, // Offset(251),   PCIe0 RTD3 Device Wake GPIO
> Number
> +  Offset(255),    P1WK, 32, // Offset(255),   PCIe1 RTD3 Device Wake GPIO
> Number
> +  Offset(259),    P2WK, 32, // Offset(259),   PCIe2 RTD3 Device Wake GPIO
> Number
> +  Offset(263),    VTDS, 8,  // Offset(263),   VT-d Enable/Disable
> +  Offset(264),    VTB1, 32, // Offset(264),   VT-d Base Address 1
> +  Offset(268),    VTB2, 32, // Offset(268),   VT-d Base Address 2
> +  Offset(272),    VTB3, 32, // Offset(272),   VT-d Base Address 3
> +  Offset(276),    VE1V, 16, // Offset(276),   VT-d Engine#1 Vendor ID
> +  Offset(278),    VE2V, 16, // Offset(278),   VT-d Engine#2 Vendor ID
> +  Offset(280),    SBN3, 8,  // Offset(280),   PCIe3 Secondary Bus Number
> (PCIe3 Endpoint Bus Number)
> +  Offset(281),    P3GP, 8,  // Offset(281),   PCIe3 GPIO Support (0=Disabled,
> 1=PCH Based, 2=I2C Based)
> +  Offset(282),    HRE3, 8,  // Offset(282),   PCIe3 HLD RST IO Expander
> Number
> +  Offset(283),    HRG3, 32, // Offset(283),   PCIe3 HLD RST GPIO Number
> +  Offset(287),    HRA3, 8,  // Offset(287),   PCIe3 HLD RST GPIO Active
> Information
> +  Offset(288),    PWE3, 8,  // Offset(288),   PCIe3 PWR Enable IO Expander
> Number
> +  Offset(289),    PWG3, 32, // Offset(289),   PCIe3 PWR Enable GPIO Number
> +  Offset(293),    PWA3, 8,  // Offset(293),   PCIe3 PWR Enable GPIO Active
> Information
> +  Offset(294),    P3WK, 32, // Offset(294),   PCIe3 RTD3 Device Wake GPIO
> Number
> +  Offset(298),    EEC3, 8,  // Offset(298),   PCIe3 Endpoint Capability
> Structure Offset
> +  Offset(299),    RPIN, 8,  // Offset(299),   RootPort Number
> +  Offset(300),    RPBA, 32, // Offset(300),   RootPortAddress
> +  Offset (500),             // Offset(304) : Offset(499), Reserved bytes
> +  }
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> asl
> new file mode 100644
> index 0000000000..0db354901d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> asl
> @@ -0,0 +1,22 @@
> +/** @file
> +  This file contains the SystemAgent SSDT Table ASL code.
> +  It defines a Global NVS table which exchanges datas between OS
> +  and BIOS.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +DefinitionBlock (
> +  "SaSsdt.aml",
> +  "SSDT",
> +  0x02,
> +  "SaSsdt",
> +  "SaSsdt ",
> +  0x3000
> +  )
> +{
> +  include ("SaNvs.asl")
> +  include ("Sa.asl")
> +}
> --
> 2.16.2.windows.1


  parent reply	other threads:[~2019-08-17  1:15 UTC|newest]

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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3C3EFB470A303B4AB093197B6777CCEC504623CD@PGSMSX111.gar.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox