From: "Kubacki, Michael A" <michael.a.kubacki@intel.com>
To: devel@edk2.groups.io
Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>,
Chasel Chiu <chasel.chiu@intel.com>,
Nate DeSimone <nathaniel.l.desimone@intel.com>,
Liming Gao <liming.gao@intel.com>,
Michael D Kinney <michael.d.kinney@intel.com>,
Ankit Sinha <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules
Date: Fri, 16 Aug 2019 17:15:54 -0700 [thread overview]
Message-ID: <20190817001603.30632-29-michael.a.kubacki@intel.com> (raw)
In-Reply-To: <20190817001603.30632-1-michael.a.kubacki@intel.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
* SaAcpiTables - SA (DMAR) ACPI tables.
* SaSsdt - SA SSDT ACPI tables.
* SaInitDxe - Generic DXE SA initialization.
* SmmAccess - Produces an instance of EFI_SMM_ACCESS2_PROTOCOL.
Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf | 50 +
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf | 49 +
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf | 116 ++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf | 48 +
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h | 25 +
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h | 230 +++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h | 1567 ++++++++++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h | 203 +++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h | 1167 ++++++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h | 237 +++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h | 15 +
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h | 50 +
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h | 193 +++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h | 91 ++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h | 23 +
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h | 71 +
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h | 139 ++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h | 17 +
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h | 53 +
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h | 162 ++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c | 157 ++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c | 570 +++++++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c | 171 ++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c | 171 ++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c | 496 ++++++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c | 179 +++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c | 122 ++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c | 717 +++++++++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c | 356 +++++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc | 250 +++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl | 794 ++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl | 1666 ++++++++++++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl | 472 ++++++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl | 369 +++++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl | 129 ++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl | 296 ++++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl | 262 +++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl | 87 +
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl | 31 +
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl | 147 ++
Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl | 22 +
41 files changed, 11970 insertions(+)
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
new file mode 100644
index 0000000000..56ddc2957f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
@@ -0,0 +1,50 @@
+## @file
+# Component description file for the ACPI tables
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010005
+BASE_NAME = SaAcpiTables
+FILE_GUID = 3c0ed5e2-91ea-4b94-820d-9daf9a3bb4a2
+MODULE_TYPE = USER_DEFINED
+VERSION_STRING = 1.0
+
+[Sources]
+ Dmar/Dmar.aslc
+ Dmar/Dmar.h
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ CoffeelakeSiliconPkg/SiPkg.dec
+
+################################################################################
+#
+# Library Class Section - list of Library Classes that are required for
+# this module.
+#
+################################################################################
+
+[LibraryClasses]
+
+################################################################################
+#
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names
+# that this module uses or produces.
+#
+################################################################################
+[Pcd]
+
+[Protocols]
+
+[PPIs]
+
+[Guids]
+
+[Depex]
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
new file mode 100644
index 0000000000..3588565aac
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
@@ -0,0 +1,49 @@
+## @file
+# Component description file for the ACPI tables
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010005
+BASE_NAME = SaSsdt
+FILE_GUID = ca89914d-2317-452e-b245-36c6fb77a9c6
+MODULE_TYPE = USER_DEFINED
+VERSION_STRING = 1.0
+
+[Sources]
+ SaSsdt.asl
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ CoffeelakeSiliconPkg/SiPkg.dec
+
+################################################################################
+#
+# Library Class Section - list of Library Classes that are required for
+# this module.
+#
+################################################################################
+
+[LibraryClasses]
+
+################################################################################
+#
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names
+# that this module uses or produces.
+#
+################################################################################
+[Pcd]
+
+[Protocols]
+
+[PPIs]
+
+[Guids]
+
+[Depex]
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
new file mode 100644
index 0000000000..9937fc60e5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
@@ -0,0 +1,116 @@
+## @file
+# Component description file for SystemAgent Initialization driver
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SaInitDxe
+FILE_GUID = DE23ACEE-CF55-4fb6-AA77-984AB53DE811
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = SaInitEntryPointDxe
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[LibraryClasses]
+UefiDriverEntryPoint
+UefiLib
+UefiBootServicesTableLib
+DxeServicesTableLib
+DebugLib
+TimerLib
+PciCf8Lib
+PciSegmentLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+IoLib
+S3BootScriptLib
+PmcLib
+PchCycleDecodingLib
+PchInfoLib
+GpioLib
+ConfigBlockLib
+SaPlatformLib
+PchPcieRpLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+PcAtChipsetPkg/PcAtChipsetPkg.dec
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+gSiPkgTokenSpaceGuid.PcdMchBaseAddress
+gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress
+
+[Sources]
+SaInitDxe.h
+SaInitDxe.c
+SaInit.h
+SaInit.c
+VTd.c
+VTd.h
+IgdOpRegionInit.h
+IgdOpRegionInit.c
+GraphicsInit.h
+GraphicsInit.c
+PciExpressInit.h
+PciExpressInit.c
+PcieComplex.c
+PcieComplex.h
+SaAcpi.c
+
+[Protocols]
+gEfiAcpiTableProtocolGuid ## CONSUMES
+gSaNvsAreaProtocolGuid ## PRODUCES
+gSaPolicyProtocolGuid ## CONSUMES
+gEfiCpuArchProtocolGuid ## CONSUMES
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+gEfiPciRootBridgeIoProtocolGuid ## CONSUMES
+gEfiPciIoProtocolGuid ## CONSUMES
+gIgdOpRegionProtocolGuid ## PRODUCES
+gEfiFirmwareVolume2ProtocolGuid ## CONSUMES
+gEfiLegacyBiosProtocolGuid ## CONSUMES
+gGopComponentName2ProtocolGuid ## CONSUMES
+gSaIotrapSmiProtocolGuid ## CONSUMES
+
+[Guids]
+gSaConfigHobGuid
+gSgAcpiTablePchStorageGuid
+gSaAcpiTableStorageGuid
+gSgAcpiTableStorageGuid
+gSaSsdtAcpiTableStorageGuid
+gPegSsdtAcpiTableStorageGuid
+gEfiEndOfDxeEventGroupGuid
+gSiConfigHobGuid ## CONSUMES
+gMiscDxeConfigGuid
+gGraphicsDxeConfigGuid
+gMemoryDxeConfigGuid
+gPcieDxeConfigGuid
+gVbiosDxeConfigGuid
+gPchInfoHobGuid
+
+[Depex]
+gEfiAcpiTableProtocolGuid AND
+gEfiFirmwareVolume2ProtocolGuid AND
+gSaPolicyProtocolGuid AND
+gEfiPciRootBridgeIoProtocolGuid AND
+gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure that PCI MMIO resource has been prepared and available for this driver to allocate.
+gEfiHiiDatabaseProtocolGuid
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
new file mode 100644
index 0000000000..9356781c9e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
@@ -0,0 +1,48 @@
+## @file
+# Component description file for the SmmAccess module
+#
+# {1323C7F8-DAD5-4126-A54B-7A05FBF41515}
+#
+# Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SmmAccess
+FILE_GUID = 1323C7F8-DAD5-4126-A54B-7A05FBF41515
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = SmmAccessDriverEntryPoint
+
+
+[LibraryClasses]
+UefiDriverEntryPoint
+BaseLib
+BaseMemoryLib
+DebugLib
+HobLib
+PciLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SmmAccessDriver.h
+SmmAccessDriver.c
+
+
+[Protocols]
+gEfiSmmAccess2ProtocolGuid ## PRODUCES
+
+
+[Guids]
+gEfiSmmPeiSmramMemoryReserveGuid
+
+
+[Depex]
+TRUE
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
new file mode 100644
index 0000000000..4339256bba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
@@ -0,0 +1,25 @@
+/** @file
+ This file describes the contents of the ACPI DMA address Remapping
+ Some additional ACPI values are defined in Acpi1_0.h and Acpi2_0.h.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_DMAR_H_
+#define _SA_DMAR_H_
+
+///
+/// Include standard ACPI table definitions
+///
+#include <IndustryStandard/Acpi30.h>
+#include <DmaRemappingTable.h>
+
+#pragma pack(1)
+
+#define EFI_ACPI_DMAR_OEM_TABLE_ID 0x20202020324B4445 ///< "EDK2 "
+#define EFI_ACPI_DMAR_OEM_CREATOR_ID 0x4C544E49 ///< "INTL"
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h
new file mode 100644
index 0000000000..54cb69066d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h
@@ -0,0 +1,230 @@
+/** @file
+ This file contains the definitions common to the MRC API and other APIs.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcCommonTypes_h_
+#define _MrcCommonTypes_h_
+
+#define INT32_MIN (0x80000000)
+#ifndef INT32_MAX //INT32_MAX->Already defined
+#define INT32_MAX (0x7FFFFFFF)
+#endif
+#define INT16_MIN (0x8000)
+#define INT16_MAX (0x7FFF)
+
+///
+/// System boot mode.
+///
+typedef enum {
+ bmCold, ///< Cold boot
+ bmWarm, ///< Warm boot
+ bmS3, ///< S3 resume
+ bmFast, ///< Fast boot
+ MrcBootModeMax, ///< MRC_BOOT_MODE enumeration maximum value.
+ MrcBootModeDelim = INT32_MAX ///< This value ensures the enum size is consistent on both sides of the PPI.
+} MrcBootMode;
+
+///
+/// DIMM memory package
+/// This enum matches SPD Module Type - SPD byte 3, bits [3:0]
+/// Note that DDR4 have different encoding for some module types
+///
+typedef enum {
+ RDimmMemoryPackage = 1,
+ UDimmMemoryPackage = 2,
+ SoDimmMemoryPackage = 3,
+ MicroDimmMemoryPackageDdr3 = 4,
+ LrDimmMemoryPackageDdr4 = 4,
+ MiniRDimmMemoryPackage = 5,
+ MiniUDimmMemoryPackage = 6,
+ MiniCDimmMemoryPackage = 7,
+ LpDimmMemoryPackage = 7,
+ SoUDimmEccMemoryPackageDdr3 = 8,
+ SoRDimmEccMemoryPackageDdr4 = 8,
+ SoRDimmEccMemoryPackageDdr3 = 9,
+ SoUDimmEccMemoryPackageDdr4 = 9,
+ SoCDimmEccMemoryPackage = 10,
+ LrDimmMemoryPackage = 11,
+ SoDimm16bMemoryPackage = 12,
+ SoDimm32bMemoryPackage = 13,
+ NonDimmMemoryPackage = 14,
+ MemoryPackageMax, ///< MEMORY_PACKAGE enumeration maximum value.
+ MemoryPackageDelim = INT32_MAX ///< This value ensures the enum size is consistent on both sides of the PPI.
+} MEMORY_PACKAGE;
+
+///
+/// Memory training I/O levels.
+///
+typedef enum {
+ DdrLevel = 0, ///< Refers to frontside of DIMM
+ LrbufLevel = 1, ///< Refers to data level at backside of LRDIMM or AEP buffer
+ RegALevel = 2, ///< Refers to cmd level at backside of register - side A
+ RegBLevel = 3, ///< Refers to cmd level at backside of register - side B
+ GsmLtMax, ///< GSM_LT enumeration maximum value.
+ GsmLtDelim = INT32_MAX ///< This value ensures the enum size is consistent on both sides of the PPI.
+} GSM_LT;
+
+///
+/// Memory training margin group selectors.
+///
+typedef enum {
+ RecEnDelay = 0, ///< Linear delay (PI ticks), where the positive increment moves the RCVEN sampling window later in time relative to the RX DQS strobes.
+ RxDqsDelay = 1, ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe later in time relative to the RX DQ signal (i.e. toward the hold side of the eye).
+ RxDqDelay = 2, ///< Linear delay (PI ticks), where the positive increment moves the RX DQ byte/nibble/bitlane later in time relative to the RX DQS signal (i.e.closing the gap between DQ and DQS in the setup side of the eye).
+ RxDqsPDelay = 3, ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe for "even" chunks later in time relative to the RX DQ signal. Even chunks are 0, 2, 4, 6 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+ RxDqsNDelay = 4, ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe for "odd" chunks later in time relative to the RX DQ signal. Odd chunks are 1, 3, 5, 7 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+ RxVref = 5, ///< Linear increment (Vref ticks), where the positive increment moves the byte/nibble/bitlane RX Vref to a higher voltage.
+ RxEq = 6, ///< RX CTLE setting indicating a set of possible resistances, capacitance, current steering, etc. values, which may be a different set of values per product. The setting combinations are indexed by integer values.
+ RxDqBitDelay = 7, ///< Linear delay (PI ticks), where the positive increment moves the RX DQ bitlane later in time relative to the RX DQS signal (i.e.closing the gap between DQ and DQS in the setup side of the eye).
+ RxVoc = 8, ///< Monotonic increment (Sense Amp setting), where the positive increment moves the byte/nibble/bitlane's effective switching point to a lower Vref value.
+ RxOdt = 9, ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+ RxOdtUp = 10, ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+ RxOdtDn = 11, ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+ DramDrvStr = 12, ///< Drive strength setting resistance setting within a set of possible resistances (or currents), which may be a different set of values per product. Indexed by integer values.
+ McOdtDelay = 13, ///<
+ McOdtDuration = 14, ///<
+ SenseAmpDelay = 15, ///< This may be used to indicate CmdToDiffAmpEn for SoC's.
+ SenseAmpDuration = 16, ///<
+ RoundTripDelay = 17, ///< This may be used to indicate CmdToRdDataValid for SoC's.
+ RxDqsBitDelay = 18, ///< Linear delay (PI ticks), where the positive increment moves the RX DQS within the bitlane later in time relative to the RX DQ signal (i.e.closing the gap between DQ and DQS in the hold side of the eye).
+ RxDqDqsDelay = 19, ///< Linear delay (PI ticks), where the positive increment moves the RX DQS per strobe later in time relative to the RX DQ signal (i.e. closing the gap between DQS and DQ in the hold side of the eye. The difference between this parameter and RxDqsDelay is that both the DQ and DQS timings may be moved in order to increase the total range of DQDQS timings.
+ WrLvlDelay = 20, ///< Linear delay (PI ticks), where the positive increment moves both the TX DQS and TX DQ signals later in time relative to all other bus signals.
+ TxDqsDelay = 21, ///< Linear delay (PI ticks), where the positive increment moves the TX DQS strobe later in time relative to all other bus signals.
+ TxDqDelay = 22, ///< Linear delay (PI ticks), where the positive increment moves the TX DQ byte/nibble/bitlane later in time relative to all other bus signals.
+ TxVref = 23, ///< Linear increment (Vref ticks), where the positive increment moves the byte/nibble/bitlane TX Vref to a higher voltage. (Assuming this will abstract away from the range specifics for DDR4, for example.)
+ TxEq = 24, ///< TX EQ setting indicating a set of possible equalization levels, which may be a different set of values per product. The setting combinations are indexed by integer values.
+ TxDqBitDelay = 25, ///< Linear delay (PI ticks), where the positive increment moves the TX DQ bitlane later in time relative to all other bus signals.
+ TxRon = 26, ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+ TxRonUp = 27, ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+ TxRonDn = 28, ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+ TxSlewRate = 29, ///< Monotonic increment, where the positive increment moves the byte/nibble/bitlane's effective slew rate to a higher slope.
+ TxImode = 30, ///< TX I-Mode Boost setting indicating a set of possible current boost levels, which may be a different set of values per product. The setting combinations are indexed by integer values.
+ WrOdt = 31, ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+ NomOdt = 32, ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+ ParkOdt = 33, ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+ TxTco = 34, ///<
+ RxCtleR = 36, ///<
+ RxCtleC = 37, ///<
+ RxDqsPBitDelay = 38, ///< Linear delay (PI ticks), where the positive increment moves the RX DQS bitlane timing for "even" chunks later in time relative to the RX DQ bitlane signal. Even chunks are 0, 2, 4, 6 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+ RxDqsNBitDelay = 39, ///< Linear delay (PI ticks), where the positive increment moves the RX DQS bitlane timing for "odd" chunks later in time relative to the RX DQ bitlane signal. Odd chunks are 1, 3, 5, 7 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+ CmdAll = 40, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_ALL category later in time relative to all other signals on the bus.
+ CmdGrp0 = 41, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_GRP0 category later in time relative to all other signals on the bus.
+ CmdGrp1 = 42, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_GRP1 category later in time relative to all other signals on the bus.
+ CmdGrp2 = 43, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_GRP2 category later in time relative to all other signals on the bus.
+ CtlAll = 44, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_ALL category later in time relative to all other signals on the bus.
+ CtlGrp0 = 45, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP0 category later in time relative to all other signals on the bus.
+ CtlGrp1 = 46, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP1 category later in time relative to all other signals on the bus.
+ CtlGrp2 = 47, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP2 category later in time relative to all other signals on the bus.
+ CtlGrp3 = 48, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP3 category later in time relative to all other signals on the bus.
+ CtlGrp4 = 49, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP4 category later in time relative to all other signals on the bus.
+ CtlGrp5 = 50, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP5 category later in time relative to all other signals on the bus.
+ CmdCtlAll = 51, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_CTL_ALL category later in time relative to all other signals on the bus.
+ CkAll = 52, ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CK_ALL category later in time relative to all other signals on the bus.
+ CmdVref = 53, ///< Linear increment (Vref ticks), where the positive increment moves the CMD Vref to a higher voltage.
+ AlertVref = 54, ///< Linear increment (Vref ticks), where the positive increment moves the ALERT Vref to a higher voltage.
+ CmdRon = 55, ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+
+ EridDelay = 60, ///< Linear delay (PI ticks), where the positive increment moves the ERID signals later in time relative to the internal sampling clock (i.e.closing the gap between ERID and internal sampling clock in the setup side of the eye). This group is applicable for DDRT DIMMs.
+ EridVref = 61, ///< Linear increment (Vref ticks), where the positive increment moves the ERID Vref to a higher voltage. This group is applicable for DDRT DIMMs.
+ ErrorVref = 62, ///< Linear increment (Vref ticks), where the positive increment moves the ERROR Vref to a higher voltage. This group is applicable for DDRT DIMMs.
+ ReqVref = 63, ///< Linear increment (Vref ticks), where the positive increment moves the REQ Vref to a higher voltage. This group is applicable for DDRT DIMMs.
+ RecEnOffset = 64, ///< Linear delay (PI ticks), where the positive increment moves the RCVEN sampling window later in time relative to the RX DQS strobes.
+ RxDqsOffset = 65, ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe later in time relative to the RX DQ signal (i.e. toward the hold side of the eye).
+ RxVrefOffset = 66, ///< Linear increment (Vref ticks), where the positive increment moves the byte/nibble/bitlane RX Vref to a higher voltage.
+ TxDqsOffset = 67, ///< Linear delay (PI ticks), where the positive increment moves the TX DQS strobe later in time relative to all other bus signals.
+ TxDqOffset = 68, ///< Linear delay (PI ticks), where the positive increment moves the TX DQ byte/nibble/bitlane later in time relative to all other bus signals.
+ GsmGtMax, ///< SSA_GSM_GT enumeration maximum value.
+ GsmGtDelim = INT32_MAX ///< This value ensures the enum size is consistent on both sides of the PPI.
+} GSM_GT;
+
+typedef enum {
+ SigRasN = 0,
+ SigCasN = 1,
+ SigWeN = 2,
+ SigBa0 = 3,
+ SigBa1 = 4,
+ SigBa2 = 5,
+ SigA0 = 6,
+ SigA1 = 7,
+ SigA2 = 8,
+ SigA3 = 9,
+ SigA4 = 10,
+ SigA5 = 11,
+ SigA6 = 12,
+ SigA7 = 13,
+ SigA8 = 14,
+ SigA9 = 15,
+ SigA10 = 16,
+ SigA11 = 17,
+ SigA12 = 18,
+ SigA13 = 19,
+ SigA14 = 20,
+ SigA15 = 21,
+ SigA16 = 22,
+ SigA17 = 23,
+ SigCs0N = 24,
+ SigCs1N = 25,
+ SigCs2N = 26,
+ SigCs3N = 27,
+ SigCs4N = 28,
+ SigCs5N = 29,
+ SigCs6N = 30,
+ SigCs7N = 31,
+ SigCs8N = 32,
+ SigCs9N = 33,
+ SigCke0 = 34,
+ SigCke1 = 35,
+ SigCke2 = 36,
+ SigCke3 = 37,
+ SigCke4 = 38,
+ SigCke5 = 39,
+ SigOdt0 = 40, //could also be used for CA-ODT for LP4
+ SigOdt1 = 41, //could also be used for CA-ODT for LP4
+ SigOdt2 = 42,
+ SigOdt3 = 43,
+ SigOdt4 = 44,
+ SigOdt5 = 45,
+ SigPar = 46,
+ SigAlertN = 47,
+ SigBg0 = 48,
+ SigBg1 = 49,
+ SigActN = 50,
+ SigCid0 = 51,
+ SigCid1 = 52,
+ SigCid2 = 53,
+ SigCk0 = 54,
+ SigCk1 = 55,
+ SigCk2 = 56,
+ SigCk3 = 57,
+ SigCk4 = 58,
+ SigCk5 = 59,
+ SigGnt0 = 60,
+ SigGnt1 = 61,
+ SigErid00 = 62,
+ SigErid01 = 63,
+ SigErid10 = 64,
+ SigErid11 = 65,
+ SigErr0 = 66,
+ SigErr1 = 67,
+ SigCa00 = 68, // First instantiation of the CA bus for a given channel
+ SigCa01 = 69,
+ SigCa02 = 70,
+ SigCa03 = 71,
+ SigCa04 = 72,
+ SigCa05 = 73,
+ SigCa10 = 74, // Second instantiation of the CA bus for a given channel
+ SigCa11 = 75,
+ SigCa12 = 76,
+ SigCa13 = 77,
+ SigCa14 = 78,
+ SigCa15 = 79,
+ GsmCsnMax,
+ GsmCsnDelim = INT32_MAX
+} GSM_CSN;
+
+
+#endif // _MrcCommonTypes_h_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h
new file mode 100644
index 0000000000..635906cc2b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h
@@ -0,0 +1,1567 @@
+/** @file
+ This file includes all the data structures that the MRC considers "global data".
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcInterface_h_
+#define _MrcInterface_h_
+
+#define MAX_CPU_SOCKETS (1) ///< The maximum number of CPUs per system.
+#define MAX_CONTROLLERS (1) ///< The maximum number of memory controllers per CPU socket.
+#define MAX_CHANNEL (2) ///< The maximum number of channels per memory controller.
+#define MAX_DIMMS_IN_CHANNEL (2) ///< The maximum number of DIMMs per channel.
+#define MAX_RANK_IN_DIMM (2) ///< The maximum number of ranks per DIMM.
+#define MAX_RANK_IN_CHANNEL (MAX_DIMMS_IN_CHANNEL * MAX_RANK_IN_DIMM) ///< The maximum number of ranks per channel.
+#define MAX_SDRAM_IN_DIMM (9) ///< The maximum number of SDRAMs per DIMM when ECC is enabled.
+#define MAX_MR_IN_DIMM (7) ///< Maximum number of mode registers in a DIMM.
+#define MAX_DEVICES_IN_DDR4 (8) ///< The maximum number of SDRAMs per DDR4 DIMM.
+#define MAX_BITS (8) ///< BITS per byte.
+#define MAX_STROBE (18) ///< Number of strobe groups.
+#define MAX_DQ (72) ///< Number of Dq bits used by the rank.
+#define CHAR_BITS (8) ///< Number of bits in a char.
+#define PSMI_SIZE_MB (64) ///< Define the max size of PSMI needed in MB
+#define BCLK_DEFAULT (100 * 1000 * 1000) ///< BCLK default value, in Hertz.
+#define MAX_COMMAND_GROUPS (2)
+#define MAX_EDGES (2) ///< Maximum number of edges.
+#define SUPPORT_DDR3 SUPPORT ///< SUPPORT means that DDR3 is supported by the MRC.
+#define ULT_SUPPORT_LPDDR3 SUPPORT ///< SUPPORT means that LPDDR3 is supported by the MRC.
+#define TRAD_SUPPORT_LPDDR3 /*UN*/SUPPORT ///< SUPPORT means that LPDDR3 is supported by the MRC.
+#define BDW_SUPPORT_LPDDR3 SUPPORT ///< SUPPORT means that LPDDR3 is supported by the MRC.
+#define JEDEC_SUPPORT_LPDDR SUPPORT ///< SUPPORT means that JEDEC SPD Spec for LPDDR3 is supported by the MRC.
+#define SUPPORT_DDR4 SUPPORT ///< SUPPORT means that DDR4 is supported by the MRC.
+#define SUPPORT_LPDDR3 (ULT_SUPPORT_LPDDR3 || TRAD_SUPPORT_LPDDR3 || BDW_SUPPORT_LPDDR3 || JEDEC_SUPPORT_LPDDR)
+#define MRC_ALL_DDR_SUPPORTED ((SUPPORT_DDR4 == SUPPORT) && ((SUPPORT_DDR3 == SUPPORT) && (SUPPORT_LPDDR3 == SUPPORT)))
+#define MRC_DDR3_LPDDR_SUPPORTED ((SUPPORT_DDR3 == SUPPORT) || (SUPPORT_LPDDR3 == SUPPORT))
+#define SPD3_MANUF_START 117 ///< The starting point for the SPD manufacturing data.
+#define SPD3_MANUF_END 127 ///< The ending point for the SPD manufacturing data.
+#if (SUPPORT_DDR4 == SUPPORT)
+#define SPD4_MANUF_START 320 ///< The starting point for the SPD manufacturing data.
+#define SPD4_MANUF_END 328 ///< The ending point for the SPD manufacturing data.
+#endif
+#if (JEDEC_SUPPORT_LPDDR == SUPPORT)
+#define SPDLP_MANUF_START 320 ///< The starting point for the SPD manufacturing data.
+#define SPDLP_MANUF_END 328 ///< The ending point for the SPD manufacturing data.
+#endif
+#include "MrcSpdData.h"
+#include "MrcRmtData.h"
+#include "MrcCommonTypes.h"
+#pragma pack (push, 1)
+
+
+///
+//////////////////////////////////////////////////////////////////////////////////////
+/// OEM platform routines and types //
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// define the oem check points the OEM can define more point and locate them in the code.
+///
+typedef enum {
+ OemFastBootPermitted, ///< before fast boot.
+ OemRestoreNonTraining,
+ OemPrintInputParameters, ///< before printing input parameters
+ OemSpdProcessingRun, ///< before spd processing code
+ OemSetOverridePreSpd, ///< before set overrides pre spd
+ OemSetOverride, ///< before set overrides
+ OemMcCapability, ///< before MC capability
+ OemMcInitRun, ///< before mc init code
+ OemMcMemoryMap, ///< before memory map
+ OemMcResetRun, ///< before jedec reset
+ OemPreTraining, ///< before the training.
+ OemMcTrainingRun, ///< before training code
+ OemEarlyCommandTraining, ///< before Early Command training
+ OemJedecInitLpddr3, ///< before Jedec Init Lpddr3
+ OemSenseAmpTraining, ///< before Sense Amp Training
+ OemReadMprTraining, ///< before Read MPR Training
+ OemReceiveEnable, ///< before Read Leveling
+ OemJedecWriteLeveling, ///< before Jedec Write Leveling
+ OemLpddrLatencySetB, ///< before LPDDR Latency Set B
+ OemWriteDqDqs, ///< before Write Timing Centering
+ OemWriteVoltage, ///< before Write Voltage Centering
+ OemEarlyWriteDqDqs2D, ///< before Early Write Timing Centering 2D
+ OemEarlyWrDsEq, ///< before Early Write Drive Strength / Equalization
+ OemEarlyReadDqDqs2D, ///< before Early Read Timing Centering 2D
+ OemEarlyReadMprDqDqs2D, ///< before Early MPR Read Timing Centering 2D
+ OemReadDqDqs, ///< before Read Timing Centering
+ OemDdr4Map, ///< before DDR4 PDA Mapping
+ OemDimmRonTraining, ///< before DIMM Ron Training
+ OemDimmODTTraining, ///< before DIMM ODT Training
+ OemWriteDriveStrengthEq, ///< before Write Drive Strength/Equalization 2D Training
+ OemWriteDriveUpDn, ///< before Write Drive Strength Up/Dn 2D Training
+ OemWriteSlewRate, ///< before Write Slew Rate Training
+ OemReadODTTraining, ///< before Read ODT algorithm.
+ OemReadEQTraining, ///< before Read Equalization Training
+ OemReadAmplifierPower, ///< before Read Amplifier Power
+ OemOptimizeComp, ///< before Comp Optimization Training
+ OemPowerSavingMeter, ///< before PowerSavingMeter step
+ OemWriteDqDqs2D, ///< before Write Timing Centering 2D
+ OemReadDqDqs2D, ///< before Read Timing Centering 2D
+ OemCmdVoltCenterPreLct, ///< before Command Voltage Centering that runs pre-LCT
+ OemCmdSlewRate, ///< before CMD Slew Rate
+ OemCmdVoltCentering, ///< before Command Voltage Centering
+ OemCmdDriveStrengthEq, ///< before Command Drive Strength Equalization
+ OemWriteVoltCentering2D, ///< before Write Voltage Centering 2D
+ OemReadVoltCentering2D, ///< before Read Voltage Centering 2D
+ OemLateCommandTraining, ///< before Late Command training
+ OemCmdNormalization, ///< before CMD Normalization
+ OemRoundTripLatency, ///< before Round Trip Latency Traiing
+ OemTurnAroundTimes, ///< before Turn Aorund Times.
+ OemRcvEnCentering1D, ///< before Receive Enable Centring
+ OemSaveMCValues, ///< before saving memory controller values
+ OemRmt, ///< before RMT crosser tool.
+ OemMemTest, ///< before Memory testing
+ OemRestoreTraining, ///< before Restoring Training Values
+ OemJedecResetDdr4Fast, ///< before JEDEC reset for DDR4 in Fast flow
+ OemSelfRefreshExit, ///< before Self Refresh Exit
+ OemNormalMode, ///< before Normal Mode on non-cold boots.
+ OemThermalConfig, ///< set Thermal config values.
+ OemTxtAliasCheck, ///< before TxT Alias Check Call.
+ OemAliasCheck, ///< before alias checking on cold boots.
+ OemHwMemInit,
+
+ OemPostTraining, ///< after the training.
+ OemForceOltm, ///< before MrcForceOltm
+ OemMrcActivate, ///< before MrcActivate call.
+ OemMrcRhPrevention, ///< before MrcRhPrevention
+ OemSaGvSwitch, ///< before SA GV switch
+ OemEngPerfGain, ///< before Energy Performance Gain.
+ OemMrcDone, ///< call to MrcOemCheckPoint when MRC was done.
+ OemFrequencySet, ///< do operation before frequency set.
+ OemFrequencySetDone, ///< do operation after frequency set.
+ OemStartMemoryConfiguration,
+ OemBeforeNormalMode, ///< call to MrcOemCheckPoint before normal mode is enalbed
+ OemAfterNormalMode, ///< call to MrcOemCheckPoint after normal mode is enalbed
+ OemMrcFillBdat,
+ OemRetrainMarginCheck,
+ OemRmtPerBit, ///< before Rank Margin Tool Per-Bit.
+ OemUpdateSaveMCValues, ///< before Updating memory controller values.
+ ///
+ ///*********************************************************************************
+ ///
+ OemNumOfCommands ///< Should always be last in the list!
+} MrcOemStatusCommand;
+
+typedef UINT8 MrcIteration; ///< Mrc invocation sequence number, start with 0 and increment by one each time MRC library is called.
+#define MRC_ITERATION_MAX ((1 << ((sizeof (MrcIteration) * 8) - 1)) + ((1 << ((sizeof (MrcIteration) * 8) - 1)) - 1))
+
+#define MAX_RCOMP (3)
+#define MAX_RCOMP_TARGETS (5)
+
+///
+/// Thermal Options
+///
+typedef struct {
+ UINT8 RaplLim2WindX; ///< Offset 110 - Power Limit 2 Time Window X value: 0=Minimal, 3=Maximum, <b>1=Default</b>
+ UINT8 RaplLim2WindY; ///< Offset 111 - Power Limit 2 Time Window Y value: 0=Minimal, 3=Maximum, <b>1=Default</b>
+ UINT8 RaplLim1WindX; ///< Offset 112 - Power Limit 1 Time Window X value: <b>0=Minimal</b>, 3=Maximum
+ UINT8 RaplLim1WindY; ///< Offset 113 - Power Limit 1 Time Window Y value: <b>0=Minimal</b>, 31=Maximum
+ UINT16 RaplLim2Pwr; ///< Offset 114 - Power Limit 2: 0=Minimal, 16383=Maximum, <b>222=Default</b>
+ UINT16 RaplLim1Pwr; ///< Offset 116 - Power Limit 1: <b>0=Minimal</b>, 16383=Maximum
+ UINT8 WarmThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///< Offset 118 - Warm Threshold (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+ UINT8 HotThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///< Offset 122 - Hot Threshold (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+ UINT8 WarmBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///< Offset 126 - Warm Budget (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+ UINT8 HotBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///< Offset 130 - Hot Budget (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+ UINT8 IdleEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+ UINT8 PdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+ UINT8 ActEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+ UINT8 RdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+ UINT8 WrEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+} ThermalMngmtEn;
+
+
+typedef struct {
+ UINT8 GdxcEnable; ///< GDXC MOT enable
+ UINT8 GdxcIotSize; ///< IOT size in multiples of 8MEG
+ UINT8 GdxcMotSize; ///< MOT size in multiples of 8MEG
+} MrcGdxc;
+
+typedef struct {
+ UINT32 ECT : 1; ///< BIT0 - Early Command Training
+ UINT32 SOT : 1; ///< BIT1 - Sense Amp Offset Training
+ UINT32 ERDMPRTC2D : 1; ///< BIT2 - Early ReadMPR Timing Centering 2D
+ UINT32 RDMPRT : 1; ///< BIT3 - Read MPR Training
+ UINT32 RCVET : 1; ///< BIT4 - Read Leveling Training (RcvEn)
+ UINT32 JWRL : 1; ///< BIT5 - Jedec Write Leveling
+ UINT32 EWRTC2D : 1; ///< BIT6 - Early Write Time Centering 2D
+ UINT32 ERDTC2D : 1; ///< BIT7 - Early Read Time Centering 2D
+ UINT32 WRTC1D : 1; ///< BIT8 - Write Timing Centering 1D
+ UINT32 WRVC1D : 1; ///< BIT9 - Write Voltage Centering 1D
+ UINT32 RDTC1D : 1; ///< BIT10 - Read Timing Centering 1D
+ UINT32 DIMMODTT : 1; ///< BIT11 - Dimm ODT Training
+ UINT32 DIMMRONT : 1; ///< BIT12 - Dimm Ron Training
+ UINT32 WRDSEQT : 1; ///< BIT13 - Write Drive Strength / Equalization Training 2D
+ UINT32 WRSRT : 1; ///< BIT14 - Write Slew Rate Training
+ UINT32 RDODTT : 1; ///< BIT15 - Read ODT Training
+ UINT32 RDEQT : 1; ///< BIT16 - Read Equalization Training
+ UINT32 RDAPT : 1; ///< BIT17 - Read Amplifier Power Training
+ UINT32 WRTC2D : 1; ///< BIT18 - Write Timing Centering 2D
+ UINT32 RDTC2D : 1; ///< BIT19 - Read Timing Centering 2D
+ UINT32 WRVC2D : 1; ///< BIT20 - Write Voltage Centering 2D
+ UINT32 RDVC2D : 1; ///< BIT21 - Read Voltage Centering 2D
+ UINT32 CMDVC : 1; ///< BIT22 - Command Voltage Centering
+ UINT32 LCT : 1; ///< BIT23 - Late Command Training
+ UINT32 RTL : 1; ///< BIT24 - Round Trip latency
+ UINT32 TAT : 1; ///< BIT25 - Turn Around Timing
+ UINT32 RMT : 1; ///< BIT26 - RMT Tool
+ UINT32 MEMTST : 1; ///< BIT27 - Memory Test
+ UINT32 ALIASCHK: 1; ///< BIT28 - SPD Alias Check
+ UINT32 RCVENC1D: 1; ///< BIT29 - Receive Enable Centering 1D
+ UINT32 RMC : 1; ///< BIT30 - Retrain Margin Check
+ UINT32 WRDSUDT : 1; ///< BIT31 - Write Drive Strength Up/Dn independently
+} TrainingStepsEn;
+
+typedef struct {
+ UINT32 CMDSR : 1; ///< BIT0 - CMD Slew Rate Training
+ UINT32 CMDDSEQ : 1; ///< BIT1 - CMD Drive Strength and Tx Equalization
+ UINT32 CMDNORM : 1; ///< BIT2 - CMD Normalization
+ UINT32 EWRDSEQ : 1; ///< BIT3 - Early DQ Write Drive Strength and Equalization Training
+ UINT32 TeRsv4 : 1; ///< BIT4 - Reserved
+ UINT32 TeRsv5 : 1; ///< BIT5 - Reserved
+ UINT32 TeRsv6 : 1; ///< BIT6 - Reserved
+ UINT32 RsvdBits :25;
+} TrainingStepsEn2;
+
+///
+/// Defines whether the MRC is executing in full or mini BIOS mode.
+///
+typedef enum {
+ MrcModeFull, ///< Select full BIOS MRC execution.
+ MrcModeMini, ///< Select mini BIOS MRC execution.
+ MrcModeMaximum ///< Delimiter.
+} MrcMode;
+
+typedef enum {
+ MrcTmPower,
+ MrcTmMargin,
+ MrcTmMax
+} TrainingModeType;
+
+typedef enum {
+ LastRxV,
+ LastRxT,
+ LastTxV,
+ LastTxT,
+ LastRcvEna,
+ LastWrLevel,
+ LastCmdT,
+ LastCmdV,
+ MAX_RESULT_TYPE
+} MrcMarginResult;
+
+typedef enum {
+ MSG_LEVEL_NEVER,
+ MSG_LEVEL_ERROR,
+ MSG_LEVEL_WARNING,
+ MSG_LEVEL_NOTE,
+ MSG_LEVEL_EVENT,
+ MSG_LEVEL_ALGO,
+ MSG_LEVEL_MMIO,
+ MSG_LEVEL_CSV,
+ MSG_LEVEL_TIME,
+ MSG_LEVEL_ALL = MRC_INT32_MAX
+} MrcDebugMsgLevel;
+
+///
+/// Define the frequencies that may be possible in the memory controller.
+/// Note that not all these values may be supported.
+///
+#define fNoInit (0)
+#define f800 (800)
+#define f1000 (1000)
+#define f1100 (1100)
+#define f1067 (1067)
+#define f1200 (1200)
+#define f1300 (1300)
+#define f1333 (1333)
+#define f1400 (1400)
+#define f1467 (1467)
+#define f1500 (1500)
+#define f1600 (1600)
+#define f1700 (1700)
+#define f1733 (1733)
+#define f1800 (1800)
+#define f1867 (1867)
+#define f1900 (1900)
+#define f2000 (2000)
+#define f2100 (2100)
+#define f2133 (2133)
+#define f2200 (2200)
+#define f2267 (2267)
+#define f2300 (2300)
+#define f2400 (2400)
+#define f2500 (2500)
+#define f2533 (2533)
+#define f2600 (2600)
+#define f2667 (2667)
+#define f2700 (2700)
+#define f2800 (2800)
+#define f2900 (2900)
+#define f2933 (2933)
+#define f3000 (3000)
+#define f3067 (3067)
+#define f3100 (3100)
+#define f3200 (3200)
+#define f3333 (3333)
+#define f3467 (3467)
+#define f3600 (3600)
+#define f3733 (3733)
+#define f3867 (3867)
+#define f4000 (4000)
+#define f4133 (4133)
+#define fInvalid (0x7FFFFFFF)
+typedef UINT32 MrcFrequency;
+
+//
+// Max supported frequency in OC mode
+// RefClk133: 15*266 + 100 = 4133 (using Odd ratio mode)
+// RefClk100: 15*200 + 100 = 3100 (using Odd ratio mode)
+//
+#define MAX_FREQ_OC_133 f4133
+#define MAX_FREQ_OC_100 f3100
+
+//
+// tCK value in femtoseconds for various frequencies
+// If Freq is in MHz, then tCK[fs] = 10^9 * 1/(Freq/2)
+//
+#define MRC_DDR_800_TCK_MIN 2500000
+#define MRC_DDR_1000_TCK_MIN 2000000
+#define MRC_DDR_1067_TCK_MIN 1875000
+#define MRC_DDR_1100_TCK_MIN 1818182
+#define MRC_DDR_1200_TCK_MIN 1666667
+#define MRC_DDR_1300_TCK_MIN 1538462
+#define MRC_DDR_1333_TCK_MIN 1500000
+#define MRC_DDR_1400_TCK_MIN 1428571
+#define MRC_DDR_1467_TCK_MIN 1363636
+#define MRC_DDR_1500_TCK_MIN 1333333
+#define MRC_DDR_1600_TCK_MIN 1250000
+#define MRC_DDR_1700_TCK_MIN 1176471
+#define MRC_DDR_1733_TCK_MIN 1153846
+#define MRC_DDR_1800_TCK_MIN 1111111
+#define MRC_DDR_1867_TCK_MIN 1071429
+#define MRC_DDR_1900_TCK_MIN 1052632
+#define MRC_DDR_2000_TCK_MIN 1000000
+#define MRC_DDR_2100_TCK_MIN 952381
+#define MRC_DDR_2133_TCK_MIN 938000
+#define MRC_DDR_2200_TCK_MIN 909091
+#define MRC_DDR_2267_TCK_MIN 882353
+#define MRC_DDR_2300_TCK_MIN 869565
+#define MRC_DDR_2400_TCK_MIN 833333
+#define MRC_DDR_2500_TCK_MIN 800000
+#define MRC_DDR_2533_TCK_MIN 789474
+#define MRC_DDR_2600_TCK_MIN 769231
+#define MRC_DDR_2667_TCK_MIN 750000
+#define MRC_DDR_2700_TCK_MIN 740741
+#define MRC_DDR_2800_TCK_MIN 714286
+#define MRC_DDR_2900_TCK_MIN 689655
+#define MRC_DDR_2933_TCK_MIN 681818
+#define MRC_DDR_3000_TCK_MIN 666667
+#define MRC_DDR_3067_TCK_MIN 652174
+#define MRC_DDR_3100_TCK_MIN 645161
+#define MRC_DDR_3200_TCK_MIN 625000
+#define MRC_DDR_3333_TCK_MIN 600000
+#define MRC_DDR_3467_TCK_MIN 576923
+#define MRC_DDR_3600_TCK_MIN 555556
+#define MRC_DDR_3733_TCK_MIN 535714
+#define MRC_DDR_3867_TCK_MIN 517241
+#define MRC_DDR_4000_TCK_MIN 500000
+#define MRC_DDR_4133_TCK_MIN 483871
+
+///
+/// Define the memory nominal voltage (VDD).
+/// Note that not all these values may be supported.
+///
+typedef enum {
+ VDD_INVALID,
+ VDD_1_00 = 1000,
+ VDD_1_05 = 1050,
+ VDD_1_10 = 1100,
+ VDD_1_15 = 1150,
+ VDD_1_20 = 1200,
+ VDD_1_25 = 1250,
+ VDD_1_30 = 1300,
+ VDD_1_35 = 1350,
+ VDD_1_40 = 1400,
+ VDD_1_45 = 1450,
+ VDD_1_50 = 1500,
+ VDD_1_55 = 1550,
+ VDD_1_60 = 1600,
+ VDD_1_65 = 1650,
+ VDD_1_70 = 1700,
+ VDD_1_75 = 1750,
+ VDD_1_80 = 1800,
+ VDD_1_85 = 1850,
+ VDD_1_90 = 1900,
+ VDD_1_95 = 1950,
+ VDD_2_00 = 2000,
+ VDD_2_05 = 2050,
+ VDD_2_10 = 2100,
+ VDD_2_15 = 2150,
+ VDD_2_20 = 2200,
+ VDD_2_25 = 2250,
+ VDD_2_30 = 2300,
+ VDD_2_35 = 2350,
+ VDD_2_40 = 2400,
+ VDD_2_45 = 2450,
+ VDD_2_50 = 2500,
+ VDD_2_55 = 2550,
+ VDD_2_60 = 2600,
+ VDD_2_65 = 2650,
+ VDD_2_70 = 2700,
+ VDD_2_75 = 2750,
+ VDD_2_80 = 2800,
+ VDD_2_85 = 2850,
+ VDD_2_90 = 2900,
+ VDD_2_95 = 2950,
+ VDD_MAXIMUM = 0x7FFFFFFF
+} MrcVddSelect;
+
+///
+/// SA GV points
+///
+typedef enum {
+ MrcSaGvPointLow,
+ MrcSaGvPointHigh,
+} MrcSaGvPoint;
+
+///
+/// SA GV modes
+/// Disabled: SA GV Disabled, run all MRC tasks
+/// FixedLow: SA GV Disabled, run only MRC tasks marked with MRC_PF_GV_LOW
+/// FixedHigh: SA GV Disabled, run only MRC tasks marked with MRC_PF_GV_HIGH
+/// Enabled: SA GV Enabled
+///
+typedef enum {
+ MrcSaGvDisabled,
+ MrcSaGvFixedLow,
+ MrcSaGvFixedHigh,
+ MrcSaGvEnabled,
+} MrcSaGv;
+
+///
+/// DIMM SPD Security Status
+///
+typedef enum {
+ MrcSpdStatusGood, ///< Memory is in a secure state.
+ MrcSpdStatusAliased, ///< Memory is aliased.
+ MrcSpdStatusLast ///< Must be last in the list
+} MrcSpdStatus;
+
+///
+/// Define the virtual channel.
+///
+typedef enum {
+ vcL, ///< Virtual channel L
+ vcS, ///< Virtual channel S
+} MrcVirtualChannel;
+
+///
+/// Define the board types.
+///
+typedef enum {
+ btCRBMB, ///< 0 - CRB Mobile
+ btCRBDT, ///< 1 - CRB Desktop
+ btUser1, ///< 2 - SV Karkom
+ btUser2, ///< 3 - SV desktop
+ btUser3, ///< 4 - SV miniDVP
+ btUser4, ///< 5 - Ult
+ btCRBEMB, ///< 6 - CRB Embedded
+ btUpServer, ///< 7 - Up Server
+ btUnknown, ///< 8 - Unknown
+ btMaximum ///< Delimiter
+} MrcBoardType;
+
+///
+/// Define the CPU family/model.
+///
+typedef enum {
+ cmCFL_ULX_ULT = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX, ///< Coffeelake ULT/ULX
+ cmCFL_DT_HALO = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO ///< Coffeelake DT/Halo
+} MrcCpuModel;
+
+///
+/// Define the CPU Tick/Tock.
+///
+typedef enum {
+ cfCfl = 0, ///< Coffeelake
+ cfMax
+} MrcCpuFamily;
+
+///
+/// Define the CPU stepping number.
+///
+typedef enum {
+ ///
+ /// Coffeelake ULX/ULT
+ ///
+ csKblH0 = EnumKblH0,
+ csCflD0 = EnumCflD0,
+ csCflW0 = EnumCflW0,
+ csCflV0 = EnumCflV0,
+ csCflUlxUltLast = csCflV0,
+
+ ///
+ /// Coffeelake DT/Halo
+ ///
+ csCflU0 = EnumCflU0,
+ csCflB0 = EnumCflB0,
+ csCflP0 = EnumCflP0,
+ csCflR0 = EnumCflR0,
+ csCflDtHaloLast = csCflR0,
+} MrcCpuStepping;
+
+typedef enum {
+ CONTROLLER_NOT_PRESENT, ///< There is no controller present in the system.
+ CONTROLLER_DISABLED, ///< There is a controller present but it is disabled.
+ CONTROLLER_PRESENT, ///< There is a controller present and it is enabled.
+ MAX_CONTROLLER_STATUS ///< Delimiter
+} MrcControllerSts;
+
+typedef enum {
+ CHANNEL_NOT_PRESENT, ///< There is no channel present on the controller.
+ CHANNEL_DISABLED, ///< There is a channel present but it is disabled.
+ CHANNEL_PRESENT, ///< There is a channel present and it is enabled.
+ MAX_CHANNEL_STATUS ///< Delimiter
+} MrcChannelSts;
+
+typedef enum {
+ DIMM_ENABLED, ///< DIMM/rank Pair is enabled, presence will be detected.
+ DIMM_DISABLED, ///< DIMM/rank Pair is disabled, regardless of presence.
+ DIMM_PRESENT, ///< There is a DIMM present in the slot/rank pair and it will be used.
+ DIMM_NOT_PRESENT, ///< There is no DIMM present in the slot/rank pair.
+ MAX_DIMM_STATUS ///< Delimiter
+} MrcDimmSts;
+
+typedef enum {
+ STD_PROFILE, ///< Standard DIMM profile select.
+ USER_PROFILE, ///< User specifies various override values.
+ XMP_PROFILE1, ///< XMP enthusiast settings select (XMP profile #1).
+ XMP_PROFILE2, ///< XMP extreme settings select (XMP profile #2).
+ MAX_PROFILE ///< Delimiter
+} MrcProfile;
+
+#define XMP_PROFILES_ENABLE (0x3)
+#define XMP1_PROFILE_ENABLE (0x1)
+#define XMP2_PROFILE_ENABLE (0x2)
+
+typedef enum {
+ MRC_REF_CLOCK_133, ///< 133MHz reference clock
+ MRC_REF_CLOCK_100, ///< 100MHz reference clock
+ MRC_REF_CLOCK_MAXIMUM ///< Delimiter
+} MrcRefClkSelect; ///< This value times the MrcClockRatio determines the MrcFrequency.
+
+typedef enum {
+ MRC_FREQ_INVALID = 0,
+ MRC_FREQ_133 = (MRC_BIT0 << MRC_REF_CLOCK_133), // Bit 0
+ MRC_FREQ_100 = (MRC_BIT0 << MRC_REF_CLOCK_100), // Bit 1
+ MRC_FREQ_133_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_133), // Bit 2
+ MRC_FREQ_100_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_100), // Bit 3
+ MRC_FREQ_MAX // Delimiter
+} MrcFreqFlag;
+
+typedef UINT32 MrcBClkRef; ///< Base clock, in Hertz, Default is 100MHz or leave at zero for default.
+
+//
+// This encoding matches CFL SC_GS_CFG.DRAM_technology and MAD_INTER_CHANNEL.DDR_TYPE registers
+//
+typedef enum {
+ MRC_DDR_TYPE_DDR4 = 0,
+ MRC_DDR_TYPE_DDR3 = 1,
+ MRC_DDR_TYPE_LPDDR3 = 2,
+ MRC_DDR_TYPE_UNKNOWN = 3,
+ MAX_MRC_DDR_TYPE ///< Delimiter
+} MrcDdrType;
+
+typedef enum {
+ MrcIterationClock,
+ MrcIterationCmdN,
+ MrcIterationCmdS,
+ MrcIterationCke,
+ MrcIterationCtl,
+ MrcIterationCmdV,
+ MrcIterationMax
+} MrcIterationType;
+
+typedef enum {
+ UpmLimit,
+ PowerLimit,
+ RetrainLimit,
+ MarginLimitMax
+} MRC_MARGIN_LIMIT_TYPE;
+
+
+typedef enum {
+ HardwareRhp,
+ Refresh2x
+} MrcRhpType;
+
+typedef enum {
+ OneIn2To1 = 1,
+ OneIn2To2,
+ OneIn2To3,
+ OneIn2To4,
+ OneIn2To5,
+ OneIn2To6,
+ OneIn2To7,
+ OneIn2To8,
+ OneIn2To9,
+ OneIn2To10,
+ OneIn2To11,
+ OneIn2To12,
+ OneIn2To13,
+ OneIn2To14,
+ OneIn2To15
+} MrcRhProbType;
+
+typedef enum {
+ MRC_POST_CODE,
+ MRC_POST_CODE_WRITE,
+ MRC_POST_CODE_READ,
+ MRC_POST_CODE_MAX
+} MrcDebugPostCode;
+
+typedef struct {
+ UINT32 MrcData;
+ UINT32 Stream;
+ UINT32 Start;
+ UINT32 End;
+ UINT32 Current;
+ int Level;
+ UINT16 PostCode[MRC_POST_CODE_MAX];
+ UINT32 TopStackAddr; ///< Initial stack address.
+ UINT32 LowestStackAddr; ///< Track the lowest stack address used through MrcPrintfVaList()
+} MrcDebug;
+
+typedef UINT16 MrcPostCode;
+typedef UINT8 MrcClockRatio; ///< This value times the MrcRefClkSelect determines the MrcFrequency.
+typedef UINT32 MrcGfxDataSize; ///< The size of the stolen graphics data memory, in MBytes.
+typedef UINT32 MrcGfxGttSize; ///< The size of the graphics translation table, in MBytes.
+
+
+///
+/// This data structure contains all the "DDR power saving data" values that are considered output by the MRC.
+/// The following are memory controller level definitions. All channels on a controller are set to these values.
+///
+typedef struct {
+ BOOLEAN BaseFlag; ///< Indicates if the base line of power was already calculated.
+ UINT16 BaseSavingRd; ///< Indicates the base line of power consume by the ddr on read.
+ UINT16 BaseSavingWr; ///< Indicates the base line of power consume by the ddr on write.
+ UINT16 BaseSavingCmd; ///< Indicates the base line of power consume by the ddr on command.
+ UINT16 MrcSavingRd; ///< Indicates the power consume by the ddr on read at the end of MRC.
+ UINT16 MrcSavingWr; ///< Indicates the power consume by the ddr on write at the end of MRC.
+ UINT16 MrcSavingCmd; ///< Indicates the power consume by the ddr on command at the end of MRC.
+} MrcOdtPowerSaving;
+
+///
+/// The memory controller capabilities.
+///
+typedef union {
+ UINT32 Data;
+ UINT16 Data16[2];
+ UINT8 Data8[4];
+} MrcCapabilityIdA;
+
+typedef union {
+ UINT32 Data;
+ UINT16 Data16[2];
+ UINT8 Data8[4];
+} MrcCapabilityIdB;
+
+typedef union {
+ UINT64 Data;
+ struct {
+ MrcCapabilityIdA A;
+ MrcCapabilityIdB B;
+ } Data32;
+} MrcCapabilityId;
+
+///
+/// MRC version description.
+///
+typedef struct {
+ UINT8 Major; ///< Major version number
+ UINT8 Minor; ///< Minor version number
+ UINT8 Rev; ///< Revision number
+ UINT8 Build; ///< Build number
+} MrcVersion;
+
+///
+/// Memory map configuration information.
+///
+typedef struct {
+ UINT32 TomMinusMe;
+ UINT32 ToludBase;
+ UINT32 BdsmBase;
+ UINT32 GttBase;
+ UINT32 GraphicsControlRegister;
+ UINT32 TsegBase;
+ BOOLEAN ReclaimEnable;
+ UINT32 RemapBase;
+ UINT32 RemapLimit;
+ UINT32 TouudBase;
+ UINT32 TotalPhysicalMemorySize;
+ UINT32 MeStolenBase;
+ UINT32 MeStolenSize;
+ UINT32 GdxcMotBase;
+ UINT32 GdxcMotSize;
+ UINT32 GdxcIotBase;
+ UINT32 GdxcIotSize;
+ UINT32 DprSize;
+ UINT32 PttStolenBase;
+ UINT32 PrmrrBase;
+ UINT32 LowestBase;
+} MrcMemoryMap;
+
+///
+/// Real time clock information.
+///
+typedef struct {
+ UINT8 Seconds; ///< Seconds, 0-59
+ UINT8 Minutes; ///< Minutes, 0-59
+ UINT8 Hours; ///< Hours, 0-23
+ UINT8 DayOfMonth; ///< Day of the month, 1-31
+ UINT8 Month; ///< Month of the year, 1-12
+ UINT16 Year; ///< Year, 0-65535
+} MrcBaseTime;
+
+///
+/// DIMM timings
+///
+typedef struct {
+ UINT32 tCK; ///< Memory cycle time, in femtoseconds.
+ UINT16 NMode; ///< Number of tCK cycles for the channel DIMM's command rate mode.
+ UINT16 tCL; ///< Number of tCK cycles for the channel DIMM's CAS latency.
+ UINT16 tCWL; ///< Number of tCK cycles for the channel DIMM's minimum CAS write latency time.
+ UINT16 tFAW; ///< Number of tCK cycles for the channel DIMM's minimum four activate window delay time.
+ UINT16 tRAS; ///< Number of tCK cycles for the channel DIMM's minimum active to precharge delay time.
+ UINT16 tRCDtRP; ///< Number of tCK cycles for the channel DIMM's minimum RAS# to CAS# delay time and Row Precharge delay time.
+ UINT16 tREFI; ///< Number of tCK cycles for the channel DIMM's minimum Average Periodic Refresh Interval.
+ UINT16 tRFC; ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+ UINT16 tRFCpb; ///< Number of tCK cycles for the channel DIMM's minimum per bank refresh recovery delay time.
+ UINT16 tRFC2; ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+ UINT16 tRFC4; ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+ UINT16 tRPab; ///< Number of tCK cycles for the channel DIMM's minimum row precharge delay time for all banks.
+ UINT16 tRRD; ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time.
+ UINT16 tRRD_L; ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for same bank groups.
+ UINT16 tRRD_S; ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for different bank groups.
+ UINT16 tRTP; ///< Number of tCK cycles for the channel DIMM's minimum internal read to precharge command delay time.
+ UINT16 tWR; ///< Number of tCK cycles for the channel DIMM's minimum write recovery time.
+ UINT16 tWTR; ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time.
+ UINT16 tWTR_L; ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for same bank groups.
+ UINT16 tWTR_S; ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for different bank groups.
+ UINT16 tCCD_L; ///< Number of tCK cycles for the channel DIMM's minimum CAS-to-CAS delay for same bank group.
+} MrcTiming;
+
+typedef struct {
+ UINT8 SG; ///< Number of tCK cycles between transactions in the same bank group.
+ UINT8 DG; ///< Number of tCK cycles between transactions when switching bank groups.
+ UINT8 DR; ///< Number of tCK cycles between transactions when switching between Ranks (in the same DIMM).
+ UINT8 DD; ///< Number of tCK cycles between transactions when switching between DIMMs
+} MrcTurnaroundTimes;
+
+typedef struct {
+ INT32 Mtb; ///< Medium time base.
+ INT32 Ftb; ///< Fine time base.
+} MrcTimeBase;
+
+typedef struct {
+ UINT8 Left; ///< The left side of the timing eye.
+ UINT8 Center; ///< The center of the timing eye.
+ UINT8 Right; ///< The right side of the timing eye.
+} MrcDqTimeMargin;
+
+typedef struct {
+ UINT8 High; ///< The high side of the Vref eye.
+ UINT8 Center; ///< The center of the Vref eye.
+ UINT8 Low; ///< The low side of the Vref eye.
+} MrcDqVrefMargin;
+
+typedef struct {
+ UINT8 Left; ///< The left side of the command eye.
+ UINT8 Right; ///< The right side of the command eye.
+ UINT8 High; ///< The high side of the command eye.
+ UINT8 Low; ///< The low side of the command eye.
+} MrcCommandMargin;
+
+typedef struct {
+ UINT8 Left; ///< The left side of the receive enable eye.
+ UINT8 Right; ///< The right side of the receive enableeye.
+} MrcRecvEnMargin;
+
+typedef struct {
+ UINT8 Left; ///< The left side of the write leveling eye.
+ UINT8 Right; ///< The right side of the write leveling eye.
+} MrcWrLevelMargin;
+
+typedef struct {
+ UINT8 SpdValid[sizeof (MrcSpd) / (CHAR_BITS * sizeof (UINT8))]; ///< Each valid bit maps to SPD byte.
+ UINT8 MrcSpdString[3]; ///< The SPD data start marker. This must be located at the start of the SPD data structure. It includes this string plus the following flag.
+ union {
+ struct {
+ UINT8 DimmNumber : 4; ///< SPD zero based DIMM number.
+ UINT8 ChannelNumber : 3; ///< SPD zero based channel number.
+ UINT8 MdSocket : 1; ///< 0 = memory down, 1 = socketed.
+ } Bit;
+ UINT8 Data;
+ } Flag;
+ MrcSpd Data; ///< The SPD data for each DIMM. SPDGeneral field = 0 when absent.
+} MrcSpdData;
+
+typedef UINT8 (*MRC_IO_READ_8) (UINT32 IoAddress);
+typedef UINT16 (*MRC_IO_READ_16) (UINT32 IoAddress);
+typedef UINT32 (*MRC_IO_READ_32) (UINT32 IoAddress);
+typedef void (*MRC_IO_WRITE_8) (UINT32 IoAddress, UINT8 Value);
+typedef void (*MRC_IO_WRITE_16) (UINT32 IoAddress, UINT16 Value);
+typedef void (*MRC_IO_WRITE_32) (UINT32 IoAddress, UINT32 Value);
+typedef UINT8 (*MRC_MMIO_READ_8) (UINT32 Address);
+typedef UINT16 (*MRC_MMIO_READ_16) (UINT32 Address);
+typedef UINT32 (*MRC_MMIO_READ_32) (UINT32 Address);
+typedef UINT64 (*MRC_MMIO_READ_64) (UINT32 Address);
+typedef UINT8 (*MRC_MMIO_WRITE_8) (UINT32 Address, UINT8 Value);
+typedef UINT16 (*MRC_MMIO_WRITE_16) (UINT32 Address, UINT16 Value);
+typedef UINT32 (*MRC_MMIO_WRITE_32) (UINT32 Address, UINT32 Value);
+typedef UINT64 (*MRC_MMIO_WRITE_64) (UINT32 Address, UINT64 Value);
+typedef UINT8 (*MRC_SMBUS_READ_8) (UINT32 Address, UINT32 *Status);
+typedef UINT16 (*MRC_SMBUS_READ_16) (UINT32 Address, UINT32 *Status);
+typedef UINT8 (*MRC_SMBUS_WRITE_8) (UINT32 Address, UINT8 Value, UINT32 *Status);
+typedef UINT16 (*MRC_SMBUS_WRITE_16) (UINT32 Address, UINT16 Value, UINT32 *Status);
+typedef UINT32 (*MRC_GET_PCI_DEVICE_ADDRESS) (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);
+typedef UINT32 (*MRC_GET_PCIE_DEVICE_ADDRESS) (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);
+typedef void (*MRC_GET_RTC_TIME) (UINT8 *Second, UINT8 *Minute, UINT8 *Hour, UINT8 *Day, UINT8 *Month, UINT16 *Year);
+typedef UINT64 (*MRC_GET_CPU_TIME) (void *MrcData);
+typedef void * (*MRC_MEMORY_COPY) (UINT8 *Destination, UINT8 *Source, UINT32 NumBytes);
+typedef void * (*MRC_MEMORY_SET_BYTE) (UINT8 *Destination, UINT32 NumBytes, UINT8 Value);
+typedef void * (*MRC_MEMORY_SET_WORD) (UINT16 *Destination, UINT32 NumWords, UINT16 Value);
+typedef void * (*MRC_MEMORY_SET_DWORD) (UINT32 *Destination, UINT32 NumDwords, UINT32 Value);
+typedef UINT64 (*MRC_LEFT_SHIFT_64) (UINT64 Data, UINT32 NumBits);
+typedef UINT64 (*MRC_RIGHT_SHIFT_64) (UINT64 Data, UINT32 NumBits);
+typedef UINT64 (*MRC_MULT_U64_U32) (UINT64 Multiplicand, UINT32 Multiplier);
+typedef UINT64 (*MRC_DIV_U64_U64) (UINT64 Dividend, UINT64 Divisor, UINT64 *Remainder);
+typedef BOOLEAN (*MRC_GET_SPD_DATA) (UINT8 BootMode, UINT8 SpdAddress, UINT8 *SpdData, UINT8 *Ddr3Table, UINT32 Ddr3TableSize, UINT8 *Ddr4Table, UINT32 Ddr4TableSize, UINT8 *LpddrTable, UINT32 LpddrTableSize);
+typedef BOOLEAN (*MRC_GET_RANDOM_NUMBER) (UINT32 *Rand);
+typedef UINT32 (*MRC_CPU_MAILBOX_READ) (UINT32 Type, UINT32 Command, UINT32 *Value, UINT32 *Status);
+typedef UINT32 (*MRC_CPU_MAILBOX_WRITE) (UINT32 Type, UINT32 Command, UINT32 Value, UINT32 *Status);
+typedef UINT32 (*MRC_GET_MEMORY_VDD) (void *MrcData, UINT32 DefaultVdd);
+typedef UINT32 (*MRC_SET_MEMORY_VDD) (void *MrcData, UINT32 DefaultVdd, UINT32 Value);
+typedef UINT32 (*MRC_CHECKPOINT) (void *MrcData, UINT32 CheckPoint, void *Scratch);
+typedef void (*MRC_DEBUG_HOOK) (void *GlobalData, UINT16 DisplayDebugNumber);
+typedef void (*MRC_PRINT_STRING) (void *String);
+typedef UINT8 (*MRC_GET_RTC_CMOS) (UINT8 Location);
+typedef UINT64 (*MRC_MSR_READ_64) (UINT32 Location);
+typedef UINT64 (*MRC_MSR_WRITE_64) (UINT32 Location, UINT64 Data);
+typedef void (*MRC_RETURN_FROM_SMC) (void *GlobalData, UINT32 MrcStatus);
+typedef void (*MRC_DRAM_RESET) (UINT32 PciEBaseAddress, UINT32 ResetValue);
+typedef void (*MRC_SET_LOCK_PRMRR) (UINT32 PrmrrBase, UINT32 PrmrrSize);
+typedef void (*MRC_TXT_ACHECK) (void);
+
+///
+/// Function calls that are called external to the MRC.
+/// This structure needs to be aligned with SA_FUNCTION_CALLS. All functions that are
+/// not apart of SA_FUNCTION_CALLS need to be at the end of the structure.
+///
+typedef struct {
+ MRC_IO_READ_8 MrcIoRead8;
+ MRC_IO_READ_16 MrcIoRead16;
+ MRC_IO_READ_32 MrcIoRead32;
+ MRC_IO_WRITE_8 MrcIoWrite8;
+ MRC_IO_WRITE_16 MrcIoWrite16;
+ MRC_IO_WRITE_32 MrcIoWrite32;
+ MRC_MMIO_READ_8 MrcMmioRead8;
+ MRC_MMIO_READ_16 MrcMmioRead16;
+ MRC_MMIO_READ_32 MrcMmioRead32;
+ MRC_MMIO_READ_64 MrcMmioRead64;
+ MRC_MMIO_WRITE_8 MrcMmioWrite8;
+ MRC_MMIO_WRITE_16 MrcMmioWrite16;
+ MRC_MMIO_WRITE_32 MrcMmioWrite32;
+ MRC_MMIO_WRITE_64 MrcMmioWrite64;
+ MRC_SMBUS_READ_8 MrcSmbusRead8;
+ MRC_SMBUS_READ_16 MrcSmbusRead16;
+ MRC_SMBUS_WRITE_8 MrcSmbusWrite8;
+ MRC_SMBUS_WRITE_16 MrcSmbusWrite16;
+ MRC_GET_PCI_DEVICE_ADDRESS MrcGetPciDeviceAddress;
+ MRC_GET_PCIE_DEVICE_ADDRESS MrcGetPcieDeviceAddress;
+ MRC_GET_RTC_TIME MrcGetRtcTime;
+ MRC_GET_CPU_TIME MrcGetCpuTime;
+ MRC_MEMORY_COPY MrcCopyMem;
+ MRC_MEMORY_SET_BYTE MrcSetMem;
+ MRC_MEMORY_SET_WORD MrcSetMemWord;
+ MRC_MEMORY_SET_DWORD MrcSetMemDword;
+ MRC_LEFT_SHIFT_64 MrcLeftShift64;
+ MRC_RIGHT_SHIFT_64 MrcRightShift64;
+ MRC_MULT_U64_U32 MrcMultU64x32;
+ MRC_DIV_U64_U64 MrcDivU64x64;
+ MRC_GET_SPD_DATA MrcGetSpdData;
+ MRC_GET_RANDOM_NUMBER MrcGetRandomNumber;
+ MRC_CPU_MAILBOX_READ MrcCpuMailboxRead;
+ MRC_CPU_MAILBOX_WRITE MrcCpuMailboxWrite;
+ MRC_GET_MEMORY_VDD MrcGetMemoryVdd;
+ MRC_SET_MEMORY_VDD MrcSetMemoryVdd;
+ MRC_CHECKPOINT MrcCheckpoint;
+ MRC_DEBUG_HOOK MrcDebugHook;
+ MRC_PRINT_STRING MrcPrintString;
+ MRC_GET_RTC_CMOS MrcRtcCmos;
+ MRC_MSR_READ_64 MrcReadMsr64;
+ MRC_MSR_WRITE_64 MrcWriteMsr64;
+ MRC_RETURN_FROM_SMC MrcReturnFromSmc;
+ MRC_DRAM_RESET MrcDramReset;
+ MRC_SET_LOCK_PRMRR MrcSetLockPrmrr;
+ MRC_TXT_ACHECK MrcTxtAcheck;
+} MRC_FUNCTION;
+
+///
+///*****************************************
+/// Output related "global data" structures.
+///*****************************************
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are SDRAM level definitions. All ranks on a rank are set to these values.
+///
+/* Commented out until needed, in order to save space.
+typedef struct {
+} MrcSdramOut;
+*/
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are rank level definitions. All ranks on a DIMM are set to these values.
+///
+typedef struct {
+//MrcSdramOut Sdram[MAX_SDRAM_IN_DIMM]; ///< The following are SDRAM level definitions.
+ UINT16 MR[MAX_MR_IN_DIMM]; ///< DRAM mode register value.
+ UINT16 MR11; ///< LPDDR3 ODT MR
+ UINT8 Ddr4PdaMr6[MAX_SDRAM_IN_DIMM]; ///< DDR4 MR6[6:0] for per-DRAM VrefDQ (PDA)
+#if (SUPPORT_DDR4 == SUPPORT)
+ UINT8 Device[MAX_SDRAM_IN_DIMM]; ///< Which Bytes are tied to which Device where BIT0 set means Byte 0
+#endif //SUPPORT_DDR4
+} MrcRankOut;
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are DIMM level definitions. All ranks on a DIMM are set to these values.
+///
+typedef struct {
+ MrcDimmSts Status; ///< See MrcDimmSts for the definition of this field.
+ MrcTiming Timing[MAX_PROFILE]; ///< The DIMMs timing values.
+ MrcVddSelect VddVoltage[MAX_PROFILE]; ///< The voltage (VDD) setting for this DIMM, per profile.
+ BOOLEAN EccSupport; ///< TRUE if ECC is enabled and supported on this DIMM.
+ BOOLEAN IgnoreNonEccDimm; ///< TRUE if a DIMM without ECC capability should be ignored.
+ BOOLEAN AddressMirrored; ///< TRUE if the DIMM is address mirrored.
+ BOOLEAN SelfRefreshTemp; ///< TRUE if the DIMM supports self refresh extended operating temperature range (SRT).
+ BOOLEAN AutoSelfRefresh; ///< TRUE if the DIMM supports automatic self refresh (ASR).
+ BOOLEAN PartialSelfRefresh; ///< TRUE if the DIMM supports Partial Array Self Refresh (PASR).
+ BOOLEAN OnDieThermalSensor; ///< TRUE if the DIMM supports On-die Thermal Sensor (ODTS) Readout.
+ BOOLEAN ExtendedTemperRange; ///< TRUE if the DIMM supports Extended Temperature Range (ETR).
+ BOOLEAN ExtendedTemperRefresh; ///< TRUE if the DIMM supports 1x Extended Temperature Refresh rate, FALSE = 2x.
+ MrcDdrType DdrType; ///< DDR type: DDR3 or LPDDR3
+ MEMORY_PACKAGE ModuleType; ///< Module type: UDIMM, SO-DIMM, etc.
+ UINT32 SdramCount; ///< The number of SDRAM components on a DIMM.
+ UINT32 DimmCapacity; ///< DIMM size in MBytes.
+ UINT32 RowSize; ///< The DIMMs row address size.
+ UINT16 ColumnSize; ///< The DIMMs column address size.
+ UINT16 Crc; ///< Calculated CRC16 of the DIMM's provided SPD. Can be used to detect DIMM change.
+ UINT8 RankInDimm; ///< The number of ranks in this DIMM.
+ UINT8 Banks; ///< Number of banks the DIMM contains.
+ UINT8 BankGroups; ///< Number of bank groups the DIMM contains.
+ UINT8 PrimaryBusWidth; ///< DIMM primary bus width.
+ UINT8 SdramWidth; ///< DIMM SDRAM width.
+ UINT8 SdramWidthIndex; ///< DIMM SDRAM width index (0 = x4, 1 = x8, 2 = x16, 3 = x32).
+ UINT8 DensityIndex; ///< Total SDRAM capacity index (0 = 256Mb, 1 = 512Mb, 2 = 1Gb, etc).
+ UINT8 tMAC; ///< Maximum Activate Count for pTRR.
+ UINT8 ReferenceRawCard; ///< Indicates which JEDEC reference design raw card was used as the basis for the module assembly.
+ UINT8 ReferenceRawCardRevision; ///< Indicates which JEDEC reference design raw card revision.
+ UINT8 XmpSupport; ///< Indicates if XMP profiles are supported. 0 = None, 1 = XMP1 only, 2 = XMP2 only, 3 = All.
+ UINT8 XmpRevision; ///< Indicates the XMP revision of this DIMM. 0 = None, 12h = 1.2, 13h = 1.3.
+ MrcFrequency Speed; ///< Max DIMM speed in the current profile - needed for SMBIOS.
+ MrcRankOut Rank[MAX_RANK_IN_DIMM]; ///< The following are rank level definitions.
+} MrcDimmOut;
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are channel level definitions. All DIMMs on a memory channel are set to these values.
+///
+typedef struct {
+ MrcChannelSts Status; ///< Indicates whether this channel should be used.
+ MrcVirtualChannel VirtualChannel; ///< define the virtual channel type A or B.
+ MrcTiming Timing[MAX_PROFILE]; ///< The channel timing values.
+ MrcTimeBase TimeBase[MAX_DIMMS_IN_CHANNEL][MAX_PROFILE]; ///< Medium and fine timebases for each DIMM in the channel and each memory profile.
+ UINT32 Capacity; ///< Amount of memory in this channel, in MBytes.
+ UINT32 DimmCount; ///< Number of valid DIMMs that exist in the channel.
+ UINT32 DataOffsetTrain[MAX_SDRAM_IN_DIMM]; ///< DataOffsetTrain CR
+ UINT32 DataCompOffset[MAX_SDRAM_IN_DIMM]; ///< DataCompOffset CR
+ UINT32 CkeCmdPiCode[MAX_COMMAND_GROUPS]; ///< CKE CmdPiCode CR, per group
+ UINT32 CmdsCmdPiCode[MAX_COMMAND_GROUPS]; ///< CmdS CmdPiCode CR, per group
+ UINT32 CmdnCmdPiCode[MAX_COMMAND_GROUPS]; ///< CmdN CmdPiCode CR, per group
+ UINT16 TxDqs[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///< TxDQS PI Code
+ UINT16 TxDq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///< TxDQ Pi Code
+ UINT16 RcvEn[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///< RcvEn PI Code
+ UINT16 WlDelay[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///< WlDelay PI Code
+ UINT8 ClkPiCode[MAX_RANK_IN_CHANNEL]; ///< Clk Pi Code
+ UINT8 CtlPiCode[MAX_RANK_IN_CHANNEL]; ///< Ctl Pi Code
+ UINT8 CkePiCode[MAX_RANK_IN_CHANNEL]; ///< Ctl Pi Code
+ UINT8 TxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///< TxEq setting
+ MrcCommandMargin Command[MAX_RANK_IN_CHANNEL]; ///< Cmd setting
+ MrcDqTimeMargin RxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS]; ///< Rx PerBit Pi Code
+ MrcDqTimeMargin TxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS]; ///< Tx PerBit Pi Code
+ MrcDqVrefMargin RxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS]; ///< Rx PerBit Vref
+ MrcDqVrefMargin TxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS]; ///< Rx PerBit Vref
+ MrcRecvEnMargin ReceiveEnable[MAX_RANK_IN_CHANNEL]; ///< Receive enable per rank
+ MrcWrLevelMargin WriteLevel[MAX_RANK_IN_CHANNEL]; ///< Write leveling per rank
+ UINT8 IoLatency[MAX_RANK_IN_CHANNEL]; ///< IOLatency
+ UINT8 RTLatency[MAX_RANK_IN_CHANNEL]; ///< RoundTripLatency
+ UINT32 RTIoComp; ///< RoundTrip IO Compensation of the Channel
+ UINT8 RxVref[MAX_SDRAM_IN_DIMM]; ///< RX Vref in steps of 7.9 mv
+ UINT8 RxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///< RxEQ Setting
+ UINT8 RxDqsP[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///< RxDQSP PI Code
+ UINT8 RxDqsN[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///< RxDQSN PI Code
+ UINT8 ValidRankBitMask; ///< Bit map of the populated ranks per channel
+ UINT8 ValidCkeBitMask; ///< Bit map of the used CKE pins per channel
+ MrcDimmOut Dimm[MAX_DIMMS_IN_CHANNEL]; ///< DIMM specific output variables.
+ MrcTurnaroundTimes tRd2Rd; ///< The system's minimal delay timings for Read command followed by Read command.
+ MrcTurnaroundTimes tRd2Wr; ///< The system's minimal delay timings for Read command followed by Write command.
+ MrcTurnaroundTimes tWr2Rd; ///< The system's minimal delay timings for Write command followed by Read command.
+ MrcTurnaroundTimes tWr2Wr; ///< The system's minimal delay timings for Write command followed by Write command.
+} MrcChannelOut;
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are memory controller level definitions. All channels on a controller are set to these values.
+///
+typedef struct {
+ MrcControllerSts Status; ///< Indicates whether this controller should be used.
+ UINT16 DeviceId; ///< The PCI device id of this memory controller.
+ UINT8 RevisionId; ///< The PCI revision id of this memory controller.
+ UINT8 ChannelCount; ///< Number of valid channels that exist on the controller.
+ MrcChannelOut Channel[MAX_CHANNEL]; ///< The following are channel level definitions.
+} MrcControllerOut;
+
+///
+///********************************************
+/// Saved data related "global data" structures.
+///********************************************
+///
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are DIMM level definitions.
+///
+typedef struct {
+ UINT8 SpdDramDeviceType; ///< Save SPD DramDeviceType information needed for SMBIOS structure creation.
+ UINT8 SpdModuleType; ///< Save SPD ModuleType information needed for SMBIOS structure creation.
+ UINT8 SpdModuleMemoryBusWidth; ///< Save SPD ModuleMemoryBusWidth information needed for SMBIOS structure creation.
+ UINT8 SpdSave[MAX_SPD_SAVE]; ///< Save SPD Manufacturing information needed for SMBIOS structure creation.
+} MrcDimmSave;
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are channel level definitions.
+///
+typedef struct {
+ MrcChannelSts Status; ///< Indicates whether this channel should be used.
+ UINT32 DimmCount; ///< Number of valid DIMMs that exist in the channel.
+ UINT8 ValidRankBitMask; ///< Bit map of the populated ranks per channel
+ MrcTiming Timing[MAX_PROFILE]; ///< The channel timing values.
+ MrcDimmOut Dimm[MAX_DIMMS_IN_CHANNEL]; ///< Save the DIMM output characteristics.
+ MrcDimmSave DimmSave[MAX_DIMMS_IN_CHANNEL]; ///< Save SPD information needed for SMBIOS structure creation.
+} MrcChannelSave;
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are controller level definitions.
+///
+typedef struct {
+ MrcControllerSts Status; ///< Indicates whether this controller should be used.
+ UINT8 ChannelCount; ///< Number of valid channels that exist on the controller.
+ MrcChannelSave Channel[MAX_CHANNEL]; ///< The following are channel level definitions.
+} MrcContSave;
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are system level definitions.
+///
+typedef struct {
+ UINT32 Crc; ///< The CRC-32 of the data in this structure.
+} MrcSaveHeader;
+
+//
+// ------- IMPORTANT NOTE --------
+// MRC_MC_REGISTER_COUNT in MrcInterface.h should match the table in MrcSaveRestore.c.
+// Update this define whenever you add/remove registers from this table.
+//
+#define MRC_REGISTER_COUNT_COMMON (1376 / sizeof (UINT32)) ///< The number of MC registers that need to be saved (common)
+#define MRC_REGISTER_COUNT_SAGV (1528 / sizeof (UINT32)) ///< The number of MC registers that need to be saved (per SA GV point)
+
+typedef struct {
+ MrcCapabilityId McCapId; ///< The memory controller's capabilities.
+ UINT32 RegSaveCommon[MRC_REGISTER_COUNT_COMMON]; ///< The MC registers that are common to both SA GV points
+ UINT32 RegSaveLow[MRC_REGISTER_COUNT_SAGV]; ///< The MC registers for the Low SA GV point
+ UINT32 RegSaveHigh[MRC_REGISTER_COUNT_SAGV]; ///< The MC registers for the High SA GV point, or for SA GV Disabled case
+ UINT32 MeStolenSize; ///< The managebility engine memory size, in Mbyte units.
+ MrcCpuStepping CpuStepping; ///< The last cold boot happended with this CPU stepping.
+ MrcCpuModel CpuModel; ///< The last cold boot happended with this CPU model.
+ MrcCpuFamily CpuFamily; ///< CPU is Coffeelake
+ MrcVersion Version; ///< The last cold boot happended with this MRC version.
+ UINT32 SaMemCfgCrc; ///< The CRC32 of the system agent memory configuration structure.
+ MrcContSave Controller[MAX_CONTROLLERS]; ///< The following are controller level definitions.
+ MrcFrequency FreqMax; ///< The system's requested maximum frequency.
+ MrcFrequency Frequency; ///< The system's common memory controller frequency.
+ UINT32 MemoryClock; ///< The system's common memory controller clock, in femtoseconds.
+ BOOLEAN OddRatioModeLow; ///< If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for SAGV Low point.
+ BOOLEAN OddRatioModeHigh; ///< If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for SAGV High point, or SAGV disabled / fixed high / fixed low
+ MrcRefClkSelect RefClk; ///< The memory controller is going to use this reference clock.
+ MrcClockRatio Ratio; ///< Request for this memory controller to use this clock ratio.
+ MrcVddSelect VddVoltage[MAX_PROFILE]; ///< The voltage (VDD) setting for all DIMMs in the system, per profile.
+ BOOLEAN EccSupport; ///< TRUE if ECC is enabled and supported on this controller.
+ MrcDdrType DdrType; ///< DDR type: DDR3, DDR4, or LPDDR3
+ UINT32 DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1]; ///< The Default XMP tCK values read from SPD.
+ UINT8 XmpProfileEnable; ///< If XMP capable DIMMs are detected, this will indicate which XMP Profiles are common among all DIMMs.
+ BOOLEAN BinnedLpddrDevices; ///< Binned LPDDR3 devices (6Gb/12Gb/etc)
+ BOOLEAN TCRSensitiveHynixDDR4; ///< TCR sensitive Hynix DDR4 in the system
+ BOOLEAN TCRSensitiveMicronDDR4; ///< TCR sensitive Micron DDR4 in the system
+ BOOLEAN LpddrEctDone; ///< Set to TRUE once Early Command Training on LPDDR is done, and we can run JEDEC Init
+ UINT8 BerEnable; ///< BER Enable (and # of Addresses)
+ UINT64 BerAddress[4]; ///< BER Addresses
+ BOOLEAN DmfcLimitedBoard; ///< Indicates if the system has 2DPC Memory Configuration which should be DMFC limited.
+ BOOLEAN DmfcLimited; ///< Indicates if the system has DMFC limited. Should only be set if DmfcLImitedBoard is TRUE.
+ BOOLEAN MixedUDimmConfig2Dpc; ///< Indicates if the system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
+ BOOLEAN ExtendedDdrOverclock; ///< Indicates if MC is capable of extended Overclock Memory frequencies.
+} MrcSaveData;
+
+typedef struct {
+ UINT32 Size; ///< The size of this structure, in bytes. Must be the first entry in this structure.
+ MrcDebug Debug; ///< MRC debug related variables used for serial output and debugging purposes.
+ MrcVersion Version; ///< The memory reference code version.
+ MrcFrequency FreqMax; ///< The requested maximum valid frequency.
+ MrcFrequency Frequency; ///< The system's common memory controller frequency.
+ UINT32 MemoryClockMax; ///< The system's common memory controller maximum clock, in femtoseconds.
+ UINT32 MemoryClock; ///< The system's common memory controller clock, in femtoseconds.
+ MrcRefClkSelect RefClk; ///< The memory controller is going to use this reference clock.
+ MrcClockRatio Ratio; ///< Request for this memory controller to use this clock ratio.
+ MrcMemoryMap MemoryMapData; ///< The system's memory map data.
+ MrcGfxDataSize GraphicsStolenSize; ///< Graphics Data Stolen Memory size in MB
+ MrcGfxGttSize GraphicsGttSize; ///< GTT graphics stolen memory size in MB
+ MrcVddSelect VddVoltage[MAX_PROFILE]; ///< The currently running voltage (VDD) setting for all DIMMs in the system, per profile.
+ MrcGdxc Gdxc; ///< GDXC enable and size.
+ BOOLEAN VddVoltageDone; ///< To determine if VddVoltageDone update has been done already
+ BOOLEAN EccSupport; ///< TRUE if ECC is enabled and supported on this controller.
+ BOOLEAN EnDumRd; ///< Enable/Disable Logic Analyzer
+ BOOLEAN RestoreMRs; ///< Enable/Disable restoring
+ BOOLEAN LpddrEctDone; ///< Set to TRUE once Early Command Training on LPDDR is done, and we can run JEDEC Init
+ BOOLEAN LpddrWLUpdated; ///< Set to TRUE once LPDDR WL Memory Set has been updated
+ BOOLEAN JedecInitDone; ///< Set to TRUE once JEDEC Init on LPDDR/DDR4 is done
+ UINT32 DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1]; ///< The Default XMP tCK values read from SPD.
+ UINT8 XmpProfileEnable; ///< If XMP capable DIMMs are detected, this will indicate which XMP Profiles are common among all DIMMs.
+ BOOLEAN Capable100; ///< The MC is capable of 100 reference clock (0 = no, 1 = yes).
+ BOOLEAN AutoSelfRefresh; ///< Indicates ASR is supported for all the DIMMS for 2xRefresh
+ MrcDdrType DdrType; ///< Current memory type: DDR3, DDR4, or LPDDR3
+ MrcSpdStatus SpdSecurityStatus; ///< Status variable to inform BIOS that memory contains an alias.
+ UINT32 MrcTotalChannelLimit; ///< The maximum allowed memory size per channel, in MBytes.
+ UINT8 SdramCount; ///< The number of SDRAM components on a DIMM.
+ UINT16 Qclkps; ///< Qclk period in pS
+ UINT8 DQPat; ///< Global Variables storing the current DQPat REUT Test
+ INT8 DQPatLC; ///< Global Variables storing the current DQPat Loopcount
+ UINT16 NumCL; ///< Global Variables storing the current number of Cachelines
+ UINT8 ValidRankMask; ///< Rank bit map - includes both channels
+ UINT8 ValidChBitMask; ///< Channel bit map of the populated channels
+ BOOLEAN UpmPwrRetrainFlag; ///< A flag that indicates if training with higher UPM/PWR limits.
+ UINT32 MarginResult[MAX_RESULT_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_EDGES]; ///< Stores last margin measurement.
+ BOOLEAN MarginSignReversed[MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_EDGES]; ///< Indicates if the Margin Sign is Reversed
+ MrcOdtPowerSaving OdtPowerSavingData; ///< ODT power savings data.
+ BOOLEAN TxDIMMVref[MAX_CHANNEL]; ///< Whether Write DIMM Vref is enabled based on Channel
+ UINT32 MchBarWriteCount; ///< The number of MMIO writes performed during MRC execution.
+ UINT32 MchBarReadCount; ///< The number of MMIO reads performed during MRC execution.
+ UINT8 BerEnable; ///< BER Enable (and # of Addresses)
+ UINT64 BerAddress[4]; ///< BER Addresses
+ UINT8 CmdVLoop; ///< Keeps track of the # of CmdV training step runned
+ UINT8 CmdVLoopStatus; ///< Keeps the last status of the CmdV training step
+ UINT8 tMAC; ///< Maximum Activate Count for pTRR.
+ UINT8 LpddrMemWriteLatencySet; ///< 0 = Set A (WL), 1 = Set B (WL) if supported
+ BOOLEAN Ddr4PdaEnable; ///< Current status of PDA - if true all the Mr6 operations need to use PDA mode.
+ BOOLEAN BinnedLpddrDevices; ///< Binned LPDDR3 devices (6Gb/12Gb/etc)
+ MrcControllerOut Controller[MAX_CONTROLLERS]; ///< The following are controller level definitions.
+ BOOLEAN TCRSensitiveHynixDDR4; ///< TCR sensitive Hynix DDR4 in the system
+ BOOLEAN TCRSensitiveMicronDDR4; ///< TCR sensitive Micron DDR4 in the system
+ BOOLEAN OddRatioMode; ///< If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz
+ BOOLEAN LpddrDramOdt; ///< Indicates if LPDDR DRAM ODT is used - Only used for 2133+
+ BOOLEAN ExtendedDdrOverclock; ///< Indicates if MC is capable of extended Overclock Memory frequencies.
+ BOOLEAN DmfcLimitedBoard; ///< Indicates if the system has 2DPC Memory Configuration which should be DMFC limited.
+ BOOLEAN DmfcLimited; ///< Indicates if the system has DMFC has been limited. Should only be set if DmfcLImitedBoard is TRUE.
+ BOOLEAN MixedUDimmConfig2Dpc; ///< Indicates if the system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
+#ifdef BDAT_SUPPORT
+ union {
+ MRC_BDAT_SCHEMA_LIST_HOB *Pointer; ///< Pointer to the BDAT schema list.
+ UINT64 Data;
+ } BdatSchemasHob;
+ union {
+ BDAT_MEMORY_DATA_HOB *Pointer; ///< Pointer to the BDAT memory data HOB.
+ UINT64 Data;
+ } BdatMemoryHob[MAX_SCHEMA_LIST_LENGTH];
+ UINT8 Margin2DResult[MAX_2D_EYE_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_2D_EYE_OFFSETS][MAX_EDGES]; ///< Stores the 2D Eye Margin
+#endif
+
+#ifdef UP_SERVER_FLAG
+ UINT8 ThermOffset[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///< TSOD Thermal Offset
+#endif
+} MrcOutput;
+
+///
+///****************************************
+/// Input related "global data" structures.
+///****************************************
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are SDRAM level definitions. All ranks on a rank are set to these values.
+///
+/* Commented out until needed, in order to save space.
+typedef struct {
+ UINT8 Placeholder; ///< TODO: Is there anything that needs to go in here?
+} MrcSdramIn;
+*/
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are rank level definitions. All ranks on a DIMM are set to these values.
+///
+/* Commented out until needed, in order to save space.
+typedef struct {
+ MrcSdramIn Sdram[MAX_SDRAM_IN_DIMM]; ///< The following are SDRAM level definitions.
+} MrcRankIn;
+*/
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are DIMM level definitions. All ranks on a DIMM are set to these values.
+///
+typedef struct {
+ MrcDimmSts Status; ///< Indicates whether this DIMM should be used.
+ MrcSpdData Spd; ///< The SPD data for each DIMM. SPDGeneral field = 0 when absent.
+ MrcTiming Timing; ///< The DIMMs requested timing overrides.
+ UINT8 SpdAddress; ///< The SMBus address for the DIMM's SPD data.
+//MrcRankIn Rank[MAX_RANK_IN_DIMM]; ///< The following are rank level definitions.
+} MrcDimmIn;
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are channel level definitions. All DIMMs on a memory channel are set to these values.
+///
+typedef struct {
+ MrcChannelSts Status; ///< Indicates whether this channel should be used.
+ UINT32 DimmCount; ///< The maximum number of DIMMs on this channel.
+ MrcDimmIn Dimm[MAX_DIMMS_IN_CHANNEL]; ///< The following are DIMM level definitions.
+ UINT8 DqsMapCpu2Dram[8]; ///< Mapping from CPU DQS pins to SDRAM DQS pins
+ UINT8 DqMapCpu2Dram[8][MAX_BITS]; ///< Mapping from CPU DQ pins to SDRAM DQ pins
+ UINT8 DQByteMap[MrcIterationMax][2]; ///< Maps which PI clocks are used by what LPDDR DQ Bytes (from CPU side), per group
+ ///< DQByteMap[0] - ClkDQByteMap:
+ ///< If clock is per rank, program to [0xFF, 0xFF]
+ ///< If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF]
+ ///< If clock is shared by 2 ranks but does not go to all bytes,
+ ///< Entry[i] defines which DQ bytes Group i services
+ ///< DQByteMap[1] - CmdNDQByteMap: Entry[0] is CmdN/CAA and Entry[1] is CmdN/CAB
+ ///< DQByteMap[2] - CmdSDQByteMap: Entry[0] is CmdS/CAA and Entry[1] is CmdS/CAB
+ ///< DQByteMap[3] - CkeDQByteMap : Entry[0] is CKE /CAA and Entry[1] is CKE /CAB
+ ///< For DDR, DQByteMap[3:1] = [0xFF, 0]
+ ///< DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0] since we have 1 CTL / rank
+ ///< Variable only exists to make the code easier to use
+ ///< DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] since we have 1 CA Vref
+ ///< Variable only exists to make the code easier to use
+} MrcChannelIn;
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are memory controller level definitions. All channels on a controller are set to these values.
+///
+typedef struct {
+ MrcControllerSts Status; ///< Indicates whether this controller should be used.
+ UINT8 ChannelCount; ///< Number of valid channels that are requested on the controller.
+ MrcChannelIn Channel[MAX_CHANNEL]; ///< The following are channel level definitions.
+} MrcControllerIn;
+
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are system level definitions. All memory controllers in the system are set to these values.
+typedef struct {
+ // Start of synchronization to the SA MEMORY_CONFIGURATION structure.
+ // Alignment of this block must be maintained and field offsets must match.
+ UINT8 Header[28]; ///< Offset 0-27 Config Block Header
+ UINT16 Size; ///< Offset 28 The size of this structure, in bytes. Must be the first entry in this structure.
+ UINT8 HobBufferSize; ///< Offset 30 Size of HOB buffer
+ UINT8 MemoryProfile; ///< Offset 31 SPD XMP profile selection - for XMP supported DIMM: <b>0=Default DIMM profile</b>, 1=Customized profile, 2=XMP profile 1, 3=XMP profile 2.
+ // The following parameters are used only when MemoryProfile is UserDefined (CUSTOM PROFILE)
+ UINT16 tCL; ///< Offset 32 User defined Memory Timing tCL value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 31=Maximum.
+ UINT16 tRCDtRP; ///< Offset 34 User defined Memory Timing tRCD value (same as tRP), valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 63=Maximum.
+ UINT16 tRAS; ///< Offset 36 User defined Memory Timing tRAS value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 64=Maximum.
+ UINT16 tWR; ///< Offset 38 User defined Memory Timing tWR value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, legal values: 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 24.
+ UINT16 tRFC; ///< Offset 40 User defined Memory Timing tRFC value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 1023=Maximum.
+ UINT16 tRRD; ///< Offset 42 User defined Memory Timing tRRD value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+ UINT16 tWTR; ///< Offset 44 User defined Memory Timing tWTR value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+ UINT16 tRTP; ///< Offset 46 User defined Memory Timing tRTP value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum. DDR4 legal values: 5, 6, 7, 8, 9, 10, 12
+ UINT16 tFAW; ///< Offset 48 User defined Memory Timing tFAW value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 63=Maximum.
+ UINT16 tCWL; ///< Offset 50 User defined Memory Timing tCWL value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 20=Maximum.
+ UINT16 tREFI; ///< Offset 52 User defined Memory Timing tREFI value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 65535=Maximum.
+ UINT16 PciIndex; ///< Offset 54 Pci index register address: <b>0xCF8=Default</b>
+ UINT16 PciData; ///< Offset 56 Pci data register address: <b>0xCFC=Default</b>
+ UINT16 VddVoltage; ///< Offset 58 DRAM voltage (Vdd) in millivolts: <b>0=Platform Default (no override)</b>, 1200=1.2V, 1350=1.35V etc.
+ UINT16 Idd3n; ///< Offset 60 EPG Active standby current (Idd3N) in milliamps from DIMM datasheet.
+ UINT16 Idd3p; ///< Offset 62 EPG Active power-down current (Idd3P) in milliamps from DIMM datasheet.
+
+ UINT32 EccSupport:1; ///< Offset 64 DIMM Ecc Support option - for Desktop only: 0=Disable, <b>1=Enable</b>
+ UINT32 MrcSafeConfig:1; ///< - MRC Safe Mode: <b>0=Disable</b>, 1=Enable
+ UINT32 RemapEnable:1; ///< - This option is used to control whether to enable/disable memory remap above 4GB: 0=Disable, <b>1=Enable</b>.
+ UINT32 ScramblerEnable:1; ///< - Memory scrambler support: 0=Disable, <b>1=Enable</b>
+ UINT32 Vc1ReadMeter:1; ///< - VC1 Read Metering Enable: 0=Disable, <b>1=Enable</b>
+ UINT32 DdrThermalSensor:1; ///< - Ddr Thermal Sensor: 0=Disable, <b>1=Enable</b>
+ UINT32 LpddrMemWriteLatencySet:1; ///< - LPDDR3 Write Latency Set option: 0=Set A, <b>1=Set B</b>
+ UINT32 Off64Bits7to8Rsvd:2; ///< - Bits 7-8 Reserved
+ UINT32 SimicsFlag:1; ///< - Option to Enable SIMICS: 0=Disable, <b>1=Enable</b>
+ UINT32 Ddr4DdpSharedClock:1; ///< - New Select if CLK0 is shared between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>, 1=Shared
+ UINT32 Ddr4DdpSharedZq:1; ///< - Select if ZQ pin is shared between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>, 1=Shared
+ // Thermal Management
+ UINT32 ThermalManagement:1; ///< - Memory Thermal Management Support: <b>0=Disable</b>, 1=Enable.
+ UINT32 PeciInjectedTemp:1; ///< - Enable/Disable memory temperatures to be injected to the processor via PECI: <b>0=Disable</b>, 1=Enable.
+ UINT32 ExttsViaTsOnBoard:1; ///< - Enable/Disable routing TS-on-Board's ALERT# and THERM# to EXTTS# pins on the PCH: <b>0=Disable</b>, 1=Enable.
+ UINT32 ExttsViaTsOnDimm:1; ///< - Enable/Disable routing TS-on-DIMM's ALERT# to EXTTS# pin on the PCH: <b>0=Disable</b>, 1=Enable.
+ UINT32 VirtualTempSensor:1; ///< - Enable/Disable Virtual Temperature Sensor (VTS): <b>0=Disable</b>, 1=Enable.
+ UINT32 Lp4DqsOscEn:1; ///< - DqDqsReTraining support: 0=Disable, <b>1=Enable</b>
+ UINT32 DualDimmPerChannelBoardType:1; ///< - DualDimmPerChannelBoardType: Option to indicate if the Memory Design for the board includes two DIMMs per channel: <b>0=Single DIMM Design</b>, 1=Dual DIMM Design
+ UINT32 ReservedBits1:13;
+ /**
+ Disables a DIMM slot in the channel even if a DIMM is present\n
+ Array index represents the channel number (0 = channel 0, 1 = channel 1)\n
+ <b>0x0 = DIMM 0 and DIMM 1 enabled</b>\n
+ 0x1 = DIMM 0 disabled, DIMM 1 enabled\n
+ 0x2 = DIMM 0 enabled, DIMM 1 disabled\n
+ 0x3 = DIMM 0 and DIMM 1 disabled (will disable the whole channel)\n
+ **/
+ UINT8 DisableDimmChannel[MAX_CHANNEL]; ///< Offset 68
+ /**
+ Selects the ratio to multiply the reference clock by for the DDR frequency\n
+ When RefClk is 133MHz\n
+ <b>0x00 = Auto</b>, 0x03 through 0x0C are valid values, all others are invalid\n
+ When RefClk is 100MHz\n
+ <b>0x00 = Auto</b>, 0x06 through 0x10 are valid values, all others are invalid\n
+ **/
+ UINT8 Ratio; ///< Offset 70
+ UINT8 ProbelessTrace; ///< Offset 71 Probeless Trace: <b>0=Disabled</b>, <b>1=Enabled</b>
+ UINT32 BClkFrequency; ///< Offset 72 Base reference clock value, in Hertz: <b>100000000 = 100Hz</b>, 125000000=125Hz, 167000000=167Hz, 250000000=250Hz
+ /**
+ - Channel Hash Enable.\n
+ NOTE: BIT7 will interleave the channels at a 2 cacheline granularity, BIT8 at 4 and BIT9 at 8\n
+ 0=BIT6, <B>1=BIT7</B>, 2=BIT8, 3=BIT9
+ **/
+ UINT8 ChHashInterleaveBit; ///< Offset 76
+ UINT8 EnergyScaleFact; ///< Offset 77 - Energy Scale Factor. 0=Minimal, 7=Maximum, <b>4=Default</b>
+ UINT8 Reserved0; ///< Offset 78 - Reserved for future use.
+ UINT8 McLock; ///< Offset 79 - Enable/Disable memory configuration register locking: 0=Disable, <b>1=Enable</b>.
+ // Training Algorithms
+ TrainingStepsEn TrainingEnables; ///< Offset 80 - Options to Enable individual training steps
+ TrainingStepsEn2 TrainingEnables2; ///< Offset 84 - Options to Enable individual training steps
+
+ UINT32 OddRatioMode:1; ///< Offset 88 - If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz: <b>0=Disable</b>, 1=Enable
+ UINT32 MrcTimeMeasure:1; ///< - Enables serial debug level to display the MRC execution times only: <b>0=Disable</b>, 1=Enable
+ UINT32 MrcFastBoot:1; ///< - Enables the MRC fast boot path for faster cold boot execution: 0=Disable, <b>1=Enable</b>
+ UINT32 DqPinsInterleaved:1; ///< - Interleaving mode of DQ/DQS pins for HSW_ULT which depends on board routing: <b>0=Disable</b>, 1=Enable
+ UINT32 RankInterleave:1; ///< - Rank Interleave Mode: 0=Disable, <b>1=Enable</b>
+ UINT32 EnhancedInterleave:1; ///< - Enhanced Interleave Mode: 0=Disable, <b>1=Enable</b>
+ UINT32 WeaklockEn:1; ///< - Weak Lock Enable: 0=Disable, <b>1=Enable</b>
+ UINT32 CmdTriStateDis:1; ///< - CMD Tri-State Support: <b>0=Enable</b>, 1=Disable. Note: This should be set to 1 (Disable) if Command RTT is not present on the platform.
+ UINT32 MemoryTrace:1; ///< - Memory Trace to second DDR channel using Stacked Mode: <b>0=Disable</b>, 1=Enable
+ UINT32 ChHashEnable:1; ///< - Channel Hash Enable: 0=Disable, <b>1=Enable</b>
+ UINT32 EnableExtts:1; ///< - Enable Extts: <b>0=Disable</b>, 1=Enable
+ UINT32 EnableCltm:1; ///< - Enable Closed Loop Thermal Management: <b>0=Disable</b>, 1=Enable
+ UINT32 EnableOltm:1; ///< - Enable Open Loop Thermal Management: <b>0=Disable</b>, 1=Enable
+ UINT32 EnablePwrDn:1; ///< - Enable Power Down control for DDR: 0=PCODE control, <b>1=BIOS control</b>
+ UINT32 EnablePwrDnLpddr:1; ///< - Enable Power Down for LPDDR: 0=PCODE control, <b>1=BIOS control</b>
+ UINT32 LockPTMregs:1; ///< - Lock PCU Thermal Management registers: 0=Disable, <b>1=Enable</b>
+ UINT32 UserPowerWeightsEn:1; ///< - Allows user to explicitly set power weight, scale factor, and channel power floor values: <b>0=Disable</b>, 1=Enable
+ UINT32 RaplLim2Lock:1; ///< - Lock DDR_RAPL_LIMIT register: <b>0=Disable</b>, 1=Enable
+ UINT32 RaplLim2Ena:1; ///< - Enable Power Limit 2: <b>0=Disable</b>, 1=Enable
+ UINT32 RaplLim1Ena:1; ///< - Enable Power Limit 1: <b>0=Disable</b>, 1=Enable
+ UINT32 SrefCfgEna:1; ///< - Enable Self Refresh: 0=Disable, <b>1=Enable</b>
+ UINT32 ThrtCkeMinDefeatLpddr:1; ///< - Throttler CKE min defeature for LPDDR: 0=Disable, <b>1=Enable</b>
+ UINT32 ThrtCkeMinDefeat:1; ///< - Throttler CKE min defeature: <b>0=Disable</b>, 1=Enable
+ UINT32 AutoSelfRefreshSupport:1; ///< - FALSE = No auto self refresh support, <b>TRUE = auto self refresh support</b>
+ UINT32 ExtTemperatureSupport:1; ///< - FALSE = No extended temperature support, <b>TRUE = extended temperature support</b>
+ UINT32 MobilePlatform:1; ///< - Memory controller device id indicates: <b>TRUE if mobile</b>, FALSE if not. Note: This will be auto-detected and updated.
+ UINT32 Force1Dpc:1; ///< - TRUE means force one DIMM per channel, <b>FALSE means no limit</b>
+ UINT32 ForceSingleRank:1; ///< - TRUE means use Rank0 only (in each DIMM): <b>0=Disable</b>, 1=Enable
+ UINT32 RhPrevention:1; ///< - RH Prevention Enable/Disable: 0=Disable, <b>1=Enable</b>
+ UINT32 VttTermination:1; ///< - Vtt Termination for Data ODT: <b>0=Disable</b>, 1=Enable
+ UINT32 VttCompForVsshi:1; ///< - Enable/Disable Vtt Comparator For Vsshi: <b>0=Disable</b>, 1=Enable
+ UINT32 ExitOnFailure:1; ///< - MRC option for exit on failure or continue on failure: 0=Disable, <b>1=Enable</b>
+
+ UINT32 VddSettleWaitTime; ///< Offset 92 - Amount of time in microseconds to wait for Vdd to settle on top of 200us required by JEDEC spec: <b>Default=0</b>
+ UINT16 FreqSaGvLow; ///< Offset 96 - SA GV: 0 is Auto/default, otherwise holds the frequency value: <b>0=Default</b>, 1067, 1200, 1333, 1400, 1600, 1800, 1867.
+ UINT16 SrefCfgIdleTmr; ///< Offset 98 - Self Refresh idle timer: <b>512=Minimal</b>, 65535=Maximum
+ UINT8 RhActProbability; ///< Offset 100 - Activation probability for Hardware RHP
+ UINT8 SmramMask; ///< Offset 101 - Reserved memory ranges for SMRAM
+ UINT16 Vc1ReadMeterThreshold; ///< Offset 102 - VC1 Read Meter Threshold (within Time Window): 0=Minimal, 0xFFFF=Maximum, <b>0x118=Default</b>
+ UINT32 Vc1ReadMeterTimeWindow; ///< Offset 104 - VC1 Read Meter Time Window: 0=Minimal, 0x1FFFF=Maximum, <b>0x320=Default</b>
+ UINT64 BerAddress[4]; ///< Offset 108 - 139 BER Address(es): <b>0=Minimal</b>, 0xFFFFFFFFFFFFFFFF=Maximum (step is 0x40)
+
+ UINT16 ChHashMask; ///< Offset 140 - Channel Hash Mask: 0x0001=BIT6 set(Minimal), 0x3FFF=BIT[19:6] set(Maximum), <b>0x30CE= BIT[19:18, 13:12 ,9:7] set</b>
+ UINT16 DdrFreqLimit; ///< Offset 142 - Memory Frequency Limit: <b>0=Auto (limited by SPD/CPU capability)</b>, for valid values see MrcFrequency in MrcInterface.h
+ ThermalMngmtEn ThermalEnables; ///< Offset 144 - 187
+
+ UINT8 MaxRttWr; ///< Offset 188 - Maximum DIMM RTT_WR to use in power training: <b>0=ODT Off</b>, 1 = 120 ohms
+ UINT8 ThrtCkeMinTmr; ///< Offset 189 - Throttler CKE min timer: 0=Minimal, 0xFF=Maximum, <b>0x30=Default</b>
+ UINT8 ThrtCkeMinTmrLpddr; ///< Offset 190 - Throttler CKE min timer for LPDDR: 0=Minimal, 0xFF=Maximum, <b>0x40=Default</b>
+ UINT8 BerEnable; ///< Offset 191 - BER Enable and # of Addresses passed in: <b>0=Minimal</b>, 8=Maximum
+ UINT8 CkeRankMapping; ///< Offset 192 - Bits [7:4] - Channel 1, bits [3:0] - Channel 0. <b>0xAA=Default</b> Bit [i] specifies which rank CKE[i] goes to.
+ UINT8 StrongWkLeaker; ///< Offset 193 - Strong Weak Leaker: 1=Minimal, <b>7=Maximum</b>
+ UINT8 CaVrefConfig; ///< Offset 194 - 0=VREF_CA goes to both CH_A and CH_B, 1=VREF_CA to CH_A, VREF_DQ_A to CH_B, <b>2=VREF_CA to CH_A, VREF_DQ_B to CH_B</b>
+ UINT8 SaGv; ///< Offset 195 - SA GV: <b>0=Disabled</b>, 1=FixedLow, 2=FixedHigh, 3=Enabled
+ UINT8 RaplPwrFlCh1; ///< Offset 196 - Power Channel 1 Floor value: <b>0=Minimal</b>, 255=Maximum
+ UINT8 RaplPwrFlCh0; ///< Offset 197 - Power Channel 0 Floor value: <b>0=Minimal</b>, 255=Maximum
+ UINT8 NModeSupport; ///< Offset 198 - Memory N Mode Support - Enable user to select Auto, 1N or 2N: <b>0=AUTO</b>, 1=1N, 2=2N.
+ UINT8 RefClk; ///< Offset 199 - Selects the DDR base reference clock. 0x01 = 100MHz, <b>0x00 = 133MHz</b>
+ UINT8 EnCmdRate; ///< Offset 200 - CMD Rate Enable: 0=Disable, 1=1 CMD, 2=2 CMDs, <b>3=3 CMDs</b>, 4=4 CMDs, 5=5 CMDs, 6=6 CMDs, 7=7 CMDs
+ UINT8 Refresh2X; ///< Offset 201 - Refresh 2x: <b>0=Disable</b>, 1=Enable for WARM or HOT, 2=Enable for HOT only
+ UINT8 EpgEnable; ///< Offset 202 - Enable Energy Performance Gain.
+ UINT8 RhSolution; ///< Offset 203 - Type of solution to be used for RHP - 0/1 = HardwareRhp/Refresh2x
+ UINT8 UserThresholdEnable; ///< Offset 204 - Flag to manually select the DIMM CLTM Thermal Threshold, 0=Disable, 1=Enable, <b>0=Default</b>
+ UINT8 UserBudgetEnable; ///< Offset 205 - Flag to manually select the Budget Registers for CLTM Memory Dimms , 0=Disable, 1=Enable, <b>0=Default</b>
+ UINT8 TsodTcritMax; ///< Offset 206 - TSOD Tcrit Maximum Value to be Configure , 0=Minimal, 128=Maximum, , <b>105=Default</b>
+
+ UINT8 TsodEventMode; ///< Offset 207 - Flag to Enable Event Mode Interruption in TSOD Configuration Register, 0=Disable, 1=Enable, <b>1=Default</b>
+ UINT8 TsodEventPolarity; ///< Offset 208 - Event Signal Polarity in TSOD Configuration Register, 0=Low, 1=High, <b>0=Default</b>
+ UINT8 TsodCriticalEventOnly; ///< Offset 209 - Critical Trigger Only in TSOD Configuration Register,0=Disable, 1=Enable, <b>1=Default</b>
+ UINT8 TsodEventOutputControl; ///< Offset 210 - Event Output Control in TSOD Configuration Register,0=Disable, 1=Enable, <b>1=Default</b>
+ UINT8 TsodAlarmwindowLockBit; ///< Offset 211 - Alarm Windows Lock Bit in TSOD Configuration Register,0=Unlock, 1=Lock, <b>0=Default</b>
+ UINT8 TsodCriticaltripLockBit;///< Offset 212 - Critical Trip Lock Bit in TSOD Configuration Register,0=Unlock, 1=Lock, <b>0=Default</b>
+ UINT8 TsodShutdownMode; ///< Offset 213 - Shutdown Mode TSOD Configuration Register,0=Enable, 1=Disable, <b>0=Default</b>
+ UINT8 TsodThigMax; ///< Offset 214 - Thigh Max Value In the for CLTM Memory Dimms , 0=Disable, 1=Enable, <b>0=Default</b>
+ UINT8 TsodManualEnable; ///< Offset 215 - Flag to manually select the TSOD Register Values , 0=Disable, 1=Enable, <b>0=Default</b>
+ UINT8 DllBwEn0; ///< Offset 216 - DllBwEn value for 1067
+ UINT8 DllBwEn1; ///< Offset 217 - DllBwEn value for 1333
+ UINT8 DllBwEn2; ///< Offset 218 - DllBwEn value for 1600
+ UINT8 DllBwEn3; ///< Offset 219 - DllBwEn value for 1867 and up
+ UINT8 RetrainOnFastFail; ///< Offset 220 - Restart MRC in Cold mode if SW MemTest fails during Fast flow. 0 = Disabled, <b>1 = Enabled</b>
+ UINT8 ForceOltmOrRefresh2x; ///< Offset 221 - Force OLTM or 2X Refresh when needed. <b>0 = Force OLTM</b>, 1 = Force 2x Refresh
+ UINT8 PowerDownMode; ///< Offset 222 - CKE Power Down Mode: <b>0xFF=AUTO</b>, 0=No Power Down, 1= APD mode, 6=PPD-DLL Off mode
+ UINT8 PwdwnIdleCounter; ///< Offset 223 - CKE Power Down Mode Idle Counter: 0=Minimal, 255=Maximum, <b>0x80=0x80 DCLK</b>
+ UINT8 IsvtIoPort; ///< Offset 224 ISVT IO Port Address: 0=Minimal, 0xFF=Maximum, <b>0x99=Default</b>
+ UINT8 Reserved3; ///< Offset 225 - ConfigBlock size must be a multiple of DWORDs
+ MrcGdxc Gdxc; ///< Offset 226 - 228 - GDXC enable and size.
+ UINT8 RMTLoopCount; ///< Offset 229 - Indicates the Loop Count to be used for Rank Margin Tool Testing: 1=Minimal, 32=Maximum, 0=AUTO, <b>0=Default</b>
+ UINT8 Reserved4[2]; ///< Offset 230 - 231 Reserved for DWORD alignment.
+ UINT32 RmtPerTask:1; ///< Offset 232 Bit 0: Rank Margin Tool Per Task. <b>0 = Disabled</b>, 1 = Enabled
+ UINT32 Off232Bit1Rsvd:2; ///< Offset 232 Bit 1-2: Reserved
+ UINT32 EnBER:1; ///< Offset 232 Bit 3: Define if EnBER is enabled for Rank Margin Tool
+ UINT32 Ddr4MixedUDimm2DpcLimit:1; ///< Offset 232 Bit 4: Enable/Disable 2667 Frequency Limitation for DDR4 U-DIMM Mixed Dimm 2DPC population. 0 = Disabled, <b>1 = Enabled</b>
+ UINT32 FastBootRmt:1; ///< Offset 232 Bit 5: Enable/Disable RMT on FastBoot. <b>0 = Disabled</b>, 1 = Enabled
+ UINT32 MrcTrainOnWarm:1; ///< Offset 232 Bit 6: Enalbes MRC trainin on warm boot : <b>0=Disable</b>, 1 = Enabled
+ UINT32 LongFlyByModeEnabled:1; ///< Offset 232 Bit 7: Long FlyBy Mode Enabled : <b>0 = Disabled</b>, 1 = Enabled
+ UINT32 Off232RsvdBits:24; ///< Offset 232 Bit 8-31: Reserved
+
+ //
+ // TurnAround Timing
+ //
+ MrcTurnaroundTimes tRd2Rd; ///< Offset 236 - User-defined overrides for Read-to-Read Turn Around Timings. <b>0 = AUTO</b>
+ MrcTurnaroundTimes tRd2Wr; ///< Offset 240 - User-defined overrides for Read-to-Write Turn Around Timings. <b>0 = AUTO</b>
+ MrcTurnaroundTimes tWr2Rd; ///< Offset 244 - User-defined overrides for Write-to-Read Turn Around Timings. <b>0 = AUTO</b>
+ MrcTurnaroundTimes tWr2Wr; ///< Offset 248 - User-defined overrides for Write-to-Write Turn Around Timings. <b>0 = AUTO</b>
+ UINT16 tRRD_L; ///< Offset 252 - User defined DDR4 Memory Timing tRRD_L value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+ UINT16 tRRD_S; ///< Offset 254 - User defined DDR4 Memory Timing tRRD_S value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+ UINT16 tWTR_L; ///< Offset 266 - User defined DDR4 Memory Timing tWTR_L value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+ UINT16 tWTR_S; ///< Offset 268 - User defined DDR4 Memory Timing tWTR_S value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+
+ //
+ // End of synchronization to the SA MEMORY_CONFIGURATION structure.
+ //
+ MrcFrequency FreqMax; ///< The requested maximum valid frequency.
+ MrcBoardType BoardType; ///< Define the board type (CRBMB,CRBDT,User1,User2). the OEM can add more boards.
+ MrcCpuStepping CpuStepping; ///< Define the CPU stepping.
+ MrcCpuModel CpuModel; ///< Define the CPU model.
+ MrcCpuFamily CpuFamily; ///< CPU is Coffeelake
+ MrcGfxDataSize GraphicsStolenSize; ///< Graphics Data Stolen Memory size in MB
+ MrcGfxGttSize GraphicsGttSize; ///< GTT graphics stolen memory size in MB
+ MrcBaseTime BaseTime; ///< RTC base time.
+ MrcIteration Iteration; ///< Number of iterations thru the MRC core call table.
+ MrcMode MrcMode; ///< The control for full or MiniBIOS MRC.
+ MrcBootMode BootMode; ///< The requested memory controller boot mode.
+ BOOLEAN TxtFlag; ///< Trusted eXecution Technology flag.
+ BOOLEAN SetRxDqs32; ///< Set DQS Delay to 32 control.
+ BOOLEAN GfxIsVersatileAcceleration; ///< iGFX engines are in Versatile Acceleration
+ BOOLEAN DDR4MAP; ///< DDR4 PDA Mapping training control.
+ POINTER_STRUCT SaMemCfgAddress; ///< Starting address of the input parameters to CRC.
+ UINT32 SaMemCfgSize; ///< The size of the input parameters to CRC.
+ UINT32 PciEBaseAddress; ///< define the PciE base address.
+ UINT32 MchBarBaseAddress; ///< define the MCH bar base address.
+ UINT32 SmbusBaseAddress; ///< This field defines the smbus base address.
+ UINT32 GdxcBaseAddress; ///< This field defines the GDXC base address.
+ UINT32 HpetBaseAddress; ///< This field defines the hpet base address.
+ UINT32 MeStolenSize; ///< define the size that the ME need in MB.
+ UINT32 MmioSize; ///< define the MMIO size in MB.
+ UINT32 TsegSize; ///< TSEG size that require by the system in MB.
+ UINT32 IedSize; ///< IED size that require by the system in MB.
+ UINT32 DprSize; ///< DPR size required by system in MB.
+ UINT32 PrmrrSize; ///< Prmrr size required by the system in MB.
+ POINTER_STRUCT SerialBuffer; ///< Pointer to the start of the serial buffer.
+ UINT32 SerialBufferSize; ///< The size of the serial buffer, in bytes.
+ UINT32 DebugStream; ///< The debug port pointer.
+ INT32 DebugLevel; ///< Indicates the level of debug messaging.
+ UINT16 VccIomV; ///< VccIO logic voltage in mV.
+ MrcControllerIn Controller[MAX_CONTROLLERS]; ///< The following are controller level definitions.
+ UINT32 HeapBase; ///< Starting address of the heap space.
+ UINT32 HeapSize; ///< Size of the heap space, in bytes.
+ UINT32 MrcStackTop; ///< Top of the stack at the beginning of MRC, for stack usage calculations.
+ BOOLEAN BdatEnable; ///< Option to enable output of training results into BDAT.
+ UINT8 BdatTestType; ///< When BdatEnable is set to TRUE, this option selects the type of training results data which will be populated into BDAT: <b>0=RMT</b>, 1=RMT Per Bit, 2=Margin 2D.
+ BOOLEAN LpddrDramOdt; ///< TRUE if LPDDR DRAM ODT is used - depends on board design
+ BOOLEAN Ddr3DramOdt; ///< TRUE if DDR3 DRAM ODT is used - depends on board design
+ BOOLEAN Ddr4DramOdt; ///< TRUE if DDR4 DRAM ODT is used - depends on board design
+ BOOLEAN EnableVrefPwrDn; ///< Setting this limits VrefGen to be off only during CKEPowerDown
+ BOOLEAN TxEqDis; ///< Disable TX Equalization
+ BOOLEAN EnVttOdt; ///< Enable VTT Termination for Data ODT
+ UINT32 CpuidModel; ///< Unique CPU identifier.
+ UINT8 CpuidStepping; ///< Revision of the CPU.
+ UINT8 CpuidSku; ///< SKU of the CPU.
+ UINT32 SiPreMemPolicyPpi;
+ TrainingModeType PowerTrainingMode; ///< 0 - Power Training. 1 - Margin Training.
+ union {
+ MRC_FUNCTION *Func; ///< External to MRC function pointers
+ UINT64 Data;
+ } Call;
+ UINT16 RcompResistor[MAX_RCOMP]; ///< Reference RCOMP resistors on motherboard
+ UINT16 RcompTarget[MAX_RCOMP_TARGETS]; ///< RCOMP target values for DqOdt, DqDrv, CmdDrv, CtlDrv, ClkDrv
+ UINT32 CleanMemory:1; ///< TRUE to request a memory clean
+ UINT32 OcSupport:1; ///< TRUE if Overclocking is enabled in BIOS
+ UINT32 RsvdBits5:30;
+ /**
+ Sets the serial debug message level\n
+ 0x00 = Disabled\n
+ 0x01 = Errors only\n
+ 0x02 = Errors and Warnings\n
+ <b>0x03 = Errors, Warnings, and Info</b>\n
+ 0x04 = Errors, Warnings, Info, and Events\n
+ 0x05 = Displays Memory Init Execution Time Summary only\n
+ **/
+ UINT8 SerialDebugLevel;
+} MrcInput;
+
+typedef struct {
+ UINT32 Size; ///< The size of this structure, in bytes. Must be the first entry in this structure.
+ MrcSaveHeader Header; ///< The header portion of the MRC saved data.
+ MrcSaveData Data; ///< The data portion of the MRC saved data.
+} MrcSave;
+
+typedef struct {
+ // Global variables that will be copied to the HOB follow.
+ UINT8 MrcDataString[4]; ///< Beginning of global data marker, starts with "MRC". Must be the first entry in this structure.
+ UINT32 MrcDataSize; ///< The size of the MRC global data area, in bytes. Must be the second entry in this structure.
+ MrcSave Save; ///< System specific save variables.
+ MrcInput Inputs; ///< System specific input variables.
+ MrcOutput Outputs; ///< System specific output variables.
+
+ // Global variables that will remain internal to the MRC library follow.
+ union {
+ void *Internal; ///< System specific output variables that remain internal to the library.
+ UINT64 Data;
+ } IntOutputs;
+} MrcParameters;
+
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h
new file mode 100644
index 0000000000..9dd9b096ba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h
@@ -0,0 +1,203 @@
+/** @file
+ Copies the memory related timing and configuration information into the
+ Compatible BIOS data (BDAT) table.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcRmtData_h_
+#define _MrcRmtData_h_
+
+#include "MrcTypes.h"
+
+#define VDD_1_350 1350 ///< VDD in millivolts
+#define VDD_1_500 1500 ///< VDD in millivolts
+#define PI_STEP_BASE 2048 ///< Magic number from spec
+#define PI_STEP_INTERVAL 128 ///< tCK is split into this amount of intervals
+#define PI_STEP ((PI_STEP_BASE) / (PI_STEP_INTERVAL))
+#define VREF_STEP_BASE 100 ///< Magic number from spec
+#define TX_VREF_STEP 7800 ///< TX Vref step in microvolts
+#define TX_VREF(VDD) (((TX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD)) ///< VDD passed in is in millivolts
+#define RX_VREF_STEP 8000 ///< TX Vref step in microvolts
+#define RX_VREF(VDD) (((RX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD)) ///< VDD passed in is in millivolts
+#define CA_VREF_STEP 8000 ///< TX Vref step in microvolts
+#define CA_VREF(VDD) (((CA_VREF_STEP) * (VREF_STEP_BASE)) / (VDD)) ///< VDD passed in is in millivolts
+
+#define MAX_SPD_RMT 512 ///< The maximum amount of data, in bytes, in an SPD structure.
+#define RMT_PRIMARY_VERSION 4 ///< The BDAT structure that is currently supported.
+#define RMT_SECONDARY_VERSION 0 ///< The BDAT structure that is currently supported.
+#define MAX_MODE_REGISTER 7 ///< Number of mode registers
+#define MAX_DRAM_DEVICE 9 ///< Maximum number of memory devices
+#define MAX_2D_EYE_TYPE 2 ///< Maximum number of supported Margin 2D Eye Types
+#define MAX_2D_EYE_OFFSETS 7 ///< Number of 2D Eye Offsets
+
+//
+// Warning: Bdat4.h has its own copy of this #define
+// make sure to change it in both places
+//
+#define MAX_SCHEMA_LIST_LENGTH (10)
+
+
+#ifdef BDAT_SUPPORT
+/*
+ BSSA result Memory Schema GUID
+ {8F4E928-0F5F-46D4-8410-479FDA279DB6}
+*/
+extern EFI_GUID gSsaBiosResultsGuid;
+/*
+ RMT Results Metadata GUID
+ {02CB1552-D659-4232-B51F-CAB1E11FCA87}
+*/
+extern EFI_GUID gRmtResultMetadataGuid;
+/*
+ RMT Results Columns GUID
+ {0E60A1EB-331F-42A1-9DE7-453E84761154}
+*/
+extern EFI_GUID gRmtResultColumnsGuid;
+
+/*
+Margin2D Results Metadata GUID
+{48265582-8E49-4AC7-AA06-E1B9A74C9716}
+*/
+extern EFI_GUID gMargin2DResultMetadataGuid;
+/*
+Margin2D Results Columns GUID
+{91A449EC-8A4A-4736-AD71-A3F6F6D752D9}
+*/
+extern EFI_GUID gMargin2DResultColumnsGuid;
+
+#endif
+/*
+ GUID for Schema List HOB
+ This is private GUID used by MemoryInit internally.
+ {3047C2AC-5E8E-4C55-A1CB-EAAD0A88861B}
+*/
+extern EFI_GUID gMrcSchemaListHobGuid;
+
+#pragma pack(push, 1)
+
+
+///
+/// SSA results buffer header.
+///
+typedef struct {
+ UINT32 Revision;
+ BOOLEAN TransferMode;
+ struct {
+ UINT32 Reserved;
+ UINT32 MetadataSize;
+ EFI_GUID MetadataType;
+ } MdBlock;
+ struct {
+ UINT32 Reserved;
+ EFI_GUID ResultType;
+ UINT32 ResultElementSize;
+ INT32 ResultCapacity;
+ INT32 ResultElementCount;
+ } RsBlock;
+} RESULTS_DATA_HDR;
+
+// start auto-generated by the BSSA CCK sourced from the result xml files.
+typedef enum {
+ DisableScrambler = 0,
+ EnableScrambler = 1,
+ DontTouchScrambler = 2,
+ SCRAMBLER_OVERRIDE_MODE_DELIM = MRC_INT32_MAX
+} SCRAMBLER_OVERRIDE_MODE;
+
+typedef struct _RMT_RESULT_METADATA {
+ BOOLEAN EnableCtlAllMargin;
+ UINT16 SinglesBurstLength;
+ UINT32 SinglesLoopCount;
+ UINT16 TurnaroundsBurstLength;
+ UINT32 TurnaroundsLoopCount;
+ SCRAMBLER_OVERRIDE_MODE ScramblerOverrideMode;
+ UINT8 PiStepUnit[2];
+ UINT16 RxVrefStepUnit[2];
+ UINT16 TxVrefStepUnit[2][2];
+ UINT16 CmdVrefStepUnit[2][2];
+ UINT8 MajorVer;
+ UINT8 MinorVer;
+ UINT8 RevVer;
+ UINT32 BuildVer;
+ UINT16 ResultEleCount;
+} RMT_RESULT_METADATA;
+
+
+typedef struct _RMT_RESULT_ROW_HEADER {
+ UINT32 ResultType : 5;
+ UINT32 Socket : 3;
+ UINT32 Controller : 2;
+ UINT32 Channel : 3;
+ UINT32 DimmA : 1;
+ UINT32 RankA : 3;
+ UINT32 DimmB : 1;
+ UINT32 RankB : 3;
+ UINT32 Lane : 8;
+ UINT32 IoLevel : 1;
+ UINT32 Reserved : 2;
+} RMT_RESULT_ROW_HEADER;
+
+typedef struct _RMT_RESULT_COLUMNS {
+ RMT_RESULT_ROW_HEADER Header;
+ UINT8 Margin[4][2];
+} RMT_RESULT_COLUMNS;
+
+// end of auto-generated by the BSSA CCK sourced from the result xml files.
+
+typedef struct _BASE_RMT_RESULT {
+ RESULTS_DATA_HDR ResultsHeader;
+ RMT_RESULT_METADATA Metadata;
+ RMT_RESULT_COLUMNS Rows[1];
+} BASE_RMT_RESULT;
+
+
+typedef struct {
+ UINT32 Data1;
+ UINT16 Data2;
+ UINT16 Data3;
+ UINT8 Data4[8];
+} BDAT_EFI_GUID;
+
+typedef struct {
+ UINT16 HobType;
+ UINT16 HobLength;
+ UINT32 Reserved;
+} BDAT_HOB_GENERIC_HEADER;
+
+typedef struct {
+ BDAT_HOB_GENERIC_HEADER Header;
+ BDAT_EFI_GUID Name;
+ ///
+ /// Guid specific data goes here
+ ///
+} BDAT_HOB_GUID_TYPE;
+
+typedef struct {
+ BDAT_EFI_GUID SchemaId; ///< The GUID uniquely identifies the format of the data contained within the structure.
+ UINT32 DataSize; ///< The total size of the memory block, including both the header as well as the schema specific data.
+ UINT16 Crc16; ///< Crc16 is computed in the same manner as the field in the BDAT_HEADER_STRUCTURE.
+} MRC_BDAT_SCHEMA_HEADER_STRUCTURE;
+
+typedef struct {
+ MRC_BDAT_SCHEMA_HEADER_STRUCTURE SchemaHeader; ///< The schema header.
+ BASE_RMT_RESULT RMT_RESULTS_WITH_META_COLUMNS;
+} BDAT_MEMORY_DATA_STRUCTURE;
+
+typedef struct {
+ BDAT_HOB_GUID_TYPE HobGuidType;
+ BDAT_MEMORY_DATA_STRUCTURE MemorySchema;
+} BDAT_MEMORY_DATA_HOB;
+
+#pragma pack (pop)
+
+typedef struct {
+ BDAT_HOB_GUID_TYPE HobGuidType;
+ UINT16 SchemaHobCount;
+ UINT16 Reserved;
+ BDAT_EFI_GUID SchemaHobGuids[MAX_SCHEMA_LIST_LENGTH];
+} MRC_BDAT_SCHEMA_LIST_HOB;
+
+#endif //_MrcRmtData_h_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h
new file mode 100644
index 0000000000..45de5084c0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h
@@ -0,0 +1,1167 @@
+/** @file
+ SPD data format header file.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcSpdData_h_
+#define _MrcSpdData_h_
+#pragma pack (push, 1)
+
+#include "MrcTypes.h"
+
+#define MAX_XMP_PROFILES (2)
+#define SPD3_MANUF_SIZE (SPD3_MANUF_END - SPD3_MANUF_START + 1) ///< The size of the SPD manufacturing data.
+#define SPD4_MANUF_SIZE (SPD4_MANUF_END - SPD4_MANUF_START + 1) ///< The size of the SPD manufacturing data.
+#define SPDLP_MANUF_SIZE (SPDLP_MANUF_END - SPDLP_MANUF_START + 1) ///< The size of the SPD manufacturing data
+
+typedef union {
+ struct {
+ UINT8 BytesUsed : 4; ///< Bits 3:0
+ UINT8 BytesTotal : 3; ///< Bits 6:4
+ UINT8 CrcCoverage : 1; ///< Bits 7:7
+ } Bits;
+ UINT8 Data;
+} SPD_DEVICE_DESCRIPTION_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 Minor : 4; ///< Bits 3:0
+ UINT8 Major : 4; ///< Bits 7:4
+ } Bits;
+ UINT8 Data;
+} SPD_REVISION_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 Type : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_DRAM_DEVICE_TYPE_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 ModuleType : 4; ///< Bits 3:0
+ UINT8 : 4; ///< Bits 7:4
+ } Bits;
+ UINT8 Data;
+} SPD_MODULE_TYPE_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 Density : 4; ///< Bits 3:0
+ UINT8 BankAddress : 3; ///< Bits 6:4
+ UINT8 : 1; ///< Bits 7:7
+ } Bits;
+ UINT8 Data;
+} SPD_SDRAM_DENSITY_BANKS_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 ColumnAddress : 3; ///< Bits 2:0
+ UINT8 RowAddress : 3; ///< Bits 5:3
+ UINT8 : 2; ///< Bits 7:6
+ } Bits;
+ UINT8 Data;
+} SPD_SDRAM_ADDRESSING_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 OperationAt1_50 : 1; ///< Bits 0:0
+ UINT8 OperationAt1_35 : 1; ///< Bits 1:1
+ UINT8 OperationAt1_25 : 1; ///< Bits 2:2
+ UINT8 : 5; ///< Bits 7:3
+ } Bits;
+ UINT8 Data;
+} SPD_MODULE_NOMINAL_VOLTAGE_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 SdramDeviceWidth : 3; ///< Bits 2:0
+ UINT8 RankCount : 3; ///< Bits 5:3
+ UINT8 : 2; ///< Bits 7:6
+ } Bits;
+ UINT8 Data;
+} SPD_MODULE_ORGANIZATION_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 PrimaryBusWidth : 3; ///< Bits 2:0
+ UINT8 BusWidthExtension : 2; ///< Bits 4:3
+ UINT8 : 3; ///< Bits 7:5
+ } Bits;
+ UINT8 Data;
+} SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 Divisor : 4; ///< Bits 3:0
+ UINT8 Dividend : 4; ///< Bits 7:4
+ } Bits;
+ UINT8 Data;
+} SPD_FINE_TIMEBASE_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 Dividend : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 Divisor : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT;
+
+typedef struct {
+ SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT Dividend; ///< Medium Timebase (MTB) Dividend
+ SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT Divisor; ///< Medium Timebase (MTB) Divisor
+} SPD_MEDIUM_TIMEBASE;
+
+typedef union {
+ struct {
+ UINT8 tCKmin : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TCK_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT16 CL4 : 1; ///< Bits 0:0
+ UINT16 CL5 : 1; ///< Bits 1:1
+ UINT16 CL6 : 1; ///< Bits 2:2
+ UINT16 CL7 : 1; ///< Bits 3:3
+ UINT16 CL8 : 1; ///< Bits 4:4
+ UINT16 CL9 : 1; ///< Bits 5:5
+ UINT16 CL10 : 1; ///< Bits 6:6
+ UINT16 CL11 : 1; ///< Bits 7:7
+ UINT16 CL12 : 1; ///< Bits 8:8
+ UINT16 CL13 : 1; ///< Bits 9:9
+ UINT16 CL14 : 1; ///< Bits 10:10
+ UINT16 CL15 : 1; ///< Bits 11:11
+ UINT16 CL16 : 1; ///< Bits 12:12
+ UINT16 CL17 : 1; ///< Bits 13:13
+ UINT16 CL18 : 1; ///< Bits 14:14
+ UINT16 : 1; ///< Bits 15:15
+ } Bits;
+ UINT16 Data;
+ UINT8 Data8[2];
+} SPD_CAS_LATENCIES_SUPPORTED_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tAAmin : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TAA_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tWRmin : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TWR_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tRCDmin : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TRCD_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tRRDmin : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TRRD_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tRPmin : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TRP_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tRPab : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TRP_AB_MTB_STRUCT;
+
+typedef union {
+ struct {
+ INT8 tRPabFine : 8; ///< Bits 7:0
+ } Bits;
+ INT8 Data;
+} SPD_TRP_AB_FTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tRPpb : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TRP_PB_MTB_STRUCT;
+
+typedef union {
+ struct {
+ INT8 tRPpbFine : 8; ///< Bits 7:0
+ } Bits;
+ INT8 Data;
+} SPD_TRP_PB_FTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT16 tRFCab : 16; ///< Bits 15:0
+ } Bits;
+ UINT16 Data;
+ UINT8 Data8[2];
+} SPD_TRFC_AB_MTB_STRUCT;
+
+typedef union {
+struct {
+ UINT16 tRFCpb : 16; ///< Bits 15:0
+ } Bits;
+ UINT16 Data;
+ UINT8 Data8[2];
+} SPD_TRFC_PB_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tRASminUpper : 4; ///< Bits 3:0
+ UINT8 tRCminUpper : 4; ///< Bits 7:4
+ } Bits;
+ UINT8 Data;
+} SPD_TRAS_TRC_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tRASmin : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TRAS_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tRCmin : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TRC_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT16 tRFCmin : 16; ///< Bits 15:0
+ } Bits;
+ UINT16 Data;
+ UINT8 Data8[2];
+} SPD_TRFC_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tWTRmin : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TWTR_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tRTPmin : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TRTP_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tFAWminUpper : 4; ///< Bits 3:0
+ UINT8 : 4; ///< Bits 7:4
+ } Bits;
+ UINT8 Data;
+} SPD_TFAW_MIN_MTB_UPPER_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tFAWmin : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TFAW_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tCWLmin : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_TCWL_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 NMode : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_SYSTEM_COMMAND_RATE_STRUCT;
+
+typedef union {
+ struct {
+ UINT16 tREFImin : 16; ///< Bits 15:0
+ } Bits;
+ UINT16 Data;
+ UINT8 Data8[2];
+} SPD_TREFI_MIN_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 RZQ6 : 1; ///< Bits 0:0
+ UINT8 RZQ7 : 1; ///< Bits 1:1
+ UINT8 : 5; ///< Bits 6:2
+ UINT8 DllOff : 1; ///< Bits 7:7
+ } Bits;
+ UINT8 Data;
+} SPD_SDRAM_OPTIONAL_FEATURES_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 ExtendedTemperatureRange : 1; ///< Bits 0:0
+ UINT8 ExtendedTemperatureRefreshRate : 1; ///< Bits 1:1
+ UINT8 AutoSelfRefresh : 1; ///< Bits 2:2
+ UINT8 OnDieThermalSensor : 1; ///< Bits 3:3
+ UINT8 : 3; ///< Bits 6:4
+ UINT8 PartialArraySelfRefresh : 1; ///< Bits 7:7
+ } Bits;
+ UINT8 Data;
+} SPD_SDRAM_THERMAL_REFRESH_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 ThermalSensorAccuracy : 7; ///< Bits 6:0
+ UINT8 ThermalSensorPresence : 1; ///< Bits 7:7
+ } Bits;
+ UINT8 Data;
+} SPD_MODULE_THERMAL_SENSOR_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 NonStandardDeviceDescription : 7; ///< Bits 6:0
+ UINT8 SdramDeviceType : 1; ///< Bits 7:7
+ } Bits;
+ UINT8 Data;
+} SPD_SDRAM_DEVICE_TYPE_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_AUTO_SELF_REFRESH_PERF_STRUCT;
+
+typedef union {
+ struct {
+ INT8 tCKminFine : 8; ///< Bits 7:0
+ } Bits;
+ INT8 Data;
+} SPD_TCK_MIN_FTB_STRUCT;
+
+typedef union {
+ struct {
+ INT8 tAAminFine : 8; ///< Bits 7:0
+ } Bits;
+ INT8 Data;
+} SPD_TAA_MIN_FTB_STRUCT;
+
+typedef union {
+ struct {
+ INT8 tRCDminFine : 8; ///< Bits 7:0
+ } Bits;
+ INT8 Data;
+} SPD_TRCD_MIN_FTB_STRUCT;
+
+typedef union {
+ struct {
+ INT8 tRPminFine : 8; ///< Bits 7:0
+ } Bits;
+ INT8 Data;
+} SPD_TRP_MIN_FTB_STRUCT;
+
+typedef union {
+ struct {
+ INT8 tRCminFine : 8; ///< Bits 7:0
+ } Bits;
+ INT8 Data;
+} SPD_TRC_MIN_FTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tMACencoding : 4; ///< Bits 3:0
+ UINT8 tMAWencoding : 2; ///< Bits 5:4
+ UINT8 Reserved : 2; ///< Bits 7:6
+ } Bits;
+ UINT8 Data;
+} SPD_PTRR_SUPPORT_STRUCT;
+
+typedef union {
+ struct {
+ INT8 tRRDminFine : 8; ///< Bits 7:0
+ } Bits;
+ INT8 Data;
+} SPD_TRRD_MIN_FTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 Height : 5; ///< Bits 4:0
+ UINT8 RawCardExtension : 3; ///< Bits 7:5
+ } Bits;
+ UINT8 Data;
+} SPD_UNBUF_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+ struct {
+ UINT8 FrontThickness : 4; ///< Bits 3:0
+ UINT8 BackThickness : 4; ///< Bits 7:4
+ } Bits;
+ UINT8 Data;
+} SPD_UNBUF_MODULE_NOMINAL_THICKNESS;
+
+typedef union {
+ struct {
+ UINT8 Card : 5; ///< Bits 4:0
+ UINT8 Revision : 2; ///< Bits 6:5
+ UINT8 Extension : 1; ///< Bits 7:7
+ } Bits;
+ UINT8 Data;
+} SPD_UNBUF_REFERENCE_RAW_CARD;
+
+typedef union {
+ struct {
+ UINT8 MappingRank1 : 1; ///< Bits 0:0
+ UINT8 : 7; ///< Bits 7:1
+ } Bits;
+ UINT8 Data;
+} SPD_UNBUF_ADDRESS_MAPPING;
+
+typedef union {
+ struct {
+ UINT8 Height : 5; ///< Bits 4:0
+ UINT8 : 3; ///< Bits 7:5
+ } Bits;
+ UINT8 Data;
+} SPD_RDIMM_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+ struct {
+ UINT8 FrontThickness : 4; ///< Bits 3:0
+ UINT8 BackThickness : 4; ///< Bits 7:4
+ } Bits;
+ UINT8 Data;
+} SPD_RDIMM_MODULE_NOMINAL_THICKNESS;
+
+typedef union {
+ struct {
+ UINT8 Card : 5; ///< Bits 4:0
+ UINT8 Revision : 2; ///< Bits 6:5
+ UINT8 Extension : 1; ///< Bits 7:7
+ } Bits;
+ UINT8 Data;
+} SPD_RDIMM_REFERENCE_RAW_CARD;
+
+typedef union {
+ struct {
+ UINT8 RegisterCount : 2; ///< Bits 1:0
+ UINT8 DramRowCount : 2; ///< Bits 3:2
+ UINT8 : 4; ///< Bits 7:4
+ } Bits;
+ UINT8 Data;
+} SPD_RDIMM_MODULE_ATTRIBUTES;
+
+typedef union {
+ struct {
+ UINT16 ContinuationCount : 7; ///< Bits 6:0
+ UINT16 ContinuationParity : 1; ///< Bits 7:7
+ UINT16 LastNonZeroByte : 8; ///< Bits 15:8
+ } Bits;
+ UINT16 Data;
+ UINT8 Data8[2];
+} SPD_MANUFACTURER_ID_CODE;
+
+typedef struct {
+ UINT8 Year; ///< Year represented in BCD (00h = 2000)
+ UINT8 Week; ///< Year represented in BCD (47h = week 47)
+} SPD_MANUFACTURING_DATE;
+
+typedef union {
+ UINT32 Data;
+ UINT16 SerialNumber16[2];
+ UINT8 SerialNumber8[4];
+} SPD_MANUFACTURER_SERIAL_NUMBER;
+
+typedef struct {
+ UINT8 Location; ///< Module Manufacturing Location
+} SPD_MANUFACTURING_LOCATION;
+
+typedef struct {
+ SPD_MANUFACTURER_ID_CODE IdCode; ///< Module Manufacturer ID Code
+ SPD_MANUFACTURING_LOCATION Location; ///< Module Manufacturing Location
+ SPD_MANUFACTURING_DATE Date; ///< Module Manufacturing Year, in BCD (range: 2000-2255)
+ SPD_MANUFACTURER_SERIAL_NUMBER SerialNumber; ///< Module Serial Number
+} SPD_UNIQUE_MODULE_ID;
+
+typedef union {
+ UINT16 Crc[1];
+ UINT8 Data8[2];
+} SPD_CYCLIC_REDUNDANCY_CODE;
+
+typedef union {
+ struct {
+ UINT8 ProfileEnable1 : 1; ///< Bits 0:0
+ UINT8 ProfileEnable2 : 1; ///< Bits 1:1
+ UINT8 ProfileConfig1 : 2; ///< Bits 3:2
+ UINT8 ProfileConfig2 : 2; ///< Bits 5:4
+ UINT8 : 2; ///< Bits 7:6
+ } Bits;
+ UINT8 Data;
+} SPD_XMP_ORG_CONFIG;
+
+typedef struct {
+ UINT16 XmpId; ///< 176-177 XMP Identification String
+ SPD_XMP_ORG_CONFIG XmpOrgConf; ///< 178 XMP Organization & Configuration
+ SPD_REVISION_STRUCT XmpRevision; ///< 179 XMP Revision
+ SPD_MEDIUM_TIMEBASE MediumTimeBase[MAX_XMP_PROFILES]; ///< 180-183 Medium Timebase (MTB)
+ SPD_FINE_TIMEBASE_STRUCT FineTimeBase; ///< 184 Fine Timebase (FTB) Dividend / Divisor
+} SPD_EXTREME_MEMORY_PROFILE_HEADER;
+
+typedef union {
+ struct {
+ UINT8 Decimal : 5;
+ UINT8 Integer : 2;
+ UINT8 : 1;
+ } Bits;
+ UINT8 Data;
+} SPD_VDD_VOLTAGE_LEVEL_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 Decimal : 7;
+ UINT8 Integer : 1;
+ } Bits;
+ UINT8 Data;
+} SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0;
+
+typedef union {
+ struct {
+ UINT8 Fine : 2; ///< Bits 1:0
+ UINT8 Medium : 2; ///< Bits 3:2
+ UINT8 : 4; ///< Bits 7:4
+ } Bits;
+ UINT8 Data;
+} SPD4_TIMEBASE_STRUCT;
+
+typedef union {
+ struct {
+ UINT32 CL7 : 1; ///< Bits 0:0
+ UINT32 CL8 : 1; ///< Bits 1:1
+ UINT32 CL9 : 1; ///< Bits 2:2
+ UINT32 CL10 : 1; ///< Bits 3:3
+ UINT32 CL11 : 1; ///< Bits 4:4
+ UINT32 CL12 : 1; ///< Bits 5:5
+ UINT32 CL13 : 1; ///< Bits 6:6
+ UINT32 CL14 : 1; ///< Bits 7:7
+ UINT32 CL15 : 1; ///< Bits 8:8
+ UINT32 CL16 : 1; ///< Bits 9:9
+ UINT32 CL17 : 1; ///< Bits 10:10
+ UINT32 CL18 : 1; ///< Bits 11:11
+ UINT32 CL19 : 1; ///< Bits 12:12
+ UINT32 CL20 : 1; ///< Bits 13:13
+ UINT32 CL21 : 1; ///< Bits 14:14
+ UINT32 CL22 : 1; ///< Bits 15:15
+ UINT32 CL23 : 1; ///< Bits 16:16
+ UINT32 CL24 : 1; ///< Bits 17:17
+ UINT32 : 14; ///< Bits 31:18
+ } Bits;
+ UINT32 Data;
+ UINT16 Data16[2];
+ UINT8 Data8[4];
+} SPD4_CAS_LATENCIES_SUPPORTED_STRUCT;
+
+typedef struct {
+ SPD_VDD_VOLTAGE_LEVEL_STRUCT Vdd; ///< 185, 220 XMP Module VDD Voltage Level
+ SPD_TCK_MIN_MTB_STRUCT tCKmin; ///< 186, 221 XMP SDRAM Minimum Cycle Time (tCKmin)
+ SPD_TAA_MIN_MTB_STRUCT tAAmin; ///< 187, 222 XMP Minimum CAS Latency Time (tAAmin)
+ SPD_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies; ///< 188-189, 223-224 XMP CAS Latencies Supported, Least Significant Byte
+ SPD_TCWL_MIN_MTB_STRUCT tCWLmin; ///< 190, 225 XMP Minimum CAS Write Latency Time (tCWLmin)
+ SPD_TRP_MIN_MTB_STRUCT tRPmin; ///< 191, 226 XMP Minimum Row Precharge Delay Time (tRPmin)
+ SPD_TRCD_MIN_MTB_STRUCT tRCDmin; ///< 192, 227 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
+ SPD_TWR_MIN_MTB_STRUCT tWRmin; ///< 193, 228 XMP Minimum Write Recovery Time (tWRmin)
+ SPD_TRAS_TRC_MIN_MTB_STRUCT tRASMintRCMinUpper; ///< 194, 229 XMP Upper Nibbles for tRAS and tRC
+ SPD_TRAS_MIN_MTB_STRUCT tRASmin; ///< 195, 230 XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+ SPD_TRC_MIN_MTB_STRUCT tRCmin; ///< 196, 231 XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+ SPD_TREFI_MIN_MTB_STRUCT tREFImin; ///< 197-198, 232-233 XMP Maximum tREFI Time (Average Periodic Refresh Interval), Least Significant Byte
+ SPD_TRFC_MIN_MTB_STRUCT tRFCmin; ///< 199-200, 234-235 XMP Minimum Refresh Recovery Delay Time (tRFCmin), Least Significant Byte
+ SPD_TRTP_MIN_MTB_STRUCT tRTPmin; ///< 201, 236 XMP Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
+ SPD_TRRD_MIN_MTB_STRUCT tRRDmin; ///< 202, 237 XMP Minimum Row Active to Row Active Delay Time (tRRDmin)
+ SPD_TFAW_MIN_MTB_UPPER_STRUCT tFAWMinUpper; ///< 203, 238 XMP Upper Nibble for tFAW
+ SPD_TFAW_MIN_MTB_STRUCT tFAWmin; ///< 204, 239 XMP Minimum Four Activate Window Delay Time (tFAWmin)
+ SPD_TWTR_MIN_MTB_STRUCT tWTRmin; ///< 205, 240 XMP Minimum Internal Write to Read Command Delay Time (tWTRmin)
+ UINT8 Reserved1[207 - 206 + 1]; ///< 206-207, 241-242 XMP Reserved
+ SPD_SYSTEM_COMMAND_RATE_STRUCT SystemCmdRate; ///< 208, 243 XMP System ADD/CMD Rate (1N or 2N mode)
+ SPD_AUTO_SELF_REFRESH_PERF_STRUCT AsrPerf; ///< 209, 244 XMP SDRAM Auto Self Refresh Performance (Sub 1x Refresh and IDD6 impact)
+ UINT8 VoltageLevel; ///< 210, 245 XMP Memory Controller Voltage Level
+ SPD_TCK_MIN_FTB_STRUCT tCKminFine; ///< 211, 246 XMP Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+ SPD_TAA_MIN_FTB_STRUCT tAAminFine; ///< 212, 247 XMP Fine Offset for Minimum CAS Latency Time (tAAmin)
+ SPD_TRP_MIN_FTB_STRUCT tRPminFine; ///< 213, 248 XMP Minimum Row Precharge Delay Time (tRPmin)
+ SPD_TRCD_MIN_FTB_STRUCT tRCDminFine; ///< 214, 249 XMP Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+ SPD_TRC_MIN_FTB_STRUCT tRCminFine; ///< 215, 250 XMP Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+ UINT8 Reserved2[218 - 216 + 1]; ///< 216-218, 251-253 XMP Reserved
+ UINT8 VendorPersonality; ///< 219, 254 XMP Vendor Personality
+} SPD_EXTREME_MEMORY_PROFILE_DATA;
+
+typedef struct {
+ SPD_EXTREME_MEMORY_PROFILE_HEADER Header; ///< 176-184 XMP header
+ SPD_EXTREME_MEMORY_PROFILE_DATA Data[MAX_XMP_PROFILES]; ///< 185-254 XMP profiles
+} SPD_EXTREME_MEMORY_PROFILE;
+
+typedef struct {
+ UINT16 XmpId; ///< 384-385 XMP Identification String
+ SPD_XMP_ORG_CONFIG XmpOrgConf; ///< 386 XMP Organization & Configuration
+ SPD_REVISION_STRUCT XmpRevision; ///< 387 XMP Revision
+ SPD4_TIMEBASE_STRUCT TimeBase[MAX_XMP_PROFILES]; ///< 388-389 Medium and Fine Timebase
+ UINT8 Reserved[392 - 390 + 1]; ///< 390-392 Reserved
+} SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0;
+
+typedef struct {
+ SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0 Vdd; ///< 393, 440 XMP Module VDD Voltage Level
+ UINT8 Reserved1[395 - 394 + 1]; ///< 394-395, 441-442 XMP Reserved
+ SPD_TCK_MIN_MTB_STRUCT tCKAVGmin; ///< 396, 443 XMP SDRAM Minimum Cycle Time (tCKAVGmin)
+ SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies; ///< 397-400, 444-447 XMP CAS Latencies Supported
+ SPD_TAA_MIN_MTB_STRUCT tAAmin; ///< 401, 448 XMP Minimum CAS Latency Time (tAAmin)
+ SPD_TRCD_MIN_MTB_STRUCT tRCDmin; ///< 402, 449 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
+ SPD_TRP_MIN_MTB_STRUCT tRPmin; ///< 403, 450 XMP Minimum Row Precharge Delay Time (tRPmin)
+ SPD_TRAS_TRC_MIN_MTB_STRUCT tRASMintRCMinUpper; ///< 404, 451 XMP Upper Nibbles for tRAS and tRC
+ SPD_TRAS_MIN_MTB_STRUCT tRASmin; ///< 405, 452 XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+ SPD_TRC_MIN_MTB_STRUCT tRCmin; ///< 406, 453 XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+ SPD_TRFC_MIN_MTB_STRUCT tRFC1min; ///< 407-408, 454-455 XMP Minimum Refresh Recovery Delay Time (tRFC1min)
+ SPD_TRFC_MIN_MTB_STRUCT tRFC2min; ///< 409-410, 456-457 XMP Minimum Refresh Recovery Delay Time (tRFC2min)
+ SPD_TRFC_MIN_MTB_STRUCT tRFC4min; ///< 411-412, 458-459 XMP Minimum Refresh Recovery Delay Time (tRFC4min)
+ SPD_TFAW_MIN_MTB_UPPER_STRUCT tFAWMinUpper; ///< 413, 460 Upper Nibble for tFAW
+ SPD_TFAW_MIN_MTB_STRUCT tFAWmin; ///< 414, 461 Minimum Four Activate Window Delay Time (tFAWmin)
+ SPD_TRRD_MIN_MTB_STRUCT tRRD_Smin; ///< 415, 462 Minimum Activate to Activate Delay Time (tRRD_Smin), different bank group
+ SPD_TRRD_MIN_MTB_STRUCT tRRD_Lmin; ///< 416, 463 Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
+ UINT8 Reserved2[424 - 417 + 1]; ///< 417-424, 464-471 XMP Reserved
+ SPD_TRRD_MIN_FTB_STRUCT tRRD_LminFine; ///< 425, 472 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin), different bank group
+ SPD_TRRD_MIN_FTB_STRUCT tRRD_SminFine; ///< 426, 473 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin), same bank group
+ SPD_TRC_MIN_FTB_STRUCT tRCminFine; ///< 427, 474 Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+ SPD_TRP_MIN_FTB_STRUCT tRPminFine; ///< 428, 475 Minimum Row Precharge Delay Time (tRPmin)
+ SPD_TRCD_MIN_FTB_STRUCT tRCDminFine; ///< 429, 476 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+ SPD_TAA_MIN_FTB_STRUCT tAAminFine; ///< 430, 477 Fine Offset for Minimum CAS Latency Time (tAAmin)
+ SPD_TCK_MIN_FTB_STRUCT tCKAVGminFine; ///< 431, 478 Fine Offset for SDRAM Maximum Cycle Time (tCKAVGmin)
+ UINT8 Reserved3[439 - 432 + 1]; ///< 432-439, 479-486 XMP Reserved
+} SPD_EXTREME_MEMORY_PROFILE_DATA_2_0;
+
+typedef struct {
+ SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0 Header; ///< 384-392 XMP header
+ SPD_EXTREME_MEMORY_PROFILE_DATA_2_0 Data[MAX_XMP_PROFILES]; ///< 393-486 XMP profiles
+} SPD_EXTREME_MEMORY_PROFILE_2_0;
+
+typedef struct {
+ SPD_DEVICE_DESCRIPTION_STRUCT Description; ///< 0 Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+ SPD_REVISION_STRUCT Revision; ///< 1 SPD Revision
+ SPD_DRAM_DEVICE_TYPE_STRUCT DramDeviceType; ///< 2 DRAM Device Type
+ SPD_MODULE_TYPE_STRUCT ModuleType; ///< 3 Module Type
+ SPD_SDRAM_DENSITY_BANKS_STRUCT SdramDensityAndBanks; ///< 4 SDRAM Density and Banks
+ SPD_SDRAM_ADDRESSING_STRUCT SdramAddressing; ///< 5 SDRAM Addressing
+ SPD_MODULE_NOMINAL_VOLTAGE_STRUCT ModuleNominalVoltage; ///< 6 Module Nominal Voltage, VDD
+ SPD_MODULE_ORGANIZATION_STRUCT ModuleOrganization; ///< 7 Module Organization
+ SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT ModuleMemoryBusWidth; ///< 8 Module Memory Bus Width
+ SPD_FINE_TIMEBASE_STRUCT FineTimebase; ///< 9 Fine Timebase (FTB) Dividend / Divisor
+ SPD_MEDIUM_TIMEBASE MediumTimebase; ///< 10-11 Medium Timebase (MTB) Dividend
+ SPD_TCK_MIN_MTB_STRUCT tCKmin; ///< 12 SDRAM Minimum Cycle Time (tCKmin)
+ UINT8 Reserved1; ///< 13 Reserved
+ SPD_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies; ///< 14-15 CAS Latencies Supported
+ SPD_TAA_MIN_MTB_STRUCT tAAmin; ///< 16 Minimum CAS Latency Time (tAAmin)
+ SPD_TWR_MIN_MTB_STRUCT tWRmin; ///< 17 Minimum Write Recovery Time (tWRmin)
+ SPD_TRCD_MIN_MTB_STRUCT tRCDmin; ///< 18 Minimum RAS# to CAS# Delay Time (tRCDmin)
+ SPD_TRRD_MIN_MTB_STRUCT tRRDmin; ///< 19 Minimum Row Active to Row Active Delay Time (tRRDmin)
+ SPD_TRP_MIN_MTB_STRUCT tRPmin; ///< 20 Minimum Row Precharge Delay Time (tRPmin)
+ SPD_TRAS_TRC_MIN_MTB_STRUCT tRASMintRCMinUpper; ///< 21 Upper Nibbles for tRAS and tRC
+ SPD_TRAS_MIN_MTB_STRUCT tRASmin; ///< 22 Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+ SPD_TRC_MIN_MTB_STRUCT tRCmin; ///< 23 Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+ SPD_TRFC_MIN_MTB_STRUCT tRFCmin; ///< 24-25 Minimum Refresh Recovery Delay Time (tRFCmin)
+ SPD_TWTR_MIN_MTB_STRUCT tWTRmin; ///< 26 Minimum Internal Write to Read Command Delay Time (tWTRmin)
+ SPD_TRTP_MIN_MTB_STRUCT tRTPmin; ///< 27 Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
+ SPD_TFAW_MIN_MTB_UPPER_STRUCT tFAWMinUpper; ///< 28 Upper Nibble for tFAW
+ SPD_TFAW_MIN_MTB_STRUCT tFAWmin; ///< 29 Minimum Four Activate Window Delay Time (tFAWmin)
+ SPD_SDRAM_OPTIONAL_FEATURES_STRUCT SdramOptionalFeatures; ///< 30 SDRAM Optional Features
+ SPD_SDRAM_THERMAL_REFRESH_STRUCT ThermalAndRefreshOptions; ///< 31 SDRAMThermalAndRefreshOptions
+ SPD_MODULE_THERMAL_SENSOR_STRUCT ModuleThermalSensor; ///< 32 Module Thermal Sensor
+ SPD_SDRAM_DEVICE_TYPE_STRUCT SdramDeviceType; ///< 33 SDRAM Device Type
+ SPD_TCK_MIN_FTB_STRUCT tCKminFine; ///< 34 Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+ SPD_TAA_MIN_FTB_STRUCT tAAminFine; ///< 35 Fine Offset for Minimum CAS Latency Time (tAAmin)
+ SPD_TRCD_MIN_FTB_STRUCT tRCDminFine; ///< 36 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+ SPD_TRP_MIN_FTB_STRUCT tRPminFine; ///< 37 Minimum Row Precharge Delay Time (tRPmin)
+ SPD_TRC_MIN_FTB_STRUCT tRCminFine; ///< 38 Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+ SPD_TRP_AB_MTB_STRUCT tRPab; ///< 39 Minimum Row Precharge Delay Time for all banks (tRPab)
+ SPD_TRP_AB_FTB_STRUCT tRPabFine; ///< 40 Fine Offset for Minimum Row Precharge Delay Time for all banks (tRPab)
+ SPD_PTRR_SUPPORT_STRUCT pTRRsupport; ///< 41 - pTRR support with TMAC value
+ UINT8 Reserved3[59 - 42 + 1]; ///< 42 - 59 Reserved
+} SPD_GENERAL_SECTION;
+
+typedef struct {
+ SPD_UNBUF_MODULE_NOMINAL_HEIGHT ModuleNominalHeight; ///< 60 Module Nominal Height
+ SPD_UNBUF_MODULE_NOMINAL_THICKNESS ModuleMaximumThickness; ///< 61 Module Maximum Thickness
+ SPD_UNBUF_REFERENCE_RAW_CARD ReferenceRawCardUsed; ///< 62 Reference Raw Card Used
+ SPD_UNBUF_ADDRESS_MAPPING AddressMappingEdgeConn; ///< 63 Address Mapping from Edge Connector to DRAM
+ UINT8 Reserved[116 - 64 + 1]; ///< 64-116 Reserved
+} SPD_MODULE_UNBUFFERED;
+
+typedef struct {
+ SPD_RDIMM_MODULE_NOMINAL_HEIGHT ModuleNominalHeight; ///< 60 Module Nominal Height
+ SPD_RDIMM_MODULE_NOMINAL_THICKNESS ModuleMaximumThickness; ///< 61 Module Maximum Thickness
+ SPD_RDIMM_REFERENCE_RAW_CARD ReferenceRawCardUsed; ///< 62 Reference Raw Card Used
+ SPD_RDIMM_MODULE_ATTRIBUTES DimmModuleAttributes; ///< 63 DIMM Module Attributes
+ UINT8 Reserved[116 - 64 + 1]; ///< 64-116 Reserved
+} SPD_MODULE_REGISTERED;
+
+typedef union {
+ SPD_MODULE_UNBUFFERED Unbuffered;
+ SPD_MODULE_REGISTERED Registered;
+} SPD_MODULE_SPECIFIC;
+
+typedef struct {
+ UINT8 ModulePartNumber[145 - 128 + 1]; ///< 128-145 Module Part Number
+} SPD_MODULE_PART_NUMBER;
+
+typedef struct {
+ UINT8 ModuleRevisionCode[147 - 146 + 1]; ///< 146-147 Module Revision Code
+} SPD_MODULE_REVISION_CODE;
+
+typedef struct {
+ UINT8 ManufactureSpecificData[175 - 150 + 1]; ///< 150-175 Manufacturer's Specific Data
+} SPD_MANUFACTURE_SPECIFIC;
+
+///
+/// DDR3 Serial Presence Detect structure
+///
+typedef struct {
+ SPD_GENERAL_SECTION General; ///< 0-59 General Section
+ SPD_MODULE_SPECIFIC Module; ///< 60-116 Module-Specific Section
+ SPD_UNIQUE_MODULE_ID ModuleId; ///< 117-125 Unique Module ID
+ SPD_CYCLIC_REDUNDANCY_CODE Crc; ///< 126-127 Cyclical Redundancy Code (CRC)
+ SPD_MODULE_PART_NUMBER ModulePartNumber; ///< 128-145 Module Part Number
+ SPD_MODULE_REVISION_CODE ModuleRevisionCode; ///< 146-147 Module Revision Code
+ SPD_MANUFACTURER_ID_CODE DramIdCode; ///< 148-149 Dram Manufacturer ID Code
+ SPD_MANUFACTURE_SPECIFIC ManufactureSpecificData; ///< 150-175 Manufacturer's Specific Data
+ SPD_EXTREME_MEMORY_PROFILE Xmp; ///< 176-254 Intel(r) Extreme Memory Profile support
+ UINT8 Reserved; ///< 255 Reserved
+} MrcSpdDdr3;
+
+typedef union {
+ struct {
+ UINT8 Density : 4; ///< Bits 3:0
+ UINT8 BankAddress : 2; ///< Bits 5:4
+ UINT8 BankGroup : 2; ///< Bits 7:6
+ } Bits;
+ UINT8 Data;
+} SPD4_SDRAM_DENSITY_BANKS_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 SignalLoading : 2; ///< Bits 1:0
+ UINT8 : 2; ///< Bits 3:2
+ UINT8 DieCount : 3; ///< Bits 6:4
+ UINT8 SdramDeviceType : 1; ///< Bits 7:7
+ } Bits;
+ UINT8 Data;
+} SPD4_SDRAM_DEVICE_TYPE_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 OperationAt1_20 : 1; ///< Bits 0:0
+ UINT8 EndurantAt1_20 : 1; ///< Bits 1:1
+ UINT8 : 6; ///< Bits 7:2
+ } Bits;
+ UINT8 Data;
+} SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tCKmax : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD4_TCK_MAX_MTB_STRUCT;
+
+typedef union {
+ struct {
+ INT8 tCKmaxFine : 8; ///< Bits 7:0
+ } Bits;
+ INT8 Data;
+} SPD4_TCK_MAX_FTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD4_SDRAM_THERMAL_REFRESH_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 Height : 5; ///< Bits 4:0
+ UINT8 RawCardExtension : 3; ///< Bits 7:5
+ } Bits;
+ UINT8 Data;
+} SPD4_UNBUF_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+ struct {
+ UINT8 Height : 5; ///< Bits 4:0
+ UINT8 RawCardExtension : 3; ///< Bits 7:5
+ } Bits;
+ UINT8 Data;
+} SPD4_RDIMM_MODULE_NOMINAL_HEIGHT;
+
+typedef struct {
+ SPD_DEVICE_DESCRIPTION_STRUCT Description; ///< 0 Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+ SPD_REVISION_STRUCT Revision; ///< 1 SPD Revision
+ SPD_DRAM_DEVICE_TYPE_STRUCT DramDeviceType; ///< 2 DRAM Device Type
+ SPD_MODULE_TYPE_STRUCT ModuleType; ///< 3 Module Type
+ SPD4_SDRAM_DENSITY_BANKS_STRUCT SdramDensityAndBanks; ///< 4 SDRAM Density and Banks
+ SPD_SDRAM_ADDRESSING_STRUCT SdramAddressing; ///< 5 SDRAM Addressing
+ SPD4_SDRAM_DEVICE_TYPE_STRUCT SdramDeviceType; ///< 6 SDRAM Device Type
+ SPD_PTRR_SUPPORT_STRUCT pTRRsupport; ///< 7 pTRR support with TMAC value
+ SPD4_SDRAM_THERMAL_REFRESH_STRUCT ThermalAndRefreshOptions; ///< 8 SDRAM Thermal and Refresh Options
+ UINT8 Reserved0[10 - 9 + 1]; ///< 9-10 Reserved
+ SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT ModuleNominalVoltage; ///< 11 Module Nominal Voltage, VDD
+ SPD_MODULE_ORGANIZATION_STRUCT ModuleOrganization; ///< 12 Module Organization
+ SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT ModuleMemoryBusWidth; ///< 13 Module Memory Bus Width
+ SPD_MODULE_THERMAL_SENSOR_STRUCT ModuleThermalSensor; ///< 14 Module Thermal Sensor
+ UINT8 Reserved1[16 - 15 + 1]; ///< 15-16 Reserved
+ SPD4_TIMEBASE_STRUCT Timebase; ///< 17 Timebases
+ SPD_TCK_MIN_MTB_STRUCT tCKmin; ///< 18 SDRAM Minimum Cycle Time (tCKmin)
+ SPD4_TCK_MAX_MTB_STRUCT tCKmax; ///< 19 SDRAM Maximum Cycle Time (tCKmax)
+ SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies; ///< 20-23 CAS Latencies Supported
+ SPD_TAA_MIN_MTB_STRUCT tAAmin; ///< 24 Minimum CAS Latency Time (tAAmin)
+ SPD_TRCD_MIN_MTB_STRUCT tRCDmin; ///< 25 Minimum RAS# to CAS# Delay Time (tRCDmin)
+ SPD_TRP_MIN_MTB_STRUCT tRPmin; ///< 26 Minimum Row Precharge Delay Time (tRPmin)
+ SPD_TRAS_TRC_MIN_MTB_STRUCT tRASMintRCMinUpper; ///< 27 Upper Nibbles for tRAS and tRC
+ SPD_TRAS_MIN_MTB_STRUCT tRASmin; ///< 28 Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+ SPD_TRC_MIN_MTB_STRUCT tRCmin; ///< 29 Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+ SPD_TRFC_MIN_MTB_STRUCT tRFC1min; ///< 30-31 Minimum Refresh Recovery Delay Time (tRFC1min)
+ SPD_TRFC_MIN_MTB_STRUCT tRFC2min; ///< 32-33 Minimum Refresh Recovery Delay Time (tRFC2min)
+ SPD_TRFC_MIN_MTB_STRUCT tRFC4min; ///< 34-35 Minimum Refresh Recovery Delay Time (tRFC4min)
+ SPD_TFAW_MIN_MTB_UPPER_STRUCT tFAWMinUpper; ///< 36 Upper Nibble for tFAW
+ SPD_TFAW_MIN_MTB_STRUCT tFAWmin; ///< 37 Minimum Four Activate Window Delay Time (tFAWmin)
+ SPD_TRRD_MIN_MTB_STRUCT tRRD_Smin; ///< 38 Minimum Activate to Activate Delay Time (tRRD_Smin), different bank group
+ SPD_TRRD_MIN_MTB_STRUCT tRRD_Lmin; ///< 39 Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
+ UINT8 Reserved2[117 - 40 + 1]; ///< 40-117 Reserved
+ SPD_TRRD_MIN_FTB_STRUCT tRRD_LminFine; ///< 118 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin), different bank group
+ SPD_TRRD_MIN_FTB_STRUCT tRRD_SminFine; ///< 119 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin), same bank group
+ SPD_TRC_MIN_FTB_STRUCT tRCminFine; ///< 120 Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+ SPD_TRP_MIN_FTB_STRUCT tRPminFine; ///< 121 Minimum Row Precharge Delay Time (tRPmin)
+ SPD_TRCD_MIN_FTB_STRUCT tRCDminFine; ///< 122 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+ SPD_TAA_MIN_FTB_STRUCT tAAminFine; ///< 123 Fine Offset for Minimum CAS Latency Time (tAAmin)
+ SPD4_TCK_MAX_FTB_STRUCT tCKmaxFine; ///< 124 Fine Offset for SDRAM Minimum Cycle Time (tCKmax)
+ SPD_TCK_MIN_FTB_STRUCT tCKminFine; ///< 125 Fine Offset for SDRAM Maximum Cycle Time (tCKmin)
+ SPD_CYCLIC_REDUNDANCY_CODE Crc; ///< 126-127 Cyclical Redundancy Code (CRC)
+} SPD4_BASE_SECTION;
+
+typedef struct {
+ SPD4_UNBUF_MODULE_NOMINAL_HEIGHT ModuleNominalHeight; ///< 128 Module Nominal Height
+ SPD_UNBUF_MODULE_NOMINAL_THICKNESS ModuleMaximumThickness; ///< 129 Module Maximum Thickness
+ SPD_UNBUF_REFERENCE_RAW_CARD ReferenceRawCardUsed; ///< 130 Reference Raw Card Used
+ SPD_UNBUF_ADDRESS_MAPPING AddressMappingEdgeConn; ///< 131 Address Mapping from Edge Connector to DRAM
+ UINT8 Reserved[253 - 132 + 1]; ///< 132-253 Reserved
+ SPD_CYCLIC_REDUNDANCY_CODE Crc; ///< 254-255 Cyclical Redundancy Code (CRC)
+} SPD4_MODULE_UNBUFFERED;
+
+typedef struct {
+ SPD4_RDIMM_MODULE_NOMINAL_HEIGHT ModuleNominalHeight; ///< 128 Module Nominal Height
+ SPD_RDIMM_MODULE_NOMINAL_THICKNESS ModuleMaximumThickness; ///< 129 Module Maximum Thickness
+ SPD_RDIMM_REFERENCE_RAW_CARD ReferenceRawCardUsed; ///< 130 Reference Raw Card Used
+ SPD_RDIMM_MODULE_ATTRIBUTES DimmModuleAttributes; ///< 131 DIMM Module Attributes
+ UINT8 Reserved[253 - 132 + 1]; ///< 253-132 Reserved
+ SPD_CYCLIC_REDUNDANCY_CODE Crc; ///< 254-255 Cyclical Redundancy Code (CRC)
+} SPD4_MODULE_REGISTERED;
+
+typedef union {
+ SPD4_MODULE_UNBUFFERED Unbuffered; ///< 128-255 Unbuffered Memory Module Types
+ SPD4_MODULE_REGISTERED Registered; ///< 128-255 Registered Memory Module Types
+} SPD4_MODULE_SPECIFIC;
+
+typedef struct {
+ UINT8 ModulePartNumber[348 - 329 + 1]; ///< 329-348 Module Part Number
+} SPD4_MODULE_PART_NUMBER;
+
+typedef struct {
+ UINT8 ManufactureSpecificData[381 - 353 + 1]; ///< 353-381 Manufacturer's Specific Data
+} SPD4_MANUFACTURE_SPECIFIC;
+
+typedef UINT8 SPD4_MODULE_REVISION_CODE;///< 349 Module Revision Code
+typedef UINT8 SPD4_DRAM_STEPPING; ///< 352 Dram Stepping
+
+typedef struct {
+ SPD_UNIQUE_MODULE_ID ModuleId; ///< 320-328 Unique Module ID
+ SPD4_MODULE_PART_NUMBER ModulePartNumber; ///< 329-348 Module Part Number
+ SPD4_MODULE_REVISION_CODE ModuleRevisionCode; ///< 349 Module Revision Code
+ SPD_MANUFACTURER_ID_CODE DramIdCode; ///< 350-351 Dram Manufacturer ID Code
+ SPD4_DRAM_STEPPING DramStepping; ///< 352 Dram Stepping
+ SPD4_MANUFACTURE_SPECIFIC ManufactureSpecificData; ///< 353-381 Manufacturer's Specific Data
+ SPD_CYCLIC_REDUNDANCY_CODE Crc; ///< 382-383 Cyclical Redundancy Code (CRC)
+} SPD4_MANUFACTURING_DATA;
+
+typedef union {
+ SPD_EXTREME_MEMORY_PROFILE_2_0 Xmp; ///< 384-463 Intel(r) Extreme Memory Profile support
+ UINT8 Reserved0[511 - 384 + 1]; ///< 384-511 Unbuffered Memory Module Types
+} SPD4_END_USER_SECTION;
+
+///
+/// DDR4 Serial Presence Detect structure
+///
+typedef struct {
+ SPD4_BASE_SECTION Base; ///< 0-127 Base Configuration and DRAM Parameters
+ SPD4_MODULE_SPECIFIC Module; ///< 128-255 Module-Specific Section
+ UINT8 Reserved0[319 - 256 + 1]; ///< 256-319 Reserved
+ SPD4_MANUFACTURING_DATA ManufactureInfo; ///< 320-383 Manufacturing Information
+ SPD4_END_USER_SECTION EndUser; ///< 384-511 End User Programmable
+} MrcSpdDdr4;
+
+typedef union {
+ struct {
+ UINT8 Fine : 2; ///< Bits 1:0
+ UINT8 Medium : 2; ///< Bits 3:2
+ UINT8 : 4; ///< Bits 7:4
+ } Bits;
+ UINT8 Data;
+} SPD_LPDDR_TIMEBASE_STRUCT;
+
+typedef union {
+ struct {
+ UINT32 CL3 : 1; ///< Bits 0:0
+ UINT32 CL6 : 1; ///< Bits 1:1
+ UINT32 CL8 : 1; ///< Bits 2:2
+ UINT32 CL9 : 1; ///< Bits 3:3
+ UINT32 CL10 : 1; ///< Bits 4:4
+ UINT32 CL11 : 1; ///< Bits 5:5
+ UINT32 CL12 : 1; ///< Bits 6:6
+ UINT32 CL14 : 1; ///< Bits 7:7
+ UINT32 CL16 : 1; ///< Bits 8:8
+ UINT32 : 1; ///< Bits 9:9
+ UINT32 CL20 : 1; ///< Bits 10:10
+ UINT32 CL22 : 1; ///< Bits 11:11
+ UINT32 CL24 : 1; ///< Bits 12:12
+ UINT32 : 1; ///< Bits 13:13
+ UINT32 CL28 : 1; ///< Bits 14:14
+ UINT32 : 1; ///< Bits 15:15
+ UINT32 CL32 : 1; ///< Bits 16:16
+ UINT32 : 1; ///< Bits 17:17
+ UINT32 CL36 : 1; ///< Bits 18:18
+ UINT32 : 1; ///< Bits 19:19
+ UINT32 CL40 : 1; ///< Bits 20:20
+ UINT32 : 11; ///< Bits 31:21
+ } Bits;
+ UINT32 Data;
+ UINT16 Data16[2];
+ UINT8 Data8[4];
+} SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 Density : 4; ///< Bits 3:0
+ UINT8 BankAddress : 2; ///< Bits 5:4
+ UINT8 BankGroup : 2; ///< Bits 7:6
+ } Bits;
+ UINT8 Data;
+} SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 SignalLoading : 2; ///< Bits 1:0
+ UINT8 ChannelsPerDie : 2; ///< Bits 3:2
+ UINT8 DieCount : 3; ///< Bits 6:4
+ UINT8 SdramPackageType : 1; ///< Bits 7:7
+ } Bits;
+ UINT8 Data;
+} SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 OperationAt1_20 : 1; ///< Bits 0:0
+ UINT8 EndurantAt1_20 : 1; ///< Bits 1:1
+ UINT8 OperationAt1_10 : 1; ///< Bits 2:2
+ UINT8 EndurantAt1_10 : 1; ///< Bits 3:3
+ UINT8 OperationAtTBD2V : 1; ///< Bits 4:4
+ UINT8 EndurantAtTBD2V : 1; ///< Bits 5:5
+ UINT8 : 2; ///< Bits 7:6
+ } Bits;
+ UINT8 Data;
+} SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 tCKmax : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_LPDDR_TCK_MAX_MTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 ReadLatencyMode : 2; ///< Bits 1:0
+ UINT8 WriteLatencySet : 2; ///< Bits 3:2
+ UINT8 : 4; ///< Bits 7:4
+ } Bits;
+ UINT8 Data;
+} SPD_LPDDR_RW_LATENCY_OPTION_STRUCT;
+
+typedef union {
+ struct {
+ INT8 tCKmaxFine : 8; ///< Bits 7:0
+ } Bits;
+ INT8 Data;
+} SPD_LPDDR_TCK_MAX_FTB_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 : 8; ///< Bits 7:0
+ } Bits;
+ UINT8 Data;
+} SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT;
+
+typedef union {
+ struct {
+ UINT8 Height : 5; ///< Bits 4:0
+ UINT8 RawCardExtension : 3; ///< Bits 7:5
+ } Bits;
+ UINT8 Data;
+} SPD_LPDDR_UNBUF_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+ struct {
+ UINT8 Height : 5; ///< Bits 4:0
+ UINT8 RawCardExtension : 3; ///< Bits 7:5
+ } Bits;
+ UINT8 Data;
+} SPD_LPDDR_RDIMM_MODULE_NOMINAL_HEIGHT;
+
+typedef struct {
+ SPD_DEVICE_DESCRIPTION_STRUCT Description; ///< 0 Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+ SPD_REVISION_STRUCT Revision; ///< 1 SPD Revision
+ SPD_DRAM_DEVICE_TYPE_STRUCT DramDeviceType; ///< 2 DRAM Device Type
+ SPD_MODULE_TYPE_STRUCT ModuleType; ///< 3 Module Type
+ SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT SdramDensityAndBanks; ///< 4 SDRAM Density and Banks
+ SPD_SDRAM_ADDRESSING_STRUCT SdramAddressing; ///< 5 SDRAM Addressing
+ SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT SdramPackageType; ///< 6 SDRAM Package Type
+ SPD_PTRR_SUPPORT_STRUCT pTRRsupport; ///< 7 pTRR support with TMAC value - SDRAM Optional Features
+ SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT ThermalAndRefreshOptions; ///< 8 SDRAM Thermal and Refresh Options
+ UINT8 Reserved0[10 - 9 + 1]; ///< 9-10 Reserved
+ SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT ModuleNominalVoltage; ///< 11 Module Nominal Voltage, VDD
+ SPD_MODULE_ORGANIZATION_STRUCT ModuleOrganization; ///< 12 Module Organization
+ SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT ModuleMemoryBusWidth; ///< 13 Module Memory Bus Width
+ SPD_MODULE_THERMAL_SENSOR_STRUCT ModuleThermalSensor; ///< 14 Module Thermal Sensor
+ UINT8 Reserved1[16 - 15 + 1]; ///< 15-16 Reserved
+ SPD_LPDDR_TIMEBASE_STRUCT Timebase; ///< 17 Timebases
+ SPD_TCK_MIN_MTB_STRUCT tCKmin; ///< 18 SDRAM Minimum Cycle Time (tCKmin)
+ SPD_LPDDR_TCK_MAX_MTB_STRUCT tCKmax; ///< 19 SDRAM Maximum Cycle Time (tCKmax)
+ SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies; ///< 20-23 CAS Latencies Supported
+ SPD_TAA_MIN_MTB_STRUCT tAAmin; ///< 24 Minimum CAS Latency Time (tAAmin)
+ SPD_LPDDR_RW_LATENCY_OPTION_STRUCT LatencySetOptions; ///< 25 Read and Write Latency Set Options
+ SPD_TRCD_MIN_MTB_STRUCT tRCDmin; ///< 26 Minimum RAS# to CAS# Delay Time (tRCDmin)
+ SPD_TRP_AB_MTB_STRUCT tRPab; ///< 27 Minimum Row Precharge Delay Time (tRPab), all banks
+ SPD_TRP_PB_MTB_STRUCT tRPpb; ///< 28 Minimum Row Precharge Delay Time (tRPpb), per bank
+ SPD_TRFC_AB_MTB_STRUCT tRFCab; ///< 29-30 Minimum Refresh Recovery Delay Time (tRFCab), all banks
+ SPD_TRFC_PB_MTB_STRUCT tRFCpb; ///< 31-32 Minimum Refresh Recovery Delay Time (tRFCpb), per bank
+ UINT8 Reserved2[119 - 33 + 1]; ///< 33-119 Reserved
+ SPD_TRP_PB_FTB_STRUCT tRPpbFine; ///< 120 Fine Offset for Minimum Row Precharge Delay Time (tRPpbFine), per bank
+ SPD_TRP_AB_FTB_STRUCT tRPabFine; ///< 121 Fine Offset for Minimum Row Precharge Delay Time (tRPabFine), all ranks
+ SPD_TRCD_MIN_FTB_STRUCT tRCDminFine; ///< 122 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+ SPD_TAA_MIN_FTB_STRUCT tAAminFine; ///< 123 Fine Offset for Minimum CAS Latency Time (tAAmin)
+ SPD_LPDDR_TCK_MAX_FTB_STRUCT tCKmaxFine; ///< 124 Fine Offset for SDRAM Maximum Cycle Time (tCKmax)
+ SPD_TCK_MIN_FTB_STRUCT tCKminFine; ///< 125 Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+ SPD_CYCLIC_REDUNDANCY_CODE Crc; ///< 126-127 Cyclical Redundancy Code (CRC)
+} SPD_LPDDR_BASE_SECTION;
+
+typedef union {
+ struct {
+ UINT8 FrontThickness : 4; ///< Bits 3:0
+ UINT8 BackThickness : 4; ///< Bits 7:4
+ } Bits;
+ UINT8 Data;
+} SPD_LPDDR_MODULE_MAXIMUM_THICKNESS;
+
+typedef union {
+ struct {
+ UINT8 Height : 5; ///< Bits 4:0
+ UINT8 RawCardExtension : 3; ///< Bits 7:5
+ } Bits;
+ UINT8 Data;
+} SPD_LPDDR_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+ struct {
+ UINT8 Card : 5; ///< Bits 4:0
+ UINT8 Revision : 2; ///< Bits 6:5
+ UINT8 Extension : 1; ///< Bits 7:7
+ } Bits;
+ UINT8 Data;
+} SPD_LPDDR_REFERENCE_RAW_CARD;
+
+typedef struct {
+ SPD_LPDDR_MODULE_NOMINAL_HEIGHT ModuleNominalHeight; ///< 128 Module Nominal Height
+ SPD_LPDDR_MODULE_MAXIMUM_THICKNESS ModuleMaximumThickness; ///< 129 Module Maximum Thickness
+ SPD_LPDDR_REFERENCE_RAW_CARD ReferenceRawCardUsed; ///< 130 Reference Raw Card Used
+ UINT8 Reserved[253 - 131 + 1]; ///< 131-253 Reserved
+ SPD_CYCLIC_REDUNDANCY_CODE Crc; ///< 254-255 Cyclical Redundancy Code (CRC)
+} SPD_LPDDR_MODULE_LPDIMM;
+
+typedef union {
+ SPD_LPDDR_MODULE_LPDIMM LpDimm; ///< 128-255 Unbuffered Memory Module Types
+} SPD_LPDDR_MODULE_SPECIFIC;
+
+typedef struct {
+ UINT8 ModulePartNumber[348 - 329 + 1]; ///< 329-348 Module Part Number
+} SPD_LPDDR_MODULE_PART_NUMBER;
+
+typedef struct {
+ UINT8 ManufactureSpecificData[381 - 353 + 1]; ///< 353-381 Manufacturer's Specific Data
+} SPD_LPDDR_MANUFACTURE_SPECIFIC;
+
+typedef UINT8 SPD_LPDDR_MODULE_REVISION_CODE;///< 349 Module Revision Code
+typedef UINT8 SPD_LPDDR_DRAM_STEPPING; ///< 352 Dram Stepping
+
+typedef struct {
+ SPD_UNIQUE_MODULE_ID ModuleId; ///< 320-328 Unique Module ID
+ SPD_LPDDR_MODULE_PART_NUMBER ModulePartNumber; ///< 329-348 Module Part Number
+ SPD_LPDDR_MODULE_REVISION_CODE ModuleRevisionCode; ///< 349 Module Revision Code
+ SPD_MANUFACTURER_ID_CODE DramIdCode; ///< 350-351 Dram Manufacturer ID Code
+ SPD_LPDDR_DRAM_STEPPING DramStepping; ///< 352 Dram Stepping
+ SPD_LPDDR_MANUFACTURE_SPECIFIC ManufactureSpecificData; ///< 353-381 Manufacturer's Specific Data
+ UINT8 Reserved[383 - 382 + 1]; ///< 382-383 Reserved
+} SPD_LPDDR_MANUFACTURING_DATA;
+
+typedef union {
+ UINT8 Reserved0[511 - 384 + 1]; ///< 384-511 End User Programmable
+} SPD_LPDDR_END_USER_SECTION;
+
+typedef struct {
+ SPD_LPDDR_BASE_SECTION Base; ///< 0-127 Base Configuration and DRAM Parameters
+ SPD_LPDDR_MODULE_SPECIFIC Module; ///< 128-255 Module-Specific Section
+ UINT8 Reserved0[319 - 256 + 1]; ///< 256-319 Reserved
+ SPD_LPDDR_MANUFACTURING_DATA ManufactureInfo; ///< 320-383 Manufacturing Information
+ SPD_LPDDR_END_USER_SECTION EndUser; ///< 384-511 End User Programmable
+} MrcSpdLpDdr;
+
+typedef union {
+ MrcSpdDdr3 Ddr3;
+ MrcSpdDdr4 Ddr4;
+ MrcSpdLpDdr Lpddr;
+} MrcSpd;
+
+#ifndef MAX_SPD_SAVE
+#define MAX_SPD_SAVE (sizeof (SPD_MANUFACTURER_ID_CODE) + \
+ sizeof (SPD_MANUFACTURING_LOCATION) + \
+ sizeof (SPD_MANUFACTURING_DATE) + \
+ sizeof (SPD_MANUFACTURER_SERIAL_NUMBER) + \
+ sizeof (SPD4_MODULE_PART_NUMBER))
+#endif
+
+#pragma pack (pop)
+#endif // _MrcSpdData_h_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h
new file mode 100644
index 0000000000..b267315f36
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h
@@ -0,0 +1,237 @@
+/** @file
+ Include the the general MRC types
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MRC_TYPES_H
+#define _MRC_TYPES_H
+
+#ifdef MRC_MINIBIOS_BUILD
+#include "MrcMiniBiosEfiDefs.h"
+#else
+#include <Base.h>
+#endif // MRC_MINIBIOS_BUILD
+
+//
+// Data Types
+//
+typedef union {
+ struct {
+ UINT32 Low;
+ UINT32 High;
+ } Data32;
+ UINT64 Data;
+} UINT64_STRUCT;
+
+typedef union {
+ struct {
+ INT32 Low;
+ INT32 High;
+ } Data32;
+ INT64 Data;
+} INT64_STRUCT;
+
+typedef union {
+ VOID *Ptr;
+ UINTN DataN;
+ UINT64 Data64;
+} POINTER_STRUCT;
+
+#define UNSUPPORT 0
+#define SUPPORT 1
+
+typedef enum {
+ mrcSuccess,
+ mrcFail,
+ mrcWrongInputParameter,
+ mrcCasError,
+ mrcTimingError,
+ mrcSenseAmpErr,
+ mrcReadMPRErr,
+ mrcReadLevelingError,
+ mrcWriteLevelingError,
+ mrcDataTimeCentering1DErr,
+ mrcWriteVoltage2DError,
+ mrcReadVoltage2DError,
+ mrcMiscTrainingError,
+ mrcWrError,
+ mrcDimmNotSupport,
+ mrcChannelNotSupport,
+ mrcPiSettingError,
+ mrcDqsPiSettingError,
+ mrcDeviceBusy,
+ mrcFrequencyChange,
+ mrcReutSequenceError,
+ mrcCrcError,
+ mrcFrequencyError,
+ mrcDimmNotExist,
+ mrcColdBootRequired,
+ mrcRoundTripLatencyError,
+ mrcMixedDimmSystem,
+ mrcAliasDetected,
+ mrcRetrain,
+ mrcRtpError,
+ mrcUnsupportedTechnology,
+ mrcMappingError,
+ mrcSocketNotSupported,
+ mrcControllerNotSupported,
+ mrcRankNotSupported,
+ mrcTurnAroundTripError
+} MrcStatus;
+
+//
+// general macros
+//
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef ABS
+#define ABS(x) (((x) < 0) ? (-(x)) : (x))
+#endif
+
+//
+// Make sure x is inside the range of [a..b]
+//
+#ifndef RANGE
+#define RANGE(x, a, b) (MIN ((b), MAX ((x), (a))))
+#endif
+
+#ifndef DIVIDECEIL
+#define DIVIDECEIL(a, b) (((a) + (b) - 1) / (b))
+#endif
+
+#ifndef DIVIDEROUND
+#define DIVIDEROUND(a, b) (((a) * (b) > 0) ? ((a) + (b) / 2) / (b) : ((a) - (b) / 2) / (b))
+#endif
+
+#ifndef DIVIDEFLOOR
+#define DIVIDEFLOOR(a, b) ((a) / (b))
+#endif
+
+//
+// Number of elements in a 1D array
+//
+#ifndef ARRAY_COUNT
+#define ARRAY_COUNT(a) (sizeof (a) / sizeof (a[0]))
+#endif
+
+//
+// use for ignore parames
+//
+// #define MRC_IGNORE_PARAM(x) ((x) = (x))
+//
+#if _MSC_EXTENSIONS
+//
+// Disable warning that make it impossible to compile at /W4
+// This only works for Microsoft* tools
+//
+//
+// Disabling bitfield type checking warnings.
+//
+#pragma warning (disable : 4214)
+//
+// Unreferenced formal parameter - We are object oriented, so we pass parameters even
+// if we don't need them.
+//
+#pragma warning (disable : 4100)
+//
+// ASSERT(FALSE) or while (TRUE) are legal constructs so supress this warning
+//
+#pragma warning(disable : 4127)
+//
+// The given function was selected for inline expansion, but the compiler did not perform the inlining.
+//
+#pragma warning(disable : 4710)
+
+#endif // _MSC_EXTENSIONS
+#define MRC_BIT0 0x00000001
+#define MRC_BIT1 0x00000002
+#define MRC_BIT2 0x00000004
+#define MRC_BIT3 0x00000008
+#define MRC_BIT4 0x00000010
+#define MRC_BIT5 0x00000020
+#define MRC_BIT6 0x00000040
+#define MRC_BIT7 0x00000080
+#define MRC_BIT8 0x00000100
+#define MRC_BIT9 0x00000200
+#define MRC_BIT10 0x00000400
+#define MRC_BIT11 0x00000800
+#define MRC_BIT12 0x00001000
+#define MRC_BIT13 0x00002000
+#define MRC_BIT14 0x00004000
+#define MRC_BIT15 0x00008000
+#define MRC_BIT16 0x00010000
+#define MRC_BIT17 0x00020000
+#define MRC_BIT18 0x00040000
+#define MRC_BIT19 0x00080000
+#define MRC_BIT20 0x00100000
+#define MRC_BIT21 0x00200000
+#define MRC_BIT22 0x00400000
+#define MRC_BIT23 0x00800000
+#define MRC_BIT24 0x01000000
+#define MRC_BIT25 0x02000000
+#define MRC_BIT26 0x04000000
+#define MRC_BIT27 0x08000000
+#define MRC_BIT28 0x10000000
+#define MRC_BIT29 0x20000000
+#define MRC_BIT30 0x40000000
+#define MRC_BIT31 0x80000000
+#define MRC_BIT32 0x100000000ULL
+#define MRC_BIT33 0x200000000ULL
+#define MRC_BIT34 0x400000000ULL
+#define MRC_BIT35 0x800000000ULL
+#define MRC_BIT36 0x1000000000ULL
+#define MRC_BIT37 0x2000000000ULL
+#define MRC_BIT38 0x4000000000ULL
+#define MRC_BIT39 0x8000000000ULL
+#define MRC_BIT40 0x10000000000ULL
+#define MRC_BIT41 0x20000000000ULL
+#define MRC_BIT42 0x40000000000ULL
+#define MRC_BIT43 0x80000000000ULL
+#define MRC_BIT44 0x100000000000ULL
+#define MRC_BIT45 0x200000000000ULL
+#define MRC_BIT46 0x400000000000ULL
+#define MRC_BIT47 0x800000000000ULL
+#define MRC_BIT48 0x1000000000000ULL
+#define MRC_BIT49 0x2000000000000ULL
+#define MRC_BIT50 0x4000000000000ULL
+#define MRC_BIT51 0x8000000000000ULL
+#define MRC_BIT52 0x10000000000000ULL
+#define MRC_BIT53 0x20000000000000ULL
+#define MRC_BIT54 0x40000000000000ULL
+#define MRC_BIT55 0x80000000000000ULL
+#define MRC_BIT56 0x100000000000000ULL
+#define MRC_BIT57 0x200000000000000ULL
+#define MRC_BIT58 0x400000000000000ULL
+#define MRC_BIT59 0x800000000000000ULL
+#define MRC_BIT60 0x1000000000000000ULL
+#define MRC_BIT61 0x2000000000000000ULL
+#define MRC_BIT62 0x4000000000000000ULL
+#define MRC_BIT63 0x8000000000000000ULL
+
+#define MRC_DEADLOOP() { volatile int __iii; __iii = 1; while (__iii); }
+
+#ifndef ASM
+#define ASM __asm
+#endif
+
+///
+/// Type Max/Min Values
+///
+#define MRC_INT32_MAX (0x7FFFFFFF)
+#define MRC_INT32_MIN (0x80000000)
+#define MRC_INT64_MAX (0x7FFFFFFFFFFFFFFFLL)
+#define MRC_INT64_MIN (0x8000000000000000LL)
+#define MRC_UINT32_MAX (0xFFFFFFFF)
+#define MRC_UINT64_MAX (0xFFFFFFFFFFFFFFFFULL)
+#define MRC_UINT_MIN (0x0)
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h
new file mode 100644
index 0000000000..d444e937d6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h
@@ -0,0 +1,15 @@
+/** @file
+ This file includes all the data structures that the MRC considers "global data".
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _UNIFIED_MrcInterface_h_
+#define _UNIFIED_MrcInterface_h_
+
+#include "Coffeelake/MrcInterface.h"
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
new file mode 100644
index 0000000000..82d798b783
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
@@ -0,0 +1,50 @@
+/** @file
+ Header file for initialization of GT PowerManagement
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GRAPHICS_INIT_H_
+#define _GRAPHICS_INIT_H_
+
+#include <Library/DxeServicesTableLib.h>
+#include <Guid/DxeServices.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Library/PciSegmentLib.h>
+#include <SaAccess.h>
+#include <Protocol/SaPolicy.h>
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <PchAccess.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+
+
+/**
+ Initialize GT ACPI tables
+
+ @param[in] ImageHandle - Handle for the image of this driver
+ @param[in] SaPolicy - SA DXE Policy protocol
+
+ @retval EFI_SUCCESS - GT ACPI initialization complete
+ @retval EFI_NOT_FOUND - Dxe System Table not found.
+ @retval EFI_OUT_OF_RESOURCES - Mmio not allocated successfully.
+**/
+EFI_STATUS
+GraphicsInit (
+ IN EFI_HANDLE ImageHandle,
+ IN SA_POLICY_PROTOCOL *SaPolicy
+ );
+
+/**
+ Do Post GT PM Init Steps after VBIOS Initialization.
+
+ @retval EFI_SUCCESS Succeed.
+**/
+EFI_STATUS
+PostPmInitEndOfDxe (
+ VOID
+ );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h
new file mode 100644
index 0000000000..0e95db3d02
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h
@@ -0,0 +1,193 @@
+/** @file
+ This is part of the implementation of an Intel Graphics drivers OpRegion /
+ Software SCI interface between system BIOS, ASL code, and Graphics drivers.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IGD_OPREGION_INIT_H_
+#define _IGD_OPREGION_INIT_H_
+
+///
+/// Statements that include other header files.
+///
+#include <Uefi/UefiBaseType.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <PchAccess.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PmcLib.h>
+#include <SaAccess.h>
+#include <IndustryStandard/Pci22.h>
+#include <CpuRegs.h>
+#include <SaInit.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/HobLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <SiConfigHob.h>
+
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/SaPolicy.h>
+
+
+#include <Private/Protocol/SaNvsArea.h>
+
+///
+/// Driver Produced Protocol Prototypes
+///
+#include <Protocol/IgdOpRegion.h>
+
+///
+///
+/// OpRegion (Miscellaneous) defines.
+///
+/// OpRegion Header defines.
+///
+typedef UINT16 STRING_REF;
+#define HEADER_SIGNATURE "IntelGraphicsMem"
+#define HEADER_SIZE 0x2000
+#define HEADER_OPREGION_VER 0x0200
+#define HEADER_OPREGION_REV 0x00
+#define HEADER_MBOX_SUPPORT (HD_MBOX5 + HD_MBOX4 + HD_MBOX3 + HD_MBOX2 + HD_MBOX1)
+#define HD_MBOX1 BIT0
+#define HD_MBOX2 BIT1
+#define HD_MBOX3 BIT2
+#define HD_MBOX4 BIT3
+#define HD_MBOX5 BIT4
+#define SVER_SIZE 32
+
+///
+/// OpRegion Mailbox 1 EQUates.
+///
+/// OpRegion Mailbox 3 EQUates.
+///
+#define ALS_ENABLE BIT0
+#define BLC_ENABLE BIT1
+#define BACKLIGHT_BRIGHTNESS 0xFF
+#define FIELD_VALID_BIT BIT31
+#define PFIT_ENABLE BIT2
+#define PFIT_OPRN_AUTO 0x00000000
+#define PFIT_OPRN_SCALING 0x00000007
+#define PFIT_OPRN_OFF 0x00000000
+#define PFIT_SETUP_AUTO 0
+#define PFIT_SETUP_SCALING 1
+#define PFIT_SETUP_OFF 2
+#define INIT_BRIGHT_LEVEL 0x64
+#define PFIT_STRETCH 6
+
+///
+/// Video BIOS / VBT defines
+///
+#define OPTION_ROM_SIGNATURE 0xAA55
+#define VBIOS_LOCATION_PRIMARY 0xC0000
+
+#define VBT_SIGNATURE SIGNATURE_32 ('$', 'V', 'B', 'T')
+///
+/// Typedef stuctures
+///
+#pragma pack(1)
+typedef struct {
+ UINT16 Signature; /// 0xAA55
+ UINT8 Size512;
+ UINT8 Reserved[21];
+ UINT16 PcirOffset;
+ UINT16 VbtOffset;
+} INTEL_VBIOS_OPTION_ROM_HEADER;
+#pragma pack()
+
+#pragma pack(1)
+typedef struct {
+ UINT32 Signature; /// "PCIR"
+ UINT16 VendorId; /// 0x8086
+ UINT16 DeviceId;
+ UINT16 Reserved0;
+ UINT16 Length;
+ UINT8 Revision;
+ UINT8 ClassCode[3];
+ UINT16 ImageLength;
+ UINT16 CodeRevision;
+ UINT8 CodeType;
+ UINT8 Indicator;
+ UINT16 Reserved1;
+} INTEL_VBIOS_PCIR_STRUCTURE;
+#pragma pack()
+
+#pragma pack(1)
+typedef struct {
+ UINT8 HeaderSignature[20];
+ UINT16 HeaderVersion;
+ UINT16 HeaderSize;
+ UINT16 HeaderVbtSize;
+ UINT8 HeaderVbtCheckSum;
+ UINT8 HeaderReserved;
+ UINT32 HeaderOffsetVbtDataBlock;
+ UINT32 HeaderOffsetAim1;
+ UINT32 HeaderOffsetAim2;
+ UINT32 HeaderOffsetAim3;
+ UINT32 HeaderOffsetAim4;
+ UINT8 DataHeaderSignature[16];
+ UINT16 DataHeaderVersion;
+ UINT16 DataHeaderSize;
+ UINT16 DataHeaderDataBlockSize;
+ UINT8 CoreBlockId;
+ UINT16 CoreBlockSize;
+ UINT16 CoreBlockBiosSize;
+ UINT8 CoreBlockBiosType;
+ UINT8 CoreBlockReleaseStatus;
+ UINT8 CoreBlockHWSupported;
+ UINT8 CoreBlockIntegratedHW;
+ UINT8 CoreBlockBiosBuild[4];
+ UINT8 CoreBlockBiosSignOn[155];
+} VBIOS_VBT_STRUCTURE;
+#pragma pack()
+///
+/// Driver Private Function definitions
+///
+
+/**
+ Graphics OpRegion / Software SCI driver installation function.
+
+ @retval EFI_SUCCESS - The driver installed without error.
+ @retval EFI_ABORTED - The driver encountered an error and could not complete
+ installation of the ACPI tables.
+**/
+EFI_STATUS
+IgdOpRegionInit (
+ VOID
+ );
+
+/**
+ Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
+ The VBT (Video BIOS Table) is a block of customizable data that is built
+ within the video BIOS and edited by customers.
+
+ @retval EFI_SUCCESS - Video BIOS VBT information returned.
+ @exception EFI_UNSUPPORTED - Could not find VBT information (*VBiosVbtPtr = NULL).
+**/
+EFI_STATUS
+GetVBiosVbtEndOfDxe (
+ VOID
+ );
+
+/**
+ Update Graphics OpRegion after PCI enumeration.
+
+ @retval EFI_SUCCESS - The function completed successfully.
+**/
+EFI_STATUS
+UpdateIgdOpRegionEndOfDxe (
+ VOID
+ );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
new file mode 100644
index 0000000000..34a2809f80
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
@@ -0,0 +1,91 @@
+/** @file
+ Header file for PciExpress Initialization Driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIEXPRESS_INITIALIZATION_DRIVER_H_
+#define _PCIEXPRESS_INITIALIZATION_DRIVER_H_
+
+#include <Library/HobLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Register/Msr.h>
+#include <SaAccess.h>
+#include <PchAccess.h>
+#include <Private/SaConfigHob.h>
+#include <Library/CpuPlatformLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Private/Protocol/SaNvsArea.h>
+
+#define GEN1 1
+#define GEN2 2
+
+///
+/// Function prototypes
+///
+/**
+ PCI Express Dxe Initialization.
+ Run before PCI Bus Init, where assignment of Bus, Memory,
+ and I/O Resources are assigned.
+
+ @param[in] SaPolicy - SA DXE Policy protocol
+
+ @retval EFI_SUCCESS - Pci Express successfully started and ready to be used
+ @exception EFI_UNSUPPORTED - Pci Express can't be initialized
+**/
+EFI_STATUS
+PciExpressInit (
+ IN SA_POLICY_PROTOCOL *SaPolicy
+ );
+
+/**
+ Find the Offset to a given Capabilities ID
+
+ @param[in] Segment - Pci Segment Number
+ @param[in] Bus - Pci Bus Number
+ @param[in] Device - Pci Device Number
+ @param[in] Function - Pci Function Number
+ @param[in] CapId - CAPID to search fo
+
+ @retval 0 - CAPID not found
+ @retval Other - CAPID found, Offset of desired CAPID
+**/
+UINT32
+PcieFindCapId (
+ IN UINT8 Segment,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT8 CapId
+ );
+
+/**
+ Search and return the offset of desired Pci Express Capability ID
+
+ @param[in] Segment - Pci Segment Number
+ @param[in] Bus - Pci Bus Number
+ @param[in] Device - Pci Device Number
+ @param[in] Function - Pci Function Number
+ @param[in] CapId - Extended CAPID to search for
+
+ @retval 0 - CAPID not found
+ @retval Other - CAPID found, Offset of desired CAPID
+**/
+UINT32
+PcieFindExtendedCapId (
+ IN UINT8 Segment,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT16 CapId
+ );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
new file mode 100644
index 0000000000..73af27e9d7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
@@ -0,0 +1,23 @@
+/** @file
+ This is header file for SA PCIE Root Complex initialization.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+EFI_STATUS
+PegInitBeforeEndOfDxe (
+ VOID
+ );
+
+/**
+ This function performs SA registers Saving/Restoring in EndOfDxe callback
+
+ @retval EFI_SUCCESS - Save/restore has done
+ @retval EFI_UNSUPPORTED - Save/restore not done successfully
+**/
+EFI_STATUS
+SaSaveRestore (
+ VOID
+ );
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
new file mode 100644
index 0000000000..d7e2423ffd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
@@ -0,0 +1,71 @@
+/** @file
+ Header file for SA Common Initialization Driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_INITIALIZATION_DRIVER_H_
+#define _SA_INITIALIZATION_DRIVER_H_
+
+#include <Uefi.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/SaPlatformLib.h>
+#include <Guid/EventGroup.h>
+#include <CpuRegs.h>
+#include <SaAccess.h>
+#include <Library/CpuPlatformLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Private/SaConfigHob.h>
+
+extern SA_POLICY_PROTOCOL *mSaPolicy;
+extern SA_CONFIG_HOB *SaConfigHob;
+
+typedef struct {
+ UINT64 BaseAddr;
+ UINT32 Offset;
+ UINT32 AndMask;
+ UINT32 OrMask;
+} BOOT_SCRIPT_REGISTER_SETTING;
+
+/**
+ SystemAgent Initialization Common Function.
+
+ @retval EFI_SUCCESS - Always.
+**/
+VOID
+SaInitEntryPoint (
+ VOID
+ );
+
+/**
+ Common function locks the PAM register as part of the SA Security requirements.
+
+ @retval EFI_SUCCESS - Always.
+**/
+VOID
+SaPamLock (
+ VOID
+ );
+/**
+ This function performs SA Security locking in EndOfDxe callback
+
+ @retval EFI_SUCCESS - Security lock has done
+ @retval EFI_UNSUPPORTED - Security lock not done successfully
+**/
+EFI_STATUS
+SaSecurityInit (
+ VOID
+ );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
new file mode 100644
index 0000000000..1991fd82c4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
@@ -0,0 +1,139 @@
+/** @file
+ Header file for SA Initialization Driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_INITIALIZATION_DXE_DRIVER_H_
+#define _SA_INITIALIZATION_DXE_DRIVER_H_
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+#include "VTd.h"
+#include "PcieComplex.h"
+#include "IgdOpRegionInit.h"
+#include <Private/Library/LegacyRegion.h>
+#include "GraphicsInit.h"
+#include "PciExpressInit.h"
+#include "SwitchableGraphicsInit.h"
+#include <Library/CpuPlatformLib.h>
+
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include <Protocol/SaPolicy.h>
+
+extern EFI_GUID gSaAcpiTableStorageGuid;
+extern EFI_GUID gSaSsdtAcpiTableStorageGuid;
+extern EFI_GUID gPegSsdtAcpiTableStorageGuid;
+
+typedef struct {
+ UINT64 Address;
+ EFI_BOOT_SCRIPT_WIDTH Width;
+ UINT32 Value;
+} BOOT_SCRIPT_PCI_REGISTER_SAVE;
+
+///
+/// Function Prototype
+///
+/**
+ This function gets registered as a callback to perform SA initialization before ExitPmAuth
+
+ @param[in] Event - A pointer to the Event that triggered the callback.
+ @param[in] Context - A pointer to private data registered with the callback function.
+
+ @retval EFI_SUCCESS - Always.
+
+**/
+VOID
+EFIAPI
+SaPciEnumCompleteCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ <b>System Agent Initialization DXE Driver Entry Point</b>
+ - <b>Introduction</b> \n
+ Based on the information/data in SA_POLICY_PROTOCOL, this module performs further SA initialization in DXE phase,
+ e.g. internal devices enable/disable, SSVID/SID programming, graphic power-management, VT-d, IGD OpRegion initialization.
+ From the perspective of a PCI Express hierarchy, the Broadwell System Agent and PCH together appear as a Root Complex with root ports the number of which depends on how the 8 PCH ports and 4 System Agent PCIe ports are configured [4x1, 2x8, 1x16].
+ There is an internal link (DMI or OPI) that connects the System Agent to the PCH component. This driver includes initialization of SA DMI, PCI Express, SA & PCH Root Complex Topology.
+ For iGFX, this module implements the initialization of the Graphics Technology Power Management from the Broadwell System Agent BIOS Specification and the initialization of the IGD OpRegion/Software SCI - BIOS Specification.
+ The ASL files that go along with the driver define the IGD OpRegion mailboxes in ACPI space and implement the software SCI interrupt mechanism.
+ The IGD OpRegion/Software SCI code serves as a communication interface between system BIOS, ASL, and Intel graphics driver including making a block of customizable data (VBT) from the Intel video BIOS available.
+ Reference Code for the SCI service functions "Get BIOS Data" and "System BIOS Callback" can be found in the ASL files, those functions can be platform specific, the sample provided in the reference code are implemented for Intel CRB.
+ This module implements the VT-d functionality described in the Broadwell System Agent BIOS Specification.
+ This module publishes the LegacyRegion protocol to control the read and write accesses to the Legacy BIOS ranges.
+ E000 and F000 segments are the legacy BIOS ranges and contain pointers to the ACPI regions, SMBIOS tables and so on. This is a private protocol used by Intel Framework.
+ This module registers CallBack function that performs SA security registers lockdown at end of post as required from Broadwell Bios Spec.
+ In addition, this module publishes the SaInfo Protocol with information such as current System Agent reference code version#.
+
+ - @pre
+ - EFI_FIRMWARE_VOLUME_PROTOCOL: Documented in Firmware Volume Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+ - SA_POLICY_PROTOCOL: A protocol published by a platform DXE module executed earlier; this is documented in this document as well.
+ - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL: Documented in the Unified Extensible Firmware Interface Specification, version 2.0, available at the URL: http://www.uefi.org/specs/
+ - EFI_BOOT_SCRIPT_SAVE_PROTOCOL: A protocol published by a platform DXE module executed earlier; refer to the Sample Code section of the Framework PCH Reference Code.
+ - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL: Documented in the Unified Extensible Firmware Interface Specification, version 2.0, available at the URL: http://www.uefi.org/specs/
+ - EFI_ACPI_TABLE_PROTOCOL : Documented in PI Specification 1.2
+ - EFI_CPU_IO_PROTOCOL: Documented in CPU I/O Protocol Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+ - EFI_DATA_HUB_PROTOCOL: Documented in EFI Data Hub Infrastructure Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+ - EFI_HII_PROTOCOL (or EFI_HII_DATABASE_PROTOCOL for UEFI 2.1): Documented in Human Interface Infrastructure Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+ (For EFI_HII_DATABASE_PROTOCOL, refer to UEFI Specification Version 2.1 available at the URL: http://www.uefi.org/)
+
+ - @result
+ IGD power-management functionality is initialized; VT-d is initialized (meanwhile, the DMAR table is updated); IGD OpRegion is initialized - IGD_OPREGION_PROTOCOL installed, IGD OpRegion allocated and mailboxes initialized, chipset initialized and ready to generate Software SCI for Internal graphics events. Publishes the SA_INFO_PROTOCOL with current SA reference code version #. Publishes the EFI_LEGACY_REGION_PROTOCOL documented in the Compatibility Support Module Specification, version 0.9, available at the URL: http://www.intel.com/technology/framework/spec.htm
+
+ - <b>References</b> \n
+ IGD OpRegion/Software SCI for Broadwell
+ Advanced Configuration and Power Interface Specification Revision 4.0a.
+
+ - <b>Porting Recommendations</b> \n
+ No modification of the DXE driver should be typically necessary.
+ This driver should be executed after all related devices (audio, video, ME, etc.) are initialized to ensure correct data in DMAR table and DMA-remapping registers.
+
+ @param[in] ImageHandle Handle for the image of this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaInitEntryPointDxe (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ SystemAgent Acpi Initialization.
+
+ @param[in] ImageHandle Handle for the image of this driver
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaAcpiInit (
+ IN EFI_HANDLE ImageHandle
+ );
+
+/**
+ This function locks the PAM register as part of the SA Security requirements.
+
+ @param[in] Event - A pointer to the Event that triggered the callback.
+ @param[in] Context - A pointer to private data registered with the callback function.
+
+ @retval EFI_SUCCESS - Always.
+**/
+VOID
+EFIAPI
+SaPamLockDxe (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h
new file mode 100644
index 0000000000..2b1b4c5880
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h
@@ -0,0 +1,17 @@
+/** @file
+ Header file for the SwitchableGraphics Dxe driver.
+ This driver loads SwitchableGraphics ACPI tables.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SWITCHABLE_GRAPHICS_DXE_H_
+#define _SWITCHABLE_GRAPHICS_DXE_H_
+
+
+#include <Protocol/FirmwareVolume2.h>
+
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
new file mode 100644
index 0000000000..c4bc47f7fe
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
@@ -0,0 +1,53 @@
+/** @file
+ This code provides a initialization of intel VT-d (Virtualization Technology for Directed I/O).
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _VT_D_H_
+#define _VT_D_H_
+
+///
+/// Include files
+///
+#include <DmaRemappingTable.h>
+#include <SaAccess.h>
+#include <PchAccess.h>
+#include <Uefi.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/AcpiTable.h>
+#include <Library/PciSegmentLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Private/PchConfigHob.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include <IndustryStandard/Pci22.h>
+
+
+#define VTD_ECAP_REG 0x10
+#define IR BIT3
+
+/**
+ Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
+ Publish the appropriate SSDT based on current configuration and capabilities.
+
+ @param[in] SaPolicy SA DXE Policy protocol
+
+ @retval EFI_SUCCESS - Vtd initialization complete
+ @retval Other - No Vtd function initiated
+**/
+EFI_STATUS
+VtdInit (
+ IN SA_POLICY_PROTOCOL *SaPolicy
+ );
+
+/**
+ PciEnumerationComplete routine for update DMAR
+**/
+VOID
+UpdateDmarPciEnumCompleteCallback (
+ VOID
+ );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h
new file mode 100644
index 0000000000..02c74c0672
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h
@@ -0,0 +1,162 @@
+/** @file
+ Header file for SMM Access Driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SMM_ACCESS_DRIVER_H_
+#define _SMM_ACCESS_DRIVER_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PciLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Uefi/UefiBaseType.h>
+
+#include <Guid/SmramMemoryReserve.h>
+#include <Protocol/SmmAccess2.h>
+#include <IndustryStandard/Pci22.h>
+#include <SaAccess.h>
+
+#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5', 's', 'a')
+
+///
+/// Private data
+///
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_SMM_ACCESS2_PROTOCOL SmmAccess;
+
+ ///
+ /// Local Data for SMM Access interface goes here
+ ///
+ UINTN NumberRegions;
+ EFI_SMRAM_DESCRIPTOR *SmramDesc;
+} SMM_ACCESS_PRIVATE_DATA;
+
+#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
+ CR (a, \
+ SMM_ACCESS_PRIVATE_DATA, \
+ SmmAccess, \
+ SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
+ )
+
+//
+// Prototypes
+// Driver model protocol interface
+//
+/**
+ <b>SMM Access Driver Entry Point</b>
+ This driver installs an SMM Access Protocol
+ - <b>Introduction</b> \n
+ This module publishes the SMM access protocol. The protocol is used by the SMM Base driver to access the SMRAM region when the processor is not in SMM.
+ The SMM Base driver uses the services provided by the SMM access protocol to open SMRAM during post and copy the SMM handler.
+ SMM access protocol is also used to close the SMRAM region once the copying is done.
+ Finally, the SMM access protocol provides services to "Lock" the SMRAM region.
+ Please refer the SMM Protocols section in the attached SMM CIS Specification version 0.9 for further details.
+ This driver is required if SMM is supported. Proper configuration of SMM registers is recommended even if SMM is not supported.
+
+ - @result
+ Publishes the _EFI_SMM_ACCESS_PROTOCOL: Documented in the System Management Mode Core Interface Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+
+ - <b>Porting Recommendations</b> \n
+ No modification of this module is recommended. Any modification should be done in compliance with the _EFI_SMM_ACCESS_PROTOCOL protocol definition.
+
+ @param[in] ImageHandle - Handle for the image of this driver
+ @param[in] SystemTable - Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS - Protocol was installed successfully
+ @exception EFI_UNSUPPORTED - Protocol was not installed
+**/
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ This routine accepts a request to "open" a region of SMRAM. The
+ region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+ The use of "open" means that the memory is visible from all boot-service
+ and SMM agents.
+
+ @param[in] This - Pointer to the SMM Access Interface.
+
+ @retval EFI_SUCCESS - The region was successfully opened.
+ @retval EFI_DEVICE_ERROR - The region could not be opened because locked by
+ chipset.
+ @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Open (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ );
+
+/**
+ This routine accepts a request to "close" a region of SMRAM. The
+ region could be legacy AB or TSEG near top of physical memory.
+ The use of "close" means that the memory is only visible from SMM agents,
+ not from BS or RT code.
+
+ @param[in] This - Pointer to the SMM Access Interface.
+
+ @retval EFI_SUCCESS - The region was successfully closed.
+ @retval EFI_DEVICE_ERROR - The region could not be closed because locked by
+ chipset.
+ @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ );
+
+/**
+ This routine accepts a request to "lock" SMRAM. The
+ region could be legacy AB or TSEG near top of physical memory.
+ The use of "lock" means that the memory can no longer be opened
+ to BS state..
+
+ @param[in] This - Pointer to the SMM Access Interface.
+
+ @retval EFI_SUCCESS - The region was successfully locked.
+ @retval EFI_DEVICE_ERROR - The region could not be locked because at least
+ one range is still open.
+ @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Lock (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ );
+
+/**
+ This routine services a user request to discover the SMRAM
+ capabilities of this platform. This will report the possible
+ ranges that are possible for SMRAM access, based upon the
+ memory controller capabilities.
+
+ @param[in] This - Pointer to the SMRAM Access Interface.
+ @param[in] SmramMapSize - Pointer to the variable containing size of the
+ buffer to contain the description information.
+ @param[in] SmramMap - Buffer containing the data describing the Smram
+ region descriptors.
+
+ @retval EFI_BUFFER_TOO_SMALL - The user did not provide a sufficient buffer.
+ @retval EFI_SUCCESS - The user provided a sufficiently-sized buffer.
+**/
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+ IN CONST EFI_SMM_ACCESS2_PROTOCOL *This,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+ );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
new file mode 100644
index 0000000000..5daa2367e6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
@@ -0,0 +1,157 @@
+/** @file
+ DXE driver for Initializing SystemAgent Graphics ACPI table initialization.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "GraphicsInit.h"
+#include "SaInit.h"
+#include <Protocol/LegacyBios.h>
+#include <Protocol/GopComponentName2.h>
+#include <SiConfigHob.h>
+
+typedef union {
+ struct {
+ UINT32 Low;
+ UINT32 High;
+ } Data32;
+ UINT64 Data;
+} UINT64_STRUCT;
+
+extern SYSTEM_AGENT_NVS_AREA_PROTOCOL mSaNvsAreaProtocol;
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64 mGttMmAdr;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64_STRUCT mMchBarBase;
+GLOBAL_REMOVE_IF_UNREFERENCED GOP_COMPONENT_NAME2_PROTOCOL *GopComponentName2Protocol = NULL;
+
+/**
+ Do Post GT PM Init Steps after VBIOS Initialization.
+
+ @retval EFI_SUCCESS Succeed.
+**/
+EFI_STATUS
+PostPmInitEndOfDxe (
+ VOID
+ )
+{
+ CHAR16 *DriverVersion;
+ UINTN Index;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_STATUS Status;
+ GRAPHICS_DXE_CONFIG *GraphicsDxeConfig;
+ EFI_PEI_HOB_POINTERS HobPtr;
+ SI_CONFIG_HOB_DATA *SiConfigHobData;
+
+ ///
+ /// Get the platform setup policy.
+ ///
+ DriverVersion = NULL;
+ LegacyBios = NULL;
+ Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) &mSaPolicy);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get Silicon Config data HOB
+ //
+ HobPtr.Guid = GetFirstGuidHob (&gSiConfigHobGuid);
+ SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA (HobPtr.Guid);
+
+ if (SiConfigHobData->CsmFlag == 1) {
+ Status = gBS->LocateProtocol (
+ &gEfiLegacyBiosProtocolGuid,
+ NULL,
+ (VOID **) &LegacyBios
+ );
+ }
+
+ if (LegacyBios == NULL) {
+ Status = gBS->LocateProtocol (&gGopComponentName2ProtocolGuid, NULL, (VOID **)&GopComponentName2Protocol);
+ if (!EFI_ERROR (Status)) {
+ Status = GopComponentName2Protocol->GetDriverVersion (
+ GopComponentName2Protocol,
+ "en-US",
+ &DriverVersion
+ );
+ if (!EFI_ERROR (Status)) {
+ for (Index = 0; (DriverVersion[Index] != '\0'); Index++) {
+ }
+ Index = (Index+1)*2;
+ CopyMem (GraphicsDxeConfig->GopVersion, DriverVersion, Index);
+ }
+ }
+ }
+
+ ///
+ /// Return final status
+ ///
+ return EFI_SUCCESS;
+}
+
+
+/**
+Initialize GT ACPI tables
+
+ @param[in] ImageHandle - Handle for the image of this driver
+ @param[in] SaPolicy - SA DXE Policy protocol
+
+ @retval EFI_SUCCESS - GT ACPI initialization complete
+ @retval EFI_NOT_FOUND - Dxe System Table not found.
+ @retval EFI_OUT_OF_RESOURCES - Mmio not allocated successfully.
+**/
+EFI_STATUS
+GraphicsInit (
+ IN EFI_HANDLE ImageHandle,
+ IN SA_POLICY_PROTOCOL *SaPolicy
+ )
+{
+ EFI_STATUS Status;
+ GRAPHICS_DXE_CONFIG *GraphicsDxeConfig;
+
+ mGttMmAdr = 0;
+ Status = EFI_SUCCESS;
+ mMchBarBase.Data32.High = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MCHBAR + 4));
+ mMchBarBase.Data32.Low = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MCHBAR));
+ mMchBarBase.Data &= (UINT64) ~BIT0;
+
+ Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Update IGD SA Global NVS
+ ///
+ DEBUG ((DEBUG_INFO, " Update Igd SA Global NVS Area.\n"));
+
+ mSaNvsAreaProtocol.Area->AlsEnable = GraphicsDxeConfig->AlsEnable;
+ ///
+ /// Initialize IGD state by checking if IGD Device 2 Function 0 is enabled in the chipset
+ ///
+ if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_DEVEN)) & B_SA_DEVEN_D2EN_MASK) {
+ mSaNvsAreaProtocol.Area->IgdState = 1;
+ } else {
+ mSaNvsAreaProtocol.Area->IgdState = 0;
+ }
+
+ mSaNvsAreaProtocol.Area->BrightnessPercentage = 100;
+ mSaNvsAreaProtocol.Area->IgdBootType = GraphicsDxeConfig->IgdBootType;
+ mSaNvsAreaProtocol.Area->IgdPanelType = GraphicsDxeConfig->IgdPanelType;
+ mSaNvsAreaProtocol.Area->IgdPanelScaling = GraphicsDxeConfig->IgdPanelScaling;
+ ///
+ /// Get SFF power mode platform data for the IGD driver. Flip the bit (bitwise xor)
+ /// since Setup value is opposite of NVS and IGD OpRegion value.
+ ///
+ mSaNvsAreaProtocol.Area->IgdDvmtMemSize = GraphicsDxeConfig->IgdDvmtMemSize;
+ mSaNvsAreaProtocol.Area->IgdFunc1Enable = 0;
+ mSaNvsAreaProtocol.Area->IgdHpllVco = MmioRead8 (mMchBarBase.Data + 0xC0F) & 0x07;
+ mSaNvsAreaProtocol.Area->IgdSciSmiMode = 0;
+ mSaNvsAreaProtocol.Area->GfxTurboIMON = GraphicsDxeConfig->GfxTurboIMON;
+
+ mSaNvsAreaProtocol.Area->EdpValid = 0;
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c
new file mode 100644
index 0000000000..6ec0691074
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c
@@ -0,0 +1,570 @@
+/** @file
+ This is part of the implementation of an Intel Graphics drivers OpRegion /
+ Software SCI interface between system BIOS, ASL code, and Graphics drivers.
+ The code in this file will load the driver and initialize the interface
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "IgdOpRegionInit.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED IGD_OPREGION_PROTOCOL mIgdOpRegion;
+
+/**
+ Get VBT data using SaPlaformPolicy
+
+ @param[out] VbtFileBuffer Pointer to VBT data buffer.
+
+ @retval EFI_SUCCESS VBT data was returned.
+ @retval EFI_NOT_FOUND VBT data not found.
+ @exception EFI_UNSUPPORTED Invalid signature in VBT data.
+**/
+EFI_STATUS
+GetIntegratedIntelVbtPtr (
+ OUT VBIOS_VBT_STRUCTURE **VbtFileBuffer
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS VbtAddress;
+ UINT32 Size;
+ GRAPHICS_DXE_CONFIG *GraphicsDxeConfig;
+
+ ///
+ /// Get the SA policy.
+ ///
+ Status = gBS->LocateProtocol (
+ &gSaPolicyProtocolGuid,
+ NULL,
+ (VOID **) &mSaPolicy
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ VbtAddress = GraphicsDxeConfig->VbtAddress;
+ Size = GraphicsDxeConfig->Size;
+
+ if (VbtAddress == 0x00000000) {
+ return EFI_NOT_FOUND;
+ } else {
+ ///
+ /// Check VBT signature
+ ///
+ *VbtFileBuffer = NULL;
+ *VbtFileBuffer = (VBIOS_VBT_STRUCTURE *) (UINTN) VbtAddress;
+ if ((*((UINT32 *) ((*VbtFileBuffer)->HeaderSignature))) != VBT_SIGNATURE) {
+ FreePool (*VbtFileBuffer);
+ *VbtFileBuffer = NULL;
+ return EFI_UNSUPPORTED;
+ }
+ }
+ if (Size == 0) {
+ return EFI_NOT_FOUND;
+ } else {
+ ///
+ /// Check VBT size
+ ///
+ if ((*VbtFileBuffer)->HeaderVbtSize > Size) {
+ (*VbtFileBuffer)->HeaderVbtSize = (UINT16) Size;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Get a pointer to an uncompressed image of the Intel video BIOS.
+
+ @Note: This function would only be called if the video BIOS at 0xC000 is
+ missing or not an Intel video BIOS. It may not be an Intel video BIOS
+ if the Intel graphic contoller is considered a secondary adapter.
+
+ @param[out] VBiosImage - Pointer to an uncompressed Intel video BIOS. This pointer must
+ be set to NULL if an uncompressed image of the Intel Video BIOS
+ is not obtainable.
+
+ @retval EFI_SUCCESS - VBiosPtr is updated.
+ @exception EFI_UNSUPPORTED - No Intel video BIOS found.
+**/
+EFI_STATUS
+GetIntegratedIntelVBiosPtr (
+ OUT INTEL_VBIOS_OPTION_ROM_HEADER **VBiosImage
+ )
+{
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN Index;
+ INTEL_VBIOS_PCIR_STRUCTURE *PcirBlockPtr;
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ INTEL_VBIOS_OPTION_ROM_HEADER *VBiosRomImage;
+
+ ///
+ /// Set as if an umcompressed Intel video BIOS image was not obtainable.
+ ///
+ VBiosRomImage = NULL;
+
+ ///
+ /// Get all PCI IO protocols
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Find the video BIOS by checking each PCI IO handle for an Intel video
+ /// BIOS OPROM.
+ ///
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ VBiosRomImage = PciIo->RomImage;
+
+ ///
+ /// If this PCI device doesn't have a ROM image, skip to the next device.
+ ///
+ if (!VBiosRomImage) {
+ continue;
+ }
+ ///
+ /// Get pointer to PCIR structure
+ ///
+ PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *) VBiosRomImage + VBiosRomImage->PcirOffset);
+
+ ///
+ /// Check if we have an Intel video BIOS OPROM.
+ ///
+ if ((VBiosRomImage->Signature == OPTION_ROM_SIGNATURE) &&
+ (PcirBlockPtr->VendorId == V_SA_MC_VID) &&
+ (PcirBlockPtr->ClassCode[0] == 0x00) &&
+ (PcirBlockPtr->ClassCode[1] == 0x00) &&
+ (PcirBlockPtr->ClassCode[2] == 0x03)
+ ) {
+ ///
+ /// Found Intel video BIOS.
+ ///
+ *VBiosImage = VBiosRomImage;
+ return EFI_SUCCESS;
+ }
+ }
+ ///
+ /// No Intel video BIOS found.
+ ///
+ ///
+ /// Free any allocated buffers
+ ///
+ FreePool (HandleBuffer);
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
+ The VBT (Video BIOS Table) is a block of customizable data that is built
+ within the video BIOS and edited by customers.
+
+ @retval EFI_SUCCESS - Video BIOS VBT information returned.
+ @exception EFI_UNSUPPORTED - Could not find VBT information (*VBiosVbtPtr = NULL).
+**/
+EFI_STATUS
+GetVBiosVbtEndOfDxe (
+ VOID
+ )
+{
+ INTEL_VBIOS_PCIR_STRUCTURE *PcirBlockPtr;
+ UINT32 PcirBlockAddress;
+ UINT16 PciVenderId;
+ INTEL_VBIOS_OPTION_ROM_HEADER *VBiosPtr;
+ VBIOS_VBT_STRUCTURE *VBiosVbtPtr;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_STATUS Status;
+ VBIOS_VBT_STRUCTURE *VbtFileBuffer;
+ UINTN Index;
+ UINT8 LegacyVbtFound;
+ GRAPHICS_DXE_CONFIG *GraphicsDxeConfig;
+ EFI_PEI_HOB_POINTERS HobPtr;
+ SI_CONFIG_HOB_DATA *SiConfigHobData;
+
+ VbtFileBuffer = NULL;
+ LegacyVbtFound = 1;
+
+ ///
+ /// Get the SA policy.
+ ///
+ Status = gBS->LocateProtocol (
+ &gSaPolicyProtocolGuid,
+ NULL,
+ (VOID **) &mSaPolicy
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ LegacyBios = NULL;
+ VBiosPtr = NULL;
+ //
+ // Get Silicon Config data HOB
+ //
+ HobPtr.Guid = GetFirstGuidHob (&gSiConfigHobGuid);
+ SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA (HobPtr.Guid);
+ if (SiConfigHobData->CsmFlag == 1) {
+ Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
+
+ if (LegacyBios) {
+ VBiosPtr = (INTEL_VBIOS_OPTION_ROM_HEADER *) (UINTN) (VBIOS_LOCATION_PRIMARY);
+ PcirBlockAddress = VBIOS_LOCATION_PRIMARY + VBiosPtr->PcirOffset;
+ PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *) (UINTN) (PcirBlockAddress);
+ PciVenderId = PcirBlockPtr->VendorId;
+ ///
+ /// If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get
+ /// the integrated Intel video BIOS (must be uncompressed).
+ ///
+ if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != V_SA_MC_VID)) {
+ GetIntegratedIntelVBiosPtr (&VBiosPtr);
+ if (VBiosPtr != NULL) {
+ ///
+ /// Video BIOS found.
+ ///
+ PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *) VBiosPtr + VBiosPtr->PcirOffset);
+ PciVenderId = PcirBlockPtr->VendorId;
+
+ if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != V_SA_MC_VID)) {
+ ///
+ /// Intel video BIOS not found.
+ ///
+ VBiosVbtPtr = NULL;
+ LegacyVbtFound = 0;
+ }
+ }
+ }
+ }
+ }
+ if ((LegacyBios == NULL) || (LegacyVbtFound == 0)) {
+ ///
+ /// No Video BIOS found, try to get VBT from FV.
+ ///
+ GetIntegratedIntelVbtPtr (&VbtFileBuffer);
+ if (VbtFileBuffer != NULL) {
+ ///
+ /// Video BIOS not found, use VBT from SaPolicy
+ ///
+ DEBUG ((DEBUG_INFO, "VBT data found\n"));
+ for (Index = 0; (GraphicsDxeConfig->GopVersion[Index] != '\0'); Index++) {
+ }
+ Index = (Index+1)*2;
+ CopyMem (mIgdOpRegion.OpRegion->Header.DVER, GraphicsDxeConfig->GopVersion, Index);
+ CopyMem (mIgdOpRegion.OpRegion->MBox4.RVBT, VbtFileBuffer, VbtFileBuffer->HeaderVbtSize);
+ return EFI_SUCCESS;
+ }
+ }
+
+ if (VBiosPtr == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ DEBUG ((DEBUG_INFO, "VBIOS found at 0x%X\n", VBiosPtr));
+ VBiosVbtPtr = (VBIOS_VBT_STRUCTURE *) ((UINT8 *) VBiosPtr + VBiosPtr->VbtOffset);
+
+ if ((*((UINT32 *) (VBiosVbtPtr->HeaderSignature))) != VBT_SIGNATURE) {
+ return EFI_UNSUPPORTED;
+ }
+
+ ///
+ /// Initialize Video BIOS version with its build number.
+ ///
+ mIgdOpRegion.OpRegion->Header.VVER[0] = VBiosVbtPtr->CoreBlockBiosBuild[0];
+ mIgdOpRegion.OpRegion->Header.VVER[1] = VBiosVbtPtr->CoreBlockBiosBuild[1];
+ mIgdOpRegion.OpRegion->Header.VVER[2] = VBiosVbtPtr->CoreBlockBiosBuild[2];
+ mIgdOpRegion.OpRegion->Header.VVER[3] = VBiosVbtPtr->CoreBlockBiosBuild[3];
+ CopyMem (mIgdOpRegion.OpRegion->MBox4.RVBT, VBiosVbtPtr, VBiosVbtPtr->HeaderVbtSize);
+
+ ///
+ /// Return final status
+ ///
+ return EFI_SUCCESS;
+}
+
+/**
+ Graphics OpRegion / Software SCI driver installation function.
+
+ @param[in] void - None
+ @retval EFI_SUCCESS - The driver installed without error.
+ @retval EFI_ABORTED - The driver encountered an error and could not complete
+ installation of the ACPI tables.
+**/
+EFI_STATUS
+IgdOpRegionInit (
+ VOID
+ )
+{
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+ UINT32 DwordData;
+ UINT64 IgdBaseAddress;
+ SA_POLICY_PROTOCOL *SaPolicy;
+ GRAPHICS_DXE_CONFIG *GraphicsDxeConfig;
+ UINT8 Index;
+ SYSTEM_AGENT_NVS_AREA_PROTOCOL *SaNvsAreaProtocol;
+
+ ///
+ /// Get the SA policy.
+ ///
+ Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **)&SaPolicy);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Locate the SA Global NVS Protocol.
+ ///
+ Status = gBS->LocateProtocol (
+ &gSaNvsAreaProtocolGuid,
+ NULL,
+ (VOID **) &SaNvsAreaProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize
+ /// the first 1K, and set the IGD OpRegion pointer in the Global NVS
+ /// area structure.
+ ///
+ Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof (IGD_OPREGION_STRUCTURE), (VOID **) &mIgdOpRegion.OpRegion);
+ ASSERT_EFI_ERROR (Status);
+
+ SetMem (mIgdOpRegion.OpRegion, sizeof (IGD_OPREGION_STRUCTURE), 0);
+ SaNvsAreaProtocol->Area->IgdOpRegionAddress = (UINT32) (UINTN) (mIgdOpRegion.OpRegion);
+
+ ///
+ /// If IGD is disabled return
+ ///
+ IgdBaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0);
+ if (PciSegmentRead32 (IgdBaseAddress + 0) == 0xFFFFFFFF) {
+ return EFI_SUCCESS;
+ }
+ ///
+ /// Initialize OpRegion Header
+ ///
+ CopyMem (mIgdOpRegion.OpRegion->Header.SIGN, HEADER_SIGNATURE, sizeof (HEADER_SIGNATURE));
+ ///
+ /// Set OpRegion Size in KBs
+ ///
+ mIgdOpRegion.OpRegion->Header.SIZE = HEADER_SIZE / 1024;
+ mIgdOpRegion.OpRegion->Header.OVER = (UINT32) (LShiftU64 (HEADER_OPREGION_VER, 16) + LShiftU64 (HEADER_OPREGION_REV, 8));
+
+ ///
+ /// All Mailboxes are supported.
+ ///
+ mIgdOpRegion.OpRegion->Header.MBOX = HEADER_MBOX_SUPPORT;
+
+ ///
+ /// Initialize OpRegion Mailbox 1 (Public ACPI Methods).
+ ///
+ /// Note - The initial setting of mailbox 1 fields is implementation specific.
+ /// Adjust them as needed many even coming from user setting in setup.
+ ///
+ ///
+ /// Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservation).
+ ///
+ /// Note - The initial setting of mailbox 3 fields is implementation specific.
+ /// Adjust them as needed many even coming from user setting in setup.
+ ///
+ ///
+ /// Do not initialize TCHE. This field is written by the graphics driver only.
+ ///
+ ///
+ /// The ALSI field is generally initialized by ASL code by reading the embedded controller.
+ ///
+ mIgdOpRegion.OpRegion->Header.PCON = GraphicsDxeConfig->PlatformConfig;
+ mIgdOpRegion.OpRegion->Header.PCON = mIgdOpRegion.OpRegion->Header.PCON | 0x2;
+
+ mIgdOpRegion.OpRegion->MBox3.BCLP = BACKLIGHT_BRIGHTNESS;
+
+ mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_STRETCH);
+
+ ///
+ /// Reporting to driver for VR IMON Calibration. Bits [5-1] values supported 14A to 31A.
+ ///
+ mIgdOpRegion.OpRegion->MBox3.PCFT = (SaNvsAreaProtocol->Area->GfxTurboIMON << 1) & 0x003E;
+
+ ///
+ /// Set Initial current Brightness
+ ///
+ mIgdOpRegion.OpRegion->MBox3.CBLV = (INIT_BRIGHT_LEVEL | FIELD_VALID_BIT);
+
+ ///
+ /// Static Backlight Brightness Level Duty cycle Mapping Table
+ ///
+ for (Index = 0; Index < MAX_BCLM_ENTRIES; Index++) {
+ mIgdOpRegion.OpRegion->MBox3.BCLM[Index] = GraphicsDxeConfig->BCLM[Index];
+ }
+
+ mIgdOpRegion.OpRegion->MBox3.IUER = 0x00;
+
+ if (!EFI_ERROR (Status)) {
+ mIgdOpRegion.OpRegion->MBox3.IUER = GraphicsDxeConfig->IuerStatusVal;
+ }
+
+ ///
+ /// Initialize hardware state:
+ /// Set ASLS Register to the OpRegion physical memory address.
+ /// Set SWSCI register bit 15 to a "1" to activate SCI interrupts.
+ ///
+ PciSegmentWrite32 (IgdBaseAddress + R_SA_IGD_ASLS_OFFSET, (UINT32) (UINTN) (mIgdOpRegion.OpRegion));
+ PciSegmentAndThenOr16 (IgdBaseAddress + R_SA_IGD_SWSCI_OFFSET, (UINT16) ~(BIT0), BIT15);
+
+ DwordData = PciSegmentRead32 (IgdBaseAddress + R_SA_IGD_ASLS_OFFSET);
+ S3BootScriptSaveMemWrite (
+ S3BootScriptWidthUint32,
+ (UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (IgdBaseAddress + R_SA_IGD_ASLS_OFFSET),
+ 1,
+ &DwordData
+ );
+ DwordData = PciSegmentRead32 (IgdBaseAddress + R_SA_IGD_SWSCI_OFFSET);
+ S3BootScriptSaveMemWrite (
+ S3BootScriptWidthUint32,
+ (UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (IgdBaseAddress + R_SA_IGD_SWSCI_OFFSET),
+ 1,
+ &DwordData
+ );
+
+ ///
+ /// Install OpRegion / Software SCI protocol
+ ///
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gIgdOpRegionProtocolGuid,
+ &mIgdOpRegion,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Return final status
+ ///
+ return EFI_SUCCESS;
+}
+
+/**
+ Update Graphics OpRegion after PCI enumeration.
+
+ @param[in] void - None
+ @retval EFI_SUCCESS - The function completed successfully.
+**/
+EFI_STATUS
+UpdateIgdOpRegionEndOfDxe (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_TYPE00 Pci;
+ UINTN Segment;
+ UINTN Bus;
+ UINTN Device;
+ UINTN Function;
+
+ Bus = 0;
+ Device = 0;
+ Function = 0;
+
+ DEBUG ((DEBUG_INFO, "UpdateIgdOpRegionEndOfDxe\n"));
+
+ mIgdOpRegion.OpRegion->Header.PCON |= BIT8; //Set External Gfx Adapter field is valid
+ mIgdOpRegion.OpRegion->Header.PCON &= (UINT32) (~BIT7); //Assume No External Gfx Adapter
+
+ ///
+ /// Get all PCI IO protocols handles
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+
+ if (!EFI_ERROR (Status)) {
+ for (Index = 0; Index < HandleCount; Index++) {
+ ///
+ /// Get the PCI IO Protocol Interface corresponding to each handle
+ ///
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo
+ );
+
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// Read the PCI configuration space
+ ///
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+
+ ///
+ /// Find the display controllers devices
+ ///
+ if (!EFI_ERROR (Status) && IS_PCI_DISPLAY (&Pci)) {
+ Status = PciIo->GetLocation (
+ PciIo,
+ &Segment,
+ &Bus,
+ &Device,
+ &Function
+ );
+
+ //
+ // Assumption: Onboard devices will be sits on Bus no 0, while external devices will be sits on Bus no > 0
+ //
+ if (!EFI_ERROR (Status) && (Bus > 0)) {
+ //External Gfx Adapter Detected and Available
+ DEBUG ((DEBUG_INFO, "PCON - External Gfx Adapter Detected and Available\n"));
+ mIgdOpRegion.OpRegion->Header.PCON |= BIT7;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Free any allocated buffers
+ ///
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+
+ ///
+ /// Return final status
+ ///
+ return Status;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
new file mode 100644
index 0000000000..bbdf0d0fab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
@@ -0,0 +1,171 @@
+/** @file
+ This driver does SA PCI Express ACPI table initialization.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PciExpressInit.h"
+
+extern SYSTEM_AGENT_NVS_AREA_PROTOCOL mSaNvsAreaProtocol;
+extern SA_CONFIG_HOB *mSaConfigHob;
+
+/**
+ PCI Express Dxe Initialization.
+ Run before PCI Bus Init, where assignment of Bus, Memory,
+ and I/O Resources are assigned.
+
+ @param[in] SaPolicy - SA DXE Policy protocol
+
+ @retval EFI_SUCCESS - Pci Express successfully started and ready to be used
+**/
+EFI_STATUS
+PciExpressInit (
+ IN SA_POLICY_PROTOCOL *SaPolicy
+ )
+{
+ EFI_STATUS Status;
+ PCIE_DXE_CONFIG *PcieDxeConfig;
+ MSR_BROADWELL_PKG_CST_CONFIG_CONTROL_REGISTER Msr;
+
+ Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig);
+ ASSERT_EFI_ERROR (Status);
+
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_BROADWELL_PKG_CST_CONFIG_CONTROL);
+ mSaNvsAreaProtocol.Area->PackageCstateLimit = (UINT8) Msr.Bits.Limit;
+
+ mSaNvsAreaProtocol.Area->PwrDnBundlesGlobalEnable = 0;
+
+ if (mSaConfigHob != NULL) {
+ mSaNvsAreaProtocol.Area->Peg0PowerDownUnusedBundles = mSaConfigHob->PowerDownUnusedBundles[0];
+ mSaNvsAreaProtocol.Area->Peg1PowerDownUnusedBundles = mSaConfigHob->PowerDownUnusedBundles[1];
+ mSaNvsAreaProtocol.Area->Peg2PowerDownUnusedBundles = mSaConfigHob->PowerDownUnusedBundles[2];
+ if (SA_PEG_MAX_FUN > 3) {
+ mSaNvsAreaProtocol.Area->Peg3PowerDownUnusedBundles = mSaConfigHob->PowerDownUnusedBundles[3];
+ }
+ }
+ ///
+ /// LTR/OBFF
+ ///
+ mSaNvsAreaProtocol.Area->Peg0LtrEnable = PcieDxeConfig->PegPwrOpt[0].LtrEnable;
+ mSaNvsAreaProtocol.Area->Peg0ObffEnable = PcieDxeConfig->PegPwrOpt[0].ObffEnable;
+ mSaNvsAreaProtocol.Area->Peg1LtrEnable = PcieDxeConfig->PegPwrOpt[1].LtrEnable;
+ mSaNvsAreaProtocol.Area->Peg1ObffEnable = PcieDxeConfig->PegPwrOpt[1].ObffEnable;
+ mSaNvsAreaProtocol.Area->Peg2LtrEnable = PcieDxeConfig->PegPwrOpt[2].LtrEnable;
+ mSaNvsAreaProtocol.Area->Peg2ObffEnable = PcieDxeConfig->PegPwrOpt[2].ObffEnable;
+ mSaNvsAreaProtocol.Area->PegLtrMaxSnoopLatency = LTR_MAX_SNOOP_LATENCY_VALUE;
+ mSaNvsAreaProtocol.Area->PegLtrMaxNoSnoopLatency = LTR_MAX_NON_SNOOP_LATENCY_VALUE;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Find the Offset to a given Capabilities ID
+ CAPID list:
+ 0x01 = PCI Power Management Interface
+ 0x04 = Slot Identification
+ 0x05 = MSI Capability
+ 0x10 = PCI Express Capability
+
+ @param[in] Segment - Pci Segment Number
+ @param[in] Bus - Pci Bus Number
+ @param[in] Device - Pci Device Number
+ @param[in] Function - Pci Function Number
+ @param[in] CapId - CAPID to search for
+
+ @retval 0 - CAPID not found
+ @retval Other - CAPID found, Offset of desired CAPID
+**/
+UINT32
+PcieFindCapId (
+ IN UINT8 Segment,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT8 CapId
+ )
+{
+ UINT64 DeviceBaseAddress;
+ UINT8 CapHeader;
+
+ ///
+ /// Always start at Offset 0x34
+ ///
+ DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+ CapHeader = PciSegmentRead8 (DeviceBaseAddress + PCI_CAPBILITY_POINTER_OFFSET);
+ if (CapHeader == 0xFF) {
+ return 0;
+ }
+
+ while (CapHeader != 0) {
+ ///
+ /// Bottom 2 bits of the pointers are reserved per PCI Local Bus Spec 2.2
+ ///
+ CapHeader &= ~(BIT1 + BIT0);
+ ///
+ /// Search for desired CapID
+ ///
+ if (PciSegmentRead8 (DeviceBaseAddress + CapHeader) == CapId) {
+ return CapHeader;
+ }
+
+ CapHeader = PciSegmentRead8 (DeviceBaseAddress + CapHeader + 1);
+ }
+
+ return 0;
+}
+
+/**
+ Search and return the offset of desired Pci Express Capability ID
+ CAPID list:
+ 0x0001 = Advanced Error Rreporting Capability
+ 0x0002 = Virtual Channel Capability
+ 0x0003 = Device Serial Number Capability
+ 0x0004 = Power Budgeting Capability
+
+ @param[in] Segment - Pci Segment Number
+ @param[in] Bus - Pci Bus Number
+ @param[in] Device - Pci Device Number
+ @param[in] Function - Pci Function Number
+ @param[in] CapId - Extended CAPID to search for
+
+ @retval 0 - CAPID not found
+ @retval Other - CAPID found, Offset of desired CAPID
+**/
+UINT32
+PcieFindExtendedCapId (
+ IN UINT8 Segment,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT16 CapId
+ )
+{
+ UINT64 DeviceBaseAddress;
+ UINT16 CapHeaderOffset;
+ UINT16 CapHeaderId;
+
+ ///
+ /// Start to search at Offset 0x100
+ /// Get Capability Header
+ ///
+ DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+ CapHeaderId = 0;
+ CapHeaderOffset = 0x100;
+
+ while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
+ ///
+ /// Search for desired CapID
+ ///
+ CapHeaderId = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset);
+ if (CapHeaderId == CapId) {
+ return CapHeaderOffset;
+ }
+
+ CapHeaderOffset = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 2) >> 4);
+ }
+
+ return 0;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
new file mode 100644
index 0000000000..1dc37334ae
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
@@ -0,0 +1,171 @@
+/** @file
+ This file will perform SA PCIE Root Complex initialization.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PciExpressInit.h"
+#include <Private/Library/SaPcieLib.h>
+#include "PcieComplex.h"
+#include <Private/Protocol/SaIotrapSmi.h>
+#include "SaInit.h"
+
+///
+/// Global variables
+///
+UINT16 mSaIotrapSmiAddress;
+extern SA_CONFIG_HOB *mSaConfigHob;
+
+///
+/// Functions
+///
+/**
+ This function gets registered as a callback to perform all SA late initialization
+
+ @param[in] Event - A pointer to the Event that triggered the callback.
+ @param[in] Context - A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+SaLateInitSmiCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ SA_IOTRAP_SMI_PROTOCOL *SaIotrapSmiProtocol;
+
+ if (mSaIotrapSmiAddress == 0) {
+ //
+ // Use global variable instead of protocol data since it maybe tampered in unsecure environment
+ // Get IOTrap address when first time this routine calling (gEfiPciEnumerationCompleteProtocolGuid callback)
+ //
+ SaIotrapSmiProtocol = NULL;
+ Status = gBS->LocateProtocol (&gSaIotrapSmiProtocolGuid, NULL, (VOID **) &SaIotrapSmiProtocol);
+ ASSERT_EFI_ERROR (Status);
+ if (SaIotrapSmiProtocol != NULL) {
+ mSaIotrapSmiAddress = SaIotrapSmiProtocol->SaIotrapSmiAddress;
+ }
+ }
+
+ ASSERT (mSaIotrapSmiAddress != 0);
+ if (mSaIotrapSmiAddress != 0) {
+ //
+ // Generate IOTRAP SMI immediately
+ //
+ DEBUG ((DEBUG_INFO, "[SA] Issue IOTRAP SMI %X\n", mSaIotrapSmiAddress));
+ IoWrite8 (mSaIotrapSmiAddress, 0);
+ }
+ if (Event != NULL) {
+ gBS->CloseEvent (Event);
+ }
+ return;
+}
+
+/**
+ This function performs Peg initialization before EndOfDxe.
+ @note This function will be executed as gEfiPciEnumerationCompleteProtocolGuid protocol callback and assumed SA DXE/SMM drivers have been dispatched.
+
+ @retval EFI_SUCCESS - Always.
+**/
+EFI_STATUS
+PegInitBeforeEndOfDxe (
+ VOID
+ )
+{
+ EFI_EVENT ReadyToBoot;
+ EFI_STATUS Status;
+ BOOLEAN AspmHasBeenHandled;
+
+ DEBUG ((DEBUG_INFO, "[SA] Pcie before EndOfDxe callback.\n"));
+ AspmHasBeenHandled = FALSE;
+ ///
+ /// SMM mode ASPM handling
+ /// Check if supported and enabled
+ ///
+ if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom == TRUE)) {
+ ///
+ /// Do the Phase 1 SMI callback
+ /// This will enumerate PCIe downstream devices
+ ///
+ SaLateInitSmiCallback (NULL, NULL);
+
+ if (mSaIotrapSmiAddress != 0) {
+ ///
+ /// Create an ReadyToBoot call back event to do the Phase 3 SMI callback
+ /// This will handle PEG ASPM programming after OROM execution
+ /// Note: Phase 2 SMI callback will be triggered in EndOfDxe callback
+ /// to initialize rest of PCIe settings prior to OPROM
+ ///
+ Status = EfiCreateEventReadyToBootEx (
+ TPL_NOTIFY,
+ (EFI_EVENT_NOTIFY) SaLateInitSmiCallback,
+ NULL,
+ &ReadyToBoot
+ );
+ ASSERT_EFI_ERROR (Status);
+ AspmHasBeenHandled = TRUE;
+ }
+ }
+
+ ///
+ /// DXE mode ASPM handling
+ /// Check if SMM mode already taken care all things
+ /// TRUE to skip DXE mode task. Otherwise do DXE mode ASPM initialization
+ ///
+ if (AspmHasBeenHandled == FALSE) {
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function performs SA registers Saving/Restoring in EndOfDxe callback
+
+ @retval EFI_SUCCESS - Save/restore has done
+ @retval EFI_UNSUPPORTED - Save/restore not done successfully
+**/
+EFI_STATUS
+SaSaveRestore (
+ VOID
+ )
+{
+ BOOLEAN SaveRestoreHasBeenHandled;
+ UINT8 SmiData;
+
+ SaveRestoreHasBeenHandled = FALSE;
+
+ if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom == TRUE)) {
+ ///
+ /// Generate the Phase 2 of SA SMI to do SA chipset save/restore and security lock
+ ///
+ SaLateInitSmiCallback (NULL, NULL);
+
+ if (mSaIotrapSmiAddress != 0) {
+ ///
+ /// Store IOTRAP SMI address into Boot Script save table
+ /// This is required to trigger this IOTRAP during S3 resume to restore all settings
+ ///
+ SmiData = 0;
+ S3BootScriptSaveIoWrite (
+ S3BootScriptWidthUint8,
+ (UINTN) mSaIotrapSmiAddress,
+ 1,
+ &SmiData
+ );
+ SaveRestoreHasBeenHandled = TRUE;
+ }
+ }
+
+ ///
+ /// Check if SMM mode already taken care this task
+ ///
+ if (SaveRestoreHasBeenHandled == TRUE) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
new file mode 100644
index 0000000000..d5a63785b4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
@@ -0,0 +1,496 @@
+/** @file
+ This is the driver that initializes the Intel System Agent.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <Private/SaConfigHob.h>
+#include <Private/Protocol/SaNvsArea.h>
+#include <Library/PchInfoLib.h>
+
+///
+/// Global Variables
+///
+GLOBAL_REMOVE_IF_UNREFERENCED SYSTEM_AGENT_NVS_AREA_PROTOCOL mSaNvsAreaProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED SA_POLICY_PROTOCOL *mSaPolicy;
+extern SA_CONFIG_HOB *mSaConfigHob;
+
+/**
+ Initialize System Agent SSDT ACPI tables
+
+ @retval EFI_SUCCESS ACPI tables are initialized successfully
+ @retval EFI_NOT_FOUND ACPI tables not found
+**/
+EFI_STATUS
+InitializeSaSsdtAcpiTables (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ EFI_FV_FILETYPE FileType;
+ UINT32 FvStatus;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINTN Size;
+ UINTN i;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+ INTN Instance;
+ EFI_ACPI_COMMON_HEADER *CurrentTable;
+ UINTN AcpiTableKey;
+ UINT8 *CurrPtr;
+ UINT8 *EndPtr;
+ UINT32 *Signature;
+ EFI_ACPI_DESCRIPTION_HEADER *SaAcpiTable;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+
+ FwVol = NULL;
+ SaAcpiTable = NULL;
+
+ ///
+ /// Locate ACPI Table protocol
+ ///
+ DEBUG ((DEBUG_INFO, "Init SA SSDT table\n"));
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_WARN, "Fail to locate EfiAcpiTableProtocol.\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ ///
+ /// Locate protocol.
+ /// There is little chance we can't find an FV protocol
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Looking for FV with ACPI storage file
+ ///
+ for (i = 0; i < NumberOfHandles; i++) {
+ ///
+ /// Get the protocol on this handle
+ /// This should not fail because of LocateHandleBuffer
+ ///
+ Status = gBS->HandleProtocol (
+ HandleBuffer[i],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **) &FwVol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// See if it has the ACPI storage file
+ ///
+ Size = 0;
+ FvStatus = 0;
+ Status = FwVol->ReadFile (
+ FwVol,
+ &gSaSsdtAcpiTableStorageGuid,
+ NULL,
+ &Size,
+ &FileType,
+ &Attributes,
+ &FvStatus
+ );
+
+ ///
+ /// If we found it, then we are done
+ ///
+ if (Status == EFI_SUCCESS) {
+ break;
+ }
+ }
+ ///
+ /// Free any allocated buffers
+ ///
+ FreePool (HandleBuffer);
+
+ ///
+ /// Sanity check that we found our data file
+ ///
+ ASSERT (FwVol != NULL);
+ if (FwVol == NULL) {
+ DEBUG ((DEBUG_INFO, "SA Global NVS table not found\n"));
+ return EFI_NOT_FOUND;
+ }
+ ///
+ /// Our exit status is determined by the success of the previous operations
+ /// If the protocol was found, Instance already points to it.
+ /// Read tables from the storage file.
+ ///
+ Instance = 0;
+ CurrentTable = NULL;
+ while (Status == EFI_SUCCESS) {
+ Status = FwVol->ReadSection (
+ FwVol,
+ &gSaSsdtAcpiTableStorageGuid,
+ EFI_SECTION_RAW,
+ Instance,
+ (VOID **) &CurrentTable,
+ &Size,
+ &FvStatus
+ );
+
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// Check the table ID to modify the table
+ ///
+ if (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->OemTableId == SIGNATURE_64 ('S', 'a', 'S', 's', 'd', 't', ' ', 0)) {
+ SaAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
+ ///
+ /// Locate the SSDT package
+ ///
+ CurrPtr = (UINT8 *) SaAcpiTable;
+ EndPtr = CurrPtr + SaAcpiTable->Length;
+
+ for (; CurrPtr <= EndPtr; CurrPtr++) {
+ Signature = (UINT32 *) (CurrPtr + 3);
+ if (*Signature == SIGNATURE_32 ('S', 'A', 'N', 'V')) {
+ ASSERT (*(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) == 0xFFFF0000);
+ ASSERT (*(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) == 0xAA55);
+ ///
+ /// SA Global NVS Area address
+ ///
+ *(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) = (UINT32) (UINTN) mSaNvsAreaProtocol.Area;
+ ///
+ /// SA Global NVS Area size
+ ///
+ *(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) =
+ sizeof (SYSTEM_AGENT_NVS_AREA);
+
+ AcpiTableKey = 0;
+ Status = AcpiTable->InstallAcpiTable (
+ AcpiTable,
+ SaAcpiTable,
+ SaAcpiTable->Length,
+ &AcpiTableKey
+ );
+ ASSERT_EFI_ERROR (Status);
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ ///
+ /// Increment the instance
+ ///
+ Instance++;
+ CurrentTable = NULL;
+ }
+ }
+
+ return Status;
+
+}
+
+/**
+ Install SSDT Table
+
+ @retval EFI_SUCCESS - SSDT Table load successful.
+**/
+EFI_STATUS
+InstallSsdtAcpiTable (
+ IN GUID SsdtTableGuid,
+ IN UINT64 Signature
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ BOOLEAN LoadTable;
+ UINTN NumberOfHandles;
+ UINTN Index;
+ INTN Instance;
+ UINTN Size;
+ UINT32 FvStatus;
+ UINTN TableHandle;
+ EFI_FV_FILETYPE FileType;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+ EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
+ EFI_ACPI_COMMON_HEADER *Table;
+
+ FwVol = NULL;
+ Table = NULL;
+
+ DEBUG ((DEBUG_INFO, "Loading SSDT Table GUID: %g\n", SsdtTableGuid));
+
+ ///
+ /// Locate FV protocol.
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Look for FV with ACPI storage file
+ ///
+ for (Index = 0; Index < NumberOfHandles; Index++) {
+ ///
+ /// Get the protocol on this handle
+ /// This should not fail because of LocateHandleBuffer
+ ///
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **) &FwVol
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (FwVol == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ ///
+ /// See if it has the ACPI storage file
+ ///
+ Size = 0;
+ FvStatus = 0;
+ Status = FwVol->ReadFile (
+ FwVol,
+ &SsdtTableGuid,
+ NULL,
+ &Size,
+ &FileType,
+ &Attributes,
+ &FvStatus
+ );
+
+ ///
+ /// If we found it, then we are done
+ ///
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+ }
+ ///
+ /// Our exit status is determined by the success of the previous operations
+ /// If the protocol was found, Instance already points to it.
+ ///
+ ///
+ /// Free any allocated buffers
+ ///
+ FreePool (HandleBuffer);
+
+ ///
+ /// Sanity check that we found our data file
+ ///
+ ASSERT (FwVol);
+
+ ///
+ /// Locate ACPI tables
+ ///
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+
+ ///
+ /// Read tables from the storage file.
+ ///
+ if (FwVol == NULL) {
+ ASSERT_EFI_ERROR (EFI_NOT_FOUND);
+ return EFI_NOT_FOUND;
+ }
+ Instance = 0;
+
+ while (Status == EFI_SUCCESS) {
+ ///
+ /// Read the ACPI tables
+ ///
+ Status = FwVol->ReadSection (
+ FwVol,
+ &SsdtTableGuid,
+ EFI_SECTION_RAW,
+ Instance,
+ (VOID **) &Table,
+ &Size,
+ &FvStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// check and load SwitchableGraphics SSDT table
+ ///
+ LoadTable = FALSE;
+ TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+
+ if (((EFI_ACPI_DESCRIPTION_HEADER *) TableHeader)->OemTableId == Signature) {
+ ///
+ /// This is the SSDT table that match the Signature
+ ///
+ DEBUG ((DEBUG_INFO, "Found out SSDT Table GUID: %g\n", SsdtTableGuid));
+ LoadTable = TRUE;
+ }
+
+ ///
+ /// Add the table
+ ///
+ if (LoadTable) {
+ TableHandle = 0;
+ Status = AcpiTable->InstallAcpiTable (
+ AcpiTable,
+ TableHeader,
+ TableHeader->Length,
+ &TableHandle
+ );
+ }
+ ///
+ /// Increment the instance
+ ///
+ Instance++;
+ Table = NULL;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function gets registered as a callback to perform Dmar Igd
+
+ @param[in] Event - A pointer to the Event that triggered the callback.
+ @param[in] Context - A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+SaAcpiEndOfDxeCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 0xFFFF) {
+ Status = PostPmInitEndOfDxe ();
+ if (EFI_SUCCESS != Status) {
+ DEBUG ((DEBUG_WARN, "[SA] EndOfDxe GraphicsInit Error, Status = %r \n", Status));
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 0xFFFF) {
+ Status = GetVBiosVbtEndOfDxe ();
+ if (EFI_SUCCESS != Status) {
+ DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Op Region Error, Status = %r \n", Status));
+ }
+
+ Status = UpdateIgdOpRegionEndOfDxe ();
+ if (EFI_SUCCESS != Status) {
+ DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Update Op Region Error, Status = %r \n", Status));
+ }
+ }
+
+ return;
+}
+
+/**
+ SystemAgent Acpi Initialization.
+
+ @param[in] ImageHandle Handle for the image of this driver
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaAcpiInit (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_CPUID_REGISTER CpuidRegs;
+ CPU_FAMILY CpuFamilyId;
+ EFI_EVENT EndOfDxeEvent;
+
+ CpuFamilyId = GetCpuFamily();
+ AsmCpuid (1, &CpuidRegs.RegEax, 0, 0, 0);
+ ///
+ /// Get the platform setup policy.
+ ///
+ Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) &mSaPolicy);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Install System Agent Global NVS protocol
+ ///
+ DEBUG ((DEBUG_INFO, "Install SA GNVS protocol\n"));
+ Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof (SYSTEM_AGENT_NVS_AREA), (VOID **) &mSaNvsAreaProtocol.Area);
+ ASSERT_EFI_ERROR (Status);
+ ZeroMem ((VOID *) mSaNvsAreaProtocol.Area, sizeof (SYSTEM_AGENT_NVS_AREA));
+ mSaNvsAreaProtocol.Area->XPcieCfgBaseAddress = (UINT32) (PcdGet64 (PcdPciExpressBaseAddress));
+ mSaNvsAreaProtocol.Area->CpuIdInfo = CpuidRegs.RegEax;
+ if (mSaConfigHob != NULL) {
+ mSaNvsAreaProtocol.Area->IpuAcpiMode = mSaConfigHob->IpuAcpiMode;
+ }
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gSaNvsAreaProtocolGuid,
+ &mSaNvsAreaProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// PciExpress Dxe Initialization
+ ///
+ DEBUG ((DEBUG_INFO, "Initializing PciExpress (Dxe)\n"));
+ PciExpressInit (mSaPolicy);
+
+ ///
+ /// GtPostInit Initialization
+ ///
+ DEBUG ((DEBUG_INFO, "Initializing GT ACPI tables\n"));
+
+ GraphicsInit (ImageHandle, mSaPolicy);
+
+ /// Vtd Initialization
+ ///
+ DEBUG ((DEBUG_INFO, "Initializing VT-d ACPI tables\n"));
+ VtdInit (mSaPolicy);
+
+ ///
+ /// IgdOpRegion Install Initialization
+ ///
+ DEBUG ((DEBUG_INFO, "Initializing IGD OpRegion\n"));
+ IgdOpRegionInit ();
+
+ ///
+ /// Register an end of DXE event for SA ACPI to do tasks before invoking any UEFI drivers,
+ /// applications, or connecting consoles,...
+ ///
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ SaAcpiEndOfDxeCallback,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+
+ ///
+ /// Install System Agent Global NVS ACPI table
+ ///
+ Status = InitializeSaSsdtAcpiTables ();
+
+ ///
+ /// Install PEG SSDT table only if PEG port is present
+ ///
+ if (IsPchLinkDmi (CpuFamilyId)) {
+ if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, SA_PEG0_FUN_NUM, R_SA_PEG_DID_OFFSET)) != V_SA_DEVICE_ID_INVALID) {
+ Status = InstallSsdtAcpiTable (gPegSsdtAcpiTableStorageGuid, SIGNATURE_64 ('P','e','g','S','s','d','t',0));
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
new file mode 100644
index 0000000000..40bb107ad0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
@@ -0,0 +1,179 @@
+/** @file
+ This is the Common driver that initializes the Intel System Agent.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInit.h"
+#include <Library/PciSegmentLib.h>
+#include <Private/SaConfigHob.h>
+#include <Protocol/PciEnumerationComplete.h>
+
+//
+// Declare I/O Ports used to perform PCI Confguration Cycles
+//
+#define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8
+#define PCI_CONFIGURATION_DATA_PORT 0xCFC
+
+/**
+ Convert a PCI Library address to PCI CF8 formatted address.
+
+ Declare macro to convert PCI Library address to PCI CF8 formatted address.
+ Bit fields of PCI Library and CF8 formatted address is as follows:
+ PCI Library formatted address CF8 Formatted Address
+ ============================= ======================
+ Bits 00..11 Register Bits 00..07 Register
+ Bits 12..14 Function Bits 08..10 Function
+ Bits 15..19 Device Bits 11..15 Device
+ Bits 20..27 Bus Bits 16..23 Bus
+ Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)
+ Bits 31..31 Must be 1
+
+ @param A The address to convert.
+
+ @retval The coverted address.
+
+**/
+#define PCI_TO_CF8_ADDRESS(A) \
+ ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
+
+///
+/// Global Variables
+///
+GLOBAL_REMOVE_IF_UNREFERENCED SA_CONFIG_HOB *mSaConfigHob;
+BOOLEAN mSkipPamLock = FALSE;
+
+/*
+ Intel(R) Core Processor Skylake BWG version 0.4.0
+
+ 18.6 System Agent Configuration Locking
+ For reliable operation and security, System BIOS must set the following bits:
+ 1. For all modern Intel processors, Intel strongly recommends that BIOS should set
+ the D_LCK bit. Set B0:D0:F0.R088h [4] = 1b to lock down SMRAM space.
+ BaseAddr values for mSaSecurityRegisters that uses PciExpressBaseAddress will be initialized at
+ Runtime inside function SaPcieInitPolicy().
+*/
+GLOBAL_REMOVE_IF_UNREFERENCED BOOT_SCRIPT_REGISTER_SETTING mSaSecurityRegisters[] = {
+ {0, R_SA_SMRAMC, 0xFFFFFFFF, BIT4}
+};
+
+/**
+ SystemAgent Initialization Common Function.
+
+ @retval EFI_SUCCESS - Always.
+**/
+
+VOID
+SaInitEntryPoint (
+ VOID
+ )
+{
+ ///
+ /// Get SaConfigHob HOB
+ ///
+ mSaConfigHob = NULL;
+ mSaConfigHob = (SA_CONFIG_HOB *) GetFirstGuidHob (&gSaConfigHobGuid);
+ if (mSaConfigHob != NULL) {
+ mSkipPamLock = mSaConfigHob->SkipPamLock;
+ }
+
+ return;
+}
+
+
+
+/**
+ Common function locks the PAM register as part of the SA Security requirements.
+
+ @retval EFI_SUCCESS - Always.
+**/
+
+VOID
+SaPamLock (
+ VOID
+ )
+{
+ UINT64 BaseAddress;
+ UINT32 Data32Or;
+
+ if (mSkipPamLock == FALSE) {
+ //
+ // Lock PAM by PAM Lock Bit
+ //
+ BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, 0, 0, 0);
+ Data32Or = BIT0;
+ DEBUG ((DEBUG_INFO, "PAM_LOCK!!\n"));
+ PciSegmentOr32 (BaseAddress + R_SA_PAM0, Data32Or);
+ }
+}
+
+/**
+ This function does SA security lock
+**/
+VOID
+SaSecurityLock (
+ VOID
+ )
+{
+ UINT8 Index;
+ UINT32 RegOffset;
+ UINT32 Data32Or;
+ UINT32 Data32;
+ UINT8 Data8;
+
+ ///
+ /// 17.2 System Agent Security Lock configuration
+ ///
+ DEBUG ((DEBUG_INFO, "DXE SaSecurityLock\n"));
+ for (Index = 0; Index < (sizeof (mSaSecurityRegisters) / sizeof (BOOT_SCRIPT_REGISTER_SETTING)); Index++) {
+ RegOffset = mSaSecurityRegisters[Index].Offset;
+ Data32Or = mSaSecurityRegisters[Index].OrMask;
+
+ if (RegOffset == R_SA_SMRAMC) {
+ ///
+ /// SMRAMC LOCK must use CF8/CFC access
+ ///
+ PciCf8Or8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC), (UINT8) Data32Or);
+ Data8 = PciCf8Read8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC));
+ Data32 = PCI_TO_CF8_ADDRESS (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC));
+ S3BootScriptSaveIoWrite (
+ S3BootScriptWidthUint32,
+ (UINTN) (PCI_CONFIGURATION_ADDRESS_PORT),
+ 1,
+ &Data32
+ );
+ S3BootScriptSaveIoWrite (
+ S3BootScriptWidthUint8,
+ (UINTN) (PCI_CONFIGURATION_DATA_PORT),
+ 1,
+ &Data8
+ );
+ }
+ }
+}
+
+/**
+ This function performs SA Security locking in EndOfDxe callback
+
+ @retval EFI_SUCCESS - Security lock has done
+ @retval EFI_UNSUPPORTED - Security lock not done successfully
+**/
+EFI_STATUS
+SaSecurityInit (
+ VOID
+ )
+{
+
+ UINT8 Index;
+
+ for (Index = 0; Index < (sizeof (mSaSecurityRegisters) / sizeof (BOOT_SCRIPT_REGISTER_SETTING)); Index++) {
+ if (mSaSecurityRegisters[Index].BaseAddr != PcdGet64 (PcdMchBaseAddress)) {
+ mSaSecurityRegisters[Index].BaseAddr = PcdGet64 (PcdPciExpressBaseAddress);
+ }
+ }
+ SaSecurityLock ();
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
new file mode 100644
index 0000000000..d646e60618
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
@@ -0,0 +1,122 @@
+/** @file
+ This is the driver that initializes the Intel System Agent.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <Private/SaConfigHob.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <MemInfoHob.h>
+
+///
+/// Global Variables
+///
+extern SA_CONFIG_HOB *mSaConfigHob;
+
+/**
+ SystemAgent Dxe Initialization.
+
+ @param[in] ImageHandle Handle for the image of this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaInitEntryPointDxe (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ VOID *Registration;
+
+ DEBUG ((DEBUG_INFO, "SaInitDxe Start\n"));
+
+ SaInitEntryPoint ();
+
+ Status = SaAcpiInit (ImageHandle);
+
+ ///
+ /// Create PCI Enumeration Completed callback for SA
+ ///
+ EfiCreateProtocolNotifyEvent (
+ &gEfiPciEnumerationCompleteProtocolGuid,
+ TPL_CALLBACK,
+ SaPciEnumCompleteCallback,
+ NULL,
+ &Registration
+ );
+
+ DEBUG ((DEBUG_INFO, "SaInitDxe End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function gets registered as a callback to perform SA initialization before EndOfDxe
+
+ @param[in] Event - A pointer to the Event that triggered the callback.
+ @param[in] Context - A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+SaPciEnumCompleteCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ VOID *ProtocolPointer;
+
+ DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback Start\n"));
+ ///
+ /// Check if this is first time called by EfiCreateProtocolNotifyEvent() or not,
+ /// if it is, we will skip it until real event is triggered
+ ///
+ Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, NULL, (VOID **) &ProtocolPointer);
+ if (EFI_SUCCESS != Status) {
+ return;
+ }
+
+ gBS->CloseEvent (Event);
+
+ Status = PegInitBeforeEndOfDxe ();
+ if (EFI_SUCCESS != Status) {
+ DEBUG ((DEBUG_WARN, "[SA] Pcie initialization before EndOfDxe Error, Status = %r \n", Status));
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ SaSaveRestore ();
+ SaSecurityInit ();
+ UpdateDmarPciEnumCompleteCallback ();
+
+ DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback End\n"));
+ return;
+}
+
+/**
+ This function locks the PAM register as part of the SA Security requirements.
+
+ @param[in] Event - A pointer to the Event that triggered the callback.
+ @param[in] Context - A pointer to private data registered with the callback function.
+
+**/
+VOID
+EFIAPI
+SaPamLockDxe (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ DEBUG ((DEBUG_INFO, "SaPamLockDxe Start\n"));
+
+ SaPamLock ();
+
+ DEBUG ((DEBUG_INFO, "SaPamLockDxe End\n"));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
new file mode 100644
index 0000000000..acbf6b7aab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
@@ -0,0 +1,717 @@
+/** @file
+ This code provides a initialization of intel VT-d (Virtualization Technology for Directed I/O).
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include "VTd.h"
+#include <CpuRegs.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <PchInfoHob.h>
+#include <PchAccess.h>
+
+
+extern SA_CONFIG_HOB *mSaConfigHob;
+
+/**
+ For device that specified by Device Num and Function Num,
+ mDevEnMap is used to check device presence.
+ 0x80 means use Device ID to detemine presence
+ 0x8F means force to update
+
+ The structure is used to check if device scope is valid when update DMAR table
+**/
+UINT16 mDevEnMap[][2] = {{0x0200, 0x80}, {0x1400, 0x80}, {0x1401, 0x80}, {0x1607, 0x8F}};
+
+BOOLEAN mInterruptRemappingSupport;
+
+/**
+ Get the corresponding device Enable/Disable bit according DevNum and FunNum
+
+ @param[in] DevNum - Device Number
+ @param[in] FunNum - Function Number
+
+ @retval If the device is found, return disable/Enable bit in FD/Deven reigster
+ @retval If not found return 0xFF
+**/
+UINT16
+GetFunDisableBit (
+ UINT8 DevNum,
+ UINT8 FunNum
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < sizeof (mDevEnMap) / 4; Index++) {
+ if (mDevEnMap[Index][0] == ((DevNum << 0x08) | FunNum)) {
+ return mDevEnMap[Index][1];
+ }
+ }
+
+ return 0xFF;
+}
+
+/**
+ Update the DRHD structure
+
+ @param[in, out] DrhdEnginePtr - A pointer to DRHD structure
+**/
+VOID
+UpdateDrhd (
+ IN OUT VOID *DrhdEnginePtr
+ )
+{
+ UINT16 Length;
+ UINT16 DisableBit;
+ BOOLEAN NeedRemove;
+ EFI_ACPI_DRHD_ENGINE1_STRUCT *DrhdEngine;
+
+ //
+ // Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE1_STRUCT Pointer
+ //
+ DrhdEngine = (EFI_ACPI_DRHD_ENGINE1_STRUCT *) DrhdEnginePtr;
+ Length = DrhdEngine->DrhdHeader.Header.Length;
+ DisableBit = GetFunDisableBit (
+ DrhdEngine->DeviceScope[0].PciPath.Device,
+ DrhdEngine->DeviceScope[0].PciPath.Function
+ );
+ NeedRemove = FALSE;
+
+ if ((DisableBit == 0xFF) ||
+ (DrhdEngine->DrhdHeader.RegisterBaseAddress == 0) ||
+ ((DisableBit == 0x80) &&
+ (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, DrhdEngine->DeviceScope[0].PciPath.Device, DrhdEngine->DeviceScope[0].PciPath.Function, 0x00)) == 0xFFFFFFFF))
+ ) {
+ NeedRemove = TRUE;
+ }
+ if (NeedRemove) {
+ Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+ }
+ ///
+ /// If no devicescope is left, we set the structure length as 0x00
+ ///
+ if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) || (DrhdEngine->DrhdHeader.Flags == 0x01)) {
+ DrhdEngine->DrhdHeader.Header.Length = Length;
+ } else {
+ DrhdEngine->DrhdHeader.Header.Length = 0;
+ }
+}
+
+/**
+ Get IOAPIC ID from LPC
+
+ @retval APIC ID
+**/
+UINT8
+GetIoApicId (
+ VOID
+ )
+{
+ UINT32 IoApicAddress;
+ UINT32 IoApicId;
+
+ IoApicAddress = PcdGet32 (PcdIoApicBaseAddress);
+ ///
+ /// Get current IO APIC ID
+ ///
+ MmioWrite8 ((UINTN) (IoApicAddress + R_IO_APIC_INDEX_OFFSET), 0);
+ IoApicId = MmioRead32 ((UINTN) (IoApicAddress + R_IO_APIC_DATA_OFFSET)) >> 24;
+
+ return (UINT8) IoApicId;
+}
+
+/**
+ Update the second DRHD structure
+
+ @param[in, out] DrhdEnginePtr - A pointer to DRHD structure
+**/
+VOID
+UpdateDrhd2 (
+ IN OUT VOID *DrhdEnginePtr
+ )
+{
+ UINT16 Length;
+ UINTN DeviceScopeNum;
+ UINTN ValidDeviceScopeNum;
+ UINT16 Index;
+ UINT8 Bus;
+ UINT8 Path[2];
+ BOOLEAN NeedRemove;
+ EFI_ACPI_DRHD_ENGINE3_STRUCT *DrhdEngine;
+ VOID *HobPtr;
+ PCH_INFO_HOB *PchInfoHob;
+
+ ///
+ /// Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE3_STRUCT Pointer
+ ///
+ DrhdEngine = (EFI_ACPI_DRHD_ENGINE3_STRUCT *) DrhdEnginePtr;
+
+ Length = DrhdEngine->DrhdHeader.Header.Length;
+ DeviceScopeNum = (DrhdEngine->DrhdHeader.Header.Length - EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) / sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+ Bus = 0;
+ ValidDeviceScopeNum = 0;
+ Path[0] = 0;
+ Path[1] = 0;
+
+ HobPtr = GetFirstGuidHob (&gPchInfoHobGuid);
+ ASSERT (HobPtr != NULL);
+ if (HobPtr == NULL) {
+ return;
+ }
+ PchInfoHob = (PCH_INFO_HOB *) GET_GUID_HOB_DATA (HobPtr);
+ ASSERT (PchInfoHob != NULL);
+ if (PchInfoHob == NULL) {
+ return;
+ }
+
+ for (Index = 0; Index < DeviceScopeNum; Index++) {
+ NeedRemove = FALSE;
+ /**
+ For HPET and APIC, update device scope if Interrupt remapping is supported. remove device scope
+ if interrupt remapping is not supported.
+ - Index = 0 - IOAPIC
+ - Index = 1 - HPET
+ **/
+ if (mInterruptRemappingSupport) {
+ if (Index == 0) {
+ ///
+ /// Update source id for IoApic's device scope entry
+ ///
+ Bus = (UINT8) PchInfoHob->IoApicBusNum;
+ Path[0] = (UINT8) PchInfoHob->IoApicDevNum;
+ Path[1] = (UINT8) PchInfoHob->IoApicFuncNum;
+ DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNumber = Bus;
+ DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
+ DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
+ //
+ // Update APIC ID
+ //
+ DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.EnumerationId = GetIoApicId ();
+ }
+ if (Index == 1) {
+ ///
+ /// Update source id for HPET's device scope entry
+ ///
+ Bus = (UINT8) PchInfoHob->HpetBusNum;
+ Path[0] = (UINT8) PchInfoHob->HpetDevNum;
+ Path[1] = (UINT8) PchInfoHob->HpetFuncNum;
+ DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNumber = Bus;
+ DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
+ DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
+ }
+ } else {
+ if ((Index == 0) || (Index == 1)) {
+ NeedRemove = TRUE;
+ }
+ }
+
+ CopyMem (
+ &DrhdEngine->DeviceScope[ValidDeviceScopeNum],
+ &DrhdEngine->DeviceScope[Index],
+ sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
+ );
+ if (NeedRemove) {
+ Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+ } else {
+ ValidDeviceScopeNum++;
+ }
+ }
+ ///
+ /// If no devicescope is left, we set the structure length as 0x00
+ ///
+ if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) || (DrhdEngine->DrhdHeader.Flags == 0x01)) {
+ DrhdEngine->DrhdHeader.Header.Length = Length;
+ } else {
+ DrhdEngine->DrhdHeader.Header.Length = 0;
+ }
+}
+
+/**
+ Update the RMRR structure
+
+ @param[in, out] RmrrPtr - A pointer to RMRR structure
+**/
+VOID
+UpdateRmrr (
+ IN OUT VOID *RmrrPtr
+ )
+{
+ UINT16 Length;
+ UINT16 DisableBit;
+ UINTN DeviceScopeNum;
+ UINTN ValidDeviceScopeNum;
+ UINTN Index;
+ BOOLEAN NeedRemove;
+ EFI_ACPI_RMRR_USB_STRUC *Rmrr;
+
+ ///
+ /// To make sure all devicescope can be checked,
+ /// we convert the RmrrPtr to EFI_ACPI_RMRR_USB_STRUC pointer
+ ///
+ Rmrr = (EFI_ACPI_RMRR_USB_STRUC *) RmrrPtr;
+
+ Length = Rmrr->RmrrHeader.Header.Length;
+ ValidDeviceScopeNum = 0;
+ DeviceScopeNum = (Rmrr->RmrrHeader.Header.Length - EFI_ACPI_RMRR_HEADER_LENGTH) / sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+ for (Index = 0; Index < DeviceScopeNum; Index++) {
+ DisableBit = GetFunDisableBit (
+ Rmrr->DeviceScope[Index].PciPath.Device,
+ Rmrr->DeviceScope[Index].PciPath.Function
+ );
+ NeedRemove = FALSE;
+ if ((DisableBit == 0xFF) ||
+ ((DisableBit == 0x80) &&
+ (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, Rmrr->DeviceScope[Index].PciPath.Device, Rmrr->DeviceScope[Index].PciPath.Function, 0x00)) == 0xFFFFFFFF))
+ ) {
+ NeedRemove = TRUE;
+ } else if (DisableBit == 0x8F) {
+ NeedRemove = FALSE;
+ }
+ CopyMem (
+ &Rmrr->DeviceScope[ValidDeviceScopeNum],
+ &Rmrr->DeviceScope[Index],
+ sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
+ );
+
+ if (Rmrr->RmrrHeader.ReservedMemoryRegionLimitAddress == 0x0) {
+ NeedRemove = TRUE;
+ }
+
+ if (NeedRemove) {
+ Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+ } else {
+ ValidDeviceScopeNum++;
+ }
+ }
+ ///
+ /// If No deviceScope is left, set length as 0x00
+ ///
+ if (Length > EFI_ACPI_RMRR_HEADER_LENGTH) {
+ Rmrr->RmrrHeader.Header.Length = Length;
+ } else {
+ Rmrr->RmrrHeader.Header.Length = 0;
+ }
+}
+
+/**
+ Update the DMAR table
+
+ @param[in, out] TableHeader - The table to be set
+ @param[in, out] Version - Version to publish
+**/
+VOID
+DmarTableUpdate (
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader,
+ IN OUT EFI_ACPI_TABLE_VERSION *Version
+ )
+{
+ EFI_ACPI_DMAR_TABLE *DmarTable;
+ EFI_ACPI_DMAR_TABLE TempDmarTable;
+ UINTN Offset;
+ UINTN StructureLen;
+ UINT64 McD0BaseAddress;
+ UINTN MchBar;
+ UINT16 IgdMode;
+ UINT16 GttMode;
+ UINT32 IgdMemSize;
+ UINT32 GttMemSize;
+ EFI_STATUS Status;
+ MISC_DXE_CONFIG *MiscDxeConfig;
+
+ IgdMemSize = 0;
+ GttMemSize = 0;
+ DmarTable = (EFI_ACPI_DMAR_TABLE *) TableHeader;
+
+ Status = GetConfigBlock ((VOID *) mSaPolicy, &gMiscDxeConfigGuid, (VOID *)&MiscDxeConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Set INTR_REMAP bit (BIT 0) if interrupt remapping is supported
+ ///
+ if (mInterruptRemappingSupport) {
+ DmarTable->DmarHeader.Flags |= BIT0;
+ }
+
+ if (mSaConfigHob->VtdData.X2ApicOptOut == 1) {
+ DmarTable->DmarHeader.Flags |= BIT1;
+ } else {
+ DmarTable->DmarHeader.Flags &= 0xFD;
+ }
+
+ ///
+ /// Get OemId
+ ///
+ CopyMem (DmarTable->DmarHeader.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (DmarTable->DmarHeader.Header.OemId));
+ DmarTable->DmarHeader.Header.OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
+ DmarTable->DmarHeader.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
+ DmarTable->DmarHeader.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
+ DmarTable->DmarHeader.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+
+ ///
+ /// Calculate IGD memsize
+ ///
+ McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, 0);
+ MchBar = PciSegmentRead32 (McD0BaseAddress + R_SA_MCHBAR) & ~BIT0;
+ IgdMode = ((PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) & B_SA_GGC_GMS_MASK) >> N_SA_GGC_GMS_OFFSET) & 0xFF;
+ if (IgdMode < 0xF0) {
+ IgdMemSize = IgdMode * 32 * (1024) * (1024);
+ } else {
+ IgdMemSize = 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024);
+ }
+ ///
+ /// Calculate GTT mem size
+ ///
+ GttMemSize = 0;
+ GttMode = (PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) & B_SA_GGC_GGMS_MASK) >> N_SA_GGC_GGMS_OFFSET;
+ if (GttMode <= V_SA_GGC_GGMS_8MB) {
+ GttMemSize = (1 << GttMode) * (1024) * (1024);
+ }
+
+ DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress = (PciSegmentRead32 (McD0BaseAddress + R_SA_TOLUD) & ~(0x01)) - IgdMemSize - GttMemSize;
+ DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress = DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress + IgdMemSize + GttMemSize - 1;
+ DEBUG ((DEBUG_INFO, "RMRR Base address IGD %016lX\n", DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress));
+ DEBUG ((DEBUG_INFO, "RMRR Limit address IGD %016lX\n", DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress));
+
+ DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress = MiscDxeConfig->RmrrUsbBaseAddress[0];
+ DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress = MiscDxeConfig->RmrrUsbBaseAddress[1];
+
+ ///
+ /// Convert to 4KB alignment.
+ ///
+ if (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress != 0x0) {
+ DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
+ DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
+ DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress += 0x1000-1;
+ }
+
+ DEBUG ((DEBUG_INFO, "RMRR Base address USB %016lX\n", DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress));
+ DEBUG ((DEBUG_INFO, "RMRR Limit address USB %016lX\n", DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress));
+
+ if (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress == 0) {
+ DEBUG ((DEBUG_WARN, "WARNING: RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress is 0.\n"));
+ }
+
+ DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress = MiscDxeConfig->RmrrCsmeBaseAddress[0];
+ DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress = MiscDxeConfig->RmrrCsmeBaseAddress[1];
+ DEBUG ((DEBUG_INFO, "RMRR Base address CSME %016lX\n", DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress));
+ DEBUG ((DEBUG_INFO, "RMRR Limit address CSME %016lX\n", DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress));
+ ///
+ /// Update DRHD structures of DmarTable
+ ///
+ DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
+ DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD3_OFFSET) &~1);
+
+ DEBUG ((DEBUG_INFO, "VTD base address1 %x\n", DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress));
+ DEBUG ((DEBUG_INFO, "VTD base address3 %x\n", DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress));
+ ///
+ /// copy DmarTable to TempDmarTable to be processed
+ ///
+ CopyMem (&TempDmarTable, DmarTable, sizeof (EFI_ACPI_DMAR_TABLE));
+
+ ///
+ /// Update DRHD structures of temp DMAR table
+ ///
+ UpdateDrhd (&TempDmarTable.DrhdEngine1);
+ UpdateDrhd2 (&TempDmarTable.DrhdEngine3);
+
+ ///
+ /// Update RMRR structures of temp DMAR table
+ ///
+ UpdateRmrr ((VOID *) &TempDmarTable.RmrrUsb);
+ UpdateRmrr ((VOID *) &TempDmarTable.RmrrIgd);
+ UpdateRmrr ((VOID *) &TempDmarTable.RmrrCsme);
+
+ ///
+ /// Remove unused device scope or entire DRHD structures
+ ///
+ Offset = (UINTN) (&TempDmarTable.DrhdEngine1);
+ if (TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length != 0) {
+ Offset += TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length;
+ }
+ if (TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length != 0) {
+ StructureLen = TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length;
+ CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.DrhdEngine3, TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length);
+ Offset += StructureLen;
+ }
+ ///
+ /// Remove unused device scope or entire RMRR structures
+ ///
+ if (TempDmarTable.RmrrUsb.RmrrHeader.Header.Length != 0) {
+ StructureLen = TempDmarTable.RmrrUsb.RmrrHeader.Header.Length;
+ CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrUsb, TempDmarTable.RmrrUsb.RmrrHeader.Header.Length);
+ Offset += StructureLen;
+ }
+ if (TempDmarTable.RmrrIgd.RmrrHeader.Header.Length != 0) {
+ StructureLen = TempDmarTable.RmrrIgd.RmrrHeader.Header.Length;
+ CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrIgd, TempDmarTable.RmrrIgd.RmrrHeader.Header.Length);
+ Offset += StructureLen;
+ }
+ if (TempDmarTable.RmrrCsme.RmrrHeader.Header.Length != 0) {
+ StructureLen = TempDmarTable.RmrrCsme.RmrrHeader.Header.Length;
+ CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrCsme, TempDmarTable.RmrrCsme.RmrrHeader.Header.Length);
+ Offset += StructureLen;
+ }
+
+ Offset = Offset - (UINTN) &TempDmarTable;
+ ///
+ /// Re-calculate DMAR table check sum
+ ///
+ TempDmarTable.DmarHeader.Header.Checksum = (UINT8) (TempDmarTable.DmarHeader.Header.Checksum + TempDmarTable.DmarHeader.Header.Length - Offset);
+ ///
+ /// Set DMAR table length
+ ///
+ TempDmarTable.DmarHeader.Header.Length = (UINT32) Offset;
+ ///
+ /// Replace DMAR table with rebuilt table TempDmarTable
+ ///
+ CopyMem ((VOID *) DmarTable, (VOID *) &TempDmarTable, TempDmarTable.DmarHeader.Header.Length);
+}
+
+/**
+ PciEnumerationComplete routine for update DMAR
+**/
+VOID
+UpdateDmarPciEnumCompleteCallback (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ EFI_FV_FILETYPE FileType;
+ UINT32 FvStatus;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINTN Size;
+ UINTN i;
+ INTN Instance;
+ EFI_ACPI_TABLE_VERSION Version;
+ EFI_ACPI_COMMON_HEADER *CurrentTable;
+ UINTN AcpiTableHandle;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+ EFI_ACPI_DESCRIPTION_HEADER *VtdAcpiTable;
+ STATIC BOOLEAN Triggered = FALSE;
+
+
+ if (Triggered) {
+ return;
+ }
+
+ Triggered = TRUE;
+
+ FwVol = NULL;
+ AcpiTable = NULL;
+ VtdAcpiTable = NULL;
+
+ DEBUG ((DEBUG_INFO, "UpdateDmarPciEnumCompleteCallback \n"));
+
+
+ ///
+ /// Fix DMAR Table always created, skip install when disabled
+ ///
+ if ((mSaConfigHob->VtdData.VtdDisable == TRUE) || (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MC_CAPID0_A_OFFSET)) & BIT23)) {
+ DEBUG ((DEBUG_INFO, "Vtd Disabled, skip DMAR Table install\n"));
+ return;
+ }
+
+
+ ///
+ /// Locate ACPI support protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+
+ ///
+ /// Locate protocol.
+ /// There is little chance we can't find an FV protocol
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Looking for FV with ACPI storage file
+ ///
+ for (i = 0; i < NumberOfHandles; i++) {
+ ///
+ /// Get the protocol on this handle
+ /// This should not fail because of LocateHandleBuffer
+ ///
+ Status = gBS->HandleProtocol (
+ HandleBuffer[i],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **) &FwVol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// See if it has the ACPI storage file
+ ///
+ Size = 0;
+ FvStatus = 0;
+ Status = FwVol->ReadFile (
+ FwVol,
+ &gSaAcpiTableStorageGuid,
+ NULL,
+ &Size,
+ &FileType,
+ &Attributes,
+ &FvStatus
+ );
+
+ ///
+ /// If we found it, then we are done
+ ///
+ if (Status == EFI_SUCCESS) {
+ break;
+ }
+ }
+ ///
+ /// Our exit status is determined by the success of the previous operations
+ /// If the protocol was found, Instance already points to it.
+ ///
+ ///
+ /// Free any allocated buffers
+ ///
+ FreePool (HandleBuffer);
+
+ ///
+ /// Sanity check that we found our data file
+ ///
+ ASSERT (FwVol);
+ if (FwVol == NULL) {
+ return;
+ }
+ ///
+ /// By default, a table belongs in all ACPI table versions published.
+ ///
+ Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
+
+ ///
+ /// Read tables from the storage file.
+ ///
+ Instance = 0;
+ CurrentTable = NULL;
+
+ while (Status == EFI_SUCCESS) {
+ Status = FwVol->ReadSection (
+ FwVol,
+ &gSaAcpiTableStorageGuid,
+ EFI_SECTION_RAW,
+ Instance,
+ (VOID **) &CurrentTable,
+ &Size,
+ &FvStatus
+ );
+
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// Check the Signature ID to modify the table
+ ///
+ switch (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Signature) {
+
+ case EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE:
+ VtdAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
+ DmarTableUpdate (VtdAcpiTable, &Version);
+ break;
+
+ default:
+ break;
+ }
+ ///
+ /// Increment the instance
+ ///
+ Instance++;
+ CurrentTable = NULL;
+ }
+ }
+ ///
+ /// Update the VTD table in the ACPI tables.
+ ///
+ AcpiTableHandle = 0;
+ if (VtdAcpiTable != NULL) {
+ Status = AcpiTable->InstallAcpiTable (
+ AcpiTable,
+ VtdAcpiTable,
+ VtdAcpiTable->Length,
+ &AcpiTableHandle
+ );
+ FreePool (VtdAcpiTable);
+ }
+}
+
+/**
+ Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
+ Publish the appropriate SSDT based on current configuration and capabilities.
+
+ @param[in] SaPolicy - SA DXE Policy protocol
+
+ @retval EFI_SUCCESS - Vtd initialization complete
+ @exception EFI_UNSUPPORTED - Vtd is not enabled by policy
+**/
+EFI_STATUS
+VtdInit (
+ IN SA_POLICY_PROTOCOL *SaPolicy
+ )
+{
+ EFI_STATUS Status;
+ UINT64 McD0BaseAddress;
+ UINT64 McD2BaseAddress;
+ UINTN MchBar;
+ SYSTEM_AGENT_NVS_AREA_PROTOCOL *SaNvsAreaProtocol;
+
+ mInterruptRemappingSupport = FALSE;
+ mSaConfigHob = NULL;
+ mSaConfigHob = GetFirstGuidHob (&gSaConfigHobGuid);
+ if (mSaConfigHob != NULL) {
+ mInterruptRemappingSupport = mSaConfigHob->VtdData.InterruptRemappingSupport;
+ }
+
+ ///
+ /// Locate the SA Global NVS Protocol.
+ ///
+ Status = gBS->LocateProtocol (
+ &gSaNvsAreaProtocolGuid,
+ NULL,
+ (VOID **) &SaNvsAreaProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, 0);
+ McD2BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0);
+ mSaPolicy = SaPolicy;
+ MchBar = PciSegmentRead32(McD0BaseAddress + R_SA_MCHBAR) & ~BIT0;
+
+ if (mSaConfigHob != NULL) {
+ SaNvsAreaProtocol->Area->VtdDisable = mSaConfigHob->VtdData.VtdDisable;
+ }
+ SaNvsAreaProtocol->Area->VtdBaseAddress1 = (MmioRead32(MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
+ SaNvsAreaProtocol->Area->VtdBaseAddress3 = (MmioRead32(MchBar + R_SA_MCHBAR_VTD3_OFFSET) &~1);
+ SaNvsAreaProtocol->Area->VtdEngine1Vid = PciSegmentRead16(McD2BaseAddress + PCI_VENDOR_ID_OFFSET);
+
+ if (mSaConfigHob != NULL) {
+ if ((mSaConfigHob->VtdData.VtdDisable) || (PciSegmentRead32 (McD0BaseAddress + R_SA_MC_CAPID0_A_OFFSET) & BIT23)) {
+ DEBUG ((DEBUG_WARN, "VTd disabled or no capability!\n"));
+ return EFI_UNSUPPORTED;
+ }
+ }
+ ///
+ /// Check SA supports VTD and VTD is enabled in setup menu
+ ///
+ DEBUG ((DEBUG_INFO, "VTd enabled\n"));
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c
new file mode 100644
index 0000000000..08fd9266c6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c
@@ -0,0 +1,356 @@
+/** @file
+ This is the driver that publishes the SMM Access Protocol
+ instance for System Agent.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SmmAccessDriver.h"
+
+static SMM_ACCESS_PRIVATE_DATA mSmmAccess;
+
+
+/**
+ This is the standard EFI driver point that
+ installs an SMM Access Protocol
+
+ @param[in] ImageHandle - Handle for the image of this driver
+ @param[in] SystemTable - Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS - Protocol was installed successfully
+ @exception EFI_UNSUPPORTED - Protocol was not installed
+ @retval EFI_NOT_FOUND - Protocol can't be found.
+ @retval EFI_OUT_OF_RESOURCES - Protocol does not have enough resources to initialize the driver.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock;
+ EFI_PEI_HOB_POINTERS *Hob;
+
+ ///
+ /// --cr-- INITIALIZE_SCRIPT (ImageHandle, SystemTable);
+ ///
+ /// Initialize Global variables
+ ///
+ ZeroMem (&mSmmAccess, sizeof (mSmmAccess));
+
+ mSmmAccess.Signature = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
+ mSmmAccess.Handle = NULL;
+
+ ///
+ /// Get Hob list
+ ///
+ Hob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
+ if (Hob == NULL) {
+ DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ DescriptorBlock = (VOID *) ((UINT8 *) Hob + sizeof (EFI_HOB_GUID_TYPE));
+
+ ///
+ /// Alloc space for mSmmAccess.SmramDesc
+ ///
+ mSmmAccess.SmramDesc = AllocateZeroPool ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof (EFI_SMRAM_DESCRIPTOR));
+ if (mSmmAccess.SmramDesc == NULL) {
+ DEBUG ((DEBUG_WARN, "Alloc mSmmAccess.SmramDesc fail.\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DEBUG ((DEBUG_INFO, "Alloc mSmmAccess.SmramDesc success.\n"));
+
+ ///
+ /// Use the HOB to publish SMRAM capabilities
+ ///
+ for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+ mSmmAccess.SmramDesc[Index].PhysicalStart = DescriptorBlock->Descriptor[Index].PhysicalStart;
+ mSmmAccess.SmramDesc[Index].CpuStart = DescriptorBlock->Descriptor[Index].CpuStart;
+ mSmmAccess.SmramDesc[Index].PhysicalSize = DescriptorBlock->Descriptor[Index].PhysicalSize;
+ mSmmAccess.SmramDesc[Index].RegionState = DescriptorBlock->Descriptor[Index].RegionState;
+ }
+
+ mSmmAccess.NumberRegions = Index;
+ mSmmAccess.SmmAccess.Open = Open;
+ mSmmAccess.SmmAccess.Close = Close;
+ mSmmAccess.SmmAccess.Lock = Lock;
+ mSmmAccess.SmmAccess.GetCapabilities = GetCapabilities;
+ mSmmAccess.SmmAccess.LockState = FALSE;
+ mSmmAccess.SmmAccess.OpenState = FALSE;
+
+ ///
+ /// Install our protocol interfaces on the device's handle
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mSmmAccess.Handle,
+ &gEfiSmmAccess2ProtocolGuid,
+ &mSmmAccess.SmmAccess,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "InstallMultipleProtocolInterfaces returned %r\n", Status));
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This routine accepts a request to "open" a region of SMRAM. The
+ region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+ The use of "open" means that the memory is visible from all boot-service
+ and SMM agents.
+
+ @param[in] This - Pointer to the SMM Access Interface.
+
+ @retval EFI_SUCCESS - The region was successfully opened.
+ @retval EFI_DEVICE_ERROR - The region could not be opened because locked by
+ chipset.
+ @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Open (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ )
+{
+ SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+ UINT64 Address;
+ UINT8 SmramControl;
+ UINTN DescriptorIndex;
+
+ SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+ for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+ if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+ DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ ///
+ /// BEGIN CHIPSET SPECIFIC CODE
+ ///
+ ///
+ /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
+ ///
+ Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+
+ SmramControl = PciRead8 (Address);
+ ///
+ /// Is SMRAM locked?
+ ///
+ for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+ if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
+ ///
+ /// Cannot Open a locked region
+ ///
+ SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+ DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ ///
+ /// Open SMRAM region
+ ///
+ SmramControl |= B_SA_SMRAMC_D_OPEN_MASK;
+ SmramControl &= ~(B_SA_SMRAMC_D_CLS_MASK);
+
+ PciWrite8 (Address, SmramControl);
+ ///
+ /// END CHIPSET SPECIFIC CODE
+ ///
+ for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+ SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64) ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+ SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) EFI_SMRAM_OPEN;
+ }
+ SmmAccess->SmmAccess.OpenState = TRUE;
+ return EFI_SUCCESS;
+}
+
+/**
+ This routine accepts a request to "close" a region of SMRAM. The
+ region could be legacy AB or TSEG near top of physical memory.
+ The use of "close" means that the memory is only visible from SMM agents,
+ not from BS or RT code.
+
+ @param[in] This - Pointer to the SMM Access Interface.
+
+ @retval EFI_SUCCESS - The region was successfully closed.
+ @retval EFI_DEVICE_ERROR - The region could not be closed because locked by chipset.
+ @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ )
+{
+ SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+ UINT64 Address;
+ UINT8 SmramControl;
+ BOOLEAN OpenState;
+ UINT8 Index;
+ UINTN DescriptorIndex;
+
+ SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+ for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+ if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+ DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
+ continue;
+ }
+
+ ///
+ /// BEGIN CHIPSET SPECIFIC CODE
+ ///
+ ///
+ /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
+ ///
+ Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+
+ SmramControl = PciRead8 (Address);
+ ///
+ /// Is SMRAM locked?
+ ///
+ if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
+ ///
+ /// Cannot Close a locked region
+ ///
+ SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+ DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// Close SMRAM region
+ ///
+ SmramControl &= ~(B_SA_SMRAMC_D_OPEN_MASK);
+
+ PciWrite8 (Address, SmramControl);
+ ///
+ /// END CHIPSET SPECIFIC CODE
+ ///
+ SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64) ~EFI_SMRAM_OPEN;
+ SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+ }
+
+ ///
+ /// Find out if any regions are still open
+ ///
+ OpenState = FALSE;
+ for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
+ if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) == EFI_SMRAM_OPEN) {
+ OpenState = TRUE;
+ }
+ }
+
+ SmmAccess->SmmAccess.OpenState = OpenState;
+ return EFI_SUCCESS;
+}
+
+/**
+ This routine accepts a request to "lock" SMRAM. The
+ region could be legacy AB or TSEG near top of physical memory.
+ The use of "lock" means that the memory can no longer be opened
+ to BS state..
+
+ @param[in] This - Pointer to the SMM Access Interface.
+
+ @retval EFI_SUCCESS - The region was successfully locked.
+ @retval EFI_DEVICE_ERROR - The region could not be locked because at least
+ one range is still open.
+ @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Lock (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ )
+{
+ SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+ UINT64 Address;
+ UINT8 SmramControl;
+ UINTN DescriptorIndex;
+
+ SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+ if (SmmAccess->SmmAccess.OpenState) {
+ DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are still open\n"));
+ return EFI_DEVICE_ERROR;
+ }
+ for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+ SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+ }
+ SmmAccess->SmmAccess.LockState = TRUE;
+
+ ///
+ /// BEGIN CHIPSET SPECIFIC CODE
+ ///
+ ///
+ /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
+ ///
+ Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+
+ SmramControl = PciRead8 (Address);
+ ///
+ /// Lock the SMRAM
+ ///
+ SmramControl |= B_SA_SMRAMC_D_LCK_MASK;
+
+ PciWrite8 (Address, SmramControl);
+ ///
+ /// END CHIPSET SPECIFIC CODE
+ ///
+ return EFI_SUCCESS;
+}
+
+/**
+ This routine services a user request to discover the SMRAM
+ capabilities of this platform. This will report the possible
+ ranges that are possible for SMRAM access, based upon the
+ memory controller capabilities.
+
+ @param[in] This - Pointer to the SMRAM Access Interface.
+ @param[in] SmramMapSize - Pointer to the variable containing size of the
+ buffer to contain the description information.
+ @param[in] SmramMap - Buffer containing the data describing the Smram
+ region descriptors.
+
+ @retval EFI_BUFFER_TOO_SMALL - The user did not provide a sufficient buffer.
+ @retval EFI_SUCCESS - The user provided a sufficiently-sized buffer.
+**/
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+ IN CONST EFI_SMM_ACCESS2_PROTOCOL *This,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+ )
+{
+ EFI_STATUS Status;
+ SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+ UINTN NecessaryBufferSize;
+
+ SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+ NecessaryBufferSize = SmmAccess->NumberRegions * sizeof (EFI_SMRAM_DESCRIPTOR);
+
+ if (*SmramMapSize < NecessaryBufferSize) {
+ DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else {
+ CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
+ Status = EFI_SUCCESS;
+ }
+
+ *SmramMapSize = NecessaryBufferSize;
+
+ return Status;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
new file mode 100644
index 0000000000..c864a0ca8f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
@@ -0,0 +1,250 @@
+/** @file
+ This file describes the contents of the ACPI DMA address Remapping
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Dmar.h"
+#include <Register/PchRegsP2sb.h>
+
+EFI_ACPI_DMAR_TABLE DmarTable = {
+ //
+ // EFI_ACPI_DMAR_HEADER
+ //
+ {
+ //
+ // EFI_ACPI_DESCRIPTION_HEADER
+ //
+ {
+ EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE,
+ sizeof (EFI_ACPI_DMAR_TABLE),
+ EFI_ACPI_DMAR_TABLE_REVISION,
+
+ //
+ // Checksum will be updated at runtime
+ //
+ 0x00,
+
+ //
+ // It is expected that these values will be programmed at runtime
+ //
+ { 'I', 'N', 'T', 'E', 'L', ' ' },
+ EFI_ACPI_DMAR_OEM_TABLE_ID,
+ 0x1,
+ EFI_ACPI_DMAR_OEM_CREATOR_ID,
+ 1
+ },
+
+ //
+ // DMAR table specific entries below:
+ //
+
+ //
+ // 39-bit addressing Host Address Width
+ //
+ 38,
+
+ //
+ // Flags
+ //
+ 0,
+
+ //
+ // Reserved fields
+ //
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+
+ //
+ // First DRHD structure, VT-d Engine #1
+ //
+ {
+ //
+ // EFI_ACPI_DMAR_DRHD_HEADER
+ //
+ {
+ {0, // Type = 0 (DRHD)
+ sizeof (EFI_ACPI_DRHD_ENGINE1_STRUCT)}, // Length of structure
+ 0, // Flag - Do not include all
+ 0, // Reserved fields
+ 0, // Segment
+ 0 // Base address of DMA-remapping hardware - Updated at boot time
+ },
+ //
+ // Device Scopes
+ //
+ {
+ {
+ {1, // Type
+ sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+ 0, // Segment number
+ 0, // Reserved
+ 0}, // Start bus number
+ {2, 0} // PCI path
+ }
+ }
+ },
+
+ //
+ //Third DRHD structure VT-d Engine# 3
+ //
+ {
+ //
+ // EFI_ACPI_DMAR_DRHD_HEADER
+ //
+ {
+ {0, // Type = 0 (DRHD)
+ sizeof (EFI_ACPI_DRHD_ENGINE3_STRUCT)}, // Length of strucure.
+ 1, // Flag - Include all
+ 0, // Reserved
+ 0, // Segment Number
+ 0 // Base address of DMA-remapping hardware.
+ },
+ {
+ //
+ // Device Scopes
+ //
+ {
+ {3, // Type=IO APIC
+ sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+ 0, // Reserved
+ 2, // Enumeration ID
+ V_P2SB_CFG_IBDF_BUS}, // Start bus number
+ {V_P2SB_CFG_IBDF_DEV, V_P2SB_CFG_IBDF_FUNC} // PCI path
+ },
+ //
+ // Device Scopes
+ //
+ {
+ {4, // Type=HPET
+ sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+ 0, // Reserved
+ 0, // Enumeration ID
+ V_P2SB_CFG_HBDF_BUS}, // Start bus number
+ {V_P2SB_CFG_HBDF_DEV, V_P2SB_CFG_HBDF_FUNC} // PCI path
+ }
+ }
+ },
+ //RMRR structure for USB devices.
+ {
+ //
+ // EFI_ACPI_DMAR_RMRR_HEADER
+ //
+ {
+ {
+ 0x1, // Type 1 - RMRR structure
+ sizeof(EFI_ACPI_RMRR_USB_STRUC) // Length
+ },
+ { 0x00, 0x00 }, // Reserved
+ 0x0000, // Segment Num
+ 0x00000000000E0000, // RMRR Base address - Updated in runtime.
+ 0x00000000000EFFFF // RMRR Limit address - Updated in runtime.
+ },
+ //
+ // Device Scopes
+ //
+ {
+ {
+ {1, // Type
+ sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+ 0, // Reserved
+ 0, // Enum ID
+ 0}, // Start bus number
+ {20, 0} // PCI path
+ },
+ {
+ {1, // Type
+ sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+ 0, // Reserved
+ 0, // Enum ID
+ 0}, // Start bus number
+ {20, 1} // PCI path
+ }
+ }
+ },
+
+ //RMRR structure for IGD device.
+ {
+ //
+ // EFI_ACPI_DMAR_RMRR_HEADER
+ //
+ {
+ {1, // Type 1 - RMRR structure
+ sizeof (EFI_ACPI_RMRR_IGD_STRUC)}, // Length
+ {0x0000}, // Reserved
+ 0x0000, // Segment Num
+ 0x0000000000000000, // RMRR Base address - Updated in runtime.
+ 0x0000000000000000 // RMRR Limit address - Updated in runtime.
+ },
+ //
+ // Device Scopes
+ //
+ {
+ {
+ {1, // Type
+ sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+ 0, // Reserved
+ 0, // Enum ID
+ 0}, // Start bus number
+ {2, 0} // PCI path
+ }
+ }
+ },
+
+ // RMRR structure for WiAMT DMA access.
+ // Keep this device in end of RMRR queue.
+ {
+ //
+ // EFI_ACPI_DMAR_RMRR_HEADER
+ //
+ {
+ {1, // Type 1 - RMRR structure
+ sizeof (EFI_ACPI_RMRR_CSME_STRUC)}, // Length
+ {0x0000}, // Reserved
+ 0x0000, // Segment Num
+ 0x0000000000000000, // RMRR Base address - Updated in runtime.
+ 0x0000000000000000 // RMRR Limit address - Updated in runtime.
+ },
+ //
+ // Device Scopes
+ //
+ {
+ {
+ {1, // Type
+ sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+ 0, // Reserved
+ 0, // Enum ID
+ 0}, // Start bus number
+ {22, 7} // PCI path
+ }
+ }
+ }
+};
+
+//
+// Dummy function required for build tools
+//
+#if defined (__GNUC__)
+VOID*
+ReferenceAcpiTable (
+ VOID
+ )
+
+{
+ //
+ // Reference the table being generated to prevent the optimizer from removing the
+ // data structure from the exeutable
+ //
+ return (VOID*)&DmarTable;
+}
+#else
+int
+main (
+ VOID
+ )
+{
+ return 0;
+}
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
new file mode 100644
index 0000000000..b431a77f05
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
@@ -0,0 +1,794 @@
+/** @file
+ This file contains the SystemAgent PCI Configuration space
+ definition.
+ It defines various System Agent PCI Configuration Space registers
+ which will be used to dynamically produce all resources in the Host Bus.
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(M64B)
+External(M64L)
+External(M32B)
+External(M32L)
+
+//
+// Define various System Agent (SA) PCI Configuration Space
+// registers which will be used to dynamically produce all
+// resources in the Host Bus _CRS.
+//
+OperationRegion (HBUS, PCI_Config, 0x00, 0x100)
+Field (HBUS, DWordAcc, NoLock, Preserve)
+{
+ Offset(0x40), // EPBAR (0:0:0:40)
+ EPEN, 1, // Enable
+ , 11,
+ EPBR, 20, // EPBAR [31:12]
+
+ Offset(0x48), // MCHBAR (0:0:0:48)
+ MHEN, 1, // Enable
+ , 14,
+ MHBR, 17, // MCHBAR [31:15]
+
+ Offset(0x50), // GGC (0:0:0:50)
+ GCLK, 1, // GGCLCK
+
+ Offset(0x54), // DEVEN (0:0:0:54)
+ D0EN, 1, // DEV0 Enable
+ D1F2, 1, // DEV1 FUN2 Enable
+ D1F1, 1, // DEV1 FUN1 Enable
+ D1F0, 1, // DEV1 FUN0 Enable
+
+ Offset(0x60), // PCIEXBAR (0:0:0:60)
+ PXEN, 1, // Enable
+ PXSZ, 2, // PCI Express Size
+ , 23,
+ PXBR, 6, // PCI Express BAR [31:26]
+
+ Offset(0x68), // DMIBAR (0:0:0:68)
+ DIEN, 1, // Enable
+ , 11,
+ DIBR, 20, // DMIBAR [31:12]
+
+ Offset(0x70), // MESEG_BASE (0:0:0:70)
+ , 20,
+ MEBR, 12, // MESEG_BASE [31:20]
+
+ Offset(0x80), // PAM0 Register (0:0:0:80)
+ PMLK, 1, // PAM Lock bit.
+ , 3,
+ PM0H, 2, // PAM 0, High Nibble
+ , 2,
+
+ Offset(0x81), // PAM1 Register (0:0:0:81)
+ PM1L, 2, // PAM1, Low Nibble
+ , 2,
+ PM1H, 2, // PAM1, High Nibble
+ , 2,
+
+ Offset(0x82), // PAM2 Register (0:0:0:82)
+ PM2L, 2, // PAM2, Low Nibble
+ , 2,
+ PM2H, 2, // PAM2, High Nibble
+ , 2,
+
+ Offset(0x83), // PAM3 Register (0:0:0:83)
+ PM3L, 2, // PAM3, Low Nibble
+ , 2,
+ PM3H, 2, // PAM3, High Nibble
+ , 2,
+
+ Offset(0x84), // PAM4 Register (0:0:0:84)
+ PM4L, 2, // PAM4, Low Nibble
+ , 2,
+ PM4H, 2, // PAM4, High Nibble
+ , 2,
+
+ Offset(0x85), // PAM5 Register (0:0:0:85)
+ PM5L, 2, // PAM5, Low Nibble
+ , 2,
+ PM5H, 2, // PAM5, High Nibble
+ , 2,
+
+ Offset(0x86), // PAM6 Register (0:0:0:86)
+ PM6L, 2, // PAM6, Low Nibble
+ , 2,
+ PM6H, 2, // PAM6, High Nibble
+ , 2,
+
+ Offset(0xA8), // Top of Upper Usable DRAM Register (0:0:0:A8)
+ , 20,
+ TUUD, 19, // TOUUD [38:20]
+
+ Offset(0xBC), // Top of Lower Usable DRAM Register (0:0:0:BC)
+ , 20,
+ TLUD, 12, // TOLUD [31:20]
+
+ Offset(0xC8), // ERRSTS register (0:0:0:C8)
+ , 7,
+ HTSE, 1 // Host Thermal Sensor Event for SMI/SCI/SERR
+}
+//
+// Define a buffer that will store all the bus, memory, and IO information
+// relating to the Host Bus. This buffer will be dynamically altered in
+// the _CRS and passed back to the OS.
+//
+Name(BUF0,ResourceTemplate()
+{
+ //
+ // Bus Number Allocation: Bus 0 to 0xFF
+ //
+ WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00,
+ 0x0000,0x00FF,0x00,0x0100,,,PB00)
+
+ //
+ // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 )
+ //
+ DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+ 0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00)
+
+ //
+ // PCI Configuration Registers ( 0x0CF8 - 0x0CFF )
+ //
+ Io(Decode16,0x0CF8,0x0CF8,1,0x08)
+
+ //
+ // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF )
+ //
+ DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+ 0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01)
+
+ //
+ // Video Buffer Area ( 0xA0000 - 0xBFFFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000)
+
+ //
+ // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000)
+
+ //
+ // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400)
+
+ //
+ // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800)
+
+ //
+ // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00)
+
+ //
+ // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000)
+
+ //
+ // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400)
+
+ //
+ // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800)
+
+ //
+ // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00)
+
+ //
+ // BIOS Extension Area ( 0xE0000 - 0xE3FFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000)
+
+ //
+ // BIOS Extension Area ( 0xE4000 - 0xE7FFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400)
+
+ //
+ // BIOS Extension Area ( 0xE8000 - 0xEBFFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800)
+
+ //
+ // BIOS Extension Area ( 0xEC000 - 0xEFFFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00)
+
+ //
+ // BIOS Area ( 0xF0000 - 0xFFFFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+ ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000)
+
+// //
+// // Memory Hole Region ( 0xF00000 - 0xFFFFFF )
+// //
+// DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+// ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE)
+
+ //
+ // PCI Memory Region ( TOLUD - 0xDFFFFFFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+ ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01)
+
+ //
+ // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) )
+ // (This is dummy range for OS compatibility, will patch it in _CRS)
+ //
+ QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+ ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
+
+ //
+ // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
+ //
+ DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+ ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03)
+})
+
+ //
+ // SA reserved resources
+ //
+ Device(SRRE) {
+ Name(_HID,EISAID("PNP0C02")) // motherboard resource
+ Name(_UID,"SARESV")
+ Method(_STA,0,Serialized) // device present and decodes its resources, but not to be displayed in OSPM
+ {
+ If(LGreaterEqual(TLUD, 0x404)) {
+ Return (3)
+ } Else {
+ Return (0)
+ }
+ }
+
+ Method(_CRS,0,Serialized)
+ {
+ Name(BUF0,ResourceTemplate(){
+ //
+ // Reserve the 0x40000000 ~ 0x403FFFFF to prevent other driver use this memory range
+ //
+ Memory32Fixed(ReadOnly,0x40000000,0x400000)
+ })
+ If(LGreaterEqual(TLUD, 0x404)) {
+ Return (BUF0)
+ } Else {
+ Return (Buffer(){})
+ }
+ }
+ }
+
+Name(EP_B, 0) // to store EP BAR
+Name(MH_B, 0) // to store MCH BAR
+Name(PC_B, 0) // to store PCIe BAR
+Name(PC_L, 0) // to store PCIe BAR Length
+Name(DM_B, 0) // to store DMI BAR
+
+//
+// Get EP BAR
+//
+Method(GEPB,0,Serialized)
+{
+ if(LEqual(EP_B,0))
+ {
+ ShiftLeft(\_SB.PCI0.EPBR,12,EP_B)
+ }
+ Return(EP_B)
+}
+
+//
+// Get MCH BAR
+//
+Method(GMHB,0,Serialized)
+{
+ if(LEqual(MH_B,0))
+ {
+ ShiftLeft(\_SB.PCI0.MHBR,15,MH_B)
+ }
+ Return(MH_B)
+}
+
+//
+// Get PCIe BAR
+//
+Method(GPCB,0,Serialized)
+{
+ if(LEqual(PC_B,0))
+ {
+ ShiftLeft(\_SB.PCI0.PXBR,26,PC_B)
+ }
+ Return(PC_B)
+}
+
+//
+// Get PCIe Length
+//
+Method(GPCL,0,Serialized)
+{
+ if(LEqual(PC_L,0)) {
+ ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L)
+ }
+ Return(PC_L)
+}
+
+//
+// Get DMI BAR
+//
+Method(GDMB,0,Serialized)
+{
+ if(LEqual(DM_B,0))
+ {
+ ShiftLeft(\_SB.PCI0.DIBR,12,DM_B)
+ }
+ Return(DM_B)
+}
+
+
+Method(_CRS,0,Serialized)
+{
+ //
+ // Fix up Max Bus Number and Length
+ //
+ Store(\_SB.PCI0.GPCL(),Local0)
+ CreateWordField(BUF0, ^PB00._MAX, PBMX)
+ Store(Subtract(ShiftRight(Local0,20),2), PBMX)
+ CreateWordField(BUF0, ^PB00._LEN, PBLN)
+ Store(Subtract(ShiftRight(Local0,20),1), PBLN)
+ //
+ // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF.
+ //
+ If(PM1L) // \_SB.PCI0
+ {
+ // PAMx != 0. Set length = 0.
+
+ CreateDwordField(BUF0, ^C000._LEN,C0LN)
+ Store(Zero,C0LN)
+ }
+
+ If(LEqual(PM1L,1))
+ {
+ CreateBitField(BUF0, ^C000._RW,C0RW)
+ Store(Zero,C0RW)
+ }
+
+ If(PM1H)
+ {
+ CreateDwordField(BUF0, ^C400._LEN,C4LN)
+ Store(Zero,C4LN)
+ }
+
+ If(LEqual(PM1H,1))
+ {
+ CreateBitField(BUF0, ^C400._RW,C4RW)
+ Store(Zero,C4RW)
+ }
+
+ If(PM2L)
+ {
+ CreateDwordField(BUF0, ^C800._LEN,C8LN)
+ Store(Zero,C8LN)
+ }
+
+ If(LEqual(PM2L,1))
+ {
+ CreateBitField(BUF0, ^C800._RW,C8RW)
+ Store(Zero,C8RW)
+ }
+
+ If(PM2H)
+ {
+ CreateDwordField(BUF0, ^CC00._LEN,CCLN)
+ Store(Zero,CCLN)
+ }
+
+ If(LEqual(PM2H,1))
+ {
+ CreateBitField(BUF0, ^CC00._RW,CCRW)
+ Store(Zero,CCRW)
+ }
+
+ If(PM3L)
+ {
+ CreateDwordField(BUF0, ^D000._LEN,D0LN)
+ Store(Zero,D0LN)
+ }
+
+ If(LEqual(PM3L,1))
+ {
+ CreateBitField(BUF0, ^D000._RW,D0RW)
+ Store(Zero,D0RW)
+ }
+
+ If(PM3H)
+ {
+ CreateDwordField(BUF0, ^D400._LEN,D4LN)
+ Store(Zero,D4LN)
+ }
+
+ If(LEqual(PM3H,1))
+ {
+ CreateBitField(BUF0, ^D400._RW,D4RW)
+ Store(Zero,D4RW)
+ }
+
+ If(PM4L)
+ {
+ CreateDwordField(BUF0, ^D800._LEN,D8LN)
+ Store(Zero,D8LN)
+ }
+
+ If(LEqual(PM4L,1))
+ {
+ CreateBitField(BUF0, ^D800._RW,D8RW)
+ Store(Zero,D8RW)
+ }
+
+ If(PM4H)
+ {
+ CreateDwordField(BUF0, ^DC00._LEN,DCLN)
+ Store(Zero,DCLN)
+ }
+
+ If(LEqual(PM4H,1))
+ {
+ CreateBitField(BUF0, ^DC00._RW,DCRW)
+ Store(Zero,DCRW)
+ }
+
+ If(PM5L)
+ {
+ CreateDwordField(BUF0, ^E000._LEN,E0LN)
+ Store(Zero,E0LN)
+ }
+
+ If(LEqual(PM5L,1))
+ {
+ CreateBitField(BUF0, ^E000._RW,E0RW)
+ Store(Zero,E0RW)
+ }
+
+ If(PM5H)
+ {
+ CreateDwordField(BUF0, ^E400._LEN,E4LN)
+ Store(Zero,E4LN)
+ }
+
+ If(LEqual(PM5H,1))
+ {
+ CreateBitField(BUF0, ^E400._RW,E4RW)
+ Store(Zero,E4RW)
+ }
+
+ If(PM6L)
+ {
+ CreateDwordField(BUF0, ^E800._LEN,E8LN)
+ Store(Zero,E8LN)
+ }
+
+ If(LEqual(PM6L,1))
+ {
+ CreateBitField(BUF0, ^E800._RW,E8RW)
+ Store(Zero,E8RW)
+ }
+
+ If(PM6H)
+ {
+ CreateDwordField(BUF0, ^EC00._LEN,ECLN)
+ Store(Zero,ECLN)
+ }
+
+ If(LEqual(PM6H,1))
+ {
+ CreateBitField(BUF0, ^EC00._RW,ECRW)
+ Store(Zero,ECRW)
+ }
+
+ If(PM0H)
+ {
+ CreateDwordField(BUF0, ^F000._LEN,F0LN)
+ Store(Zero,F0LN)
+ }
+
+ If(LEqual(PM0H,1))
+ {
+ CreateBitField(BUF0, ^F000._RW,F0RW)
+ Store(Zero,F0RW)
+ }
+
+ // Enable the 1MB region between 15-16MB if HENA = 1.
+ //
+ // If( MCHC.HENA)
+ // {
+ // CreateDwordField(BUF0, HOLE._LEN,H0LN)
+ // Store(0x100000,H0LN)
+ // }
+
+ //
+ // Create pointers to Memory Sizing values.
+ //
+ CreateDwordField(BUF0, ^PM01._MIN,M1MN)
+ CreateDwordField(BUF0, ^PM01._MAX,M1MX)
+ CreateDwordField(BUF0, ^PM01._LEN,M1LN)
+
+ //
+ // Set Memory Size Values. TLUD represents bits 31:20 of phyical
+ // TOM, so shift these bits into the correct position and fix up
+ // the Memory Region available to PCI.
+ //
+ Store (M32L, M1LN)
+ Store (M32B, M1MN)
+ Subtract (Add (M1MN, M1LN), 1, M1MX)
+
+ //
+ // Create pointers to Memory Sizing values.
+ // Patch PM02 range basing on memory size and OS type
+ //
+ If (LEqual(M64L, 0)) {
+ CreateQwordField(BUF0, ^PM02._LEN,MSLN)
+ //
+ // Set resource length to 0
+ //
+ Store (0, MSLN)
+ }
+ Else {
+ CreateQwordField(BUF0, ^PM02._LEN,M2LN)
+ CreateQwordField(BUF0, ^PM02._MIN,M2MN)
+ CreateQwordField(BUF0, ^PM02._MAX,M2MX)
+ //
+ // Set 64bit MMIO resource Base and Length
+ //
+ Store (M64L, M2LN)
+ Store (M64B, M2MN)
+ Subtract (Add (M2MN, M2LN), 1, M2MX)
+ }
+ Return(BUF0)
+}
+
+//
+//Name(GUID,UUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))
+//
+Name(GUID,Buffer(){0x5b, 0x4d, 0xdb, 0x33,
+ 0xf7, 0x1f,
+ 0x1c, 0x40,
+ 0x96, 0x57,
+ 0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66})
+
+
+Name(SUPP,0) // PCI _OSC Support Field value
+Name(CTRL,0) // PCI _OSC Control Field value
+Name(XCNT, 0) // Variable used in _OSC for counting
+
+Method(_OSC,4,Serialized)
+{
+ //
+ // Check for proper UUID
+ // Save the capabilities buffer
+ //
+ Store(Arg3,Local0)
+
+ //
+ // Create DWord-adressable fields from the Capabilties Buffer
+ //
+ CreateDWordField(Local0,0,CDW1)
+ CreateDWordField(Local0,4,CDW2)
+ CreateDWordField(Local0,8,CDW3)
+
+
+ //
+ // Check for proper UUID
+ //
+ If(LEqual(Arg0,GUID))
+ {
+ // Save Capabilities DWord2 & 3
+ Store(CDW2,SUPP)
+ Store(CDW3,CTRL)
+
+ //
+ // You can clear bits in CTRL here if you don't want OS to take
+ // control
+ //
+ If(LNot(NEXP))
+ {
+ And(CTRL, 0xFFFFFFF8, CTRL) // disable Native hot plug, PME
+ }
+
+ If(LEqual(TBTS, 1)) {
+ // \_OSC disallow only Advanced Error Reporting control
+ And(CTRL, 0xFFFFFFF7, CTRL)
+ }
+
+ If(Not(And(CDW1,1))) // Query flag clear?
+ { // Disable GPEs for features granted native control.
+ If(And(CTRL,0x01))
+ {
+ NHPG()
+ }
+ If(And(CTRL,0x04)) // PME control granted?
+ {
+ NPME()
+ }
+ }
+
+ If(LNotEqual(Arg1,One))
+ {
+ //
+ // Unknown revision
+ //
+ Or(CDW1,0x08,CDW1)
+ }
+
+ If(LNotEqual(CDW3,CTRL))
+ {
+ //
+ // Capabilities bits were masked
+ //
+ Or(CDW1,0x10,CDW1)
+ }
+ //
+ // Update DWORD3 in the buffer
+ //
+ Store(CTRL,CDW3)
+ Store(CTRL,OSCC)
+ Return(Local0)
+ } Else {
+ Or(CDW1,4,CDW1) // Unrecognized UUID
+ Return(Local0)
+ }
+} // End _OSC
+
+//
+// Added code for Dual IRQ support. Two set of ACPI IRQ tables were generated.
+// Code has been added to select the appropriate IRQ table by checking the CPUID.
+//
+Scope(\_SB.PCI0)
+{
+ Method(AR00) {
+ Return(\_SB.AR00)
+ }
+
+ Method(PD00) {
+ Return(\_SB.PD00)
+ }
+
+ Method(AR02) {
+ Return(\_SB.AR02)
+ }
+
+ Method(PD02) {
+ Return(\_SB.PD02)
+ }
+
+ Method(AR04) {
+ Return(\_SB.AR04)
+ }
+
+ Method(PD04) {
+ Return(\_SB.PD04)
+ }
+
+ Method(AR05) {
+ Return(\_SB.AR05)
+ }
+
+ Method(PD05) {
+ Return(\_SB.PD05)
+ }
+
+ Method(AR06) {
+ Return(\_SB.AR06)
+ }
+
+ Method(PD06) {
+ Return(\_SB.PD06)
+ }
+
+ Method(AR07) {
+ Return(\_SB.AR07)
+ }
+
+ Method(PD07) {
+ Return(\_SB.PD07)
+ }
+
+ Method(AR08) {
+ Return(\_SB.AR08)
+ }
+
+ Method(PD08) {
+ Return(\_SB.PD08)
+ }
+
+ Method(AR09) {
+ Return(\_SB.AR09)
+ }
+
+ Method(PD09) {
+ Return(\_SB.PD09)
+ }
+
+ Method(AR0A) {
+ Return(\_SB.AR0A)
+ }
+
+ Method(PD0A) {
+ Return(\_SB.PD0A)
+ }
+
+ Method(AR0B) {
+ Return(\_SB.AR0B)
+ }
+
+ Method(PD0B) {
+ Return(\_SB.PD0B)
+ }
+
+ //
+ // Add device scope definition for System Agent
+ // P.E.G. Root Port D1F0
+ //
+ Device(PEG0) {
+ Name(_ADR, 0x00010000)
+ Device(PEGP) { // P.E.G. Port Slot x16
+ Name(_ADR, 0x00000000)
+ }
+ }
+ //
+ // P.E.G. Root Port D1F1
+ //
+ Device(PEG1) {
+ Name(_ADR, 0x00010001)
+ Device(PEGP) { // P.E.G. Port Slot x8
+ Name(_ADR, 0x00000000)
+ }
+ }
+ //
+ // P.E.G. Root Port D1F2
+ //
+ Device(PEG2) {
+ Name(_ADR, 0x00010002)
+ Device(PEGP) { // P.E.G. Port Slot x4
+ Name(_ADR, 0x00000000)
+ }
+ }
+ //
+ // I.G.D
+ //
+ Device(GFX0) {
+ Name(_ADR, 0x00020000)
+ }
+ //
+ // SA Thermal Device
+ //
+ Device(B0D4) {
+ Method(_DSM,4,serialized){if(PCIC(Arg0)) { return(PCID(Arg0,Arg1,Arg2,Arg3)) }; Return(Buffer() {0})}
+ Name(_ADR, 0x00040000)
+ }
+ //
+ // Device IPU0 is the IPU PCI device
+ //
+ Device(IPU0) {
+ Name(_ADR, 0x00050000)
+ }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
new file mode 100644
index 0000000000..e7a797c973
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
@@ -0,0 +1,1666 @@
+/** @file
+ This file contains the IGD OpRegion/Software ACPI Reference
+ Code.
+ It defines the methods to enable/disable output switching,
+ store display switching and LCD brightness BIOS control
+ and return valid addresses for all display device encoders
+ present in the system, etc.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(\ECST, MethodObj)
+External(\PBCL, MethodObj)
+External(HDOS, MethodObj)
+External(\ECON, IntObj)
+External(\PNHM, IntObj)
+External(OSYS, IntObj)
+External(CPSC)
+External(\GUAM, MethodObj)
+External(DSEN)
+External(S0ID)
+
+Name(TMP1,Package() {0xFFFFFFFF})
+Name(TMP2,Package() {0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP3,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP4,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP5,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP6,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP7,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP8,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF})
+Name(TMP9,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPA,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF })
+Name(TMPB,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPC,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPD,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPE,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPF,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF})
+Name(TMPG,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF})
+
+// Enable/Disable Output Switching. In WIN2K/WINXP, _DOS = 0 will
+// get called during initialization to prepare for an ACPI Display
+// Switch Event. During an ACPI Display Switch, the OS will call
+// _DOS = 2 immediately after a Notify=0x80 to temporarily disable
+// all Display Switching. After ACPI Display Switching is complete,
+// the OS will call _DOS = 0 to re-enable ACPI Display Switching.
+Method(_DOS,1)
+{
+ //
+ // Store Display Switching and LCD brightness BIOS control bit
+ //
+ Store(And(Arg0,7),DSEN)
+
+ If(LEqual(And(Arg0, 0x3), 0)) // If _DOS[1:0]=0
+ {
+ If(CondRefOf(HDOS))
+ {
+ HDOS()
+ }
+ }
+}
+
+//
+// Enumerate the Display Environment. This method will return
+// valid addresses for all display device encoders present in the
+// system. The Miniport Driver will reject the addresses for every
+// encoder that does not have an attached display device. After
+// enumeration is complete, the OS will call the _DGS methods
+// during a display switch only for the addresses accepted by the
+// Miniport Driver. For hot-insertion and removal of display
+// devices, a re-enumeration notification will be required so the
+// address of the newly present display device will be accepted by
+// the Miniport Driver.
+//
+Method(_DOD,0)
+{
+ If (LEqual(IPTP,1)) {
+ //
+ // Increment number of devices if IPU is enabled
+ //
+ Store(1, NDID)
+ } Else {
+ Store(0, NDID)
+ }
+
+ If(LNotEqual(DIDL, Zero))
+ {
+ Store(SDDL(DIDL),DID1)
+ }
+ If(LNotEqual(DDL2, Zero))
+ {
+ Store(SDDL(DDL2),DID2)
+ }
+ If(LNotEqual(DDL3, Zero))
+ {
+ Store(SDDL(DDL3),DID3)
+ }
+ If(LNotEqual(DDL4, Zero))
+ {
+ Store(SDDL(DDL4),DID4)
+ }
+ If(LNotEqual(DDL5, Zero))
+ {
+ Store(SDDL(DDL5),DID5)
+ }
+ If(LNotEqual(DDL6, Zero))
+ {
+ Store(SDDL(DDL6),DID6)
+ }
+ If(LNotEqual(DDL7, Zero))
+ {
+ Store(SDDL(DDL7),DID7)
+ }
+ If(LNotEqual(DDL8, Zero))
+ {
+ Store(SDDL(DDL8),DID8)
+ }
+ If(LNotEqual(DDL9, Zero))
+ {
+ Store(SDDL(DDL9),DID9)
+ }
+ If(LNotEqual(DD10, Zero))
+ {
+ Store(SDDL(DD10),DIDA)
+ }
+ If(LNotEqual(DD11, Zero))
+ {
+ Store(SDDL(DD11),DIDB)
+ }
+ If(LNotEqual(DD12, Zero))
+ {
+ Store(SDDL(DD12),DIDC)
+ }
+ If(LNotEqual(DD13, Zero))
+ {
+ Store(SDDL(DD13),DIDD)
+ }
+ If(LNotEqual(DD14, Zero))
+ {
+ Store(SDDL(DD14),DIDE)
+ }
+ If(LNotEqual(DD15, Zero))
+ {
+ Store(SDDL(DD15),DIDF)
+ }
+
+ //
+ // Enumerate the encoders. Note that for
+ // current silicon, the maximum number of encoders
+ // possible is 15.
+ //
+ If(LEqual(NDID,1))
+ {
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMP1,0))
+ } Else {
+ Store(Or(0x10000,DID1),Index(TMP1,0))
+ }
+ Return(TMP1)
+ }
+
+ If(LEqual(NDID,2))
+ {
+ Store(Or(0x10000,DID1),Index(TMP2,0))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMP2,1))
+ } Else {
+ Store(Or(0x10000,DID2),Index(TMP2,1))
+ }
+ Return(TMP2)
+ }
+
+ If(LEqual(NDID,3))
+ {
+ Store(Or(0x10000,DID1),Index(TMP3,0))
+ Store(Or(0x10000,DID2),Index(TMP3,1))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMP3,2))
+ } Else {
+ Store(Or(0x10000,DID3),Index(TMP3,2))
+ }
+ Return(TMP3)
+ }
+
+ If(LEqual(NDID,4))
+ {
+ Store(Or(0x10000,DID1),Index(TMP4,0))
+ Store(Or(0x10000,DID2),Index(TMP4,1))
+ Store(Or(0x10000,DID3),Index(TMP4,2))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMP4,3))
+ } Else {
+ Store(Or(0x10000,DID4),Index(TMP4,3))
+ }
+ Return(TMP4)
+ }
+
+ If(LEqual(NDID,5))
+ {
+ Store(Or(0x10000,DID1),Index(TMP5,0))
+ Store(Or(0x10000,DID2),Index(TMP5,1))
+ Store(Or(0x10000,DID3),Index(TMP5,2))
+ Store(Or(0x10000,DID4),Index(TMP5,3))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMP5,4))
+ } Else {
+ Store(Or(0x10000,DID5),Index(TMP5,4))
+ }
+ Return(TMP5)
+ }
+
+ If(LEqual(NDID,6))
+ {
+ Store(Or(0x10000,DID1),Index(TMP6,0))
+ Store(Or(0x10000,DID2),Index(TMP6,1))
+ Store(Or(0x10000,DID3),Index(TMP6,2))
+ Store(Or(0x10000,DID4),Index(TMP6,3))
+ Store(Or(0x10000,DID5),Index(TMP6,4))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMP6,5))
+ } Else {
+ Store(Or(0x10000,DID6),Index(TMP6,5))
+ }
+ Return(TMP6)
+ }
+
+ If(LEqual(NDID,7))
+ {
+ Store(Or(0x10000,DID1),Index(TMP7,0))
+ Store(Or(0x10000,DID2),Index(TMP7,1))
+ Store(Or(0x10000,DID3),Index(TMP7,2))
+ Store(Or(0x10000,DID4),Index(TMP7,3))
+ Store(Or(0x10000,DID5),Index(TMP7,4))
+ Store(Or(0x10000,DID6),Index(TMP7,5))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMP7,6))
+ } Else {
+ Store(Or(0x10000,DID7),Index(TMP7,6))
+ }
+ Return(TMP7)
+ }
+
+ If(LEqual(NDID,8))
+ {
+ Store(Or(0x10000,DID1),Index(TMP8,0))
+ Store(Or(0x10000,DID2),Index(TMP8,1))
+ Store(Or(0x10000,DID3),Index(TMP8,2))
+ Store(Or(0x10000,DID4),Index(TMP8,3))
+ Store(Or(0x10000,DID5),Index(TMP8,4))
+ Store(Or(0x10000,DID6),Index(TMP8,5))
+ Store(Or(0x10000,DID7),Index(TMP8,6))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMP8,7))
+ } Else {
+ Store(Or(0x10000,DID8),Index(TMP8,7))
+ }
+ Return(TMP8)
+ }
+
+ If(LEqual(NDID,9))
+ {
+ Store(Or(0x10000,DID1),Index(TMP9,0))
+ Store(Or(0x10000,DID2),Index(TMP9,1))
+ Store(Or(0x10000,DID3),Index(TMP9,2))
+ Store(Or(0x10000,DID4),Index(TMP9,3))
+ Store(Or(0x10000,DID5),Index(TMP9,4))
+ Store(Or(0x10000,DID6),Index(TMP9,5))
+ Store(Or(0x10000,DID7),Index(TMP9,6))
+ Store(Or(0x10000,DID8),Index(TMP9,7))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMP9,8))
+ } Else {
+ Store(Or(0x10000,DID9),Index(TMP9,8))
+ }
+ Return(TMP9)
+ }
+
+ If(LEqual(NDID,0x0A))
+ {
+ Store(Or(0x10000,DID1),Index(TMPA,0))
+ Store(Or(0x10000,DID2),Index(TMPA,1))
+ Store(Or(0x10000,DID3),Index(TMPA,2))
+ Store(Or(0x10000,DID4),Index(TMPA,3))
+ Store(Or(0x10000,DID5),Index(TMPA,4))
+ Store(Or(0x10000,DID6),Index(TMPA,5))
+ Store(Or(0x10000,DID7),Index(TMPA,6))
+ Store(Or(0x10000,DID8),Index(TMPA,7))
+ Store(Or(0x10000,DID9),Index(TMPA,8))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMPA,9))
+ } Else {
+ Store(Or(0x10000,DIDA),Index(TMPA,9))
+ }
+ Return(TMPA)
+ }
+
+ If(LEqual(NDID,0x0B))
+ {
+ Store(Or(0x10000,DID1),Index(TMPB,0))
+ Store(Or(0x10000,DID2),Index(TMPB,1))
+ Store(Or(0x10000,DID3),Index(TMPB,2))
+ Store(Or(0x10000,DID4),Index(TMPB,3))
+ Store(Or(0x10000,DID5),Index(TMPB,4))
+ Store(Or(0x10000,DID6),Index(TMPB,5))
+ Store(Or(0x10000,DID7),Index(TMPB,6))
+ Store(Or(0x10000,DID8),Index(TMPB,7))
+ Store(Or(0x10000,DID9),Index(TMPB,8))
+ Store(Or(0x10000,DIDA),Index(TMPB,9))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMPB,10))
+ } Else {
+ Store(Or(0x10000,DIDB),Index(TMPB,10))
+ }
+ Return(TMPB)
+ }
+
+ If(LEqual(NDID,0x0C))
+ {
+ Store(Or(0x10000,DID1),Index(TMPC,0))
+ Store(Or(0x10000,DID2),Index(TMPC,1))
+ Store(Or(0x10000,DID3),Index(TMPC,2))
+ Store(Or(0x10000,DID4),Index(TMPC,3))
+ Store(Or(0x10000,DID5),Index(TMPC,4))
+ Store(Or(0x10000,DID6),Index(TMPC,5))
+ Store(Or(0x10000,DID7),Index(TMPC,6))
+ Store(Or(0x10000,DID8),Index(TMPC,7))
+ Store(Or(0x10000,DID9),Index(TMPC,8))
+ Store(Or(0x10000,DIDA),Index(TMPC,9))
+ Store(Or(0x10000,DIDB),Index(TMPC,10))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMPC,11))
+ } Else {
+ Store(Or(0x10000,DIDC),Index(TMPC,11))
+ }
+ Return(TMPC)
+ }
+
+ If(LEqual(NDID,0x0D))
+ {
+ Store(Or(0x10000,DID1),Index(TMPD,0))
+ Store(Or(0x10000,DID2),Index(TMPD,1))
+ Store(Or(0x10000,DID3),Index(TMPD,2))
+ Store(Or(0x10000,DID4),Index(TMPD,3))
+ Store(Or(0x10000,DID5),Index(TMPD,4))
+ Store(Or(0x10000,DID6),Index(TMPD,5))
+ Store(Or(0x10000,DID7),Index(TMPD,6))
+ Store(Or(0x10000,DID8),Index(TMPD,7))
+ Store(Or(0x10000,DID9),Index(TMPD,8))
+ Store(Or(0x10000,DIDA),Index(TMPD,9))
+ Store(Or(0x10000,DIDB),Index(TMPD,10))
+ Store(Or(0x10000,DIDC),Index(TMPD,11))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMPD,12))
+ } Else {
+ Store(Or(0x10000,DIDD),Index(TMPD,12))
+ }
+ Return(TMPD)
+ }
+
+ If(LEqual(NDID,0x0E))
+ {
+ Store(Or(0x10000,DID1),Index(TMPE,0))
+ Store(Or(0x10000,DID2),Index(TMPE,1))
+ Store(Or(0x10000,DID3),Index(TMPE,2))
+ Store(Or(0x10000,DID4),Index(TMPE,3))
+ Store(Or(0x10000,DID5),Index(TMPE,4))
+ Store(Or(0x10000,DID6),Index(TMPE,5))
+ Store(Or(0x10000,DID7),Index(TMPE,6))
+ Store(Or(0x10000,DID8),Index(TMPE,7))
+ Store(Or(0x10000,DID9),Index(TMPE,8))
+ Store(Or(0x10000,DIDA),Index(TMPE,9))
+ Store(Or(0x10000,DIDB),Index(TMPE,10))
+ Store(Or(0x10000,DIDC),Index(TMPE,11))
+ Store(Or(0x10000,DIDD),Index(TMPE,12))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMPE,13))
+ } Else {
+ Store(Or(0x10000,DIDE),Index(TMPE,13))
+ }
+ Return(TMPE)
+ }
+
+ If(LEqual(NDID,0x0F))
+ {
+ Store(Or(0x10000,DID1),Index(TMPF,0))
+ Store(Or(0x10000,DID2),Index(TMPF,1))
+ Store(Or(0x10000,DID3),Index(TMPF,2))
+ Store(Or(0x10000,DID4),Index(TMPF,3))
+ Store(Or(0x10000,DID5),Index(TMPF,4))
+ Store(Or(0x10000,DID6),Index(TMPF,5))
+ Store(Or(0x10000,DID7),Index(TMPF,6))
+ Store(Or(0x10000,DID8),Index(TMPF,7))
+ Store(Or(0x10000,DID9),Index(TMPF,8))
+ Store(Or(0x10000,DIDA),Index(TMPF,9))
+ Store(Or(0x10000,DIDB),Index(TMPF,10))
+ Store(Or(0x10000,DIDC),Index(TMPF,11))
+ Store(Or(0x10000,DIDD),Index(TMPF,12))
+ Store(Or(0x10000,DIDE),Index(TMPF,13))
+ If (LEqual(IPTP,1)) {
+ //
+ // IGFX need report IPUA as GFX0 child
+ //
+ Store(0x00023480,Index(TMPF,14))
+ } Else {
+ Store(Or(0x10000,DIDF),Index(TMPF,14))
+ }
+ Return(TMPF)
+ }
+
+ If(LEqual(NDID,0x10))
+ {
+ Store(Or(0x10000,DID1),Index(TMPG,0))
+ Store(Or(0x10000,DID2),Index(TMPG,1))
+ Store(Or(0x10000,DID3),Index(TMPG,2))
+ Store(Or(0x10000,DID4),Index(TMPG,3))
+ Store(Or(0x10000,DID5),Index(TMPG,4))
+ Store(Or(0x10000,DID6),Index(TMPG,5))
+ Store(Or(0x10000,DID7),Index(TMPG,6))
+ Store(Or(0x10000,DID8),Index(TMPG,7))
+ Store(Or(0x10000,DID9),Index(TMPG,8))
+ Store(Or(0x10000,DIDA),Index(TMPG,9))
+ Store(Or(0x10000,DIDB),Index(TMPG,10))
+ Store(Or(0x10000,DIDC),Index(TMPG,11))
+ Store(Or(0x10000,DIDD),Index(TMPG,12))
+ Store(Or(0x10000,DIDE),Index(TMPG,13))
+ Store(Or(0x10000,DIDF),Index(TMPG,14))
+ //
+ // IGFX need report IPUA as GFX0 child
+ // NDID can only be 0x10 if IPU is enabled
+ //
+ Store(0x00023480,Index(TMPG,15))
+ Return(TMPG)
+ }
+
+ //
+ // If nothing else, return Unknown LFP.
+ // (Prevents compiler warning.)
+ //
+ Return(Package() {0x00000400})
+}
+
+Device(DD01)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DID1),0x400))
+ {
+ Store(0x1, EDPV)
+ Store(NXD1, NXDX)
+ Store(DID1, DIDX)
+ Return(1)
+ }
+ If(LEqual(DID1,0))
+ {
+ Return(1)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DID1))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ Return(CDDS(DID1))
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD1)
+ }
+ Return(NDDS(DID1))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD02)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DID2),0x400))
+ {
+ Store(0x2, EDPV)
+ Store(NXD2, NXDX)
+ Store(DID2, DIDX)
+ Return(2)
+ }
+ If(LEqual(DID2,0))
+ {
+ Return(2)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DID2))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(LIDS,0))
+ {
+ Return(0x0)
+ }
+ Return(CDDS(DID2))
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ //
+ // Return the Next State.
+ //
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD2)
+ }
+ Return(NDDS(DID2))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD03)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DID3),0x400))
+ {
+ Store(0x3, EDPV)
+ Store(NXD3, NXDX)
+ Store(DID3, DIDX)
+ Return(3)
+ }
+ If(LEqual(DID3,0))
+ {
+ Return(3)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DID3))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DID3,0))
+ {
+ Return(0x0B)
+ }
+ Else
+ {
+ Return(CDDS(DID3))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD3)
+ }
+ Return(NDDS(DID3))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD04)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DID4),0x400))
+ {
+ Store(0x4, EDPV)
+ Store(NXD4, NXDX)
+ Store(DID4, DIDX)
+ Return(4)
+ }
+ If(LEqual(DID4,0))
+ {
+ Return(4)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DID4))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DID4,0))
+ {
+ Return(0x0B)
+ }
+ Else
+ {
+ Return(CDDS(DID4))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD4)
+ }
+ Return(NDDS(DID4))
+ }
+
+ //
+ // Device Set State. (See table above.)
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD05)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DID5),0x400))
+ {
+ Store(0x5, EDPV)
+ Store(NXD5, NXDX)
+ Store(DID5, DIDX)
+ Return(5)
+ }
+ If(LEqual(DID5,0))
+ {
+ Return(5)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DID5))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DID5,0))
+ {
+ Return(0x0B)
+ }
+ Else
+ {
+ Return(CDDS(DID5))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD5)
+ }
+ Return(NDDS(DID5))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD06)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DID6),0x400))
+ {
+ Store(0x6, EDPV)
+ Store(NXD6, NXDX)
+ Store(DID6, DIDX)
+ Return(6)
+ }
+ If(LEqual(DID6,0))
+ {
+ Return(6)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DID6))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DID6,0))
+ {
+ Return(0x0B)
+ }
+ Else
+ {
+ Return(CDDS(DID6))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD6)
+ }
+ Return(NDDS(DID6))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD07)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DID7),0x400))
+ {
+ Store(0x7, EDPV)
+ Store(NXD7, NXDX)
+ Store(DID7, DIDX)
+ Return(7)
+ }
+ If(LEqual(DID7,0))
+ {
+ Return(7)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DID7))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DID7,0))
+ {
+ Return(0x0B)
+ }
+ Else
+ {
+ Return(CDDS(DID7))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD7)
+ }
+ Return(NDDS(DID7))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD08)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DID8),0x400))
+ {
+ Store(0x8, EDPV)
+ Store(NXD8, NXDX)
+ Store(DID8, DIDX)
+ Return(8)
+ }
+ If(LEqual(DID8,0))
+ {
+ Return(8)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DID8))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DID8,0))
+ {
+ Return(0x0B)
+ }
+ Else
+ {
+ Return(CDDS(DID8))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD8)
+ }
+ Return(NDDS(DID8))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD09)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DID9),0x400))
+ {
+ Store(0x9, EDPV)
+ Store(NXD8, NXDX)
+ Store(DID9, DIDX)
+ Return(9)
+ }
+ If(LEqual(DID9,0))
+ {
+ Return(9)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DID9))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DID9,0))
+ {
+ Return(0x0B)
+ }
+ Else
+ {
+ Return(CDDS(DID9))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD8)
+ }
+ Return(NDDS(DID9))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD0A)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DIDA),0x400))
+ {
+ Store(0xA, EDPV)
+ Store(NXD8, NXDX)
+ Store(DIDA, DIDX)
+ Return(0x0A)
+ }
+ If(LEqual(DIDA,0))
+ {
+ Return(0x0A)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DIDA))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DIDA,0))
+ {
+ Return(0x0B)
+ }
+ Else
+ {
+ Return(CDDS(DIDA))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD8)
+ }
+ Return(NDDS(DIDA))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD0B)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DIDB),0x400))
+ {
+ Store(0xB, EDPV)
+ Store(NXD8, NXDX)
+ Store(DIDB, DIDX)
+ Return(0X0B)
+ }
+ If(LEqual(DIDB,0))
+ {
+ Return(0x0B)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DIDB))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DIDB,0))
+ {
+ Return(0x0B)
+ }
+ Else
+ {
+ Return(CDDS(DIDB))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD8)
+ }
+ Return(NDDS(DIDB))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD0C)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DIDC),0x400))
+ {
+ Store(0xC, EDPV)
+ Store(NXD8, NXDX)
+ Store(DIDC, DIDX)
+ Return(0X0C)
+ }
+ If(LEqual(DIDC,0))
+ {
+ Return(0x0C)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DIDC))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DIDC,0))
+ {
+ Return(0x0C)
+ }
+ Else
+ {
+ Return(CDDS(DIDC))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD8)
+ }
+ Return(NDDS(DIDC))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD0D)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DIDD),0x400))
+ {
+ Store(0xD, EDPV)
+ Store(NXD8, NXDX)
+ Store(DIDD, DIDX)
+ Return(0X0D)
+ }
+ If(LEqual(DIDD,0))
+ {
+ Return(0x0D)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DIDD))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DIDD,0))
+ {
+ Return(0x0D)
+ }
+ Else
+ {
+ Return(CDDS(DIDD))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD8)
+ }
+ Return(NDDS(DIDD))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD0E)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DIDE),0x400))
+ {
+ Store(0xE, EDPV)
+ Store(NXD8, NXDX)
+ Store(DIDE, DIDX)
+ Return(0X0E)
+ }
+ If(LEqual(DIDE,0))
+ {
+ Return(0x0E)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DIDE))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DIDE,0))
+ {
+ Return(0x0E)
+ }
+ Else
+ {
+ Return(CDDS(DIDE))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD8)
+ }
+ Return(NDDS(DIDE))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+Device(DD0F)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(And(0x0F00,DIDF),0x400))
+ {
+ Store(0xF, EDPV)
+ Store(NXD8, NXDX)
+ Store(DIDF, DIDX)
+ Return(0X0F)
+ }
+ If(LEqual(DIDF,0))
+ {
+ Return(0x0F)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DIDF))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(DIDC,0))
+ {
+ Return(0x0F)
+ }
+ Else
+ {
+ Return(CDDS(DIDF))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXD8)
+ }
+ Return(NDDS(DIDF))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+}
+
+//
+//Device for eDP
+//
+Device(DD1F)
+{
+ //
+ // Return Unique ID.
+ //
+ Method(_ADR,0,Serialized)
+ {
+ If(LEqual(EDPV, 0x0))
+ {
+ Return(0x1F)
+ }
+ Else
+ {
+ Return(And(0xFFFF,DIDX))
+ }
+ }
+
+ //
+ // Return the Current Status.
+ //
+ Method(_DCS,0)
+ {
+ If(LEqual(EDPV, 0x0))
+ {
+ Return(0x00)
+ }
+ Else
+ {
+ Return(CDDS(DIDX))
+ }
+ }
+
+ //
+ // Query Graphics State (active or inactive).
+ //
+ Method(_DGS,0)
+ {
+ If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
+ {
+ Return (NXDX)
+ }
+ Return(NDDS(DIDX))
+ }
+
+ //
+ // Device Set State.
+ //
+ Method(_DSS,1)
+ {
+ DSST(Arg0)
+ }
+
+ //
+ // Query List of Brightness Control Levels Supported.
+ //
+ Method(_BCL,0)
+ {
+ //
+ // List of supported brightness levels in the following sequence.
+ // Level when machine has full power.
+ // Level when machine is on batteries.
+ // Other supported levels.
+ //
+ If(CondRefOf(\PBCL)) {
+ Return (PBCL())
+ } Else {
+ Return(Package(){80, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100})
+ }
+ }
+
+ //
+ // Set the Brightness Level.
+ //
+ Method (_BCM,1)
+ {
+ //
+ // Set the requested level if it is between 0 and 100%.
+ //
+ If(LAnd(LGreaterEqual(Arg0,0),LLessEqual(Arg0,100)))
+ {
+ \_SB.PCI0.GFX0.AINT(1, Arg0)
+ Store(Arg0,BRTL) // Store Brightness Level.
+ }
+ }
+
+ //
+ // Brightness Query Current level.
+ //
+ Method (_BQC,0)
+ {
+ Return(BRTL)
+ }
+}
+
+Method(SDDL,1)
+{
+ Increment(NDID)
+ Store(And(Arg0,0xF0F),Local0)
+ Or(0x80000000,Local0, Local1)
+ If(LEqual(DIDL,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DDL2,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DDL3,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DDL4,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DDL5,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DDL6,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DDL7,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DDL8,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DDL9,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DD10,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DD11,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DD12,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DD13,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DD14,Local0))
+ {
+ Return(Local1)
+ }
+ If(LEqual(DD15,Local0))
+ {
+ Return(Local1)
+ }
+ Return(0)
+}
+
+Method(CDDS,1)
+{
+ Store(And(Arg0,0xF0F),Local0)
+
+ If(LEqual(0, Local0))
+ {
+ Return(0x1D)
+ }
+ If(LEqual(CADL, Local0))
+ {
+ Return(0x1F)
+ }
+ If(LEqual(CAL2, Local0))
+ {
+ Return(0x1F)
+ }
+ If(LEqual(CAL3, Local0))
+ {
+ Return(0x1F)
+ }
+ If(LEqual(CAL4, Local0))
+ {
+ Return(0x1F)
+ }
+ If(LEqual(CAL5, Local0))
+ {
+ Return(0x1F)
+ }
+ If(LEqual(CAL6, Local0))
+ {
+ Return(0x1F)
+ }
+ If(LEqual(CAL7, Local0))
+ {
+ Return(0x1F)
+ }
+ If(LEqual(CAL8, Local0))
+ {
+ Return(0x1F)
+ }
+ Return(0x1D)
+}
+
+Method(NDDS,1)
+{
+ Store(And(Arg0,0xF0F),Local0)
+
+ If(LEqual(0, Local0))
+ {
+ Return(0)
+ }
+ If(LEqual(NADL, Local0))
+ {
+ Return(1)
+ }
+ If(LEqual(NDL2, Local0))
+ {
+ Return(1)
+ }
+ If(LEqual(NDL3, Local0))
+ {
+ Return(1)
+ }
+ If(LEqual(NDL4, Local0))
+ {
+ Return(1)
+ }
+ If(LEqual(NDL5, Local0))
+ {
+ Return(1)
+ }
+ If(LEqual(NDL6, Local0))
+ {
+ Return(1)
+ }
+ If(LEqual(NDL7, Local0))
+ {
+ Return(1)
+ }
+ If(LEqual(NDL8, Local0))
+ {
+ Return(1)
+ }
+ Return(0)
+}
+
+//
+// Device Set State Table
+// BIT31 BIT30 Execution
+// 0 0 Don't implement.
+// 0 1 Cache change. Nothing to Implement.
+// 1 0 Don't Implement.
+// 1 1 Display Switch Complete. Implement.
+//
+Method(DSST,1)
+{
+ If(LEqual(And(Arg0,0xC0000000),0xC0000000))
+ {
+ //
+ // State change was performed by the
+ // Video Drivers. Simply update the
+ // New State.
+ //
+ Store(NSTE,CSTE)
+ }
+}
+
+//
+// Include IGD OpRegion/Software SCI interrupt handler/DSM which is used by
+// the graphics drivers to request data from system BIOS.
+//
+include ("IgfxOpRn.asl")
+include ("IgfxDsm.asl")
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl
new file mode 100644
index 0000000000..7edbe45e2e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl
@@ -0,0 +1,472 @@
+/** @file
+ IGD OpRegion/Software SCI Reference Code.
+ This file contains ASL code with the purpose of handling events
+ i.e. hotkeys and other system interrupts.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+/************************************************************************;
+;* ACPI Notification Methods
+;************************************************************************/
+
+
+/************************************************************************;
+;*
+;* Name: PDRD
+;*
+;* Description: Check if the graphics driver is ready to process
+;* notifications and video extensions.
+;*
+;* Usage: This method is to be called prior to performing any
+;* notifications or handling video extensions.
+;* Ex: If (PDRD()) {Return (FAIL)}
+;*
+;* Input: None
+;*
+;* Output: None
+;*
+;* References: DRDY (Driver ready status), ASLP (Driver recommended
+;* sleep timeout value).
+;*
+;************************************************************************/
+
+External(HNOT, MethodObj)
+
+Method(PDRD)
+{
+ //
+ // If DRDY is clear, the driver is not ready. If the return value is
+ // !=0, do not perform any notifications or video extension handling.
+ //
+ Return(LNot(DRDY))
+}
+
+/************************************************************************;
+;*
+;* Name: PSTS
+;*
+;* Description: Check if the graphics driver has completed the previous
+;* "notify" command.
+;*
+;* Usage: This method is called before every "notify" command. A
+;* "notify" should only be set if the driver has completed the
+;* previous command. Else, ignore the event and exit the parent
+;* method.
+;* Ex: If (PSTS()) {Return (FAIL)}
+;*
+;* Input: None
+;*
+;* Output: None
+;*
+;* References: CSTS (Notification status), ASLP (Driver recommended sleep
+;* timeout value).
+;*
+;************************************************************************/
+
+Method(PSTS)
+{
+ If(LGreater(CSTS, 2))
+ {
+ //
+ // Sleep for ASLP milliseconds if the status is not "success,
+ // failure, or pending"
+ //
+ Sleep(ASLP)
+ }
+
+ Return(LEqual(CSTS, 3)) // Return True if still Dispatched
+}
+
+/************************************************************************;
+;*
+;* Name: GNOT
+;*
+;* Description: Call the appropriate methods to query the graphics driver
+;* status. If all methods return success, do a notification of
+;* the graphics device.
+;*
+;* Usage: This method is to be called when a graphics device
+;* notification is required (display switch hotkey, etc).
+;*
+;* Input: Arg0 = Current event type:
+;* 1 = display switch
+;* 2 = lid
+;* 3 = dock
+;* Arg1 = Notification type:
+;* 0 = Re-enumeration
+;* 0x80 = Display switch
+;*
+;* Output: Returns 0 = success, 1 = failure
+;*
+;* References: PDRD and PSTS methods. OSYS (OS version)
+;*
+;************************************************************************/
+
+Method(GNOT, 2)
+{
+ //
+ // Check for 1. Driver loaded, 2. Driver ready.
+ // If any of these cases is not met, skip this event and return failure.
+ //
+ If(PDRD())
+ {
+ Return(0x1) // Return failure if driver not loaded.
+ }
+
+ Store(Arg0, CEVT) // Set up the current event value
+ Store(3, CSTS) // CSTS=BIOS dispatched an event
+
+ If(LAnd(LEqual(CHPD, 0), LEqual(Arg1, 0))) // Do not re-enum if driver supports hotplug
+ {
+ //
+ // Re-enumerate the Graphics Device for non-XP operating systems.
+ //
+ Notify(\_SB.PCI0.GFX0, Arg1)
+ }
+
+ If(CondRefOf(HNOT))
+ {
+ HNOT(Arg0) //Notification handler for Switchable graphics
+ }
+ Else
+ {
+ Notify(\_SB.PCI0.GFX0,0x80)
+ }
+
+ Return(0x0) // Return success
+}
+
+/************************************************************************;
+;*
+;* Name: GHDS
+;*
+;* Description: Handle a hotkey display switching event (performs a
+;* Notify(GFX0, 0).
+;*
+;* Usage: This method must be called when a hotkey event occurs and the
+;* purpose of that hotkey is to do a display switch.
+;*
+;* Input: Arg0 = Toggle table number.
+;*
+;* Output: Returns 0 = success, 1 = failure.
+;* CEVT and TIDX are indirect outputs.
+;*
+;* References: TIDX, GNOT
+;*
+;************************************************************************/
+
+Method(GHDS, 1)
+{
+ Store(Arg0, TIDX) // Store the table number
+ //
+ // Call GNOT for CEVT = 1 = hotkey, notify value = 0
+ //
+ Return(GNOT(1, 0)) // Return stats from GNOT
+}
+
+/************************************************************************;
+;*
+;* Name: GLID
+;*
+;* Description: Handle a lid event (performs the Notify(GFX0, 0), but not the
+;* lid notify).
+;*
+;* Usage: This method must be called when a lid event occurs. A
+;* Notify(LID0, 0x80) must follow the call to this method.
+;*
+;* Input: Arg0 = Lid state:
+;* 0 = All closed
+;* 1 = internal LFP lid open
+;* 2 = external lid open
+;* 3 = both external and internal open
+;*
+;* Output: Returns 0=success, 1=failure.
+;* CLID and CEVT are indirect outputs.
+;*
+;* References: CLID, GNOT
+;*
+;************************************************************************/
+
+Method(GLID, 1)
+{
+
+ If (LEqual(Arg0,1))
+ {
+ Store(3,CLID)
+ }
+ Else
+ {
+ Store(Arg0, CLID)
+ }
+ //
+ //Store(Arg0, CLID) // Store the current lid state
+ // Call GNOT for CEVT=2=Lid, notify value = 0
+ //
+ if (GNOT(2, 0)) {
+ Or (CLID, 0x80000000, CLID)
+ Return (1) // Return Fail
+ }
+
+ Return (0) // Return Pass
+}
+
+/************************************************************************;
+;*
+;* Name: GDCK
+;*
+;* Description: Handle a docking event by updating the current docking status
+;* and doing a notification.
+;*
+;* Usage: This method must be called when a docking event occurs.
+;*
+;* Input: Arg0 = Docking state:
+;* 0 = Undocked
+;* 1 = Docked
+;*
+;* Output: Returns 0=success, 1=failure.
+;* CDCK and CEVT are indirect outputs.
+;*
+;* References: CDCK, GNOT
+;*
+;************************************************************************/
+
+Method(GDCK, 1)
+{
+ Store(Arg0, CDCK) // Store the current dock state
+ //
+ // Call GNOT for CEVT=4=Dock, notify value = 0
+ //
+ Return(GNOT(4, 0)) // Return stats from GNOT
+}
+
+/************************************************************************;
+;* ASLE Interrupt Methods
+;************************************************************************/
+
+/************************************************************************;
+;*
+;* Name: PARD
+;*
+;* Description: Check if the driver is ready to handle ASLE interrupts
+;* generate by the system BIOS.
+;*
+;* Usage: This method must be called before generating each ASLE
+;* interrupt.
+;*
+;* Input: None
+;*
+;* Output: Returns 0 = success, 1 = failure.
+;*
+;* References: ARDY (Driver readiness), ASLP (Driver recommended sleep
+;* timeout value)
+;*
+;************************************************************************/
+
+Method(PARD)
+{
+ If(LNot(ARDY))
+ {
+ //
+ // Sleep for ASLP milliseconds if the driver is not ready.
+ //
+ Sleep(ASLP)
+ }
+ //
+ // If ARDY is clear, the driver is not ready. If the return value is
+ // !=0, do not generate the ASLE interrupt.
+ //
+ Return(LNot(ARDY))
+}
+
+//
+// Intel Ultrabook Event Handler. Arg0 represents the Ultrabook Event Bit # to pass
+// to the Intel Graphics Driver. Note that this is a serialized method, meaning
+// sumultaneous events are not allowed.
+//
+Method(IUEH,1,Serialized)
+{
+ And(IUER,0xC0,IUER) // Clear all button events on entry.
+ XOr(IUER,Shiftleft(1,Arg0),IUER) // Toggle status.
+
+ If(LLessEqual(Arg0,4)) // Button Event?
+ {
+ Return(AINT(5,0)) // Generate event and return status.
+
+ }
+ Else // Indicator Event.
+ {
+ Return(AINT(Arg0,0)) // Generate event and return status.
+ }
+}
+
+/************************************************************************;
+;*
+;* Name: AINT
+;*
+;* Description: Call the appropriate methods to generate an ASLE interrupt.
+;* This process includes ensuring the graphics driver is ready
+;* to process the interrupt, ensuring the driver supports the
+;* interrupt of interest, and passing information about the event
+;* to the graphics driver.
+;*
+;* Usage: This method must called to generate an ASLE interrupt.
+;*
+;* Input: Arg0 = ASLE command function code:
+;* 0 = Set ALS illuminance
+;* 1 = Set backlight brightness
+;* 2 = Do Panel Fitting
+;* 4 = Reserved
+;* 5 = Button Indicator Event
+;* 6 = Convertible Indicator Event
+;* 7 = Docking Indicator Event
+;* Arg1 = If Arg0 = 0, current ALS reading:
+;* 0 = Reading below sensor range
+;* 1-0xFFFE = Current sensor reading
+;* 0xFFFF = Reading above sensor range
+;* Arg1 = If Arg0 = 1, requested backlight percentage
+;*
+;* Output: Returns 0 = success, 1 = failure
+;*
+;* References: PARD method.
+;*
+;************************************************************************/
+
+Method(AINT, 2)
+{
+ //
+ // Return failure if the requested feature is not supported by the
+ // driver.
+ //
+ If(LNot(And(TCHE, ShiftLeft(1, Arg0))))
+ {
+ Return(0x1)
+ }
+ //
+ // Return failure if the driver is not ready to handle an ASLE
+ // interrupt.
+ //
+ If(PARD())
+ {
+ Return(0x1)
+ }
+ //
+ // Handle Intel Ultrabook Events.
+ //
+ If(LAnd(LGreaterEqual(Arg0,5),LLessEqual(Arg0,7)))
+ {
+ Store(ShiftLeft(1,Arg0), ASLC) // Set Ultrbook Event [6:4].
+ Store(0x01, ASLE) // Generate ASLE interrupt
+
+ Store(0,Local2) // Use Local2 as a timeout counter. Intialize to zero.
+
+ While(LAnd(LLess(Local2,250),LNotEqual(ASLC,0))) // Wait 1 second or until Driver ACKs a success.
+ {
+ Sleep(4) // Delay 4 ms.
+ Increment(Local2) // Increment Timeout.
+ }
+
+ Return(0) // Return success
+ }
+ //
+ // Evaluate the first argument (Panel fitting, backlight brightness, or ALS).
+ //
+ If(LEqual(Arg0, 2)) // Arg0 = 2, so request a panel fitting mode change.
+ {
+ If(CPFM) // If current mode field is non-zero use it.
+ {
+ And(CPFM, 0x0F, Local0) // Create variables without reserved
+ And(EPFM, 0x0F, Local1) // or valid bits.
+
+ If(LEqual(Local0, 1)) // If current mode is centered,
+ {
+ If(And(Local1, 6)) // and if stretched is enabled,
+ {
+ Store(6, PFIT) // request stretched.
+ }
+ Else // Otherwise,
+ {
+ If(And(Local1, 8)) // if aspect ratio is enabled,
+ {
+ Store(8, PFIT) // request aspect ratio.
+ }
+ Else // Only centered mode is enabled
+ {
+ Store(1, PFIT) // so request centered. (No change.)
+ }
+ }
+ }
+ If(LEqual(Local0, 6)) // If current mode is stretched,
+ {
+ If(And(Local1, 8)) // and if aspect ratio is enabled,
+ {
+ Store(8, PFIT) // request aspect ratio.
+ }
+ Else // Otherwise,
+ {
+ If(And(Local1, 1)) // if centered is enabled,
+ {
+ Store(1, PFIT) // request centered.
+ }
+ Else // Only stretched mode is enabled
+ {
+ Store(6, PFIT) // so request stretched. (No change.)
+ }
+ }
+ }
+ If(LEqual(Local0, 8)) // If current mode is aspect ratio,
+ {
+ If(And(Local1, 1)) // and if centered is enabled,
+ {
+ Store(1, PFIT) // request centered.
+ }
+ Else // Otherwise,
+ {
+ If(And(Local1, 6)) // if stretched is enabled,
+ {
+ Store(6, PFIT) // request stretched.
+ }
+ Else // Only aspect ratio mode is enabled
+ {
+ Store(8, PFIT) // so request aspect ratio. (No change.)
+ }
+ }
+ }
+ }
+ //
+ // The following code for panel fitting (within the Else condition) is retained for backward compatiblity.
+ //
+ Else // If CFPM field is zero use PFIT and toggle the
+ {
+ Xor(PFIT,7,PFIT) // mode setting between stretched and centered only.
+ }
+ Or(PFIT,0x80000000,PFIT) // Set the valid bit for all cases.
+ Store(4, ASLC) // Store "Panel fitting event" to ASLC[31:1]
+ }
+ Else
+ {
+ If(LEqual(Arg0, 1)) // Arg0=1, so set the backlight brightness.
+ {
+ Store(Divide(Multiply(Arg1, 255), 100), BCLP) // Convert from percent to 0-255.
+ Or(BCLP, 0x80000000, BCLP) // Set the valid bit.
+ Store(2, ASLC) // Store "Backlight control event" to ASLC[31:1]
+ }
+ Else
+ {
+ If(LEqual(Arg0, 0)) // Arg0=0, so set the ALS illuminace
+ {
+ Store(Arg1, ALSI)
+ Store(1, ASLC) // Store "ALS event" to ASLC[31:1]
+ }
+ Else
+ {
+ Return(0x1) // Unsupported function
+ }
+ }
+ }
+
+ Store(0x01, ASLE) // Generate ASLE interrupt
+ Return(0x0) // Return success
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl
new file mode 100644
index 0000000000..e7b3c92cda
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl
@@ -0,0 +1,369 @@
+/** @file
+ IGD OpRegion/_DSM Reference Code.
+ This file contains Get BIOS Data and Callback functions for
+ the Integrated Graphics Device (IGD) OpRegion/DSM mechanism
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// _DSM Device Specific Method
+//
+// Arg0: UUID Unique function identifier
+// Arg1: Integer Revision Level
+// Arg2: Integer Function Index (1 = Return Supported Functions)
+// Arg3: Additional Inputs/Package Parameters Bits [31:0] input as {Byte0, Byte1, Byte2, Byte3} to BIOS which is passed as 32 bit DWORD by Driver
+//
+Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj}) {
+
+ If (LEqual(Arg0, ToUUID ("3E5B41C6-EB1D-4260-9D15-C71FBADAE414"))) {
+ //
+ // _DSM Definition for Igd functions
+ // Arguments:
+ // Arg0: UUID: 3E5B41C6-EB1D-4260-9D15-C71FBADAE414
+ // Arg1: Revision ID: 1
+ // Arg2: Function Index: 16
+ // Arg3: Additional Inputs Bits[31:0] Arg3 {Byte0, Byte1, Byte2, Byte3}
+ //
+ // Return:
+ // Success for simple notification, Opregion update for some routines and a Package for AKSV
+ //
+ //
+ // Switch by function index
+ //
+ Switch(ToInteger(Arg2)) {
+ //
+ // Function Index: 0
+ // Standard query - A bitmask of functions supported
+ //
+ // Return: A bitmask of functions supported
+ //
+ Case (0)
+ {
+ If (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+ Store("iGfx Supported Functions Bitmap ", Debug)
+ Return (0x1E7FF) // bit 11 and 12 is not supported
+ }
+ }
+
+ //
+ // Function Index: 1
+ // Adapter Power State Notification
+ // Arg3 Bits [7:0]: Adapter Power State bits [7:0] from Driver 00h = D0; 01h = D1; 02h = D2; 04h = D3 (Cold/Hot); 08h = D4 (Hibernate Notification)
+ // Return: Success
+ //
+ Case(1) {
+ If (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+ Store(" Adapter Power State Notification ", Debug)
+
+ //
+ // Handle Low Power S0 Idle Capability if enabled
+ //
+ If(LAnd(LEqual(S0ID, 1),LLess(OSYS, 2015))) {
+ //
+ // Call GUAM to trigger CS Entry
+ // If Adapter Power State Notification = D1 (Arg3[0]=0x01)
+ //
+ If (LEqual (And(DerefOf (Index (Arg3,0)), 0xFF), 0x01)) {
+ // GUAM - Global User Absent Mode Notification Method
+ \GUAM(One) // 0x01 - Power State Standby (CS Entry)
+ }
+ Store(And(DerefOf (Index (Arg3,1)), 0xFF), Local0)
+ //
+ // Call GUAM
+ // If Display Turn ON Notification (Arg3 [1] == 0) for CS Exit
+ //
+ If (LEqual (Local0, 0)) {
+ // GUAM - Global User Absent Mode Notification Method
+ \GUAM(0)
+ }
+ }
+
+ // Upon notification from driver that the Adapter Power State = D0,
+ // check if previous lid event failed. If it did, retry the lid
+ // event here.
+ If(LEqual(DerefOf (Index (Arg3,0)), 0)) {
+ Store(CLID, Local0)
+ If(And(0x80000000,Local0)) {
+ And(CLID, 0x0000000F, CLID)
+ GLID(CLID)
+ }
+ }
+ Return(0x01)
+ }
+ }
+ //
+ // Function Index: 2
+ // Display Power State Notification
+ // Arg3: Display Power State Bits [15:8]
+ // 00h = On
+ // 01h = Standby
+ // 02h = Suspend
+ // 04h = Off
+ // 08h = Reduced On
+ // Return: Success
+ //
+ Case(2) {
+ if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+
+ Store("Display Power State Notification ", Debug)
+ Return(0x01)
+ }
+ }
+
+ //
+ // Function Index: 3
+ // BIOS POST Completion Notification
+ // Return: Success
+ //
+ Case(3) {
+ if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+ Store("BIOS POST Completion Notification ", Debug)
+ Return(0x01) // Not supported, but no failure
+ }
+ }
+
+ //
+ // Function Index: 4
+ // Pre-Hires Set Mode
+ // Return: Success
+ //
+ Case(4) {
+ if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+ Store("Pre-Hires Set Mode ", Debug)
+ Return(0x01) // Not supported, but no failure
+ }
+ }
+
+ //
+ // Function Index: 5
+ // Post-Hires Set Mode
+ // Return: Success
+ //
+ Case(5) {
+ if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+ Store("Post-Hires Set Mode ", Debug)
+ Return(0x01) // Not supported, but no failure
+ }
+ }
+
+ //
+ // Function Index: 6
+ // SetDisplayDeviceNotification (Display Switch)
+ // Return: Success
+ //
+ Case(6) {
+ if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+ Store("SetDisplayDeviceNotification", Debug)
+ Return(0x01) // Not supported, but no failure
+ }
+ }
+
+ //
+ // Function Index: 7
+ // SetBootDevicePreference
+ // Return: Success
+ //
+ Case(7) {
+ if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+ //<TODO> An OEM may elect to implement this method. In that case,
+ // the input values must be saved into non-volatile storage for
+ // parsing during the next boot. The following Sample code is Intel
+ // validated implementation.
+
+ Store("SetBootDevicePreference ", Debug)
+ And(DerefOf (Index (Arg3,0)), 0xFF, IBTT) // Save the boot display to NVS
+ Return(0x01)
+ }
+ }
+
+ //
+ // Function Index: 8
+ // SetPanelPreference
+ // Return: Success
+ //
+ Case(8) {
+ if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+ // An OEM may elect to implement this method. In that case,
+ // the input values must be saved into non-volatile storage for
+ // parsing during the next boot. The following Sample code is Intel
+ // validated implementation.
+
+ Store("SetPanelPreference ", Debug)
+
+ // Set the panel-related NVRAM variables based the input from the driver.
+ And(DerefOf (Index (Arg3,0)), 0xFF, IPSC)
+
+ // Change panel type if a change is requested by the driver (Change if
+ // panel type input is non-zero). Zero=No change requested.
+ If(And(DerefOf (Index (Arg3,1)), 0xFF)) {
+ And(DerefOf (Index (Arg3,1)), 0xFF, IPAT)
+ Decrement(IPAT) // 0 = no change, so fit to CMOS map
+ }
+ And(ShiftRight(DerefOf (Index (Arg3,2)), 4), 0x7, IBIA)
+ Return(0x01) // Success
+ }
+ }
+
+ //
+ // Function Index: 9
+ // FullScreenDOS
+ // Return: Success
+ //
+ Case(9) {
+ if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+ Store("FullScreenDOS ", Debug)
+ Return(0x01) // Not supported, but no failure
+ }
+ }
+
+ //
+ // Function Index: 10
+ // APM Complete
+ // Return: Adjusted Lid State
+ //
+ Case(10) {
+ if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+
+ Store("APM Complete ", Debug)
+ Store(ShiftLeft(LIDS, 8), Local0) // Report the lid state
+ Add(Local0, 0x100, Local0) // Adjust the lid state, 0 = Unknown
+ Return(Local0)
+ }
+ }
+
+ //
+ //
+ // Function Index: 13
+ // GetBootDisplayPreference
+ // Arg3 Bits [30:16] : Boot Device Ports
+ // Arg3 Bits [7:0] : Boot Device Type
+ // Return: Boot device port and Boot device type from saved configuration
+ //
+ Case(13) {
+ if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+
+ Store("GetBootDisplayPreference ", Debug)
+ Or(ShiftLeft(DerefOf (Index (Arg3,3)), 24), ShiftLeft(DerefOf (Index (Arg3,2)), 16), Local0) // Combine Arg3 Bits [31:16]
+ And(Local0, 0xEFFF0000, Local0)
+ And(Local0, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), Local0)
+ Or(IBTT, Local0, Local0) // Arg3 Bits [7:0] = Boot device type
+ Return(Local0)
+ }
+ }
+
+ //
+ // Function Index: 14
+ // GetPanelDetails
+ // Return: Different Panel Settings
+ //
+ Case(14) {
+ if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+ Store("GetPanelDetails ", Debug)
+
+ // Report the scaling setting
+ // Bits [7:0] - Panel Scaling
+ // Bits contain the panel scaling user setting from CMOS
+ // 00h = On: Auto
+ // 01h = On: Force Scaling
+ // 02h = Off
+ // 03h = Maintain Aspect Ratio
+
+ Store(IPSC, Local0)
+ Or(Local0, ShiftLeft(IPAT, 8), Local0)
+
+ // Adjust panel type, 0 = VBT default
+ // Bits [15:8] - Panel Type
+ // Bits contain the panel type user setting from CMOS
+ // 00h = Not Valid, use default Panel Type & Timings from VBT
+ // 01h - 0Fh = Panel Number
+
+ Add(Local0, 0x100, Local0)
+
+ // Report the lid state and Adjust it
+ // Bits [16] - Lid State
+ // Bits contain the current panel lid state
+ // 0 = Lid Open
+ // 1 = Lid Closed
+
+ Or(Local0, ShiftLeft(LIDS, 16), Local0)
+ Add(Local0, 0x10000, Local0)
+
+ // Report the BIA setting
+ // Bits [22:20] - Backlight Image Adaptation (BIA) Control
+ // Bits contain the backlight image adaptation control user setting from CMOS
+ // 000 = VBT Default
+ // 001 = BIA Disabled (BLC may still be enabled)
+ // 010 - 110 = BIA Enabled at Aggressiveness Level [1 - 5]
+
+ Or(Local0, ShiftLeft(IBIA, 20), Local0)
+ Return(Local0)
+ }
+ }
+
+ //
+ // Function Index: 15
+ // GetInternalGraphics
+ // Return: Different Internal Grahics Settings
+ //
+
+ Case(15) {
+ if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+ Store("GetInternalGraphics ", Debug)
+
+ Store(GIVD, Local0) // Local0[0] - VGA mode(1=VGA)
+ Xor(Local0, 1, Local0) // Invert the VGA mode polarity
+
+ Or(Local0, ShiftLeft(GMFN, 1), Local0) // Local0[1] - # IGD PCI functions-1
+ // Local0[3:2] - Reserved
+ // Local0[4] - IGD D3 support(0=cold)
+ // Local0[10:5] - Reserved
+ Or(Local0, ShiftLeft(3, 11), Local0) // Local0[12:11] - DVMT version (11b = 5.0)
+
+ //
+ // Report DVMT 5.0 Total Graphics memory size.
+ //
+ Or(Local0, ShiftLeft(IDMS, 17), Local0) // Bits 20:17 are for Gfx total memory size
+
+ // If the "Set Internal Graphics" call is supported, the modified
+ // settings flag must be programmed per the specification. This means
+ // that the flag must be set to indicate that system BIOS requests
+ // these settings. Once "Set Internal Graphics" is called, the
+ // modified settings flag must be cleared on all subsequent calls to
+ // this function.
+
+ // Report the graphics frequency based on B0:D2:F0:RF0h[12]. Must
+ // take into account the current VCO.
+
+ Or(ShiftLeft(DeRefOf(Index(DeRefOf(Index(CDCT, HVCO)), CDVL)), 21),Local0, Local0)
+ Return(Local0)
+ }
+ }
+
+ //
+ // Function Index: 16
+ // GetAKSV
+ // Retrun: 5 bytes of AKSV
+ //
+ Case(16) {
+ if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+
+ Store("GetAKSV ", Debug)
+ Name (KSVP, Package()
+ {
+ 0x80000000,
+ 0x8000
+ })
+ Store(KSV0, Index(KSVP,0)) // First four bytes of AKSV
+ Store(KSV1, Index(KSVP,1)) // Fifth byte of AKSV
+ Return(KSVP) // Success
+ }
+ }
+ } // End of switch(Arg2)
+
+ } // End of if (ToUUID("3E5B41C6-EB1D-4260-9D15-C71FBADAE414D"))
+
+ Return (Buffer () {0x00})
+} // End of _DSM
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl
new file mode 100644
index 0000000000..26e560a358
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl
@@ -0,0 +1,129 @@
+/** @file
+ IGD OpRegion/Software SCI Reference Code.
+ This file contains Get BIOS Data Area funciton support for
+ the Integrated Graphics Device (IGD) OpRegion/Software SCI mechanism
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+Method (GBDA, 0, Serialized)
+{
+ //
+ // Supported calls: Sub-function 0
+ //
+ If (LEqual(GESF, 0))
+ {
+ //
+ //<NOTE> Reference code is set to Intel's validated implementation.
+ //
+ Store(0x0000659, PARM)
+ Store(Zero, GESF) // Clear the exit parameter
+ Return(SUCC) // Success
+ }
+ //
+ // Requested callbacks: Sub-function 1
+ //
+ If (LEqual(GESF, 1))
+ {
+ //
+ //<NOTE> Call back functions are where the driver calls the
+ // system BIOS at function indicated event.
+ //
+ Store(0x300482, PARM)
+ If(LEqual(S0ID, One)){
+ Or(PARM, 0x100, PARM) //Request Fn 8 callback in CS systems
+ }
+ Store(Zero, GESF) // Clear the exit parameter
+ Return(SUCC) // Success
+ }
+ //
+ // Get Boot display Preferences: Sub-function 4
+ //
+ If (LEqual(GESF, 4))
+ {
+ //
+ //<NOTE> Get Boot Display Preferences function.
+ //
+ And(PARM, 0xEFFF0000, PARM) // PARM[30:16] = Boot device ports
+ And(PARM, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), PARM)
+ Or(IBTT, PARM, PARM) // PARM[7:0] = Boot device type
+ Store(Zero, GESF) // Clear the exit parameter
+ Return(SUCC) // Success
+ }
+ //
+ // Panel details: Sub-function 5
+ //
+ If (LEqual(GESF, 5))
+ {
+ //
+ //<NOTE> Get Panel Details function.
+ //
+ Store(IPSC, PARM) // Report the scaling setting
+ Or(PARM, ShiftLeft(IPAT, 8), PARM)
+ Add(PARM, 0x100, PARM) // Adjust panel type, 0 = VBT default
+ Or(PARM, ShiftLeft(LIDS, 16), PARM) // Report the lid state
+ Add(PARM, 0x10000, PARM) // Adjust the lid state, 0 = Unknown
+ Or(PARM, ShiftLeft(IBIA, 20), PARM) // Report the BIA setting
+ Store(Zero, GESF)
+ Return(SUCC)
+ }
+ //
+ // Internal graphics: Sub-function 7
+ //
+ If (LEqual(GESF, 7))
+ {
+ Store(GIVD, PARM) // PARM[0] - VGA mode(1=VGA)
+ Xor(PARM, 1, PARM) // Invert the VGA mode polarity
+ Or(PARM, ShiftLeft(GMFN, 1), PARM) // PARM[1] - # IGD PCI functions-1
+ // PARM[3:2] - Reserved
+ // PARM[4] - IGD D3 support(0=cold)
+ // PARM[10:5] - Reserved
+ Or(PARM, ShiftLeft(3, 11), PARM) // PARM[12:11] - DVMT mode(11b = 5.0)
+
+ //
+ // Report DVMT 5.0 Total Graphics memory size.
+ //
+ Or(PARM, ShiftLeft(IDMS, 17), PARM) // Bits 20:17 are for Gfx total memory size
+ //
+ // If the "Set Internal Graphics" call is supported, the modified
+ // settings flag must be programmed per the specification. This means
+ // that the flag must be set to indicate that system BIOS requests
+ // these settings. Once "Set Internal Graphics" is called, the
+ // modified settings flag must be cleared on all subsequent calls to
+ // this function.
+ // Report the graphics frequency based on B0:D2:F0:RF0h[12]. Must
+ // take into account the current VCO.
+ //
+ Or(ShiftLeft(Derefof(Index(Derefof(Index(CDCT, HVCO)), CDVL)), 21),PARM, PARM)
+ Store(1, GESF) // Set the modified settings flag
+ Return(SUCC)
+ }
+ //
+ // Spread spectrum clocks: Sub-function 10
+ //
+ If (LEqual(GESF, 10))
+ {
+ Store(0, PARM) // Assume SSC is disabled
+ If(ISSC)
+ {
+ Or(PARM, 3, PARM) // If SSC enabled, return SSC1+Enabled
+ }
+ Store(0, GESF) // Set the modified settings flag
+ Return(SUCC) // Success
+ }
+
+ If (LEqual(GESF, 11))
+ {
+ Store(KSV0, PARM) // First four bytes of AKSV
+ Store(KSV1, GESF) // Fifth byte of AKSV
+
+ Return(SUCC) // Success
+ }
+ //
+ // A call to a reserved "Get BIOS data" function was received.
+ //
+ Store(Zero, GESF) // Clear the exit parameter
+ Return(CRIT) // Reserved, "Critical failure"
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl
new file mode 100644
index 0000000000..a26cbdb00c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl
@@ -0,0 +1,296 @@
+/** @file
+ IGD OpRegion/Software SCI Reference Code.
+ This file contains the interrupt handler code for the Integrated
+ Graphics Device (IGD) OpRegion/Software SCI mechanism.
+ It defines OperationRegions to cover the IGD PCI configuration space
+ as described in the IGD OpRegion specification.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+// Define an OperationRegion to cover the GMCH PCI configuration space as
+// described in the IGD OpRegion specificiation.
+//
+Scope(\_SB.PCI0)
+{
+ OperationRegion(MCHP, PCI_Config, 0x40, 0xC0)
+ Field(MCHP, AnyAcc, NoLock, Preserve)
+ {
+ Offset(0x14),
+ AUDE, 8,
+
+ Offset(0x60), // Top of Memory register
+ TASM, 10, // Total system memory (64MB gran)
+ , 6,
+ }
+}
+
+//
+// Define an OperationRegion to cover the IGD PCI configuration space as
+// described in the IGD OpRegion specificiation.
+//
+OperationRegion(IGDP, PCI_Config, 0x40, 0xC0)
+Field(IGDP, AnyAcc, NoLock, Preserve)
+{
+ Offset(0x10), // Mirror of gfx control reg
+ , 1,
+ GIVD, 1, // IGD VGA disable bit
+ , 2,
+ GUMA, 3, // Stolen memory size
+ , 9,
+ Offset(0x14),
+ , 4,
+ GMFN, 1, // Gfx function 1 enable
+ , 27,
+ Offset(0xA4),
+ ASLE, 8, // Reg 0xE4, ASLE interrupt register
+ , 24, // Only use first byte of ASLE reg
+ Offset(0xA8), // Reg 0xE8, SWSCI control register
+ GSSE, 1, // Graphics SCI event (1=event pending)
+ GSSB, 14, // Graphics SCI scratchpad bits
+ GSES, 1, // Graphics event select (1=SCI)
+ Offset(0xB0), // Gfx Clk Frequency and Gating Control
+ , 12,
+ CDVL, 1, // Core display clock value
+ , 3, // Graphics Core Display Clock Select
+ Offset(0xB5),
+ LBPC, 8, // Legacy brightness control
+ Offset(0xBC),
+ ASLS, 32, // Reg 0xFC, Address of the IGD OpRegion
+}
+
+//
+// Define an OperationRegion to cover the IGD OpRegion layout.
+//
+OperationRegion(IGDM, SystemMemory, ASLB, 0x2000)
+Field(IGDM, AnyAcc, NoLock, Preserve)
+{
+ //
+ // OpRegion Header
+ //
+ SIGN, 128, // Signature-"IntelGraphicsMem"
+ SIZE, 32, // OpRegion Size
+ OVER, 32, // OpRegion Version
+ SVER, 256, // System BIOS Version
+ VVER, 128, // VBIOS Version
+ GVER, 128, // Driver version
+ MBOX, 32, // Mailboxes supported
+ DMOD, 32, // Driver Model
+ PCON, 32, // Platform Configuration
+ DVER, 64, // GOP Version
+ //
+ // OpRegion Mailbox 1 (Public ACPI Methods)
+ // Note: Mailbox 1 is normally reserved for desktop platforms.
+ //
+ Offset(0x100),
+ DRDY, 32, // Driver readiness (ACPI notification)
+ CSTS, 32, // Notification status
+ CEVT, 32, // Current event
+ Offset(0x120),
+ DIDL, 32, // Supported display device ID list
+ DDL2, 32, // Allows for 8 devices
+ DDL3, 32,
+ DDL4, 32,
+ DDL5, 32,
+ DDL6, 32,
+ DDL7, 32,
+ DDL8, 32,
+ CPDL, 32, // Currently present display list
+ CPL2, 32, // Allows for 8 devices
+ CPL3, 32,
+ CPL4, 32,
+ CPL5, 32,
+ CPL6, 32,
+ CPL7, 32,
+ CPL8, 32,
+ CADL, 32, // Currently active display list
+ CAL2, 32, // Allows for 8 devices
+ CAL3, 32,
+ CAL4, 32,
+ CAL5, 32,
+ CAL6, 32,
+ CAL7, 32,
+ CAL8, 32,
+ NADL, 32, // Next active display list
+ NDL2, 32, // Allows for 8 devices
+ NDL3, 32,
+ NDL4, 32,
+ NDL5, 32,
+ NDL6, 32,
+ NDL7, 32,
+ NDL8, 32,
+ ASLP, 32, // ASL sleep timeout
+ TIDX, 32, // Toggle table index
+ CHPD, 32, // Current hot plug enable indicator
+ CLID, 32, // Current lid state indicator
+ CDCK, 32, // Current docking state indicator
+ SXSW, 32, // Display switch notify on resume
+ EVTS, 32, // Events supported by ASL (diag only)
+ CNOT, 32, // Current OS notifications (diag only)
+ NRDY, 32,
+ //
+ //Extended DIDL list
+ //
+ DDL9, 32,
+ DD10, 32,
+ DD11, 32,
+ DD12, 32,
+ DD13, 32,
+ DD14, 32,
+ DD15, 32,
+ //
+ //Extended Currently attached Display Device List CPD2
+ //
+ CPL9, 32,
+ CP10, 32,
+ CP11, 32,
+ CP12, 32,
+ CP13, 32,
+ CP14, 32,
+ CP15, 32,
+ //
+ // OpRegion Mailbox 2 (Software SCI Interface)
+ //
+ Offset(0x200), // SCIC
+ SCIE, 1, // SCI entry bit (1=call unserviced)
+ GEFC, 4, // Entry function code
+ GXFC, 3, // Exit result
+ GESF, 8, // Entry/exit sub-function/parameter
+ , 16, // SCIC[31:16] reserved
+ Offset(0x204), // PARM
+ PARM, 32, // PARM register (extra parameters)
+ DSLP, 32, // Driver sleep time out
+ //
+ // OpRegion Mailbox 3 (BIOS to Driver Notification)
+ // Note: Mailbox 3 is normally reserved for desktop platforms.
+ //
+ Offset(0x300),
+ ARDY, 32, // Driver readiness (power conservation)
+ ASLC, 32, // ASLE interrupt command/status
+ TCHE, 32, // Technology enabled indicator
+ ALSI, 32, // Current ALS illuminance reading
+ BCLP, 32, // Backlight brightness
+ PFIT, 32, // Panel fitting state or request
+ CBLV, 32, // Current brightness level
+ BCLM, 320, // Backlight brightness level duty cycle mapping table
+ CPFM, 32, // Current panel fitting mode
+ EPFM, 32, // Enabled panel fitting modes
+ PLUT, 592, // Optional. 74-byte Panel LUT Table
+ PFMB, 32, // Optional. PWM Frequency and Minimum Brightness
+ CCDV, 32, // Optional. Gamma, Brightness, Contrast values.
+ PCFT, 32, // Optional. Power Conservation Features
+ SROT, 32, // Supported rotation angle.
+ IUER, 32, // Optional. Intel Ultrabook Event Register.
+ FDSS, 64, // Optional. FFS Display Physical address
+ FDSP, 32, // Optional. FFS Display Size
+ STAT, 32, // State Indicator
+ //
+ // OpRegion Mailbox 4 (VBT)
+ //
+ Offset(0x400),
+ RVBT, 0xC000, // 6K bytes maximum VBT image
+ //
+ // OpRegion Mailbox 5 (BIOS to Driver Notification Extension)
+ //
+ Offset(0x1C00),
+ PHED, 32, // Panel Header
+ BDDC, 2048, // Panel EDID (Max 256 bytes)
+
+}
+
+//
+// Convert boot display type into a port mask.
+//
+Name (DBTB, Package()
+{
+ 0x0000, // Automatic
+ 0x0007, // Port-0 : Integrated CRT
+ 0x0038, // Port-1 : DVO-A, or Integrated LVDS
+ 0x01C0, // Port-2 : SDVO-B, or SDVO-B/C
+ 0x0E00, // Port-3 : SDVO-C
+ 0x003F, // [CRT + DVO-A / Integrated LVDS]
+ 0x01C7, // [CRT + SDVO-B] or [CRT + SDVO-B/C]
+ 0x0E07, // [CRT + SDVO-C]
+ 0x01F8, // [DVO-A / Integrated LVDS + SDVO-B]
+ 0x0E38, // [DVO-A / Integrated LVDS + SDVO-C]
+ 0x0FC0, // [SDVO-B + SDVO-C]
+ 0x0000, // Reserved
+ 0x0000, // Reserved
+ 0x0000, // Reserved
+ 0x0000, // Reserved
+ 0x0000, // Reserved
+ 0x7000, // Port-4: Integrated TV
+ 0x7007, // [Integrated TV + CRT]
+ 0x7038, // [Integrated TV + LVDS]
+ 0x71C0, // [Integrated TV + DVOB]
+ 0x7E00 // [Integrated TV + DVOC]
+})
+
+//
+// Core display clock value table.
+//
+Name (CDCT, Package()
+{
+ Package() {228, 320},
+ Package() {222, 333},
+ Package() {222, 333},
+ Package() { 0, 0},
+ Package() {222, 333},
+})
+
+//
+// Defined exit result values:
+//
+Name (SUCC, 1) // Exit result: Success
+Name (NVLD, 2) // Exit result: Invalid parameter
+Name (CRIT, 4) // Exit result: Critical failure
+Name (NCRT, 6) // Exit result: Non-critical failure
+
+/************************************************************************;
+;*
+;* Name: GSCI
+;*
+;* Description: Handles an SCI generated by the graphics driver. The
+;* PARM and SCIC input fields are parsed to determine the
+;* functionality requested by the driver. GBDA or SBCB
+;* is called based on the input data in SCIC.
+;*
+;* Usage: The method must be called in response to a GPE 06 event
+;* which will be generated by the graphics driver.
+;* Ex: Method(\_GPE._L06) {Return(\_SB.PCI0.GFX0.GSCI())}
+;*
+;* Input: PARM and SCIC are indirect inputs
+;*
+;* Output: PARM and SIC are indirect outputs
+;*
+;* References: GBDA (Get BIOS Data method), SBCB (System BIOS Callback
+;* method)
+;*
+;************************************************************************/
+
+Method (GSCI, 0, Serialized)
+{
+ Include("IgfxOpGbda.asl") // "Get BIOS Data" Functions
+ Include("IgfxOpSbcb.asl") // "System BIOS CallBacks"
+
+ If (LEqual(GEFC, 4))
+ {
+ Store(GBDA(), GXFC) // Process Get BIOS Data functions
+ }
+
+ If (LEqual(GEFC, 6))
+ {
+ Store(SBCB(), GXFC) // Process BIOS Callback functions
+ }
+
+ Store(0, GEFC) // Wipe out the entry function code
+ Store(1, CPSC) // Clear CPUSCI_STS to clear the PCH TCO SCI status
+ Store(0, GSSE) // Clear the SCI generation bit in PCI space.
+ Store(0, SCIE) // Clr SCI serviced bit to signal completion
+
+ Return(Zero)
+}
+
+Include("IgfxCommon.asl") // IGD SCI mobile features
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl
new file mode 100644
index 0000000000..0167d922ff
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl
@@ -0,0 +1,262 @@
+/** @file
+ This file contains the system BIOS call back functionality for the
+ OpRegion/Software SCI mechanism.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+Method (SBCB, 0, Serialized)
+{
+ //
+ // Supported Callbacks: Sub-function 0
+ //
+ If (LEqual(GESF, 0x0))
+ {
+ //
+ //<NOTE> An OEM may support the driver->SBIOS status callbacks, but
+ // the supported callbacks value must be modified. The code that is
+ // executed upon reception of the callbacks must be also be updated
+ // to perform the desired functionality.
+ //
+ Store(0x00000000, PARM) // No callbacks supported
+ //Store(0x000787FD, PARM) // Used for Intel test implementaion
+ Store(0x000F87DD, PARM)
+ Store(Zero, GESF) // Clear the exit parameter
+ Return(SUCC) // "Success"
+ }
+ //
+ // BIOS POST Completion: Sub-function 1
+ //
+ If (LEqual(GESF, 1))
+ {
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Not supported, but no failure
+ }
+ //
+ // Pre-Hires Set Mode: Sub-function 3
+ //
+ If (LEqual(GESF, 3))
+ {
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Not supported, but no failure
+ }
+ //
+ // Post-Hires Set Mode: Sub-function 4
+ //
+ If (LEqual(GESF, 4))
+ {
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Not supported, but no failure
+ }
+ //
+ // Display Switch: Sub-function 5
+ //
+ If (LEqual(GESF, 5))
+ {
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Not supported, but no failure
+ }
+ //
+ // Adapter Power State: Sub-function 7
+ //
+ If (LEqual(GESF, 7))
+ {
+ //
+ // Handle Low Power S0 Idle Capability if enabled
+ //
+ If(LAnd(LEqual(S0ID, 1),LLess(OSYS, 2015))) {
+ //
+ // Call GUAM to trigger CS Entry
+ // If Adapter Power State Notification = D1 (PARM[7:0]=0x01)
+ //
+ If (LEqual (And(PARM,0xFF), 0x01)) {
+ // GUAM - Global User Absent Mode Notification Method
+ \GUAM(One) // 0x01 - Power State Standby (CS Entry)
+ }
+ If (LEqual (And(PARM,0xFF), 0x00)) {
+ // GUAM - Global User Absent Mode Notification Method
+ \GUAM(0)
+ }
+ }
+ //
+ // Upon notification from driver that the Adapter Power State = D0,
+ // check if previous lid event failed. If it did, retry the lid
+ // event here.
+ //
+ If(LEqual(PARM, 0))
+ {
+ Store(CLID, Local0)
+ If(And(0x80000000,Local0))
+ {
+ And(CLID, 0x0000000F, CLID)
+ GLID(CLID)
+ }
+ }
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Not supported, but no failure
+ }
+ //
+ // Display Power State: Sub-function 8
+ //
+ If (LEqual(GESF, 8))
+ {
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Not supported, but no failure
+ }
+ //
+ // Set Boot Display: Sub-function 9
+ //
+ If (LEqual(GESF, 9))
+ {
+ //
+ //<NOTE> An OEM may elect to implement this method. In that case,
+ // the input values must be saved into non-volatile storage for
+ // parsing during the next boot. The following Sample code is Intel
+ // validated implementation.
+ //
+ And(PARM, 0xFF, IBTT) // Save the boot display to NVS
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Reserved, "Critical failure"
+ }
+ //
+ // Set Panel Details: Sub-function 10 (0Ah)
+ //
+ If (LEqual(GESF, 10))
+ {
+ //
+ //<NOTE> An OEM may elect to implement this method. In that case,
+ // the input values must be saved into non-volatile storage for
+ // parsing during the next boot. The following Sample code is Intel
+ // validated implementation.
+ // Set the panel-related NVRAM variables based the input from the driver.
+ //
+ And(PARM, 0xFF, IPSC)
+ //
+ // Change panel type if a change is requested by the driver (Change if
+ // panel type input is non-zero). Zero=No change requested.
+ //
+ If(And(ShiftRight(PARM, 8), 0xFF))
+ {
+ And(ShiftRight(PARM, 8), 0xFF, IPAT)
+ Decrement(IPAT) // 0 = no change, so fit to CMOS map
+ }
+ And(ShiftRight(PARM, 20), 0x7, IBIA)
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Success
+ }
+ //
+ // Set Internal Graphics: Sub-function 11 (0Bh)
+ //
+ If (LEqual(GESF, 11))
+ {
+ //
+ //<NOTE> An OEM may elect to implement this method. In that case,
+ // the input values must be saved into non-volatile storage for
+ // parsing during the next boot. The following Sample code is Intel
+ // validated implementation.
+ //
+ And(ShiftRight(PARM, 1), 1, IF1E) // Program the function 1 option
+ If(And(PARM, ShiftLeft(0xF, 13))) // Use fixed memory if fixed size != 0
+ {
+ //
+ // Fixed memory
+ //
+ And(ShiftRight(PARM, 13), 0xF, IDMS) // Program fixed memory size
+ }
+ Else
+ {
+ //
+ // DVMT memory
+ //
+ And(ShiftRight(PARM, 17), 0xF, IDMS) // Program fixed memory size
+ }
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Success
+ }
+ //
+ // Post-Hires to DOS FS: Sub-function 16 (10h)
+ //
+ If (LEqual(GESF, 16))
+ {
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Not supported, but no failure
+ }
+ //
+ // APM Complete: Sub-function 17 (11h)
+ //
+ If (LEqual(GESF, 17))
+ {
+ Store(ShiftLeft(LIDS, 8), PARM) // Report the lid state
+ Add(PARM, 0x100, PARM) // Adjust the lid state, 0 = Unknown
+ Store(Zero, GESF) // Clear the exit parameter
+ Return(SUCC) // Not supported, but no failure
+ }
+ //
+ // Set Spread Spectrum Clocks: Sub-function 18 (12h)
+ //
+ If (LEqual(GESF, 18))
+ {
+ //
+ //<NOTE> An OEM may elect to implement this method. In that case,
+ // the input values must be saved into non-volatile storage for
+ // parsing during the next boot. The following Sample code is Intel
+ // validated implementation.
+ //
+ If(And(PARM, 1))
+ {
+ If(LEqual(ShiftRight(PARM, 1), 1))
+ {
+ Store(1, ISSC) // Enable HW SSC, only for clock 1
+ }
+ Else
+ {
+ Store(Zero, GESF)
+ Return(CRIT) // Failure, as the SSC clock must be 1
+ }
+ }
+ Else
+ {
+ Store(0, ISSC) // Disable SSC
+ }
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Success
+ }
+ //
+ // Post VBE/PM Callback: Sub-function 19 (13h)
+ //
+ If (LEqual(GESF, 19))
+ {
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Not supported, but no failure
+ }
+ //
+ // Set PAVP Data: Sub-function 20 (14h)
+ //
+ If (LEqual(GESF, 20))
+ {
+ And(PARM, 0xF, PAVP) // Store PAVP info
+ Store(Zero, GESF) // Clear the exit parameter
+ Store(Zero, PARM)
+ Return(SUCC) // Success
+ }
+
+ //
+ // A call to a reserved "System BIOS callbacks" function was received
+ //
+ Store(Zero, GESF) // Clear the exit parameter
+ Return(SUCC) // Reserved, "Critical failure"
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
new file mode 100644
index 0000000000..e4e47ddf1e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
@@ -0,0 +1,87 @@
+/** @file
+ This file contains the device definition of the System Agent
+ ACPI reference code.
+ Currently defines the device objects for the
+ System Agent IPU device
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Device IPUA is the IPU AVStream virtual device and it appears under GFX0
+//
+Scope (\_SB.PCI0.GFX0)
+{
+ Device(IPUA) // IPU AVStream virtual device name
+ {
+ /*
+ The identifier for this device (Same as in
+ _DOD above). This is required so GFX driver can
+ associate a matching device ID for the AVStream
+ driver and provide it to PnP (this device ID
+ should appear in the INF file of the AVStream
+ driver).
+ */
+ Name(_ADR, 0x00003480)
+ /*
+ The following is a technique that may be used (per OEM needs) to prevent
+ the load of the camera device in one of the following cases:
+ - Camera device is fused out
+ - If the platform setup requires that in a secured boot the camera device
+ should not be enabled
+ */
+ Method (_STA, 0, NotSerialized) {
+ If(LEqual(IPTP,1)){ // IGFX need report IPU AVStream virtual device as GFX0 child
+ Return (0xF)
+ } Else { // IGFX should NOT report IPU AVStream virtual device as GFX0 child
+ Return (0x0)
+ }
+ }
+ } // End SKC0
+} // end I.G.D
+
+Scope(\_SB.PCI0.IPU0)
+{
+//----------------------------------------------------------------------------------------
+// Intel Proprietary Passing LTR information from BIOS to IPU Driver. DSM Method
+//
+// Method(_DSM, 0x4, Serialized, 0, {IntObj, BuffObj}, {BuffObj, IntObj, IntObj, PkgObj})
+// Arguments:
+// Arg0: GUID: "9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90"
+// Arg1: Integer Revision Level (Current revision is 0)
+// Arg2: Integer Function Index
+// 0x1 - return UINT 32bit LTR values
+// 0x2 - return UINT 32bit Fill Time
+//
+//-----------------------------------------------------------------------------------------
+Method (_DSM, 4, NotSerialized) { // _DSM: Device-Specific Method
+ If (LEqual(Arg0, ToUUID("9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90")))
+ {
+ // Function 0 : Query Function
+ If (LEqual(Arg2, 0))
+ {
+ // Revision 0
+ If (LEqual(Arg1, 0)) // The current revision is 0
+ {
+ Return(Buffer() { 0x07 }) // There are 2 function defined other than Query.
+ } Else {
+ Return(0) // Revision mismatch
+ }
+ }
+ // Function 1 : Return UINT 32bit LTR values
+ If(LEqual(Arg2, 1))
+ {
+ Return(0x64503C19)
+ }
+ // Function 2 : Return UINT 32bit Fill Time
+ If(LEqual(Arg2, 2))
+ {
+ Return(0xFFF0783C)
+ }
+ }
+
+ Return(0) // Function number or GUID mismatch but normal return.
+ }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
new file mode 100644
index 0000000000..4817968240
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
@@ -0,0 +1,31 @@
+/** @file
+ This file contains the device definition of the System Agent
+ ACPI reference code.
+ Currently defines the device objects for the
+ System Agent PCI Express* ports (PEG), iGfx and other devices.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(\_SB.PCI0, DeviceObj)
+External(\_SB.PCI0.GFX0, DeviceObj)
+External(\_SB.PCI0.IPU0, DeviceObj)
+External(\_SB.PCI0.B0D3, DeviceObj)
+External(\_SB.PCI0.PCIC, MethodObj)
+External(\_SB.PCI0.PCID, MethodObj)
+
+
+///
+/// I.G.D
+///
+Scope (\_SB.PCI0.GFX0)
+{
+ include("Igfx.asl")
+} // end I.G.D
+
+///
+/// IPU Device
+///
+include("Ipu.asl")
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
new file mode 100644
index 0000000000..09d36ade53
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
@@ -0,0 +1,147 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+ //
+ // Define SA NVS Area operatino region.
+ //
+
+
+
+ OperationRegion(SANV,SystemMemory, 0xFFFF0000,0xAA55)
+ Field(SANV,AnyAcc,Lock,Preserve)
+ { Offset(0), ASLB, 32, // Offset(0), IGD OpRegion base address
+ Offset(4), IMON, 8, // Offset(4), IMON Current Value
+ Offset(5), IGDS, 8, // Offset(5), IGD State (Primary Display = 1)
+ Offset(6), IBTT, 8, // Offset(6), IGD Boot Display Device
+ Offset(7), IPAT, 8, // Offset(7), IGD Panel Type CMOS option
+ Offset(8), IPSC, 8, // Offset(8), IGD Panel Scaling
+ Offset(9), IBIA, 8, // Offset(9), IGD BIA Configuration
+ Offset(10), ISSC, 8, // Offset(10), IGD SSC Configuration
+ Offset(11), IDMS, 8, // Offset(11), IGD DVMT Memory Size
+ Offset(12), IF1E, 8, // Offset(12), IGD Function 1 Enable
+ Offset(13), HVCO, 8, // Offset(13), HPLL VCO
+ Offset(14), GSMI, 8, // Offset(14), GMCH SMI/SCI mode (0=SCI)
+ Offset(15), PAVP, 8, // Offset(15), IGD PAVP data
+ Offset(16), CADL, 8, // Offset(16), Current Attached Device List
+ Offset(17), CSTE, 16, // Offset(17), Current Display State
+ Offset(19), NSTE, 16, // Offset(19), Next Display State
+ Offset(21), NDID, 8, // Offset(21), Number of Valid Device IDs
+ Offset(22), DID1, 32, // Offset(22), Device ID 1
+ Offset(26), DID2, 32, // Offset(26), Device ID 2
+ Offset(30), DID3, 32, // Offset(30), Device ID 3
+ Offset(34), DID4, 32, // Offset(34), Device ID 4
+ Offset(38), DID5, 32, // Offset(38), Device ID 5
+ Offset(42), DID6, 32, // Offset(42), Device ID 6
+ Offset(46), DID7, 32, // Offset(46), Device ID 7
+ Offset(50), DID8, 32, // Offset(50), Device ID 8
+ Offset(54), DID9, 32, // Offset(54), Device ID 9
+ Offset(58), DIDA, 32, // Offset(58), Device ID 10
+ Offset(62), DIDB, 32, // Offset(62), Device ID 11
+ Offset(66), DIDC, 32, // Offset(66), Device ID 12
+ Offset(70), DIDD, 32, // Offset(70), Device ID 13
+ Offset(74), DIDE, 32, // Offset(74), Device ID 14
+ Offset(78), DIDF, 32, // Offset(78), Device ID 15
+ Offset(82), DIDX, 32, // Offset(82), Device ID for eDP device
+ Offset(86), NXD1, 32, // Offset(86), Next state DID1 for _DGS
+ Offset(90), NXD2, 32, // Offset(90), Next state DID2 for _DGS
+ Offset(94), NXD3, 32, // Offset(94), Next state DID3 for _DGS
+ Offset(98), NXD4, 32, // Offset(98), Next state DID4 for _DGS
+ Offset(102), NXD5, 32, // Offset(102), Next state DID5 for _DGS
+ Offset(106), NXD6, 32, // Offset(106), Next state DID6 for _DGS
+ Offset(110), NXD7, 32, // Offset(110), Next state DID7 for _DGS
+ Offset(114), NXD8, 32, // Offset(114), Next state DID8 for _DGS
+ Offset(118), NXDX, 32, // Offset(118), Next state DID for eDP
+ Offset(122), LIDS, 8, // Offset(122), Lid State (Lid Open = 1)
+ Offset(123), KSV0, 32, // Offset(123), First four bytes of AKSV (manufacturing mode)
+ Offset(127), KSV1, 8, // Offset(127), Fifth byte of AKSV (manufacturing mode)
+ Offset(128), BRTL, 8, // Offset(128), Brightness Level Percentage
+ Offset(129), ALSE, 8, // Offset(129), Ambient Light Sensor Enable
+ Offset(130), ALAF, 8, // Offset(130), Ambient Light Adjusment Factor
+ Offset(131), LLOW, 8, // Offset(131), LUX Low Value
+ Offset(132), LHIH, 8, // Offset(132), LUX High Value
+ Offset(133), ALFP, 8, // Offset(133), Active LFP
+ Offset(134), IPTP, 8, // Offset(134), IPU ACPI device type (0=Disabled, 1=AVStream virtual device as child of GFX)
+ Offset(135), EDPV, 8, // Offset(135), Check for eDP display device
+ Offset(136), SGMD, 8, // Offset(136), SG Mode (0=Disabled, 1=SG Muxed, 2=SG Muxless, 3=DGPU Only)
+ Offset(137), SGFL, 8, // Offset(137), SG Feature List
+ Offset(138), SGGP, 8, // Offset(138), PCIe0 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+ Offset(139), HRE0, 8, // Offset(139), PCIe0 HLD RST IO Expander Number
+ Offset(140), HRG0, 32, // Offset(140), PCIe0 HLD RST GPIO Number
+ Offset(144), HRA0, 8, // Offset(144), PCIe0 HLD RST GPIO Active Information
+ Offset(145), PWE0, 8, // Offset(145), PCIe0 PWR Enable IO Expander Number
+ Offset(146), PWG0, 32, // Offset(146), PCIe0 PWR Enable GPIO Number
+ Offset(150), PWA0, 8, // Offset(150), PCIe0 PWR Enable GPIO Active Information
+ Offset(151), P1GP, 8, // Offset(151), PCIe1 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+ Offset(152), HRE1, 8, // Offset(152), PCIe1 HLD RST IO Expander Number
+ Offset(153), HRG1, 32, // Offset(153), PCIe1 HLD RST GPIO Number
+ Offset(157), HRA1, 8, // Offset(157), PCIe1 HLD RST GPIO Active Information
+ Offset(158), PWE1, 8, // Offset(158), PCIe1 PWR Enable IO Expander Number
+ Offset(159), PWG1, 32, // Offset(159), PCIe1 PWR Enable GPIO Number
+ Offset(163), PWA1, 8, // Offset(163), PCIe1 PWR Enable GPIO Active Information
+ Offset(164), P2GP, 8, // Offset(164), PCIe2 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+ Offset(165), HRE2, 8, // Offset(165), PCIe2 HLD RST IO Expander Number
+ Offset(166), HRG2, 32, // Offset(166), PCIe2 HLD RST GPIO Number
+ Offset(170), HRA2, 8, // Offset(170), PCIe2 HLD RST GPIO Active Information
+ Offset(171), PWE2, 8, // Offset(171), PCIe2 PWR Enable IO Expander Number
+ Offset(172), PWG2, 32, // Offset(172), PCIe2 PWR Enable GPIO Number
+ Offset(176), PWA2, 8, // Offset(176), PCIe2 PWR Enable GPIO Active Information
+ Offset(177), DLPW, 16, // Offset(177), Delay after power enable for PCIe
+ Offset(179), DLHR, 16, // Offset(179), Delay after Hold Reset for PCIe
+ Offset(181), EECP, 8, // Offset(181), PCIe0 Endpoint Capability Structure Offset
+ Offset(182), XBAS, 32, // Offset(182), Any Device's PCIe Config Space Base Address
+ Offset(186), GBAS, 16, // Offset(186), GPIO Base Address
+ Offset(188), NVGA, 32, // Offset(188), NVIG opregion address
+ Offset(192), NVHA, 32, // Offset(192), NVHM opregion address
+ Offset(196), AMDA, 32, // Offset(196), AMDA opregion address
+ Offset(200), LTRX, 8, // Offset(200), Latency Tolerance Reporting Enable
+ Offset(201), OBFX, 8, // Offset(201), Optimized Buffer Flush and Fill
+ Offset(202), LTRY, 8, // Offset(202), Latency Tolerance Reporting Enable
+ Offset(203), OBFY, 8, // Offset(203), Optimized Buffer Flush and Fill
+ Offset(204), LTRZ, 8, // Offset(204), Latency Tolerance Reporting Enable
+ Offset(205), OBFZ, 8, // Offset(205), Optimized Buffer Flush and Fill
+ Offset(206), LTRW, 8, // Offset(206), Latency Tolerance Reporting Enable
+ Offset(207), OBFA, 8, // Offset(207), Optimized Buffer Flush and Fill
+ Offset(208), SMSL, 16, // Offset(208), SA Peg Latency Tolerance Reporting Max Snoop Latency
+ Offset(210), SNSL, 16, // Offset(210), SA Peg Latency Tolerance Reporting Max No Snoop Latency
+ Offset(212), P0UB, 8, // Offset(212), Peg0 Unused Bundle Control
+ Offset(213), P1UB, 8, // Offset(213), Peg1 Unused Bundle Control
+ Offset(214), P2UB, 8, // Offset(214), Peg2 Unused Bundle Control
+ Offset(215), P3UB, 8, // Offset(215), Peg3 Unused Bundle Control
+ Offset(216), PCSL, 8, // Offset(216), The lowest C-state for the package
+ Offset(217), PBGE, 8, // Offset(217), Pegx Unused Bundle Control Global Enable (0=Disabled, 1=Enabled)
+ Offset(218), M64B, 64, // Offset(218), Base of above 4GB MMIO resource
+ Offset(226), M64L, 64, // Offset(226), Length of above 4GB MMIO resource
+ Offset(234), CPEX, 32, // Offset(234), CPU ID info to get Family Id or Stepping
+ Offset(238), EEC1, 8, // Offset(238), PCIe1 Endpoint Capability Structure Offset
+ Offset(239), EEC2, 8, // Offset(239), PCIe2 Endpoint Capability Structure Offset
+ Offset(240), SBN0, 8, // Offset(240), PCIe0 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+ Offset(241), SBN1, 8, // Offset(241), PCIe1 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+ Offset(242), SBN2, 8, // Offset(242), PCIe2 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+ Offset(243), M32B, 32, // Offset(243), Base of below 4GB MMIO resource
+ Offset(247), M32L, 32, // Offset(247), Length of below 4GB MMIO resource
+ Offset(251), P0WK, 32, // Offset(251), PCIe0 RTD3 Device Wake GPIO Number
+ Offset(255), P1WK, 32, // Offset(255), PCIe1 RTD3 Device Wake GPIO Number
+ Offset(259), P2WK, 32, // Offset(259), PCIe2 RTD3 Device Wake GPIO Number
+ Offset(263), VTDS, 8, // Offset(263), VT-d Enable/Disable
+ Offset(264), VTB1, 32, // Offset(264), VT-d Base Address 1
+ Offset(268), VTB2, 32, // Offset(268), VT-d Base Address 2
+ Offset(272), VTB3, 32, // Offset(272), VT-d Base Address 3
+ Offset(276), VE1V, 16, // Offset(276), VT-d Engine#1 Vendor ID
+ Offset(278), VE2V, 16, // Offset(278), VT-d Engine#2 Vendor ID
+ Offset(280), SBN3, 8, // Offset(280), PCIe3 Secondary Bus Number (PCIe3 Endpoint Bus Number)
+ Offset(281), P3GP, 8, // Offset(281), PCIe3 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+ Offset(282), HRE3, 8, // Offset(282), PCIe3 HLD RST IO Expander Number
+ Offset(283), HRG3, 32, // Offset(283), PCIe3 HLD RST GPIO Number
+ Offset(287), HRA3, 8, // Offset(287), PCIe3 HLD RST GPIO Active Information
+ Offset(288), PWE3, 8, // Offset(288), PCIe3 PWR Enable IO Expander Number
+ Offset(289), PWG3, 32, // Offset(289), PCIe3 PWR Enable GPIO Number
+ Offset(293), PWA3, 8, // Offset(293), PCIe3 PWR Enable GPIO Active Information
+ Offset(294), P3WK, 32, // Offset(294), PCIe3 RTD3 Device Wake GPIO Number
+ Offset(298), EEC3, 8, // Offset(298), PCIe3 Endpoint Capability Structure Offset
+ Offset(299), RPIN, 8, // Offset(299), RootPort Number
+ Offset(300), RPBA, 32, // Offset(300), RootPortAddress
+ Offset (500), // Offset(304) : Offset(499), Reserved bytes
+ }
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
new file mode 100644
index 0000000000..0db354901d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
@@ -0,0 +1,22 @@
+/** @file
+ This file contains the SystemAgent SSDT Table ASL code.
+ It defines a Global NVS table which exchanges datas between OS
+ and BIOS.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+DefinitionBlock (
+ "SaSsdt.aml",
+ "SSDT",
+ 0x02,
+ "SaSsdt",
+ "SaSsdt ",
+ 0x3000
+ )
+{
+ include ("SaNvs.asl")
+ include ("Sa.asl")
+}
--
2.16.2.windows.1
next prev parent reply other threads:[~2019-08-17 0:16 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 ` Kubacki, Michael A [this message]
2019-08-17 0:53 ` [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Nate DeSimone
2019-08-17 1:15 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:14 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:15 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-19 18:09 ` Sinha, Ankit
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-17 0:16 ` [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: " Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:17 ` Chiu, Chasel
2019-08-17 20:08 ` Chaganty, Rangasai V
2019-08-17 0:16 ` [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:17 ` Chiu, Chasel
2019-08-17 7:50 ` Chaganty, Rangasai V
2019-08-17 0:16 ` [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-17 20:11 ` Chaganty, Rangasai V
2019-08-17 0:16 ` [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:17 ` Chiu, Chasel
2019-08-17 20:00 ` Chaganty, Rangasai V
2019-08-19 18:14 ` [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Sinha, Ankit
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=20190817001603.30632-29-michael.a.kubacki@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