From: "Chiu, Chasel" <chasel.chiu@intel.com>
To: "Kubacki, Michael A" <michael.a.kubacki@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Chaganty, Rangasai V" <rangasai.v.chaganty@intel.com>,
"Desimone, Nathaniel L" <nathaniel.l.desimone@intel.com>,
"Gao, Liming" <liming.gao@intel.com>,
"Kinney, Michael D" <michael.d.kinney@intel.com>,
"Sinha, Ankit" <ankit.sinha@intel.com>
Subject: Re: [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules
Date: Sat, 17 Aug 2019 01:15:10 +0000 [thread overview]
Message-ID: <3C3EFB470A303B4AB093197B6777CCEC504623CD@PGSMSX111.gar.corp.intel.com> (raw)
In-Reply-To: <20190817001603.30632-29-michael.a.kubacki@intel.com>
Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent:
> Add modules
>
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
>
> * SaAcpiTables - SA (DMAR) ACPI tables.
> * SaSsdt - SA SSDT ACPI tables.
> * SaInitDxe - Generic DXE SA initialization.
> * SmmAccess - Produces an instance of EFI_SMM_ACCESS2_PROTOCOL.
>
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
> | 50 +
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
> | 49 +
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> | 116 ++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess
> .inf | 48 +
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
> | 25 +
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcCommonTypes.h | 230 +++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcInterface.h | 1567 ++++++++++++++++++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcRmtData.h | 203 +++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcSpdData.h | 1167 ++++++++++++++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcTypes.h | 237 +++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInt
> erface.h | 15 +
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
> | 50 +
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.
> h | 193 +++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
> | 91 ++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
> | 23 +
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
> | 71 +
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
> | 139 ++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraph
> icsInit.h | 17 +
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
> | 53 +
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess
> Driver.h | 162 ++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
> | 157 ++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.
> c | 570 +++++++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
> | 171 ++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
> | 171 ++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
> | 496 ++++++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
> | 179 +++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
> | 122 ++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
> | 717 +++++++++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess
> Driver.c | 356 +++++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
> | 250 +++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
> | 794 ++++++++++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
> | 1666 ++++++++++++++++++++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCom
> mon.asl | 472 ++++++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.a
> sl | 369 +++++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGb
> da.asl | 129 ++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.
> asl | 296 ++++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbc
> b.asl | 262 +++
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
> | 87 +
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
> | 31 +
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
> | 147 ++
>
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
> | 22 +
> 41 files changed, 11970 insertions(+)
>
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.i
> nf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.i
> nf
> new file mode 100644
> index 0000000000..56ddc2957f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.i
> nf
> @@ -0,0 +1,50 @@
> +## @file
> +# Component description file for the ACPI tables
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010005
> +BASE_NAME = SaAcpiTables
> +FILE_GUID = 3c0ed5e2-91ea-4b94-820d-9daf9a3bb4a2
> +MODULE_TYPE = USER_DEFINED
> +VERSION_STRING = 1.0
> +
> +[Sources]
> + Dmar/Dmar.aslc
> + Dmar/Dmar.h
> +
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + CoffeelakeSiliconPkg/SiPkg.dec
> +
> +###############################################################
> #################
> +#
> +# Library Class Section - list of Library Classes that are required for
> +# this module.
> +#
> +###############################################################
> #################
> +
> +[LibraryClasses]
> +
> +###############################################################
> #################
> +#
> +# Protocol C Name Section - list of Protocol and Protocol Notify C Names
> +# that this module uses or produces.
> +#
> +###############################################################
> #################
> +[Pcd]
> +
> +[Protocols]
> +
> +[PPIs]
> +
> +[Guids]
> +
> +[Depex]
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.i
> nf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> inf
> new file mode 100644
> index 0000000000..3588565aac
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> inf
> @@ -0,0 +1,49 @@
> +## @file
> +# Component description file for the ACPI tables
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010005
> +BASE_NAME = SaSsdt
> +FILE_GUID = ca89914d-2317-452e-b245-36c6fb77a9c6
> +MODULE_TYPE = USER_DEFINED
> +VERSION_STRING = 1.0
> +
> +[Sources]
> + SaSsdt.asl
> +
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + CoffeelakeSiliconPkg/SiPkg.dec
> +
> +###############################################################
> #################
> +#
> +# Library Class Section - list of Library Classes that are required for
> +# this module.
> +#
> +###############################################################
> #################
> +
> +[LibraryClasses]
> +
> +###############################################################
> #################
> +#
> +# Protocol C Name Section - list of Protocol and Protocol Notify C Names
> +# that this module uses or produces.
> +#
> +###############################################################
> #################
> +[Pcd]
> +
> +[Protocols]
> +
> +[PPIs]
> +
> +[Guids]
> +
> +[Depex]
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> new file mode 100644
> index 0000000000..9937fc60e5
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> @@ -0,0 +1,116 @@
> +## @file
> +# Component description file for SystemAgent Initialization driver
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = SaInitDxe
> +FILE_GUID = DE23ACEE-CF55-4fb6-AA77-984AB53DE811
> +VERSION_STRING = 1.0
> +MODULE_TYPE = DXE_DRIVER
> +ENTRY_POINT = SaInitEntryPointDxe
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[LibraryClasses]
> +UefiDriverEntryPoint
> +UefiLib
> +UefiBootServicesTableLib
> +DxeServicesTableLib
> +DebugLib
> +TimerLib
> +PciCf8Lib
> +PciSegmentLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +CpuPlatformLib
> +IoLib
> +S3BootScriptLib
> +PmcLib
> +PchCycleDecodingLib
> +PchInfoLib
> +GpioLib
> +ConfigBlockLib
> +SaPlatformLib
> +PchPcieRpLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +UefiCpuPkg/UefiCpuPkg.dec
> +IntelSiliconPkg/IntelSiliconPkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +PcAtChipsetPkg/PcAtChipsetPkg.dec
> +
> +[Pcd]
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
> +gSiPkgTokenSpaceGuid.PcdMchBaseAddress
> +gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress
> +
> +[Sources]
> +SaInitDxe.h
> +SaInitDxe.c
> +SaInit.h
> +SaInit.c
> +VTd.c
> +VTd.h
> +IgdOpRegionInit.h
> +IgdOpRegionInit.c
> +GraphicsInit.h
> +GraphicsInit.c
> +PciExpressInit.h
> +PciExpressInit.c
> +PcieComplex.c
> +PcieComplex.h
> +SaAcpi.c
> +
> +[Protocols]
> +gEfiAcpiTableProtocolGuid ## CONSUMES
> +gSaNvsAreaProtocolGuid ## PRODUCES
> +gSaPolicyProtocolGuid ## CONSUMES
> +gEfiCpuArchProtocolGuid ## CONSUMES
> +gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
> +gEfiPciRootBridgeIoProtocolGuid ## CONSUMES
> +gEfiPciIoProtocolGuid ## CONSUMES
> +gIgdOpRegionProtocolGuid ## PRODUCES
> +gEfiFirmwareVolume2ProtocolGuid ## CONSUMES
> +gEfiLegacyBiosProtocolGuid ## CONSUMES
> +gGopComponentName2ProtocolGuid ## CONSUMES
> +gSaIotrapSmiProtocolGuid ## CONSUMES
> +
> +[Guids]
> +gSaConfigHobGuid
> +gSgAcpiTablePchStorageGuid
> +gSaAcpiTableStorageGuid
> +gSgAcpiTableStorageGuid
> +gSaSsdtAcpiTableStorageGuid
> +gPegSsdtAcpiTableStorageGuid
> +gEfiEndOfDxeEventGroupGuid
> +gSiConfigHobGuid ## CONSUMES
> +gMiscDxeConfigGuid
> +gGraphicsDxeConfigGuid
> +gMemoryDxeConfigGuid
> +gPcieDxeConfigGuid
> +gVbiosDxeConfigGuid
> +gPchInfoHobGuid
> +
> +[Depex]
> +gEfiAcpiTableProtocolGuid AND
> +gEfiFirmwareVolume2ProtocolGuid AND
> +gSaPolicyProtocolGuid AND
> +gEfiPciRootBridgeIoProtocolGuid AND
> +gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure
> that PCI MMIO resource has been prepared and available for this driver to
> allocate.
> +gEfiHiiDatabaseProtocolGuid
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ss.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ss.inf
> new file mode 100644
> index 0000000000..9356781c9e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ss.inf
> @@ -0,0 +1,48 @@
> +## @file
> +# Component description file for the SmmAccess module
> +#
> +# {1323C7F8-DAD5-4126-A54B-7A05FBF41515}
> +#
> +# Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = SmmAccess
> +FILE_GUID = 1323C7F8-DAD5-4126-A54B-7A05FBF41515
> +VERSION_STRING = 1.0
> +MODULE_TYPE = DXE_DRIVER
> +ENTRY_POINT = SmmAccessDriverEntryPoint
> +
> +
> +[LibraryClasses]
> +UefiDriverEntryPoint
> +BaseLib
> +BaseMemoryLib
> +DebugLib
> +HobLib
> +PciLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +SmmAccessDriver.h
> +SmmAccessDriver.c
> +
> +
> +[Protocols]
> +gEfiSmmAccess2ProtocolGuid ## PRODUCES
> +
> +
> +[Guids]
> +gEfiSmmPeiSmramMemoryReserveGuid
> +
> +
> +[Depex]
> +TRUE
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
> new file mode 100644
> index 0000000000..4339256bba
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
> @@ -0,0 +1,25 @@
> +/** @file
> + This file describes the contents of the ACPI DMA address Remapping
> + Some additional ACPI values are defined in Acpi1_0.h and Acpi2_0.h.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_DMAR_H_
> +#define _SA_DMAR_H_
> +
> +///
> +/// Include standard ACPI table definitions
> +///
> +#include <IndustryStandard/Acpi30.h>
> +#include <DmaRemappingTable.h>
> +
> +#pragma pack(1)
> +
> +#define EFI_ACPI_DMAR_OEM_TABLE_ID 0x20202020324B4445 ///<
> "EDK2 "
> +#define EFI_ACPI_DMAR_OEM_CREATOR_ID 0x4C544E49 ///< "INTL"
> +#pragma pack()
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcCommonTypes.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcCommonTypes.h
> new file mode 100644
> index 0000000000..54cb69066d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcCommonTypes.h
> @@ -0,0 +1,230 @@
> +/** @file
> + This file contains the definitions common to the MRC API and other APIs.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MrcCommonTypes_h_
> +#define _MrcCommonTypes_h_
> +
> +#define INT32_MIN (0x80000000)
> +#ifndef INT32_MAX //INT32_MAX->Already defined
> +#define INT32_MAX (0x7FFFFFFF)
> +#endif
> +#define INT16_MIN (0x8000)
> +#define INT16_MAX (0x7FFF)
> +
> +///
> +/// System boot mode.
> +///
> +typedef enum {
> + bmCold, ///< Cold boot
> + bmWarm, ///< Warm boot
> + bmS3, ///< S3 resume
> + bmFast, ///< Fast boot
> + MrcBootModeMax, ///< MRC_BOOT_MODE enumeration
> maximum value.
> + MrcBootModeDelim = INT32_MAX ///< This value ensures the
> enum size is consistent on both sides of the PPI.
> +} MrcBootMode;
> +
> +///
> +/// DIMM memory package
> +/// This enum matches SPD Module Type - SPD byte 3, bits [3:0]
> +/// Note that DDR4 have different encoding for some module types
> +///
> +typedef enum {
> + RDimmMemoryPackage = 1,
> + UDimmMemoryPackage = 2,
> + SoDimmMemoryPackage = 3,
> + MicroDimmMemoryPackageDdr3 = 4,
> + LrDimmMemoryPackageDdr4 = 4,
> + MiniRDimmMemoryPackage = 5,
> + MiniUDimmMemoryPackage = 6,
> + MiniCDimmMemoryPackage = 7,
> + LpDimmMemoryPackage = 7,
> + SoUDimmEccMemoryPackageDdr3 = 8,
> + SoRDimmEccMemoryPackageDdr4 = 8,
> + SoRDimmEccMemoryPackageDdr3 = 9,
> + SoUDimmEccMemoryPackageDdr4 = 9,
> + SoCDimmEccMemoryPackage = 10,
> + LrDimmMemoryPackage = 11,
> + SoDimm16bMemoryPackage = 12,
> + SoDimm32bMemoryPackage = 13,
> + NonDimmMemoryPackage = 14,
> + MemoryPackageMax, ///< MEMORY_PACKAGE
> enumeration maximum value.
> + MemoryPackageDelim = INT32_MAX ///< This value ensures the
> enum size is consistent on both sides of the PPI.
> +} MEMORY_PACKAGE;
> +
> +///
> +/// Memory training I/O levels.
> +///
> +typedef enum {
> + DdrLevel = 0, ///< Refers to frontside of DIMM
> + LrbufLevel = 1, ///< Refers to data level at backside of
> LRDIMM or AEP buffer
> + RegALevel = 2, ///< Refers to cmd level at backside of
> register - side A
> + RegBLevel = 3, ///< Refers to cmd level at backside of
> register - side B
> + GsmLtMax, ///< GSM_LT enumeration maximum
> value.
> + GsmLtDelim = INT32_MAX ///< This value ensures the enum
> size is consistent on both sides of the PPI.
> +} GSM_LT;
> +
> +///
> +/// Memory training margin group selectors.
> +///
> +typedef enum {
> + RecEnDelay = 0, ///< Linear delay (PI ticks), where the
> positive increment moves the RCVEN sampling window later in time relative to
> the RX DQS strobes.
> + RxDqsDelay = 1, ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS strobe later in time relative to the RX DQ
> signal (i.e. toward the hold side of the eye).
> + RxDqDelay = 2, ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQ byte/nibble/bitlane later in time relative
> to the RX DQS signal (i.e.closing the gap between DQ and DQS in the setup side
> of the eye).
> + RxDqsPDelay = 3, ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS strobe for "even" chunks later in time
> relative to the RX DQ signal. Even chunks are 0, 2, 4, 6 within the 0 to 7 chunks
> of an 8 burst length cacheline, for example.
> + RxDqsNDelay = 4, ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS strobe for "odd" chunks later in time
> relative to the RX DQ signal. Odd chunks are 1, 3, 5, 7 within the 0 to 7 chunks
> of an 8 burst length cacheline, for example.
> + RxVref = 5, ///< Linear increment (Vref ticks), where the
> positive increment moves the byte/nibble/bitlane RX Vref to a higher voltage.
> + RxEq = 6, ///< RX CTLE setting indicating a set of
> possible resistances, capacitance, current steering, etc. values, which may be a
> different set of values per product. The setting combinations are indexed by
> integer values.
> + RxDqBitDelay = 7, ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQ bitlane later in time relative to the RX DQS
> signal (i.e.closing the gap between DQ and DQS in the setup side of the eye).
> + RxVoc = 8, ///< Monotonic increment (Sense Amp
> setting), where the positive increment moves the byte/nibble/bitlane's
> effective switching point to a lower Vref value.
> + RxOdt = 9, ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> + RxOdtUp = 10, ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> + RxOdtDn = 11, ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> + DramDrvStr = 12, ///< Drive strength setting resistance
> setting within a set of possible resistances (or currents), which may be a
> different set of values per product. Indexed by integer values.
> + McOdtDelay = 13, ///<
> + McOdtDuration = 14, ///<
> + SenseAmpDelay = 15, ///< This may be used to indicate
> CmdToDiffAmpEn for SoC's.
> + SenseAmpDuration = 16, ///<
> + RoundTripDelay = 17, ///< This may be used to indicate
> CmdToRdDataValid for SoC's.
> + RxDqsBitDelay = 18, ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS within the bitlane later in time relative
> to the RX DQ signal (i.e.closing the gap between DQ and DQS in the hold side of
> the eye).
> + RxDqDqsDelay = 19, ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS per strobe later in time relative to the RX
> DQ signal (i.e. closing the gap between DQS and DQ in the hold side of the eye.
> The difference between this parameter and RxDqsDelay is that both the DQ
> and DQS timings may be moved in order to increase the total range of DQDQS
> timings.
> + WrLvlDelay = 20, ///< Linear delay (PI ticks), where the
> positive increment moves both the TX DQS and TX DQ signals later in time
> relative to all other bus signals.
> + TxDqsDelay = 21, ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQS strobe later in time relative to all other
> bus signals.
> + TxDqDelay = 22, ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQ byte/nibble/bitlane later in time relative
> to all other bus signals.
> + TxVref = 23, ///< Linear increment (Vref ticks), where
> the positive increment moves the byte/nibble/bitlane TX Vref to a higher
> voltage. (Assuming this will abstract away from the range specifics for DDR4, for
> example.)
> + TxEq = 24, ///< TX EQ setting indicating a set of
> possible equalization levels, which may be a different set of values per product.
> The setting combinations are indexed by integer values.
> + TxDqBitDelay = 25, ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQ bitlane later in time relative to all other
> bus signals.
> + TxRon = 26, ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> + TxRonUp = 27, ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> + TxRonDn = 28, ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> + TxSlewRate = 29, ///< Monotonic increment, where the
> positive increment moves the byte/nibble/bitlane's effective slew rate to a
> higher slope.
> + TxImode = 30, ///< TX I-Mode Boost setting indicating a
> set of possible current boost levels, which may be a different set of values per
> product. The setting combinations are indexed by integer values.
> + WrOdt = 31, ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> + NomOdt = 32, ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> + ParkOdt = 33, ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> + TxTco = 34, ///<
> + RxCtleR = 36, ///<
> + RxCtleC = 37, ///<
> + RxDqsPBitDelay = 38, ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS bitlane timing for "even" chunks later in
> time relative to the RX DQ bitlane signal. Even chunks are 0, 2, 4, 6 within the
> 0 to 7 chunks of an 8 burst length cacheline, for example.
> + RxDqsNBitDelay = 39, ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS bitlane timing for "odd" chunks later in
> time relative to the RX DQ bitlane signal. Odd chunks are 1, 3, 5, 7 within the 0
> to 7 chunks of an 8 burst length cacheline, for example.
> + CmdAll = 40, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_ALL category later in
> time relative to all other signals on the bus.
> + CmdGrp0 = 41, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_GRP0 category later
> in time relative to all other signals on the bus.
> + CmdGrp1 = 42, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_GRP1 category later
> in time relative to all other signals on the bus.
> + CmdGrp2 = 43, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_GRP2 category later
> in time relative to all other signals on the bus.
> + CtlAll = 44, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_ALL category later in
> time relative to all other signals on the bus.
> + CtlGrp0 = 45, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP0 category later
> in time relative to all other signals on the bus.
> + CtlGrp1 = 46, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP1 category later
> in time relative to all other signals on the bus.
> + CtlGrp2 = 47, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP2 category later
> in time relative to all other signals on the bus.
> + CtlGrp3 = 48, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP3 category later
> in time relative to all other signals on the bus.
> + CtlGrp4 = 49, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP4 category later
> in time relative to all other signals on the bus.
> + CtlGrp5 = 50, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP5 category later
> in time relative to all other signals on the bus.
> + CmdCtlAll = 51, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_CTL_ALL category
> later in time relative to all other signals on the bus.
> + CkAll = 52, ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CK_ALL category later in
> time relative to all other signals on the bus.
> + CmdVref = 53, ///< Linear increment (Vref ticks), where
> the positive increment moves the CMD Vref to a higher voltage.
> + AlertVref = 54, ///< Linear increment (Vref ticks), where
> the positive increment moves the ALERT Vref to a higher voltage.
> + CmdRon = 55, ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +
> + EridDelay = 60, ///< Linear delay (PI ticks), where the
> positive increment moves the ERID signals later in time relative to the internal
> sampling clock (i.e.closing the gap between ERID and internal sampling clock in
> the setup side of the eye). This group is applicable for DDRT DIMMs.
> + EridVref = 61, ///< Linear increment (Vref ticks), where
> the positive increment moves the ERID Vref to a higher voltage. This group is
> applicable for DDRT DIMMs.
> + ErrorVref = 62, ///< Linear increment (Vref ticks), where
> the positive increment moves the ERROR Vref to a higher voltage. This group is
> applicable for DDRT DIMMs.
> + ReqVref = 63, ///< Linear increment (Vref ticks), where
> the positive increment moves the REQ Vref to a higher voltage. This group is
> applicable for DDRT DIMMs.
> + RecEnOffset = 64, ///< Linear delay (PI ticks), where the
> positive increment moves the RCVEN sampling window later in time relative to
> the RX DQS strobes.
> + RxDqsOffset = 65, ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS strobe later in time relative to the RX DQ
> signal (i.e. toward the hold side of the eye).
> + RxVrefOffset = 66, ///< Linear increment (Vref ticks), where
> the positive increment moves the byte/nibble/bitlane RX Vref to a higher
> voltage.
> + TxDqsOffset = 67, ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQS strobe later in time relative to all other
> bus signals.
> + TxDqOffset = 68, ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQ byte/nibble/bitlane later in time relative
> to all other bus signals.
> + GsmGtMax, ///< SSA_GSM_GT enumeration
> maximum value.
> + GsmGtDelim = INT32_MAX ///< This value ensures the enum
> size is consistent on both sides of the PPI.
> +} GSM_GT;
> +
> +typedef enum {
> + SigRasN = 0,
> + SigCasN = 1,
> + SigWeN = 2,
> + SigBa0 = 3,
> + SigBa1 = 4,
> + SigBa2 = 5,
> + SigA0 = 6,
> + SigA1 = 7,
> + SigA2 = 8,
> + SigA3 = 9,
> + SigA4 = 10,
> + SigA5 = 11,
> + SigA6 = 12,
> + SigA7 = 13,
> + SigA8 = 14,
> + SigA9 = 15,
> + SigA10 = 16,
> + SigA11 = 17,
> + SigA12 = 18,
> + SigA13 = 19,
> + SigA14 = 20,
> + SigA15 = 21,
> + SigA16 = 22,
> + SigA17 = 23,
> + SigCs0N = 24,
> + SigCs1N = 25,
> + SigCs2N = 26,
> + SigCs3N = 27,
> + SigCs4N = 28,
> + SigCs5N = 29,
> + SigCs6N = 30,
> + SigCs7N = 31,
> + SigCs8N = 32,
> + SigCs9N = 33,
> + SigCke0 = 34,
> + SigCke1 = 35,
> + SigCke2 = 36,
> + SigCke3 = 37,
> + SigCke4 = 38,
> + SigCke5 = 39,
> + SigOdt0 = 40, //could also be used for CA-ODT for LP4
> + SigOdt1 = 41, //could also be used for CA-ODT for LP4
> + SigOdt2 = 42,
> + SigOdt3 = 43,
> + SigOdt4 = 44,
> + SigOdt5 = 45,
> + SigPar = 46,
> + SigAlertN = 47,
> + SigBg0 = 48,
> + SigBg1 = 49,
> + SigActN = 50,
> + SigCid0 = 51,
> + SigCid1 = 52,
> + SigCid2 = 53,
> + SigCk0 = 54,
> + SigCk1 = 55,
> + SigCk2 = 56,
> + SigCk3 = 57,
> + SigCk4 = 58,
> + SigCk5 = 59,
> + SigGnt0 = 60,
> + SigGnt1 = 61,
> + SigErid00 = 62,
> + SigErid01 = 63,
> + SigErid10 = 64,
> + SigErid11 = 65,
> + SigErr0 = 66,
> + SigErr1 = 67,
> + SigCa00 = 68, // First instantiation of the CA bus for a given channel
> + SigCa01 = 69,
> + SigCa02 = 70,
> + SigCa03 = 71,
> + SigCa04 = 72,
> + SigCa05 = 73,
> + SigCa10 = 74, // Second instantiation of the CA bus for a given channel
> + SigCa11 = 75,
> + SigCa12 = 76,
> + SigCa13 = 77,
> + SigCa14 = 78,
> + SigCa15 = 79,
> + GsmCsnMax,
> + GsmCsnDelim = INT32_MAX
> +} GSM_CSN;
> +
> +
> +#endif // _MrcCommonTypes_h_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcInterface.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcInterface.h
> new file mode 100644
> index 0000000000..635906cc2b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcInterface.h
> @@ -0,0 +1,1567 @@
> +/** @file
> + This file includes all the data structures that the MRC considers "global
> data".
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MrcInterface_h_
> +#define _MrcInterface_h_
> +
> +#define MAX_CPU_SOCKETS (1) ///< The maximum number of
> CPUs per system.
> +#define MAX_CONTROLLERS (1) ///< The maximum number of
> memory controllers per CPU socket.
> +#define MAX_CHANNEL (2) ///< The maximum number of
> channels per memory controller.
> +#define MAX_DIMMS_IN_CHANNEL (2) ///< The maximum number of
> DIMMs per channel.
> +#define MAX_RANK_IN_DIMM (2) ///< The maximum number of
> ranks per DIMM.
> +#define MAX_RANK_IN_CHANNEL (MAX_DIMMS_IN_CHANNEL *
> MAX_RANK_IN_DIMM) ///< The maximum number of ranks per channel.
> +#define MAX_SDRAM_IN_DIMM (9) ///< The maximum number of
> SDRAMs per DIMM when ECC is enabled.
> +#define MAX_MR_IN_DIMM (7) ///< Maximum number of mode
> registers in a DIMM.
> +#define MAX_DEVICES_IN_DDR4 (8) ///< The maximum number of
> SDRAMs per DDR4 DIMM.
> +#define MAX_BITS (8) ///< BITS per byte.
> +#define MAX_STROBE (18) ///< Number of strobe groups.
> +#define MAX_DQ (72) ///< Number of Dq bits used by the
> rank.
> +#define CHAR_BITS (8) ///< Number of bits in a char.
> +#define PSMI_SIZE_MB (64) ///< Define the max size of PSMI
> needed in MB
> +#define BCLK_DEFAULT (100 * 1000 * 1000) ///< BCLK default value,
> in Hertz.
> +#define MAX_COMMAND_GROUPS (2)
> +#define MAX_EDGES (2) ///< Maximum number of edges.
> +#define SUPPORT_DDR3 SUPPORT ///< SUPPORT means that DDR3
> is supported by the MRC.
> +#define ULT_SUPPORT_LPDDR3 SUPPORT ///< SUPPORT means that
> LPDDR3 is supported by the MRC.
> +#define TRAD_SUPPORT_LPDDR3 /*UN*/SUPPORT ///< SUPPORT means
> that LPDDR3 is supported by the MRC.
> +#define BDW_SUPPORT_LPDDR3 SUPPORT ///< SUPPORT means that
> LPDDR3 is supported by the MRC.
> +#define JEDEC_SUPPORT_LPDDR SUPPORT ///< SUPPORT means that
> JEDEC SPD Spec for LPDDR3 is supported by the MRC.
> +#define SUPPORT_DDR4 SUPPORT ///< SUPPORT means that DDR4
> is supported by the MRC.
> +#define SUPPORT_LPDDR3 (ULT_SUPPORT_LPDDR3 ||
> TRAD_SUPPORT_LPDDR3 || BDW_SUPPORT_LPDDR3 ||
> JEDEC_SUPPORT_LPDDR)
> +#define MRC_ALL_DDR_SUPPORTED ((SUPPORT_DDR4 == SUPPORT) &&
> ((SUPPORT_DDR3 == SUPPORT) && (SUPPORT_LPDDR3 == SUPPORT)))
> +#define MRC_DDR3_LPDDR_SUPPORTED ((SUPPORT_DDR3 == SUPPORT) ||
> (SUPPORT_LPDDR3 == SUPPORT))
> +#define SPD3_MANUF_START 117 ///< The starting point for the
> SPD manufacturing data.
> +#define SPD3_MANUF_END 127 ///< The ending point for the
> SPD manufacturing data.
> +#if (SUPPORT_DDR4 == SUPPORT)
> +#define SPD4_MANUF_START 320 ///< The starting point for the
> SPD manufacturing data.
> +#define SPD4_MANUF_END 328 ///< The ending point for the
> SPD manufacturing data.
> +#endif
> +#if (JEDEC_SUPPORT_LPDDR == SUPPORT)
> +#define SPDLP_MANUF_START 320 ///< The starting point for the
> SPD manufacturing data.
> +#define SPDLP_MANUF_END 328 ///< The ending point for the
> SPD manufacturing data.
> +#endif
> +#include "MrcSpdData.h"
> +#include "MrcRmtData.h"
> +#include "MrcCommonTypes.h"
> +#pragma pack (push, 1)
> +
> +
> +///
> +//////////////////////////////////////////////////////////////////////////////
> ////////
> +/// OEM platform routines and types //
> +//////////////////////////////////////////////////////////////////////////////
> ////////
> +///
> +/// define the oem check points the OEM can define more point and locate
> them in the code.
> +///
> +typedef enum {
> + OemFastBootPermitted, ///< before fast boot.
> + OemRestoreNonTraining,
> + OemPrintInputParameters, ///< before printing input parameters
> + OemSpdProcessingRun, ///< before spd processing code
> + OemSetOverridePreSpd, ///< before set overrides pre spd
> + OemSetOverride, ///< before set overrides
> + OemMcCapability, ///< before MC capability
> + OemMcInitRun, ///< before mc init code
> + OemMcMemoryMap, ///< before memory map
> + OemMcResetRun, ///< before jedec reset
> + OemPreTraining, ///< before the training.
> + OemMcTrainingRun, ///< before training code
> + OemEarlyCommandTraining, ///< before Early Command training
> + OemJedecInitLpddr3, ///< before Jedec Init Lpddr3
> + OemSenseAmpTraining, ///< before Sense Amp Training
> + OemReadMprTraining, ///< before Read MPR Training
> + OemReceiveEnable, ///< before Read Leveling
> + OemJedecWriteLeveling, ///< before Jedec Write Leveling
> + OemLpddrLatencySetB, ///< before LPDDR Latency Set B
> + OemWriteDqDqs, ///< before Write Timing Centering
> + OemWriteVoltage, ///< before Write Voltage Centering
> + OemEarlyWriteDqDqs2D, ///< before Early Write Timing Centering 2D
> + OemEarlyWrDsEq, ///< before Early Write Drive Strength /
> Equalization
> + OemEarlyReadDqDqs2D, ///< before Early Read Timing Centering 2D
> + OemEarlyReadMprDqDqs2D, ///< before Early MPR Read Timing
> Centering 2D
> + OemReadDqDqs, ///< before Read Timing Centering
> + OemDdr4Map, ///< before DDR4 PDA Mapping
> + OemDimmRonTraining, ///< before DIMM Ron Training
> + OemDimmODTTraining, ///< before DIMM ODT Training
> + OemWriteDriveStrengthEq, ///< before Write Drive Strength/Equalization
> 2D Training
> + OemWriteDriveUpDn, ///< before Write Drive Strength Up/Dn 2D
> Training
> + OemWriteSlewRate, ///< before Write Slew Rate Training
> + OemReadODTTraining, ///< before Read ODT algorithm.
> + OemReadEQTraining, ///< before Read Equalization Training
> + OemReadAmplifierPower, ///< before Read Amplifier Power
> + OemOptimizeComp, ///< before Comp Optimization Training
> + OemPowerSavingMeter, ///< before PowerSavingMeter step
> + OemWriteDqDqs2D, ///< before Write Timing Centering 2D
> + OemReadDqDqs2D, ///< before Read Timing Centering 2D
> + OemCmdVoltCenterPreLct, ///< before Command Voltage Centering that
> runs pre-LCT
> + OemCmdSlewRate, ///< before CMD Slew Rate
> + OemCmdVoltCentering, ///< before Command Voltage Centering
> + OemCmdDriveStrengthEq, ///< before Command Drive Strength
> Equalization
> + OemWriteVoltCentering2D, ///< before Write Voltage Centering 2D
> + OemReadVoltCentering2D, ///< before Read Voltage Centering 2D
> + OemLateCommandTraining, ///< before Late Command training
> + OemCmdNormalization, ///< before CMD Normalization
> + OemRoundTripLatency, ///< before Round Trip Latency Traiing
> + OemTurnAroundTimes, ///< before Turn Aorund Times.
> + OemRcvEnCentering1D, ///< before Receive Enable Centring
> + OemSaveMCValues, ///< before saving memory controller values
> + OemRmt, ///< before RMT crosser tool.
> + OemMemTest, ///< before Memory testing
> + OemRestoreTraining, ///< before Restoring Training Values
> + OemJedecResetDdr4Fast, ///< before JEDEC reset for DDR4 in Fast flow
> + OemSelfRefreshExit, ///< before Self Refresh Exit
> + OemNormalMode, ///< before Normal Mode on non-cold boots.
> + OemThermalConfig, ///< set Thermal config values.
> + OemTxtAliasCheck, ///< before TxT Alias Check Call.
> + OemAliasCheck, ///< before alias checking on cold boots.
> + OemHwMemInit,
> +
> + OemPostTraining, ///< after the training.
> + OemForceOltm, ///< before MrcForceOltm
> + OemMrcActivate, ///< before MrcActivate call.
> + OemMrcRhPrevention, ///< before MrcRhPrevention
> + OemSaGvSwitch, ///< before SA GV switch
> + OemEngPerfGain, ///< before Energy Performance Gain.
> + OemMrcDone, ///< call to MrcOemCheckPoint when MRC was
> done.
> + OemFrequencySet, ///< do operation before frequency set.
> + OemFrequencySetDone, ///< do operation after frequency set.
> + OemStartMemoryConfiguration,
> + OemBeforeNormalMode, ///< call to MrcOemCheckPoint before
> normal mode is enalbed
> + OemAfterNormalMode, ///< call to MrcOemCheckPoint after normal
> mode is enalbed
> + OemMrcFillBdat,
> + OemRetrainMarginCheck,
> + OemRmtPerBit, ///< before Rank Margin Tool Per-Bit.
> + OemUpdateSaveMCValues, ///< before Updating memory controller
> values.
> + ///
> +
> ///*************************************************************
> ********************
> + ///
> + OemNumOfCommands ///< Should always be last in the list!
> +} MrcOemStatusCommand;
> +
> +typedef UINT8 MrcIteration; ///< Mrc invocation sequence number, start with
> 0 and increment by one each time MRC library is called.
> +#define MRC_ITERATION_MAX ((1 << ((sizeof (MrcIteration) * 8) - 1)) + ((1 <<
> ((sizeof (MrcIteration) * 8) - 1)) - 1))
> +
> +#define MAX_RCOMP (3)
> +#define MAX_RCOMP_TARGETS (5)
> +
> +///
> +/// Thermal Options
> +///
> +typedef struct {
> + UINT8 RaplLim2WindX; ///< Offset 110 - Power
> Limit 2 Time Window X value: 0=Minimal, 3=Maximum, <b>1=Default</b>
> + UINT8 RaplLim2WindY; ///< Offset 111 - Power
> Limit 2 Time Window Y value: 0=Minimal, 3=Maximum, <b>1=Default</b>
> + UINT8 RaplLim1WindX; ///< Offset 112 - Power
> Limit 1 Time Window X value: <b>0=Minimal</b>, 3=Maximum
> + UINT8 RaplLim1WindY; ///< Offset 113 - Power
> Limit 1 Time Window Y value: <b>0=Minimal</b>, 31=Maximum
> + UINT16 RaplLim2Pwr; ///< Offset 114 - Power
> Limit 2: 0=Minimal, 16383=Maximum, <b>222=Default</b>
> + UINT16 RaplLim1Pwr; ///< Offset 116 - Power
> Limit 1: <b>0=Minimal</b>, 16383=Maximum
> + UINT8 WarmThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///<
> Offset 118 - Warm Threshold (Channel 0, Dimm 0): 0=Minimal,
> <b>255=Maximum</b>
> + UINT8 HotThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///<
> Offset 122 - Hot Threshold (Channel 0, Dimm 0): 0=Minimal,
> <b>255=Maximum</b>
> + UINT8 WarmBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///<
> Offset 126 - Warm Budget (Channel 0, Dimm 0): 0=Minimal,
> <b>255=Maximum</b>
> + UINT8 HotBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///<
> Offset 130 - Hot Budget (Channel 0, Dimm 0): 0=Minimal,
> <b>255=Maximum</b>
> + UINT8 IdleEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> + UINT8 PdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> + UINT8 ActEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> + UINT8 RdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> + UINT8 WrEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> +} ThermalMngmtEn;
> +
> +
> +typedef struct {
> + UINT8 GdxcEnable; ///< GDXC MOT enable
> + UINT8 GdxcIotSize; ///< IOT size in multiples of 8MEG
> + UINT8 GdxcMotSize; ///< MOT size in multiples of 8MEG
> +} MrcGdxc;
> +
> +typedef struct {
> + UINT32 ECT : 1; ///< BIT0 - Early Command Training
> + UINT32 SOT : 1; ///< BIT1 - Sense Amp Offset Training
> + UINT32 ERDMPRTC2D : 1; ///< BIT2 - Early ReadMPR Timing Centering 2D
> + UINT32 RDMPRT : 1; ///< BIT3 - Read MPR Training
> + UINT32 RCVET : 1; ///< BIT4 - Read Leveling Training (RcvEn)
> + UINT32 JWRL : 1; ///< BIT5 - Jedec Write Leveling
> + UINT32 EWRTC2D : 1; ///< BIT6 - Early Write Time Centering 2D
> + UINT32 ERDTC2D : 1; ///< BIT7 - Early Read Time Centering 2D
> + UINT32 WRTC1D : 1; ///< BIT8 - Write Timing Centering 1D
> + UINT32 WRVC1D : 1; ///< BIT9 - Write Voltage Centering 1D
> + UINT32 RDTC1D : 1; ///< BIT10 - Read Timing Centering 1D
> + UINT32 DIMMODTT : 1; ///< BIT11 - Dimm ODT Training
> + UINT32 DIMMRONT : 1; ///< BIT12 - Dimm Ron Training
> + UINT32 WRDSEQT : 1; ///< BIT13 - Write Drive Strength / Equalization
> Training 2D
> + UINT32 WRSRT : 1; ///< BIT14 - Write Slew Rate Training
> + UINT32 RDODTT : 1; ///< BIT15 - Read ODT Training
> + UINT32 RDEQT : 1; ///< BIT16 - Read Equalization Training
> + UINT32 RDAPT : 1; ///< BIT17 - Read Amplifier Power Training
> + UINT32 WRTC2D : 1; ///< BIT18 - Write Timing Centering 2D
> + UINT32 RDTC2D : 1; ///< BIT19 - Read Timing Centering 2D
> + UINT32 WRVC2D : 1; ///< BIT20 - Write Voltage Centering 2D
> + UINT32 RDVC2D : 1; ///< BIT21 - Read Voltage Centering 2D
> + UINT32 CMDVC : 1; ///< BIT22 - Command Voltage Centering
> + UINT32 LCT : 1; ///< BIT23 - Late Command Training
> + UINT32 RTL : 1; ///< BIT24 - Round Trip latency
> + UINT32 TAT : 1; ///< BIT25 - Turn Around Timing
> + UINT32 RMT : 1; ///< BIT26 - RMT Tool
> + UINT32 MEMTST : 1; ///< BIT27 - Memory Test
> + UINT32 ALIASCHK: 1; ///< BIT28 - SPD Alias Check
> + UINT32 RCVENC1D: 1; ///< BIT29 - Receive Enable Centering 1D
> + UINT32 RMC : 1; ///< BIT30 - Retrain Margin Check
> + UINT32 WRDSUDT : 1; ///< BIT31 - Write Drive Strength Up/Dn
> independently
> +} TrainingStepsEn;
> +
> +typedef struct {
> + UINT32 CMDSR : 1; ///< BIT0 - CMD Slew Rate Training
> + UINT32 CMDDSEQ : 1; ///< BIT1 - CMD Drive Strength and Tx Equalization
> + UINT32 CMDNORM : 1; ///< BIT2 - CMD Normalization
> + UINT32 EWRDSEQ : 1; ///< BIT3 - Early DQ Write Drive Strength and
> Equalization Training
> + UINT32 TeRsv4 : 1; ///< BIT4 - Reserved
> + UINT32 TeRsv5 : 1; ///< BIT5 - Reserved
> + UINT32 TeRsv6 : 1; ///< BIT6 - Reserved
> + UINT32 RsvdBits :25;
> +} TrainingStepsEn2;
> +
> +///
> +/// Defines whether the MRC is executing in full or mini BIOS mode.
> +///
> +typedef enum {
> + MrcModeFull, ///< Select full BIOS MRC execution.
> + MrcModeMini, ///< Select mini BIOS MRC execution.
> + MrcModeMaximum ///< Delimiter.
> +} MrcMode;
> +
> +typedef enum {
> + MrcTmPower,
> + MrcTmMargin,
> + MrcTmMax
> +} TrainingModeType;
> +
> +typedef enum {
> + LastRxV,
> + LastRxT,
> + LastTxV,
> + LastTxT,
> + LastRcvEna,
> + LastWrLevel,
> + LastCmdT,
> + LastCmdV,
> + MAX_RESULT_TYPE
> +} MrcMarginResult;
> +
> +typedef enum {
> + MSG_LEVEL_NEVER,
> + MSG_LEVEL_ERROR,
> + MSG_LEVEL_WARNING,
> + MSG_LEVEL_NOTE,
> + MSG_LEVEL_EVENT,
> + MSG_LEVEL_ALGO,
> + MSG_LEVEL_MMIO,
> + MSG_LEVEL_CSV,
> + MSG_LEVEL_TIME,
> + MSG_LEVEL_ALL = MRC_INT32_MAX
> +} MrcDebugMsgLevel;
> +
> +///
> +/// Define the frequencies that may be possible in the memory controller.
> +/// Note that not all these values may be supported.
> +///
> +#define fNoInit (0)
> +#define f800 (800)
> +#define f1000 (1000)
> +#define f1100 (1100)
> +#define f1067 (1067)
> +#define f1200 (1200)
> +#define f1300 (1300)
> +#define f1333 (1333)
> +#define f1400 (1400)
> +#define f1467 (1467)
> +#define f1500 (1500)
> +#define f1600 (1600)
> +#define f1700 (1700)
> +#define f1733 (1733)
> +#define f1800 (1800)
> +#define f1867 (1867)
> +#define f1900 (1900)
> +#define f2000 (2000)
> +#define f2100 (2100)
> +#define f2133 (2133)
> +#define f2200 (2200)
> +#define f2267 (2267)
> +#define f2300 (2300)
> +#define f2400 (2400)
> +#define f2500 (2500)
> +#define f2533 (2533)
> +#define f2600 (2600)
> +#define f2667 (2667)
> +#define f2700 (2700)
> +#define f2800 (2800)
> +#define f2900 (2900)
> +#define f2933 (2933)
> +#define f3000 (3000)
> +#define f3067 (3067)
> +#define f3100 (3100)
> +#define f3200 (3200)
> +#define f3333 (3333)
> +#define f3467 (3467)
> +#define f3600 (3600)
> +#define f3733 (3733)
> +#define f3867 (3867)
> +#define f4000 (4000)
> +#define f4133 (4133)
> +#define fInvalid (0x7FFFFFFF)
> +typedef UINT32 MrcFrequency;
> +
> +//
> +// Max supported frequency in OC mode
> +// RefClk133: 15*266 + 100 = 4133 (using Odd ratio mode)
> +// RefClk100: 15*200 + 100 = 3100 (using Odd ratio mode)
> +//
> +#define MAX_FREQ_OC_133 f4133
> +#define MAX_FREQ_OC_100 f3100
> +
> +//
> +// tCK value in femtoseconds for various frequencies
> +// If Freq is in MHz, then tCK[fs] = 10^9 * 1/(Freq/2)
> +//
> +#define MRC_DDR_800_TCK_MIN 2500000
> +#define MRC_DDR_1000_TCK_MIN 2000000
> +#define MRC_DDR_1067_TCK_MIN 1875000
> +#define MRC_DDR_1100_TCK_MIN 1818182
> +#define MRC_DDR_1200_TCK_MIN 1666667
> +#define MRC_DDR_1300_TCK_MIN 1538462
> +#define MRC_DDR_1333_TCK_MIN 1500000
> +#define MRC_DDR_1400_TCK_MIN 1428571
> +#define MRC_DDR_1467_TCK_MIN 1363636
> +#define MRC_DDR_1500_TCK_MIN 1333333
> +#define MRC_DDR_1600_TCK_MIN 1250000
> +#define MRC_DDR_1700_TCK_MIN 1176471
> +#define MRC_DDR_1733_TCK_MIN 1153846
> +#define MRC_DDR_1800_TCK_MIN 1111111
> +#define MRC_DDR_1867_TCK_MIN 1071429
> +#define MRC_DDR_1900_TCK_MIN 1052632
> +#define MRC_DDR_2000_TCK_MIN 1000000
> +#define MRC_DDR_2100_TCK_MIN 952381
> +#define MRC_DDR_2133_TCK_MIN 938000
> +#define MRC_DDR_2200_TCK_MIN 909091
> +#define MRC_DDR_2267_TCK_MIN 882353
> +#define MRC_DDR_2300_TCK_MIN 869565
> +#define MRC_DDR_2400_TCK_MIN 833333
> +#define MRC_DDR_2500_TCK_MIN 800000
> +#define MRC_DDR_2533_TCK_MIN 789474
> +#define MRC_DDR_2600_TCK_MIN 769231
> +#define MRC_DDR_2667_TCK_MIN 750000
> +#define MRC_DDR_2700_TCK_MIN 740741
> +#define MRC_DDR_2800_TCK_MIN 714286
> +#define MRC_DDR_2900_TCK_MIN 689655
> +#define MRC_DDR_2933_TCK_MIN 681818
> +#define MRC_DDR_3000_TCK_MIN 666667
> +#define MRC_DDR_3067_TCK_MIN 652174
> +#define MRC_DDR_3100_TCK_MIN 645161
> +#define MRC_DDR_3200_TCK_MIN 625000
> +#define MRC_DDR_3333_TCK_MIN 600000
> +#define MRC_DDR_3467_TCK_MIN 576923
> +#define MRC_DDR_3600_TCK_MIN 555556
> +#define MRC_DDR_3733_TCK_MIN 535714
> +#define MRC_DDR_3867_TCK_MIN 517241
> +#define MRC_DDR_4000_TCK_MIN 500000
> +#define MRC_DDR_4133_TCK_MIN 483871
> +
> +///
> +/// Define the memory nominal voltage (VDD).
> +/// Note that not all these values may be supported.
> +///
> +typedef enum {
> + VDD_INVALID,
> + VDD_1_00 = 1000,
> + VDD_1_05 = 1050,
> + VDD_1_10 = 1100,
> + VDD_1_15 = 1150,
> + VDD_1_20 = 1200,
> + VDD_1_25 = 1250,
> + VDD_1_30 = 1300,
> + VDD_1_35 = 1350,
> + VDD_1_40 = 1400,
> + VDD_1_45 = 1450,
> + VDD_1_50 = 1500,
> + VDD_1_55 = 1550,
> + VDD_1_60 = 1600,
> + VDD_1_65 = 1650,
> + VDD_1_70 = 1700,
> + VDD_1_75 = 1750,
> + VDD_1_80 = 1800,
> + VDD_1_85 = 1850,
> + VDD_1_90 = 1900,
> + VDD_1_95 = 1950,
> + VDD_2_00 = 2000,
> + VDD_2_05 = 2050,
> + VDD_2_10 = 2100,
> + VDD_2_15 = 2150,
> + VDD_2_20 = 2200,
> + VDD_2_25 = 2250,
> + VDD_2_30 = 2300,
> + VDD_2_35 = 2350,
> + VDD_2_40 = 2400,
> + VDD_2_45 = 2450,
> + VDD_2_50 = 2500,
> + VDD_2_55 = 2550,
> + VDD_2_60 = 2600,
> + VDD_2_65 = 2650,
> + VDD_2_70 = 2700,
> + VDD_2_75 = 2750,
> + VDD_2_80 = 2800,
> + VDD_2_85 = 2850,
> + VDD_2_90 = 2900,
> + VDD_2_95 = 2950,
> + VDD_MAXIMUM = 0x7FFFFFFF
> +} MrcVddSelect;
> +
> +///
> +/// SA GV points
> +///
> +typedef enum {
> + MrcSaGvPointLow,
> + MrcSaGvPointHigh,
> +} MrcSaGvPoint;
> +
> +///
> +/// SA GV modes
> +/// Disabled: SA GV Disabled, run all MRC tasks
> +/// FixedLow: SA GV Disabled, run only MRC tasks marked with
> MRC_PF_GV_LOW
> +/// FixedHigh: SA GV Disabled, run only MRC tasks marked with
> MRC_PF_GV_HIGH
> +/// Enabled: SA GV Enabled
> +///
> +typedef enum {
> + MrcSaGvDisabled,
> + MrcSaGvFixedLow,
> + MrcSaGvFixedHigh,
> + MrcSaGvEnabled,
> +} MrcSaGv;
> +
> +///
> +/// DIMM SPD Security Status
> +///
> +typedef enum {
> + MrcSpdStatusGood, ///< Memory is in a secure state.
> + MrcSpdStatusAliased, ///< Memory is aliased.
> + MrcSpdStatusLast ///< Must be last in the list
> +} MrcSpdStatus;
> +
> +///
> +/// Define the virtual channel.
> +///
> +typedef enum {
> + vcL, ///< Virtual channel L
> + vcS, ///< Virtual channel S
> +} MrcVirtualChannel;
> +
> +///
> +/// Define the board types.
> +///
> +typedef enum {
> + btCRBMB, ///< 0 - CRB Mobile
> + btCRBDT, ///< 1 - CRB Desktop
> + btUser1, ///< 2 - SV Karkom
> + btUser2, ///< 3 - SV desktop
> + btUser3, ///< 4 - SV miniDVP
> + btUser4, ///< 5 - Ult
> + btCRBEMB, ///< 6 - CRB Embedded
> + btUpServer, ///< 7 - Up Server
> + btUnknown, ///< 8 - Unknown
> + btMaximum ///< Delimiter
> +} MrcBoardType;
> +
> +///
> +/// Define the CPU family/model.
> +///
> +typedef enum {
> + cmCFL_ULX_ULT = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX,
> ///< Coffeelake ULT/ULX
> + cmCFL_DT_HALO = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO
> ///< Coffeelake DT/Halo
> +} MrcCpuModel;
> +
> +///
> +/// Define the CPU Tick/Tock.
> +///
> +typedef enum {
> + cfCfl = 0, ///< Coffeelake
> + cfMax
> +} MrcCpuFamily;
> +
> +///
> +/// Define the CPU stepping number.
> +///
> +typedef enum {
> + ///
> + /// Coffeelake ULX/ULT
> + ///
> + csKblH0 = EnumKblH0,
> + csCflD0 = EnumCflD0,
> + csCflW0 = EnumCflW0,
> + csCflV0 = EnumCflV0,
> + csCflUlxUltLast = csCflV0,
> +
> + ///
> + /// Coffeelake DT/Halo
> + ///
> + csCflU0 = EnumCflU0,
> + csCflB0 = EnumCflB0,
> + csCflP0 = EnumCflP0,
> + csCflR0 = EnumCflR0,
> + csCflDtHaloLast = csCflR0,
> +} MrcCpuStepping;
> +
> +typedef enum {
> + CONTROLLER_NOT_PRESENT, ///< There is no controller present in the
> system.
> + CONTROLLER_DISABLED, ///< There is a controller present but it is
> disabled.
> + CONTROLLER_PRESENT, ///< There is a controller present and it is
> enabled.
> + MAX_CONTROLLER_STATUS ///< Delimiter
> +} MrcControllerSts;
> +
> +typedef enum {
> + CHANNEL_NOT_PRESENT, ///< There is no channel present on the
> controller.
> + CHANNEL_DISABLED, ///< There is a channel present but it is disabled.
> + CHANNEL_PRESENT, ///< There is a channel present and it is enabled.
> + MAX_CHANNEL_STATUS ///< Delimiter
> +} MrcChannelSts;
> +
> +typedef enum {
> + DIMM_ENABLED, ///< DIMM/rank Pair is enabled, presence will be
> detected.
> + DIMM_DISABLED, ///< DIMM/rank Pair is disabled, regardless of
> presence.
> + DIMM_PRESENT, ///< There is a DIMM present in the slot/rank pair
> and it will be used.
> + DIMM_NOT_PRESENT, ///< There is no DIMM present in the slot/rank
> pair.
> + MAX_DIMM_STATUS ///< Delimiter
> +} MrcDimmSts;
> +
> +typedef enum {
> + STD_PROFILE, ///< Standard DIMM profile select.
> + USER_PROFILE, ///< User specifies various override values.
> + XMP_PROFILE1, ///< XMP enthusiast settings select (XMP profile #1).
> + XMP_PROFILE2, ///< XMP extreme settings select (XMP profile #2).
> + MAX_PROFILE ///< Delimiter
> +} MrcProfile;
> +
> +#define XMP_PROFILES_ENABLE (0x3)
> +#define XMP1_PROFILE_ENABLE (0x1)
> +#define XMP2_PROFILE_ENABLE (0x2)
> +
> +typedef enum {
> + MRC_REF_CLOCK_133, ///< 133MHz reference clock
> + MRC_REF_CLOCK_100, ///< 100MHz reference clock
> + MRC_REF_CLOCK_MAXIMUM ///< Delimiter
> +} MrcRefClkSelect; ///< This value times the MrcClockRatio determines
> the MrcFrequency.
> +
> +typedef enum {
> + MRC_FREQ_INVALID = 0,
> + MRC_FREQ_133 = (MRC_BIT0 << MRC_REF_CLOCK_133), // Bit 0
> + MRC_FREQ_100 = (MRC_BIT0 << MRC_REF_CLOCK_100), // Bit 1
> + MRC_FREQ_133_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_133), // Bit
> 2
> + MRC_FREQ_100_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_100), // Bit
> 3
> + MRC_FREQ_MAX // Delimiter
> +} MrcFreqFlag;
> +
> +typedef UINT32 MrcBClkRef; ///< Base clock, in Hertz, Default is 100MHz or
> leave at zero for default.
> +
> +//
> +// This encoding matches CFL SC_GS_CFG.DRAM_technology and
> MAD_INTER_CHANNEL.DDR_TYPE registers
> +//
> +typedef enum {
> + MRC_DDR_TYPE_DDR4 = 0,
> + MRC_DDR_TYPE_DDR3 = 1,
> + MRC_DDR_TYPE_LPDDR3 = 2,
> + MRC_DDR_TYPE_UNKNOWN = 3,
> + MAX_MRC_DDR_TYPE ///< Delimiter
> +} MrcDdrType;
> +
> +typedef enum {
> + MrcIterationClock,
> + MrcIterationCmdN,
> + MrcIterationCmdS,
> + MrcIterationCke,
> + MrcIterationCtl,
> + MrcIterationCmdV,
> + MrcIterationMax
> +} MrcIterationType;
> +
> +typedef enum {
> + UpmLimit,
> + PowerLimit,
> + RetrainLimit,
> + MarginLimitMax
> +} MRC_MARGIN_LIMIT_TYPE;
> +
> +
> +typedef enum {
> + HardwareRhp,
> + Refresh2x
> +} MrcRhpType;
> +
> +typedef enum {
> + OneIn2To1 = 1,
> + OneIn2To2,
> + OneIn2To3,
> + OneIn2To4,
> + OneIn2To5,
> + OneIn2To6,
> + OneIn2To7,
> + OneIn2To8,
> + OneIn2To9,
> + OneIn2To10,
> + OneIn2To11,
> + OneIn2To12,
> + OneIn2To13,
> + OneIn2To14,
> + OneIn2To15
> +} MrcRhProbType;
> +
> +typedef enum {
> + MRC_POST_CODE,
> + MRC_POST_CODE_WRITE,
> + MRC_POST_CODE_READ,
> + MRC_POST_CODE_MAX
> +} MrcDebugPostCode;
> +
> +typedef struct {
> + UINT32 MrcData;
> + UINT32 Stream;
> + UINT32 Start;
> + UINT32 End;
> + UINT32 Current;
> + int Level;
> + UINT16 PostCode[MRC_POST_CODE_MAX];
> + UINT32 TopStackAddr; ///< Initial stack address.
> + UINT32 LowestStackAddr; ///< Track the lowest stack address used through
> MrcPrintfVaList()
> +} MrcDebug;
> +
> +typedef UINT16 MrcPostCode;
> +typedef UINT8 MrcClockRatio; ///< This value times the MrcRefClkSelect
> determines the MrcFrequency.
> +typedef UINT32 MrcGfxDataSize; ///< The size of the stolen graphics data
> memory, in MBytes.
> +typedef UINT32 MrcGfxGttSize; ///< The size of the graphics translation
> table, in MBytes.
> +
> +
> +///
> +/// This data structure contains all the "DDR power saving data" values that
> are considered output by the MRC.
> +/// The following are memory controller level definitions. All channels on a
> controller are set to these values.
> +///
> +typedef struct {
> + BOOLEAN BaseFlag; ///< Indicates if the base line of power was
> already calculated.
> + UINT16 BaseSavingRd; ///< Indicates the base line of power consume by
> the ddr on read.
> + UINT16 BaseSavingWr; ///< Indicates the base line of power consume
> by the ddr on write.
> + UINT16 BaseSavingCmd; ///< Indicates the base line of power consume
> by the ddr on command.
> + UINT16 MrcSavingRd; ///< Indicates the power consume by the ddr on
> read at the end of MRC.
> + UINT16 MrcSavingWr; ///< Indicates the power consume by the ddr on
> write at the end of MRC.
> + UINT16 MrcSavingCmd; ///< Indicates the power consume by the ddr on
> command at the end of MRC.
> +} MrcOdtPowerSaving;
> +
> +///
> +/// The memory controller capabilities.
> +///
> +typedef union {
> + UINT32 Data;
> + UINT16 Data16[2];
> + UINT8 Data8[4];
> +} MrcCapabilityIdA;
> +
> +typedef union {
> + UINT32 Data;
> + UINT16 Data16[2];
> + UINT8 Data8[4];
> +} MrcCapabilityIdB;
> +
> +typedef union {
> + UINT64 Data;
> + struct {
> + MrcCapabilityIdA A;
> + MrcCapabilityIdB B;
> + } Data32;
> +} MrcCapabilityId;
> +
> +///
> +/// MRC version description.
> +///
> +typedef struct {
> + UINT8 Major; ///< Major version number
> + UINT8 Minor; ///< Minor version number
> + UINT8 Rev; ///< Revision number
> + UINT8 Build; ///< Build number
> +} MrcVersion;
> +
> +///
> +/// Memory map configuration information.
> +///
> +typedef struct {
> + UINT32 TomMinusMe;
> + UINT32 ToludBase;
> + UINT32 BdsmBase;
> + UINT32 GttBase;
> + UINT32 GraphicsControlRegister;
> + UINT32 TsegBase;
> + BOOLEAN ReclaimEnable;
> + UINT32 RemapBase;
> + UINT32 RemapLimit;
> + UINT32 TouudBase;
> + UINT32 TotalPhysicalMemorySize;
> + UINT32 MeStolenBase;
> + UINT32 MeStolenSize;
> + UINT32 GdxcMotBase;
> + UINT32 GdxcMotSize;
> + UINT32 GdxcIotBase;
> + UINT32 GdxcIotSize;
> + UINT32 DprSize;
> + UINT32 PttStolenBase;
> + UINT32 PrmrrBase;
> + UINT32 LowestBase;
> +} MrcMemoryMap;
> +
> +///
> +/// Real time clock information.
> +///
> +typedef struct {
> + UINT8 Seconds; ///< Seconds, 0-59
> + UINT8 Minutes; ///< Minutes, 0-59
> + UINT8 Hours; ///< Hours, 0-23
> + UINT8 DayOfMonth; ///< Day of the month, 1-31
> + UINT8 Month; ///< Month of the year, 1-12
> + UINT16 Year; ///< Year, 0-65535
> +} MrcBaseTime;
> +
> +///
> +/// DIMM timings
> +///
> +typedef struct {
> + UINT32 tCK; ///< Memory cycle time, in femtoseconds.
> + UINT16 NMode; ///< Number of tCK cycles for the channel DIMM's
> command rate mode.
> + UINT16 tCL; ///< Number of tCK cycles for the channel DIMM's CAS
> latency.
> + UINT16 tCWL; ///< Number of tCK cycles for the channel DIMM's
> minimum CAS write latency time.
> + UINT16 tFAW; ///< Number of tCK cycles for the channel DIMM's minimum
> four activate window delay time.
> + UINT16 tRAS; ///< Number of tCK cycles for the channel DIMM's minimum
> active to precharge delay time.
> + UINT16 tRCDtRP; ///< Number of tCK cycles for the channel DIMM's
> minimum RAS# to CAS# delay time and Row Precharge delay time.
> + UINT16 tREFI; ///< Number of tCK cycles for the channel DIMM's minimum
> Average Periodic Refresh Interval.
> + UINT16 tRFC; ///< Number of tCK cycles for the channel DIMM's minimum
> refresh recovery delay time.
> + UINT16 tRFCpb; ///< Number of tCK cycles for the channel DIMM's
> minimum per bank refresh recovery delay time.
> + UINT16 tRFC2; ///< Number of tCK cycles for the channel DIMM's minimum
> refresh recovery delay time.
> + UINT16 tRFC4; ///< Number of tCK cycles for the channel DIMM's minimum
> refresh recovery delay time.
> + UINT16 tRPab; ///< Number of tCK cycles for the channel DIMM's minimum
> row precharge delay time for all banks.
> + UINT16 tRRD; ///< Number of tCK cycles for the channel DIMM's minimum
> row active to row active delay time.
> + UINT16 tRRD_L; ///< Number of tCK cycles for the channel DIMM's
> minimum row active to row active delay time for same bank groups.
> + UINT16 tRRD_S; ///< Number of tCK cycles for the channel DIMM's
> minimum row active to row active delay time for different bank groups.
> + UINT16 tRTP; ///< Number of tCK cycles for the channel DIMM's minimum
> internal read to precharge command delay time.
> + UINT16 tWR; ///< Number of tCK cycles for the channel DIMM's minimum
> write recovery time.
> + UINT16 tWTR; ///< Number of tCK cycles for the channel DIMM's
> minimum internal write to read command delay time.
> + UINT16 tWTR_L; ///< Number of tCK cycles for the channel DIMM's
> minimum internal write to read command delay time for same bank groups.
> + UINT16 tWTR_S; ///< Number of tCK cycles for the channel DIMM's
> minimum internal write to read command delay time for different bank
> groups.
> + UINT16 tCCD_L; ///< Number of tCK cycles for the channel DIMM's
> minimum CAS-to-CAS delay for same bank group.
> +} MrcTiming;
> +
> +typedef struct {
> + UINT8 SG; ///< Number of tCK cycles between transactions in the same
> bank group.
> + UINT8 DG; ///< Number of tCK cycles between transactions when
> switching bank groups.
> + UINT8 DR; ///< Number of tCK cycles between transactions when
> switching between Ranks (in the same DIMM).
> + UINT8 DD; ///< Number of tCK cycles between transactions when
> switching between DIMMs
> +} MrcTurnaroundTimes;
> +
> +typedef struct {
> + INT32 Mtb; ///< Medium time base.
> + INT32 Ftb; ///< Fine time base.
> +} MrcTimeBase;
> +
> +typedef struct {
> + UINT8 Left; ///< The left side of the timing eye.
> + UINT8 Center; ///< The center of the timing eye.
> + UINT8 Right; ///< The right side of the timing eye.
> +} MrcDqTimeMargin;
> +
> +typedef struct {
> + UINT8 High; ///< The high side of the Vref eye.
> + UINT8 Center; ///< The center of the Vref eye.
> + UINT8 Low; ///< The low side of the Vref eye.
> +} MrcDqVrefMargin;
> +
> +typedef struct {
> + UINT8 Left; ///< The left side of the command eye.
> + UINT8 Right; ///< The right side of the command eye.
> + UINT8 High; ///< The high side of the command eye.
> + UINT8 Low; ///< The low side of the command eye.
> +} MrcCommandMargin;
> +
> +typedef struct {
> + UINT8 Left; ///< The left side of the receive enable eye.
> + UINT8 Right; ///< The right side of the receive enableeye.
> +} MrcRecvEnMargin;
> +
> +typedef struct {
> + UINT8 Left; ///< The left side of the write leveling eye.
> + UINT8 Right; ///< The right side of the write leveling eye.
> +} MrcWrLevelMargin;
> +
> +typedef struct {
> + UINT8 SpdValid[sizeof (MrcSpd) / (CHAR_BITS * sizeof (UINT8))]; ///<
> Each valid bit maps to SPD byte.
> + UINT8 MrcSpdString[3]; ///< The SPD data start marker. This must be
> located at the start of the SPD data structure. It includes this string plus the
> following flag.
> + union {
> + struct {
> + UINT8 DimmNumber : 4; ///< SPD zero based DIMM number.
> + UINT8 ChannelNumber : 3; ///< SPD zero based channel number.
> + UINT8 MdSocket : 1; ///< 0 = memory down, 1 = socketed.
> + } Bit;
> + UINT8 Data;
> + } Flag;
> + MrcSpd Data; ///< The SPD data for each DIMM. SPDGeneral field =
> 0 when absent.
> +} MrcSpdData;
> +
> +typedef UINT8 (*MRC_IO_READ_8) (UINT32 IoAddress);
> +typedef UINT16 (*MRC_IO_READ_16) (UINT32 IoAddress);
> +typedef UINT32 (*MRC_IO_READ_32) (UINT32 IoAddress);
> +typedef void (*MRC_IO_WRITE_8) (UINT32 IoAddress, UINT8
> Value);
> +typedef void (*MRC_IO_WRITE_16) (UINT32 IoAddress,
> UINT16 Value);
> +typedef void (*MRC_IO_WRITE_32) (UINT32 IoAddress,
> UINT32 Value);
> +typedef UINT8 (*MRC_MMIO_READ_8) (UINT32 Address);
> +typedef UINT16 (*MRC_MMIO_READ_16) (UINT32 Address);
> +typedef UINT32 (*MRC_MMIO_READ_32) (UINT32 Address);
> +typedef UINT64 (*MRC_MMIO_READ_64) (UINT32 Address);
> +typedef UINT8 (*MRC_MMIO_WRITE_8) (UINT32 Address,
> UINT8 Value);
> +typedef UINT16 (*MRC_MMIO_WRITE_16) (UINT32 Address,
> UINT16 Value);
> +typedef UINT32 (*MRC_MMIO_WRITE_32) (UINT32 Address,
> UINT32 Value);
> +typedef UINT64 (*MRC_MMIO_WRITE_64) (UINT32 Address,
> UINT64 Value);
> +typedef UINT8 (*MRC_SMBUS_READ_8) (UINT32 Address,
> UINT32 *Status);
> +typedef UINT16 (*MRC_SMBUS_READ_16) (UINT32 Address,
> UINT32 *Status);
> +typedef UINT8 (*MRC_SMBUS_WRITE_8) (UINT32 Address,
> UINT8 Value, UINT32 *Status);
> +typedef UINT16 (*MRC_SMBUS_WRITE_16) (UINT32 Address,
> UINT16 Value, UINT32 *Status);
> +typedef UINT32 (*MRC_GET_PCI_DEVICE_ADDRESS) (UINT8 Bus, UINT8
> Device, UINT8 Function, UINT8 Offset);
> +typedef UINT32 (*MRC_GET_PCIE_DEVICE_ADDRESS) (UINT8 Bus, UINT8
> Device, UINT8 Function, UINT8 Offset);
> +typedef void (*MRC_GET_RTC_TIME) (UINT8 *Second, UINT8
> *Minute, UINT8 *Hour, UINT8 *Day, UINT8 *Month, UINT16 *Year);
> +typedef UINT64 (*MRC_GET_CPU_TIME) (void *MrcData);
> +typedef void * (*MRC_MEMORY_COPY) (UINT8 *Destination,
> UINT8 *Source, UINT32 NumBytes);
> +typedef void * (*MRC_MEMORY_SET_BYTE) (UINT8 *Destination,
> UINT32 NumBytes, UINT8 Value);
> +typedef void * (*MRC_MEMORY_SET_WORD) (UINT16
> *Destination, UINT32 NumWords, UINT16 Value);
> +typedef void * (*MRC_MEMORY_SET_DWORD) (UINT32
> *Destination, UINT32 NumDwords, UINT32 Value);
> +typedef UINT64 (*MRC_LEFT_SHIFT_64) (UINT64 Data, UINT32
> NumBits);
> +typedef UINT64 (*MRC_RIGHT_SHIFT_64) (UINT64 Data, UINT32
> NumBits);
> +typedef UINT64 (*MRC_MULT_U64_U32) (UINT64 Multiplicand,
> UINT32 Multiplier);
> +typedef UINT64 (*MRC_DIV_U64_U64) (UINT64 Dividend,
> UINT64 Divisor, UINT64 *Remainder);
> +typedef BOOLEAN (*MRC_GET_SPD_DATA) (UINT8 BootMode,
> UINT8 SpdAddress, UINT8 *SpdData, UINT8 *Ddr3Table, UINT32 Ddr3TableSize,
> UINT8 *Ddr4Table, UINT32 Ddr4TableSize, UINT8 *LpddrTable, UINT32
> LpddrTableSize);
> +typedef BOOLEAN (*MRC_GET_RANDOM_NUMBER) (UINT32
> *Rand);
> +typedef UINT32 (*MRC_CPU_MAILBOX_READ) (UINT32 Type,
> UINT32 Command, UINT32 *Value, UINT32 *Status);
> +typedef UINT32 (*MRC_CPU_MAILBOX_WRITE) (UINT32 Type,
> UINT32 Command, UINT32 Value, UINT32 *Status);
> +typedef UINT32 (*MRC_GET_MEMORY_VDD) (void *MrcData,
> UINT32 DefaultVdd);
> +typedef UINT32 (*MRC_SET_MEMORY_VDD) (void *MrcData,
> UINT32 DefaultVdd, UINT32 Value);
> +typedef UINT32 (*MRC_CHECKPOINT) (void *MrcData, UINT32
> CheckPoint, void *Scratch);
> +typedef void (*MRC_DEBUG_HOOK) (void *GlobalData,
> UINT16 DisplayDebugNumber);
> +typedef void (*MRC_PRINT_STRING) (void *String);
> +typedef UINT8 (*MRC_GET_RTC_CMOS) (UINT8 Location);
> +typedef UINT64 (*MRC_MSR_READ_64) (UINT32 Location);
> +typedef UINT64 (*MRC_MSR_WRITE_64) (UINT32 Location,
> UINT64 Data);
> +typedef void (*MRC_RETURN_FROM_SMC) (void *GlobalData,
> UINT32 MrcStatus);
> +typedef void (*MRC_DRAM_RESET) (UINT32
> PciEBaseAddress, UINT32 ResetValue);
> +typedef void (*MRC_SET_LOCK_PRMRR) (UINT32 PrmrrBase,
> UINT32 PrmrrSize);
> +typedef void (*MRC_TXT_ACHECK) (void);
> +
> +///
> +/// Function calls that are called external to the MRC.
> +/// This structure needs to be aligned with SA_FUNCTION_CALLS. All
> functions that are
> +/// not apart of SA_FUNCTION_CALLS need to be at the end of the structure.
> +///
> +typedef struct {
> + MRC_IO_READ_8 MrcIoRead8;
> + MRC_IO_READ_16 MrcIoRead16;
> + MRC_IO_READ_32 MrcIoRead32;
> + MRC_IO_WRITE_8 MrcIoWrite8;
> + MRC_IO_WRITE_16 MrcIoWrite16;
> + MRC_IO_WRITE_32 MrcIoWrite32;
> + MRC_MMIO_READ_8 MrcMmioRead8;
> + MRC_MMIO_READ_16 MrcMmioRead16;
> + MRC_MMIO_READ_32 MrcMmioRead32;
> + MRC_MMIO_READ_64 MrcMmioRead64;
> + MRC_MMIO_WRITE_8 MrcMmioWrite8;
> + MRC_MMIO_WRITE_16 MrcMmioWrite16;
> + MRC_MMIO_WRITE_32 MrcMmioWrite32;
> + MRC_MMIO_WRITE_64 MrcMmioWrite64;
> + MRC_SMBUS_READ_8 MrcSmbusRead8;
> + MRC_SMBUS_READ_16 MrcSmbusRead16;
> + MRC_SMBUS_WRITE_8 MrcSmbusWrite8;
> + MRC_SMBUS_WRITE_16 MrcSmbusWrite16;
> + MRC_GET_PCI_DEVICE_ADDRESS MrcGetPciDeviceAddress;
> + MRC_GET_PCIE_DEVICE_ADDRESS MrcGetPcieDeviceAddress;
> + MRC_GET_RTC_TIME MrcGetRtcTime;
> + MRC_GET_CPU_TIME MrcGetCpuTime;
> + MRC_MEMORY_COPY MrcCopyMem;
> + MRC_MEMORY_SET_BYTE MrcSetMem;
> + MRC_MEMORY_SET_WORD MrcSetMemWord;
> + MRC_MEMORY_SET_DWORD MrcSetMemDword;
> + MRC_LEFT_SHIFT_64 MrcLeftShift64;
> + MRC_RIGHT_SHIFT_64 MrcRightShift64;
> + MRC_MULT_U64_U32 MrcMultU64x32;
> + MRC_DIV_U64_U64 MrcDivU64x64;
> + MRC_GET_SPD_DATA MrcGetSpdData;
> + MRC_GET_RANDOM_NUMBER MrcGetRandomNumber;
> + MRC_CPU_MAILBOX_READ MrcCpuMailboxRead;
> + MRC_CPU_MAILBOX_WRITE MrcCpuMailboxWrite;
> + MRC_GET_MEMORY_VDD MrcGetMemoryVdd;
> + MRC_SET_MEMORY_VDD MrcSetMemoryVdd;
> + MRC_CHECKPOINT MrcCheckpoint;
> + MRC_DEBUG_HOOK MrcDebugHook;
> + MRC_PRINT_STRING MrcPrintString;
> + MRC_GET_RTC_CMOS MrcRtcCmos;
> + MRC_MSR_READ_64 MrcReadMsr64;
> + MRC_MSR_WRITE_64 MrcWriteMsr64;
> + MRC_RETURN_FROM_SMC MrcReturnFromSmc;
> + MRC_DRAM_RESET MrcDramReset;
> + MRC_SET_LOCK_PRMRR MrcSetLockPrmrr;
> + MRC_TXT_ACHECK MrcTxtAcheck;
> +} MRC_FUNCTION;
> +
> +///
> +///*****************************************
> +/// Output related "global data" structures.
> +///*****************************************
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are SDRAM level definitions. All ranks on a rank are set to
> these values.
> +///
> +/* Commented out until needed, in order to save space.
> +typedef struct {
> +} MrcSdramOut;
> +*/
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are rank level definitions. All ranks on a DIMM are set to
> these values.
> +///
> +typedef struct {
> +//MrcSdramOut Sdram[MAX_SDRAM_IN_DIMM]; ///< The
> following are SDRAM level definitions.
> + UINT16 MR[MAX_MR_IN_DIMM]; ///< DRAM mode
> register value.
> + UINT16 MR11; ///< LPDDR3 ODT MR
> + UINT8 Ddr4PdaMr6[MAX_SDRAM_IN_DIMM]; ///< DDR4 MR6[6:0]
> for per-DRAM VrefDQ (PDA)
> +#if (SUPPORT_DDR4 == SUPPORT)
> + UINT8 Device[MAX_SDRAM_IN_DIMM]; ///< Which Bytes are
> tied to which Device where BIT0 set means Byte 0
> +#endif //SUPPORT_DDR4
> +} MrcRankOut;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are DIMM level definitions. All ranks on a DIMM are set to
> these values.
> +///
> +typedef struct {
> + MrcDimmSts Status; ///< See MrcDimmSts for the
> definition of this field.
> + MrcTiming Timing[MAX_PROFILE]; ///< The DIMMs timing values.
> + MrcVddSelect VddVoltage[MAX_PROFILE]; ///< The voltage (VDD) setting
> for this DIMM, per profile.
> + BOOLEAN EccSupport; ///< TRUE if ECC is enabled and
> supported on this DIMM.
> + BOOLEAN IgnoreNonEccDimm; ///< TRUE if a DIMM without
> ECC capability should be ignored.
> + BOOLEAN AddressMirrored; ///< TRUE if the DIMM is address
> mirrored.
> + BOOLEAN SelfRefreshTemp; ///< TRUE if the DIMM supports
> self refresh extended operating temperature range (SRT).
> + BOOLEAN AutoSelfRefresh; ///< TRUE if the DIMM supports
> automatic self refresh (ASR).
> + BOOLEAN PartialSelfRefresh; ///< TRUE if the DIMM supports
> Partial Array Self Refresh (PASR).
> + BOOLEAN OnDieThermalSensor; ///< TRUE if the DIMM supports
> On-die Thermal Sensor (ODTS) Readout.
> + BOOLEAN ExtendedTemperRange; ///< TRUE if the DIMM
> supports Extended Temperature Range (ETR).
> + BOOLEAN ExtendedTemperRefresh; ///< TRUE if the DIMM
> supports 1x Extended Temperature Refresh rate, FALSE = 2x.
> + MrcDdrType DdrType; ///< DDR type: DDR3 or LPDDR3
> + MEMORY_PACKAGE ModuleType; ///< Module type: UDIMM,
> SO-DIMM, etc.
> + UINT32 SdramCount; ///< The number of SDRAM
> components on a DIMM.
> + UINT32 DimmCapacity; ///< DIMM size in MBytes.
> + UINT32 RowSize; ///< The DIMMs row address size.
> + UINT16 ColumnSize; ///< The DIMMs column address size.
> + UINT16 Crc; ///< Calculated CRC16 of the DIMM's
> provided SPD. Can be used to detect DIMM change.
> + UINT8 RankInDimm; ///< The number of ranks in this
> DIMM.
> + UINT8 Banks; ///< Number of banks the DIMM
> contains.
> + UINT8 BankGroups; ///< Number of bank groups the
> DIMM contains.
> + UINT8 PrimaryBusWidth; ///< DIMM primary bus width.
> + UINT8 SdramWidth; ///< DIMM SDRAM width.
> + UINT8 SdramWidthIndex; ///< DIMM SDRAM width index (0 =
> x4, 1 = x8, 2 = x16, 3 = x32).
> + UINT8 DensityIndex; ///< Total SDRAM capacity index (0 =
> 256Mb, 1 = 512Mb, 2 = 1Gb, etc).
> + UINT8 tMAC; ///< Maximum Activate Count for pTRR.
> + UINT8 ReferenceRawCard; ///< Indicates which JEDEC
> reference design raw card was used as the basis for the module assembly.
> + UINT8 ReferenceRawCardRevision; ///< Indicates which JEDEC
> reference design raw card revision.
> + UINT8 XmpSupport; ///< Indicates if XMP profiles are
> supported. 0 = None, 1 = XMP1 only, 2 = XMP2 only, 3 = All.
> + UINT8 XmpRevision; ///< Indicates the XMP revision of this
> DIMM. 0 = None, 12h = 1.2, 13h = 1.3.
> + MrcFrequency Speed; ///< Max DIMM speed in the current
> profile - needed for SMBIOS.
> + MrcRankOut Rank[MAX_RANK_IN_DIMM]; ///< The following are rank
> level definitions.
> +} MrcDimmOut;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are channel level definitions. All DIMMs on a memory
> channel are set to these values.
> +///
> +typedef struct {
> + MrcChannelSts Status; ///<
> Indicates whether this channel should be used.
> + MrcVirtualChannel VirtualChannel;
> ///< define the virtual channel type A or B.
> + MrcTiming Timing[MAX_PROFILE];
> ///< The channel timing values.
> + MrcTimeBase TimeBase[MAX_DIMMS_IN_CHANNEL][MAX_PROFILE];
> ///< Medium and fine timebases for each DIMM in the channel and each
> memory profile.
> + UINT32 Capacity; ///<
> Amount of memory in this channel, in MBytes.
> + UINT32 DimmCount; ///<
> Number of valid DIMMs that exist in the channel.
> + UINT32 DataOffsetTrain[MAX_SDRAM_IN_DIMM];
> ///< DataOffsetTrain CR
> + UINT32 DataCompOffset[MAX_SDRAM_IN_DIMM];
> ///< DataCompOffset CR
> + UINT32 CkeCmdPiCode[MAX_COMMAND_GROUPS];
> ///< CKE CmdPiCode CR, per group
> + UINT32 CmdsCmdPiCode[MAX_COMMAND_GROUPS];
> ///< CmdS CmdPiCode CR, per group
> + UINT32 CmdnCmdPiCode[MAX_COMMAND_GROUPS];
> ///< CmdN CmdPiCode CR, per group
> + UINT16
> TxDqs[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///<
> TxDQS PI Code
> + UINT16
> TxDq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///<
> TxDQ Pi Code
> + UINT16
> RcvEn[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///<
> RcvEn PI Code
> + UINT16
> WlDelay[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///<
> WlDelay PI Code
> + UINT8 ClkPiCode[MAX_RANK_IN_CHANNEL];
> ///< Clk Pi Code
> + UINT8 CtlPiCode[MAX_RANK_IN_CHANNEL];
> ///< Ctl Pi Code
> + UINT8 CkePiCode[MAX_RANK_IN_CHANNEL];
> ///< Ctl Pi Code
> + UINT8 TxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];
> ///< TxEq setting
> + MrcCommandMargin Command[MAX_RANK_IN_CHANNEL];
> ///< Cmd setting
> + MrcDqTimeMargin
> RxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];
> ///< Rx PerBit Pi Code
> + MrcDqTimeMargin
> TxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];
> ///< Tx PerBit Pi Code
> + MrcDqVrefMargin
> RxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];
> ///< Rx PerBit Vref
> + MrcDqVrefMargin
> TxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];
> ///< Rx PerBit Vref
> + MrcRecvEnMargin ReceiveEnable[MAX_RANK_IN_CHANNEL];
> ///< Receive enable per rank
> + MrcWrLevelMargin WriteLevel[MAX_RANK_IN_CHANNEL];
> ///< Write leveling per rank
> + UINT8 IoLatency[MAX_RANK_IN_CHANNEL];
> ///< IOLatency
> + UINT8 RTLatency[MAX_RANK_IN_CHANNEL];
> ///< RoundTripLatency
> + UINT32 RTIoComp; ///<
> RoundTrip IO Compensation of the Channel
> + UINT8 RxVref[MAX_SDRAM_IN_DIMM];
> ///< RX Vref in steps of 7.9 mv
> + UINT8 RxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];
> ///< RxEQ Setting
> + UINT8
> RxDqsP[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///<
> RxDQSP PI Code
> + UINT8
> RxDqsN[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM]; ///<
> RxDQSN PI Code
> + UINT8 ValidRankBitMask; ///<
> Bit map of the populated ranks per channel
> + UINT8 ValidCkeBitMask; ///< Bit
> map of the used CKE pins per channel
> + MrcDimmOut Dimm[MAX_DIMMS_IN_CHANNEL];
> ///< DIMM specific output variables.
> + MrcTurnaroundTimes tRd2Rd;
> ///< The system's minimal delay timings for Read command followed by Read
> command.
> + MrcTurnaroundTimes tRd2Wr;
> ///< The system's minimal delay timings for Read command followed by Write
> command.
> + MrcTurnaroundTimes tWr2Rd;
> ///< The system's minimal delay timings for Write command followed by Read
> command.
> + MrcTurnaroundTimes tWr2Wr;
> ///< The system's minimal delay timings for Write command followed by Write
> command.
> +} MrcChannelOut;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are memory controller level definitions. All channels on a
> controller are set to these values.
> +///
> +typedef struct {
> + MrcControllerSts Status; ///< Indicates whether this controller
> should be used.
> + UINT16 DeviceId; ///< The PCI device id of this memory
> controller.
> + UINT8 RevisionId; ///< The PCI revision id of this memory
> controller.
> + UINT8 ChannelCount; ///< Number of valid channels that
> exist on the controller.
> + MrcChannelOut Channel[MAX_CHANNEL]; ///< The following are
> channel level definitions.
> +} MrcControllerOut;
> +
> +///
> +///********************************************
> +/// Saved data related "global data" structures.
> +///********************************************
> +///
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered to be needed
> +/// by the MRC between power state transitions (S0->S3->S0) and also fast
> and warm boot modes.
> +/// The following are DIMM level definitions.
> +///
> +typedef struct {
> + UINT8 SpdDramDeviceType; ///< Save SPD DramDeviceType
> information needed for SMBIOS structure creation.
> + UINT8 SpdModuleType; ///< Save SPD ModuleType information
> needed for SMBIOS structure creation.
> + UINT8 SpdModuleMemoryBusWidth; ///< Save SPD
> ModuleMemoryBusWidth information needed for SMBIOS structure creation.
> + UINT8 SpdSave[MAX_SPD_SAVE]; ///< Save SPD Manufacturing
> information needed for SMBIOS structure creation.
> +} MrcDimmSave;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered to be needed
> +/// by the MRC between power state transitions (S0->S3->S0) and also fast
> and warm boot modes.
> +/// The following are channel level definitions.
> +///
> +typedef struct {
> + MrcChannelSts Status; ///< Indicates whether this
> channel should be used.
> + UINT32 DimmCount; ///< Number of valid DIMMs
> that exist in the channel.
> + UINT8 ValidRankBitMask; ///< Bit map of the
> populated ranks per channel
> + MrcTiming Timing[MAX_PROFILE]; ///< The channel timing
> values.
> + MrcDimmOut Dimm[MAX_DIMMS_IN_CHANNEL]; ///< Save the
> DIMM output characteristics.
> + MrcDimmSave DimmSave[MAX_DIMMS_IN_CHANNEL]; ///< Save SPD
> information needed for SMBIOS structure creation.
> +} MrcChannelSave;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered to be needed
> +/// by the MRC between power state transitions (S0->S3->S0) and also fast
> and warm boot modes.
> +/// The following are controller level definitions.
> +///
> +typedef struct {
> + MrcControllerSts Status; ///< Indicates whether this controller
> should be used.
> + UINT8 ChannelCount; ///< Number of valid channels that
> exist on the controller.
> + MrcChannelSave Channel[MAX_CHANNEL]; ///< The following are
> channel level definitions.
> +} MrcContSave;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered to be needed
> +/// by the MRC between power state transitions (S0->S3->S0) and also fast
> and warm boot modes.
> +/// The following are system level definitions.
> +///
> +typedef struct {
> + UINT32 Crc; ///< The CRC-32 of the data in this structure.
> +} MrcSaveHeader;
> +
> +//
> +// ------- IMPORTANT NOTE --------
> +// MRC_MC_REGISTER_COUNT in MrcInterface.h should match the table in
> MrcSaveRestore.c.
> +// Update this define whenever you add/remove registers from this table.
> +//
> +#define MRC_REGISTER_COUNT_COMMON (1376 / sizeof (UINT32)) ///< The
> number of MC registers that need to be saved (common)
> +#define MRC_REGISTER_COUNT_SAGV (1528 / sizeof (UINT32)) ///< The
> number of MC registers that need to be saved (per SA GV point)
> +
> +typedef struct {
> + MrcCapabilityId McCapId; ///< The memory
> controller's capabilities.
> + UINT32 RegSaveCommon[MRC_REGISTER_COUNT_COMMON];
> ///< The MC registers that are common to both SA GV points
> + UINT32 RegSaveLow[MRC_REGISTER_COUNT_SAGV]; ///< The
> MC registers for the Low SA GV point
> + UINT32 RegSaveHigh[MRC_REGISTER_COUNT_SAGV]; ///< The
> MC registers for the High SA GV point, or for SA GV Disabled case
> + UINT32 MeStolenSize; ///< The managebility
> engine memory size, in Mbyte units.
> + MrcCpuStepping CpuStepping; ///< The last cold
> boot happended with this CPU stepping.
> + MrcCpuModel CpuModel; ///< The last cold
> boot happended with this CPU model.
> + MrcCpuFamily CpuFamily; ///< CPU is Coffeelake
> + MrcVersion Version; ///< The last cold boot
> happended with this MRC version.
> + UINT32 SaMemCfgCrc; ///< The CRC32 of the
> system agent memory configuration structure.
> + MrcContSave Controller[MAX_CONTROLLERS]; ///< The
> following are controller level definitions.
> + MrcFrequency FreqMax; ///< The system's
> requested maximum frequency.
> + MrcFrequency Frequency; ///< The system's
> common memory controller frequency.
> + UINT32 MemoryClock; ///< The system's
> common memory controller clock, in femtoseconds.
> + BOOLEAN OddRatioModeLow; ///< If Odd Ratio
> Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for
> SAGV Low point.
> + BOOLEAN OddRatioModeHigh; ///< If Odd Ratio
> Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for
> SAGV High point, or SAGV disabled / fixed high / fixed low
> + MrcRefClkSelect RefClk; ///< The memory
> controller is going to use this reference clock.
> + MrcClockRatio Ratio; ///< Request for this
> memory controller to use this clock ratio.
> + MrcVddSelect VddVoltage[MAX_PROFILE]; ///< The voltage
> (VDD) setting for all DIMMs in the system, per profile.
> + BOOLEAN EccSupport; ///< TRUE if ECC is
> enabled and supported on this controller.
> + MrcDdrType DdrType; ///< DDR type: DDR3,
> DDR4, or LPDDR3
> + UINT32 DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1]; ///< The
> Default XMP tCK values read from SPD.
> + UINT8 XmpProfileEnable; ///< If XMP capable
> DIMMs are detected, this will indicate which XMP Profiles are common among
> all DIMMs.
> + BOOLEAN BinnedLpddrDevices; ///< Binned LPDDR3
> devices (6Gb/12Gb/etc)
> + BOOLEAN TCRSensitiveHynixDDR4; ///< TCR sensitive
> Hynix DDR4 in the system
> + BOOLEAN TCRSensitiveMicronDDR4; ///< TCR sensitive
> Micron DDR4 in the system
> + BOOLEAN LpddrEctDone; ///< Set to TRUE once Early
> Command Training on LPDDR is done, and we can run JEDEC Init
> + UINT8 BerEnable; ///< BER Enable (and # of
> Addresses)
> + UINT64 BerAddress[4]; ///< BER Addresses
> + BOOLEAN DmfcLimitedBoard; ///< Indicates if the
> system has 2DPC Memory Configuration which should be DMFC limited.
> + BOOLEAN DmfcLimited; ///< Indicates if the system
> has DMFC limited. Should only be set if DmfcLImitedBoard is TRUE.
> + BOOLEAN MixedUDimmConfig2Dpc; ///< Indicates if the
> system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
> + BOOLEAN ExtendedDdrOverclock; ///< Indicates if MC is
> capable of extended Overclock Memory frequencies.
> +} MrcSaveData;
> +
> +typedef struct {
> + UINT32 Size; ///< The size of this structure, in
> bytes. Must be the first entry in this structure.
> + MrcDebug Debug; ///< MRC debug related
> variables used for serial output and debugging purposes.
> + MrcVersion Version; ///< The memory reference code
> version.
> + MrcFrequency FreqMax; ///< The requested maximum
> valid frequency.
> + MrcFrequency Frequency; ///< The system's common
> memory controller frequency.
> + UINT32 MemoryClockMax; ///< The system's common
> memory controller maximum clock, in femtoseconds.
> + UINT32 MemoryClock; ///< The system's common
> memory controller clock, in femtoseconds.
> + MrcRefClkSelect RefClk; ///< The memory controller is
> going to use this reference clock.
> + MrcClockRatio Ratio; ///< Request for this memory
> controller to use this clock ratio.
> + MrcMemoryMap MemoryMapData; ///< The system's
> memory map data.
> + MrcGfxDataSize GraphicsStolenSize; ///< Graphics Data Stolen
> Memory size in MB
> + MrcGfxGttSize GraphicsGttSize; ///< GTT graphics stolen
> memory size in MB
> + MrcVddSelect VddVoltage[MAX_PROFILE]; ///< The currently
> running voltage (VDD) setting for all DIMMs in the system, per profile.
> + MrcGdxc Gdxc; ///< GDXC enable and size.
> + BOOLEAN VddVoltageDone; ///< To determine if
> VddVoltageDone update has been done already
> + BOOLEAN EccSupport; ///< TRUE if ECC is enabled and
> supported on this controller.
> + BOOLEAN EnDumRd; ///< Enable/Disable Logic
> Analyzer
> + BOOLEAN RestoreMRs; ///< Enable/Disable restoring
> + BOOLEAN LpddrEctDone; ///< Set to TRUE once Early
> Command Training on LPDDR is done, and we can run JEDEC Init
> + BOOLEAN LpddrWLUpdated; ///< Set to TRUE once
> LPDDR WL Memory Set has been updated
> + BOOLEAN JedecInitDone; ///< Set to TRUE once JEDEC
> Init on LPDDR/DDR4 is done
> + UINT32 DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1];
> ///< The Default XMP tCK values read from SPD.
> + UINT8 XmpProfileEnable; ///< If XMP capable DIMMs are
> detected, this will indicate which XMP Profiles are common among all DIMMs.
> + BOOLEAN Capable100; ///< The MC is capable of 100
> reference clock (0 = no, 1 = yes).
> + BOOLEAN AutoSelfRefresh; ///< Indicates ASR is
> supported for all the DIMMS for 2xRefresh
> + MrcDdrType DdrType; ///< Current memory type:
> DDR3, DDR4, or LPDDR3
> + MrcSpdStatus SpdSecurityStatus; ///< Status variable to
> inform BIOS that memory contains an alias.
> + UINT32 MrcTotalChannelLimit; ///< The maximum allowed
> memory size per channel, in MBytes.
> + UINT8 SdramCount; ///< The number of SDRAM
> components on a DIMM.
> + UINT16 Qclkps; ///< Qclk period in pS
> + UINT8 DQPat; ///< Global Variables storing the
> current DQPat REUT Test
> + INT8 DQPatLC; ///< Global Variables storing the
> current DQPat Loopcount
> + UINT16 NumCL; ///< Global Variables storing the
> current number of Cachelines
> + UINT8 ValidRankMask; ///< Rank bit map - includes
> both channels
> + UINT8 ValidChBitMask; ///< Channel bit map of the
> populated channels
> + BOOLEAN UpmPwrRetrainFlag; ///< A flag that indicates if
> training with higher UPM/PWR limits.
> + UINT32
> MarginResult[MAX_RESULT_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHANNE
> L][MAX_SDRAM_IN_DIMM][MAX_EDGES]; ///< Stores last margin
> measurement.
> + BOOLEAN
> MarginSignReversed[MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_SDRA
> M_IN_DIMM][MAX_EDGES]; ///< Indicates if the Margin Sign is Reversed
> + MrcOdtPowerSaving OdtPowerSavingData; ///< ODT power savings
> data.
> + BOOLEAN TxDIMMVref[MAX_CHANNEL]; ///< Whether Write
> DIMM Vref is enabled based on Channel
> + UINT32 MchBarWriteCount; ///< The number of MMIO
> writes performed during MRC execution.
> + UINT32 MchBarReadCount; ///< The number of MMIO
> reads performed during MRC execution.
> + UINT8 BerEnable; ///< BER Enable (and # of
> Addresses)
> + UINT64 BerAddress[4]; ///< BER Addresses
> + UINT8 CmdVLoop; ///< Keeps track of the # of
> CmdV training step runned
> + UINT8 CmdVLoopStatus; ///< Keeps the last status of
> the CmdV training step
> + UINT8 tMAC; ///< Maximum Activate Count for
> pTRR.
> + UINT8 LpddrMemWriteLatencySet; ///< 0 = Set A (WL), 1 = Set
> B (WL) if supported
> + BOOLEAN Ddr4PdaEnable; ///< Current status of PDA - if
> true all the Mr6 operations need to use PDA mode.
> + BOOLEAN BinnedLpddrDevices; ///< Binned LPDDR3 devices
> (6Gb/12Gb/etc)
> + MrcControllerOut Controller[MAX_CONTROLLERS]; ///< The following
> are controller level definitions.
> + BOOLEAN TCRSensitiveHynixDDR4; ///< TCR sensitive Hynix
> DDR4 in the system
> + BOOLEAN TCRSensitiveMicronDDR4; ///< TCR sensitive Micron
> DDR4 in the system
> + BOOLEAN OddRatioMode; ///< If Odd Ratio Mode is
> enabled, QCLK frequency has an addition of 133/100 MHz
> + BOOLEAN LpddrDramOdt; ///< Indicates if LPDDR
> DRAM ODT is used - Only used for 2133+
> + BOOLEAN ExtendedDdrOverclock; ///< Indicates if MC is
> capable of extended Overclock Memory frequencies.
> + BOOLEAN DmfcLimitedBoard; ///< Indicates if the system
> has 2DPC Memory Configuration which should be DMFC limited.
> + BOOLEAN DmfcLimited; ///< Indicates if the system has
> DMFC has been limited. Should only be set if DmfcLImitedBoard is TRUE.
> + BOOLEAN MixedUDimmConfig2Dpc; ///< Indicates if the
> system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
> +#ifdef BDAT_SUPPORT
> + union {
> + MRC_BDAT_SCHEMA_LIST_HOB *Pointer; ///< Pointer to the
> BDAT schema list.
> + UINT64 Data;
> + } BdatSchemasHob;
> + union {
> + BDAT_MEMORY_DATA_HOB *Pointer; ///< Pointer to the BDAT
> memory data HOB.
> + UINT64 Data;
> + } BdatMemoryHob[MAX_SCHEMA_LIST_LENGTH];
> + UINT8
> Margin2DResult[MAX_2D_EYE_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHAN
> NEL][MAX_2D_EYE_OFFSETS][MAX_EDGES]; ///< Stores the 2D Eye Margin
> +#endif
> +
> +#ifdef UP_SERVER_FLAG
> + UINT8 ThermOffset[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> ///< TSOD Thermal Offset
> +#endif
> +} MrcOutput;
> +
> +///
> +///****************************************
> +/// Input related "global data" structures.
> +///****************************************
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are SDRAM level definitions. All ranks on a rank are set to
> these values.
> +///
> +/* Commented out until needed, in order to save space.
> +typedef struct {
> + UINT8 Placeholder; ///< TODO: Is there anything that needs to go in here?
> +} MrcSdramIn;
> +*/
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are rank level definitions. All ranks on a DIMM are set to
> these values.
> +///
> +/* Commented out until needed, in order to save space.
> +typedef struct {
> + MrcSdramIn Sdram[MAX_SDRAM_IN_DIMM]; ///< The following are
> SDRAM level definitions.
> +} MrcRankIn;
> +*/
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are DIMM level definitions. All ranks on a DIMM are set to
> these values.
> +///
> +typedef struct {
> + MrcDimmSts Status; ///< Indicates whether this DIMM should
> be used.
> + MrcSpdData Spd; ///< The SPD data for each DIMM.
> SPDGeneral field = 0 when absent.
> + MrcTiming Timing; ///< The DIMMs requested timing
> overrides.
> + UINT8 SpdAddress; ///< The SMBus address for the DIMM's
> SPD data.
> +//MrcRankIn Rank[MAX_RANK_IN_DIMM]; ///< The following are rank level
> definitions.
> +} MrcDimmIn;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are channel level definitions. All DIMMs on a memory
> channel are set to these values.
> +///
> +typedef struct {
> + MrcChannelSts Status; ///< Indicates whether this channel
> should be used.
> + UINT32 DimmCount; ///< The maximum number of
> DIMMs on this channel.
> + MrcDimmIn Dimm[MAX_DIMMS_IN_CHANNEL]; ///< The following
> are DIMM level definitions.
> + UINT8 DqsMapCpu2Dram[8]; ///< Mapping from CPU DQS
> pins to SDRAM DQS pins
> + UINT8 DqMapCpu2Dram[8][MAX_BITS]; ///< Mapping from CPU
> DQ pins to SDRAM DQ pins
> + UINT8 DQByteMap[MrcIterationMax][2]; ///< Maps which PI clocks
> are used by what LPDDR DQ Bytes (from CPU side), per group
> + ///< DQByteMap[0] - ClkDQByteMap:
> + ///< If clock is per rank, program to [0xFF,
> 0xFF]
> + ///< If clock is shared by 2 ranks, program
> to [0xFF, 0] or [0, 0xFF]
> + ///< If clock is shared by 2 ranks but does
> not go to all bytes,
> + ///< Entry[i] defines which DQ
> bytes Group i services
> + ///< DQByteMap[1] - CmdNDQByteMap:
> Entry[0] is CmdN/CAA and Entry[1] is CmdN/CAB
> + ///< DQByteMap[2] - CmdSDQByteMap:
> Entry[0] is CmdS/CAA and Entry[1] is CmdS/CAB
> + ///< DQByteMap[3] - CkeDQByteMap :
> Entry[0] is CKE /CAA and Entry[1] is CKE /CAB
> + ///< For DDR, DQByteMap[3:1]
> = [0xFF, 0]
> + ///< DQByteMap[4] - CtlDQByteMap :
> Always program to [0xFF, 0] since we have 1 CTL / rank
> + ///< Variable only
> exists to make the code easier to use
> + ///< DQByteMap[5] - CmdVDQByteMap:
> Always program to [0xFF, 0] since we have 1 CA Vref
> + ///< Variable only
> exists to make the code easier to use
> +} MrcChannelIn;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are memory controller level definitions. All channels on a
> controller are set to these values.
> +///
> +typedef struct {
> + MrcControllerSts Status; ///< Indicates whether this controller
> should be used.
> + UINT8 ChannelCount; ///< Number of valid channels that
> are requested on the controller.
> + MrcChannelIn Channel[MAX_CHANNEL]; ///< The following are channel
> level definitions.
> +} MrcControllerIn;
> +
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are system level definitions. All memory controllers in the
> system are set to these values.
> +typedef struct {
> + // Start of synchronization to the SA MEMORY_CONFIGURATION structure.
> + // Alignment of this block must be maintained and field offsets must match.
> + UINT8 Header[28]; ///< Offset 0-27 Config Block Header
> + UINT16 Size; ///< Offset 28 The size of this structure, in bytes.
> Must be the first entry in this structure.
> + UINT8 HobBufferSize; ///< Offset 30 Size of HOB buffer
> + UINT8 MemoryProfile; ///< Offset 31 SPD XMP profile selection - for
> XMP supported DIMM: <b>0=Default DIMM profile</b>, 1=Customized profile,
> 2=XMP profile 1, 3=XMP profile 2.
> + // The following parameters are used only when MemoryProfile is
> UserDefined (CUSTOM PROFILE)
> + UINT16 tCL; ///< Offset 32 User defined Memory Timing tCL
> value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 31=Maximum.
> + UINT16 tRCDtRP; ///< Offset 34 User defined Memory Timing
> tRCD value (same as tRP), valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 63=Maximum.
> + UINT16 tRAS; ///< Offset 36 User defined Memory Timing
> tRAS value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 64=Maximum.
> + UINT16 tWR; ///< Offset 38 User defined Memory Timing
> tWR value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> legal values: 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 24.
> + UINT16 tRFC; ///< Offset 40 User defined Memory Timing
> tRFC value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 1023=Maximum.
> + UINT16 tRRD; ///< Offset 42 User defined Memory Timing
> tRRD value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 15=Maximum.
> + UINT16 tWTR; ///< Offset 44 User defined Memory Timing
> tWTR value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 28=Maximum.
> + UINT16 tRTP; ///< Offset 46 User defined Memory Timing
> tRTP value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 15=Maximum. DDR4 legal values: 5, 6, 7, 8, 9, 10, 12
> + UINT16 tFAW; ///< Offset 48 User defined Memory Timing
> tFAW value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 63=Maximum.
> + UINT16 tCWL; ///< Offset 50 User defined Memory Timing
> tCWL value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 20=Maximum.
> + UINT16 tREFI; ///< Offset 52 User defined Memory Timing
> tREFI value, valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 65535=Maximum.
> + UINT16 PciIndex; ///< Offset 54 Pci index register address:
> <b>0xCF8=Default</b>
> + UINT16 PciData; ///< Offset 56 Pci data register address:
> <b>0xCFC=Default</b>
> + UINT16 VddVoltage; ///< Offset 58 DRAM voltage (Vdd) in
> millivolts: <b>0=Platform Default (no override)</b>, 1200=1.2V, 1350=1.35V
> etc.
> + UINT16 Idd3n; ///< Offset 60 EPG Active standby current
> (Idd3N) in milliamps from DIMM datasheet.
> + UINT16 Idd3p; ///< Offset 62 EPG Active power-down current
> (Idd3P) in milliamps from DIMM datasheet.
> +
> + UINT32 EccSupport:1; ///< Offset 64 DIMM Ecc Support
> option - for Desktop only: 0=Disable, <b>1=Enable</b>
> + UINT32 MrcSafeConfig:1; ///< - MRC Safe Mode:
> <b>0=Disable</b>, 1=Enable
> + UINT32 RemapEnable:1; ///< - This option is used to control
> whether to enable/disable memory remap above 4GB: 0=Disable,
> <b>1=Enable</b>.
> + UINT32 ScramblerEnable:1; ///< - Memory scrambler support:
> 0=Disable, <b>1=Enable</b>
> + UINT32 Vc1ReadMeter:1; ///< - VC1 Read Metering Enable:
> 0=Disable, <b>1=Enable</b>
> + UINT32 DdrThermalSensor:1; ///< - Ddr Thermal Sensor:
> 0=Disable, <b>1=Enable</b>
> + UINT32 LpddrMemWriteLatencySet:1; ///< - LPDDR3 Write Latency Set
> option: 0=Set A, <b>1=Set B</b>
> + UINT32 Off64Bits7to8Rsvd:2; ///< - Bits 7-8 Reserved
> + UINT32 SimicsFlag:1; ///< - Option to Enable SIMICS:
> 0=Disable, <b>1=Enable</b>
> + UINT32 Ddr4DdpSharedClock:1; ///< - New Select if CLK0 is shared
> between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>,
> 1=Shared
> + UINT32 Ddr4DdpSharedZq:1; ///< - Select if ZQ pin is shared
> between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>,
> 1=Shared
> + // Thermal Management
> + UINT32 ThermalManagement:1; ///< - Memory Thermal
> Management Support: <b>0=Disable</b>, 1=Enable.
> + UINT32 PeciInjectedTemp:1; ///< - Enable/Disable memory
> temperatures to be injected to the processor via PECI: <b>0=Disable</b>,
> 1=Enable.
> + UINT32 ExttsViaTsOnBoard:1; ///< - Enable/Disable routing
> TS-on-Board's ALERT# and THERM# to EXTTS# pins on the PCH:
> <b>0=Disable</b>, 1=Enable.
> + UINT32 ExttsViaTsOnDimm:1; ///< - Enable/Disable routing
> TS-on-DIMM's ALERT# to EXTTS# pin on the PCH: <b>0=Disable</b>, 1=Enable.
> + UINT32 VirtualTempSensor:1; ///< - Enable/Disable Virtual
> Temperature Sensor (VTS): <b>0=Disable</b>, 1=Enable.
> + UINT32 Lp4DqsOscEn:1; ///< - DqDqsReTraining support:
> 0=Disable, <b>1=Enable</b>
> + UINT32 DualDimmPerChannelBoardType:1; ///< -
> DualDimmPerChannelBoardType: Option to indicate if the Memory Design for
> the board includes two DIMMs per channel: <b>0=Single DIMM Design</b>,
> 1=Dual DIMM Design
> + UINT32 ReservedBits1:13;
> + /**
> + Disables a DIMM slot in the channel even if a DIMM is present\n
> + Array index represents the channel number (0 = channel 0, 1 = channel 1)\n
> + <b>0x0 = DIMM 0 and DIMM 1 enabled</b>\n
> + 0x1 = DIMM 0 disabled, DIMM 1 enabled\n
> + 0x2 = DIMM 0 enabled, DIMM 1 disabled\n
> + 0x3 = DIMM 0 and DIMM 1 disabled (will disable the whole channel)\n
> + **/
> + UINT8 DisableDimmChannel[MAX_CHANNEL]; ///< Offset 68
> + /**
> + Selects the ratio to multiply the reference clock by for the DDR frequency\n
> + When RefClk is 133MHz\n
> + <b>0x00 = Auto</b>, 0x03 through 0x0C are valid values, all others are
> invalid\n
> + When RefClk is 100MHz\n
> + <b>0x00 = Auto</b>, 0x06 through 0x10 are valid values, all others are
> invalid\n
> + **/
> + UINT8 Ratio; ///< Offset 70
> + UINT8 ProbelessTrace; ///< Offset 71 Probeless Trace:
> <b>0=Disabled</b>, <b>1=Enabled</b>
> + UINT32 BClkFrequency; ///< Offset 72 Base reference clock value, in
> Hertz: <b>100000000 = 100Hz</b>, 125000000=125Hz, 167000000=167Hz,
> 250000000=250Hz
> + /**
> + - Channel Hash Enable.\n
> + NOTE: BIT7 will interleave the channels at a 2 cacheline granularity, BIT8 at
> 4 and BIT9 at 8\n
> + 0=BIT6, <B>1=BIT7</B>, 2=BIT8, 3=BIT9
> + **/
> + UINT8 ChHashInterleaveBit; ///< Offset 76
> + UINT8 EnergyScaleFact; ///< Offset 77 - Energy Scale Factor.
> 0=Minimal, 7=Maximum, <b>4=Default</b>
> + UINT8 Reserved0; ///< Offset 78 - Reserved for future use.
> + UINT8 McLock; ///< Offset 79 - Enable/Disable memory
> configuration register locking: 0=Disable, <b>1=Enable</b>.
> + // Training Algorithms
> + TrainingStepsEn TrainingEnables; ///< Offset 80 - Options to Enable
> individual training steps
> + TrainingStepsEn2 TrainingEnables2; ///< Offset 84 - Options to Enable
> individual training steps
> +
> + UINT32 OddRatioMode:1; ///< Offset 88 - If Odd Ratio Mode is
> enabled, QCLK frequency has an addition of 133/100 MHz: <b>0=Disable</b>,
> 1=Enable
> + UINT32 MrcTimeMeasure:1; ///< - Enables serial debug level to
> display the MRC execution times only: <b>0=Disable</b>, 1=Enable
> + UINT32 MrcFastBoot:1; ///< - Enables the MRC fast boot path for
> faster cold boot execution: 0=Disable, <b>1=Enable</b>
> + UINT32 DqPinsInterleaved:1; ///< - Interleaving mode of DQ/DQS pins
> for HSW_ULT which depends on board routing: <b>0=Disable</b>, 1=Enable
> + UINT32 RankInterleave:1; ///< - Rank Interleave Mode: 0=Disable,
> <b>1=Enable</b>
> + UINT32 EnhancedInterleave:1; ///< - Enhanced Interleave Mode:
> 0=Disable, <b>1=Enable</b>
> + UINT32 WeaklockEn:1; ///< - Weak Lock Enable: 0=Disable,
> <b>1=Enable</b>
> + UINT32 CmdTriStateDis:1; ///< - CMD Tri-State Support:
> <b>0=Enable</b>, 1=Disable. Note: This should be set to 1 (Disable) if
> Command RTT is not present on the platform.
> + UINT32 MemoryTrace:1; ///< - Memory Trace to second DDR
> channel using Stacked Mode: <b>0=Disable</b>, 1=Enable
> + UINT32 ChHashEnable:1; ///< - Channel Hash Enable: 0=Disable,
> <b>1=Enable</b>
> + UINT32 EnableExtts:1; ///< - Enable Extts: <b>0=Disable</b>,
> 1=Enable
> + UINT32 EnableCltm:1; ///< - Enable Closed Loop Thermal
> Management: <b>0=Disable</b>, 1=Enable
> + UINT32 EnableOltm:1; ///< - Enable Open Loop Thermal
> Management: <b>0=Disable</b>, 1=Enable
> + UINT32 EnablePwrDn:1; ///< - Enable Power Down control for
> DDR: 0=PCODE control, <b>1=BIOS control</b>
> + UINT32 EnablePwrDnLpddr:1; ///< - Enable Power Down for LPDDR:
> 0=PCODE control, <b>1=BIOS control</b>
> + UINT32 LockPTMregs:1; ///< - Lock PCU Thermal Management
> registers: 0=Disable, <b>1=Enable</b>
> + UINT32 UserPowerWeightsEn:1; ///< - Allows user to explicitly set
> power weight, scale factor, and channel power floor values: <b>0=Disable</b>,
> 1=Enable
> + UINT32 RaplLim2Lock:1; ///< - Lock DDR_RAPL_LIMIT register:
> <b>0=Disable</b>, 1=Enable
> + UINT32 RaplLim2Ena:1; ///< - Enable Power Limit 2:
> <b>0=Disable</b>, 1=Enable
> + UINT32 RaplLim1Ena:1; ///< - Enable Power Limit 1:
> <b>0=Disable</b>, 1=Enable
> + UINT32 SrefCfgEna:1; ///< - Enable Self Refresh: 0=Disable,
> <b>1=Enable</b>
> + UINT32 ThrtCkeMinDefeatLpddr:1; ///< - Throttler CKE min defeature for
> LPDDR: 0=Disable, <b>1=Enable</b>
> + UINT32 ThrtCkeMinDefeat:1; ///< - Throttler CKE min defeature:
> <b>0=Disable</b>, 1=Enable
> + UINT32 AutoSelfRefreshSupport:1; ///< - FALSE = No auto self refresh
> support, <b>TRUE = auto self refresh support</b>
> + UINT32 ExtTemperatureSupport:1; ///< - FALSE = No extended
> temperature support, <b>TRUE = extended temperature support</b>
> + UINT32 MobilePlatform:1; ///< - Memory controller device id
> indicates: <b>TRUE if mobile</b>, FALSE if not. Note: This will be
> auto-detected and updated.
> + UINT32 Force1Dpc:1; ///< - TRUE means force one DIMM per
> channel, <b>FALSE means no limit</b>
> + UINT32 ForceSingleRank:1; ///< - TRUE means use Rank0 only (in
> each DIMM): <b>0=Disable</b>, 1=Enable
> + UINT32 RhPrevention:1; ///< - RH Prevention Enable/Disable:
> 0=Disable, <b>1=Enable</b>
> + UINT32 VttTermination:1; ///< - Vtt Termination for Data ODT:
> <b>0=Disable</b>, 1=Enable
> + UINT32 VttCompForVsshi:1; ///< - Enable/Disable Vtt Comparator
> For Vsshi: <b>0=Disable</b>, 1=Enable
> + UINT32 ExitOnFailure:1; ///< - MRC option for exit on failure or
> continue on failure: 0=Disable, <b>1=Enable</b>
> +
> + UINT32 VddSettleWaitTime; ///< Offset 92 - Amount of time in
> microseconds to wait for Vdd to settle on top of 200us required by JEDEC spec:
> <b>Default=0</b>
> + UINT16 FreqSaGvLow; ///< Offset 96 - SA GV: 0 is Auto/default,
> otherwise holds the frequency value: <b>0=Default</b>, 1067, 1200, 1333,
> 1400, 1600, 1800, 1867.
> + UINT16 SrefCfgIdleTmr; ///< Offset 98 - Self Refresh idle timer:
> <b>512=Minimal</b>, 65535=Maximum
> + UINT8 RhActProbability; ///< Offset 100 - Activation probability for
> Hardware RHP
> + UINT8 SmramMask; ///< Offset 101 - Reserved memory ranges
> for SMRAM
> + UINT16 Vc1ReadMeterThreshold; ///< Offset 102 - VC1 Read Meter
> Threshold (within Time Window): 0=Minimal, 0xFFFF=Maximum,
> <b>0x118=Default</b>
> + UINT32 Vc1ReadMeterTimeWindow; ///< Offset 104 - VC1 Read Meter
> Time Window: 0=Minimal, 0x1FFFF=Maximum, <b>0x320=Default</b>
> + UINT64 BerAddress[4]; ///< Offset 108 - 139 BER Address(es):
> <b>0=Minimal</b>, 0xFFFFFFFFFFFFFFFF=Maximum (step is 0x40)
> +
> + UINT16 ChHashMask; ///< Offset 140 - Channel Hash Mask:
> 0x0001=BIT6 set(Minimal), 0x3FFF=BIT[19:6] set(Maximum), <b>0x30CE=
> BIT[19:18, 13:12 ,9:7] set</b>
> + UINT16 DdrFreqLimit; ///< Offset 142 - Memory Frequency Limit:
> <b>0=Auto (limited by SPD/CPU capability)</b>, for valid values see
> MrcFrequency in MrcInterface.h
> + ThermalMngmtEn ThermalEnables; ///< Offset 144 - 187
> +
> + UINT8 MaxRttWr; ///< Offset 188 - Maximum DIMM RTT_WR to
> use in power training: <b>0=ODT Off</b>, 1 = 120 ohms
> + UINT8 ThrtCkeMinTmr; ///< Offset 189 - Throttler CKE min timer:
> 0=Minimal, 0xFF=Maximum, <b>0x30=Default</b>
> + UINT8 ThrtCkeMinTmrLpddr; ///< Offset 190 - Throttler CKE min timer
> for LPDDR: 0=Minimal, 0xFF=Maximum, <b>0x40=Default</b>
> + UINT8 BerEnable; ///< Offset 191 - BER Enable and # of
> Addresses passed in: <b>0=Minimal</b>, 8=Maximum
> + UINT8 CkeRankMapping; ///< Offset 192 - Bits [7:4] - Channel 1, bits
> [3:0] - Channel 0. <b>0xAA=Default</b> Bit [i] specifies which rank CKE[i] goes
> to.
> + UINT8 StrongWkLeaker; ///< Offset 193 - Strong Weak Leaker:
> 1=Minimal, <b>7=Maximum</b>
> + UINT8 CaVrefConfig; ///< Offset 194 - 0=VREF_CA goes to both
> CH_A and CH_B, 1=VREF_CA to CH_A, VREF_DQ_A to CH_B, <b>2=VREF_CA to
> CH_A, VREF_DQ_B to CH_B</b>
> + UINT8 SaGv; ///< Offset 195 - SA GV: <b>0=Disabled</b>,
> 1=FixedLow, 2=FixedHigh, 3=Enabled
> + UINT8 RaplPwrFlCh1; ///< Offset 196 - Power Channel 1 Floor value:
> <b>0=Minimal</b>, 255=Maximum
> + UINT8 RaplPwrFlCh0; ///< Offset 197 - Power Channel 0 Floor value:
> <b>0=Minimal</b>, 255=Maximum
> + UINT8 NModeSupport; ///< Offset 198 - Memory N Mode Support
> - Enable user to select Auto, 1N or 2N: <b>0=AUTO</b>, 1=1N, 2=2N.
> + UINT8 RefClk; ///< Offset 199 - Selects the DDR base reference
> clock. 0x01 = 100MHz, <b>0x00 = 133MHz</b>
> + UINT8 EnCmdRate; ///< Offset 200 - CMD Rate Enable: 0=Disable,
> 1=1 CMD, 2=2 CMDs, <b>3=3 CMDs</b>, 4=4 CMDs, 5=5 CMDs, 6=6 CMDs, 7=7
> CMDs
> + UINT8 Refresh2X; ///< Offset 201 - Refresh 2x: <b>0=Disable</b>,
> 1=Enable for WARM or HOT, 2=Enable for HOT only
> + UINT8 EpgEnable; ///< Offset 202 - Enable Energy Performance
> Gain.
> + UINT8 RhSolution; ///< Offset 203 - Type of solution to be used
> for RHP - 0/1 = HardwareRhp/Refresh2x
> + UINT8 UserThresholdEnable; ///< Offset 204 - Flag to manually select
> the DIMM CLTM Thermal Threshold, 0=Disable, 1=Enable, <b>0=Default</b>
> + UINT8 UserBudgetEnable; ///< Offset 205 - Flag to manually select the
> Budget Registers for CLTM Memory Dimms , 0=Disable, 1=Enable,
> <b>0=Default</b>
> + UINT8 TsodTcritMax; ///< Offset 206 - TSOD Tcrit Maximum Value
> to be Configure , 0=Minimal, 128=Maximum, , <b>105=Default</b>
> +
> + UINT8 TsodEventMode; ///< Offset 207 - Flag to Enable Event Mode
> Interruption in TSOD Configuration Register, 0=Disable, 1=Enable,
> <b>1=Default</b>
> + UINT8 TsodEventPolarity; ///< Offset 208 - Event Signal Polarity in
> TSOD Configuration Register, 0=Low, 1=High, <b>0=Default</b>
> + UINT8 TsodCriticalEventOnly; ///< Offset 209 - Critical Trigger Only in
> TSOD Configuration Register,0=Disable, 1=Enable, <b>1=Default</b>
> + UINT8 TsodEventOutputControl; ///< Offset 210 - Event Output Control in
> TSOD Configuration Register,0=Disable, 1=Enable, <b>1=Default</b>
> + UINT8 TsodAlarmwindowLockBit; ///< Offset 211 - Alarm Windows Lock Bit
> in TSOD Configuration Register,0=Unlock, 1=Lock, <b>0=Default</b>
> + UINT8 TsodCriticaltripLockBit;///< Offset 212 - Critical Trip Lock Bit in TSOD
> Configuration Register,0=Unlock, 1=Lock, <b>0=Default</b>
> + UINT8 TsodShutdownMode; ///< Offset 213 - Shutdown Mode TSOD
> Configuration Register,0=Enable, 1=Disable, <b>0=Default</b>
> + UINT8 TsodThigMax; ///< Offset 214 - Thigh Max Value In the for
> CLTM Memory Dimms , 0=Disable, 1=Enable, <b>0=Default</b>
> + UINT8 TsodManualEnable; ///< Offset 215 - Flag to manually select
> the TSOD Register Values , 0=Disable, 1=Enable, <b>0=Default</b>
> + UINT8 DllBwEn0; ///< Offset 216 - DllBwEn value for 1067
> + UINT8 DllBwEn1; ///< Offset 217 - DllBwEn value for 1333
> + UINT8 DllBwEn2; ///< Offset 218 - DllBwEn value for 1600
> + UINT8 DllBwEn3; ///< Offset 219 - DllBwEn value for 1867 and
> up
> + UINT8 RetrainOnFastFail; ///< Offset 220 - Restart MRC in Cold mode if
> SW MemTest fails during Fast flow. 0 = Disabled, <b>1 = Enabled</b>
> + UINT8 ForceOltmOrRefresh2x; ///< Offset 221 - Force OLTM or 2X Refresh
> when needed. <b>0 = Force OLTM</b>, 1 = Force 2x Refresh
> + UINT8 PowerDownMode; ///< Offset 222 - CKE Power Down Mode:
> <b>0xFF=AUTO</b>, 0=No Power Down, 1= APD mode, 6=PPD-DLL Off mode
> + UINT8 PwdwnIdleCounter; ///< Offset 223 - CKE Power Down Mode
> Idle Counter: 0=Minimal, 255=Maximum, <b>0x80=0x80 DCLK</b>
> + UINT8 IsvtIoPort; ///< Offset 224 ISVT IO Port Address: 0=Minimal,
> 0xFF=Maximum, <b>0x99=Default</b>
> + UINT8 Reserved3; ///< Offset 225 - ConfigBlock size must be a
> multiple of DWORDs
> + MrcGdxc Gdxc; ///< Offset 226 - 228 - GDXC enable and size.
> + UINT8 RMTLoopCount; ///< Offset 229 - Indicates the Loop Count
> to be used for Rank Margin Tool Testing: 1=Minimal, 32=Maximum, 0=AUTO,
> <b>0=Default</b>
> + UINT8 Reserved4[2]; ///< Offset 230 - 231 Reserved for DWORD
> alignment.
> + UINT32 RmtPerTask:1; ///< Offset 232 Bit 0: Rank Margin Tool
> Per Task. <b>0 = Disabled</b>, 1 = Enabled
> + UINT32 Off232Bit1Rsvd:2; ///< Offset 232 Bit 1-2: Reserved
> + UINT32 EnBER:1; ///< Offset 232 Bit 3: Define if EnBER is
> enabled for Rank Margin Tool
> + UINT32 Ddr4MixedUDimm2DpcLimit:1; ///< Offset 232 Bit 4:
> Enable/Disable 2667 Frequency Limitation for DDR4 U-DIMM Mixed Dimm
> 2DPC population. 0 = Disabled, <b>1 = Enabled</b>
> + UINT32 FastBootRmt:1; ///< Offset 232 Bit 5: Enable/Disable
> RMT on FastBoot. <b>0 = Disabled</b>, 1 = Enabled
> + UINT32 MrcTrainOnWarm:1; ///< Offset 232 Bit 6: Enalbes MRC
> trainin on warm boot : <b>0=Disable</b>, 1 = Enabled
> + UINT32 LongFlyByModeEnabled:1; ///< Offset 232 Bit 7: Long FlyBy
> Mode Enabled : <b>0 = Disabled</b>, 1 = Enabled
> + UINT32 Off232RsvdBits:24; ///< Offset 232 Bit 8-31: Reserved
> +
> + //
> + // TurnAround Timing
> + //
> + MrcTurnaroundTimes tRd2Rd; ///< Offset 236 - User-defined overrides
> for Read-to-Read Turn Around Timings. <b>0 = AUTO</b>
> + MrcTurnaroundTimes tRd2Wr; ///< Offset 240 - User-defined overrides
> for Read-to-Write Turn Around Timings. <b>0 = AUTO</b>
> + MrcTurnaroundTimes tWr2Rd; ///< Offset 244 - User-defined overrides
> for Write-to-Read Turn Around Timings. <b>0 = AUTO</b>
> + MrcTurnaroundTimes tWr2Wr; ///< Offset 248 - User-defined overrides
> for Write-to-Write Turn Around Timings. <b>0 = AUTO</b>
> + UINT16 tRRD_L; ///< Offset 252 - User defined DDR4 Memory
> Timing tRRD_L value, valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 15=Maximum.
> + UINT16 tRRD_S; ///< Offset 254 - User defined DDR4 Memory
> Timing tRRD_S value, valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 15=Maximum.
> + UINT16 tWTR_L; ///< Offset 266 - User defined DDR4 Memory
> Timing tWTR_L value, valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 28=Maximum.
> + UINT16 tWTR_S; ///< Offset 268 - User defined DDR4 Memory
> Timing tWTR_S value, valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 28=Maximum.
> +
> + //
> + // End of synchronization to the SA MEMORY_CONFIGURATION structure.
> + //
> + MrcFrequency FreqMax; ///< The requested maximum
> valid frequency.
> + MrcBoardType BoardType; ///< Define the board type
> (CRBMB,CRBDT,User1,User2). the OEM can add more boards.
> + MrcCpuStepping CpuStepping; ///< Define the CPU stepping.
> + MrcCpuModel CpuModel; ///< Define the CPU model.
> + MrcCpuFamily CpuFamily; ///< CPU is Coffeelake
> + MrcGfxDataSize GraphicsStolenSize; ///< Graphics Data Stolen
> Memory size in MB
> + MrcGfxGttSize GraphicsGttSize; ///< GTT graphics stolen
> memory size in MB
> + MrcBaseTime BaseTime; ///< RTC base time.
> + MrcIteration Iteration; ///< Number of iterations thru the
> MRC core call table.
> + MrcMode MrcMode; ///< The control for full or
> MiniBIOS MRC.
> + MrcBootMode BootMode; ///< The requested memory
> controller boot mode.
> + BOOLEAN TxtFlag; ///< Trusted eXecution Technology
> flag.
> + BOOLEAN SetRxDqs32; ///< Set DQS Delay to 32 control.
> + BOOLEAN GfxIsVersatileAcceleration; ///< iGFX engines are in
> Versatile Acceleration
> + BOOLEAN DDR4MAP; ///< DDR4 PDA Mapping training
> control.
> + POINTER_STRUCT SaMemCfgAddress; ///< Starting address of
> the input parameters to CRC.
> + UINT32 SaMemCfgSize; ///< The size of the input
> parameters to CRC.
> + UINT32 PciEBaseAddress; ///< define the PciE base
> address.
> + UINT32 MchBarBaseAddress; ///< define the MCH bar base
> address.
> + UINT32 SmbusBaseAddress; ///< This field defines the
> smbus base address.
> + UINT32 GdxcBaseAddress; ///< This field defines the GDXC
> base address.
> + UINT32 HpetBaseAddress; ///< This field defines the hpet
> base address.
> + UINT32 MeStolenSize; ///< define the size that the ME
> need in MB.
> + UINT32 MmioSize; ///< define the MMIO size in MB.
> + UINT32 TsegSize; ///< TSEG size that require by the
> system in MB.
> + UINT32 IedSize; ///< IED size that require by the
> system in MB.
> + UINT32 DprSize; ///< DPR size required by system in
> MB.
> + UINT32 PrmrrSize; ///< Prmrr size required by the
> system in MB.
> + POINTER_STRUCT SerialBuffer; ///< Pointer to the start of the
> serial buffer.
> + UINT32 SerialBufferSize; ///< The size of the serial buffer, in
> bytes.
> + UINT32 DebugStream; ///< The debug port pointer.
> + INT32 DebugLevel; ///< Indicates the level of debug
> messaging.
> + UINT16 VccIomV; ///< VccIO logic voltage in mV.
> + MrcControllerIn Controller[MAX_CONTROLLERS]; ///< The following are
> controller level definitions.
> + UINT32 HeapBase; ///< Starting address of the heap
> space.
> + UINT32 HeapSize; ///< Size of the heap space, in
> bytes.
> + UINT32 MrcStackTop; ///< Top of the stack at the
> beginning of MRC, for stack usage calculations.
> + BOOLEAN BdatEnable; ///< Option to enable output of
> training results into BDAT.
> + UINT8 BdatTestType; ///< When BdatEnable is set to
> TRUE, this option selects the type of training results data which will be
> populated into BDAT: <b>0=RMT</b>, 1=RMT Per Bit, 2=Margin 2D.
> + BOOLEAN LpddrDramOdt; ///< TRUE if LPDDR DRAM ODT
> is used - depends on board design
> + BOOLEAN Ddr3DramOdt; ///< TRUE if DDR3 DRAM ODT
> is used - depends on board design
> + BOOLEAN Ddr4DramOdt; ///< TRUE if DDR4 DRAM ODT
> is used - depends on board design
> + BOOLEAN EnableVrefPwrDn; ///< Setting this limits VrefGen
> to be off only during CKEPowerDown
> + BOOLEAN TxEqDis; ///< Disable TX Equalization
> + BOOLEAN EnVttOdt; ///< Enable VTT Termination for
> Data ODT
> + UINT32 CpuidModel; ///< Unique CPU identifier.
> + UINT8 CpuidStepping; ///< Revision of the CPU.
> + UINT8 CpuidSku; ///< SKU of the CPU.
> + UINT32 SiPreMemPolicyPpi;
> + TrainingModeType PowerTrainingMode; ///< 0 - Power Training. 1 -
> Margin Training.
> + union {
> + MRC_FUNCTION *Func; ///< External to MRC function
> pointers
> + UINT64 Data;
> + } Call;
> + UINT16 RcompResistor[MAX_RCOMP]; ///< Reference RCOMP
> resistors on motherboard
> + UINT16 RcompTarget[MAX_RCOMP_TARGETS]; ///< RCOMP target
> values for DqOdt, DqDrv, CmdDrv, CtlDrv, ClkDrv
> + UINT32 CleanMemory:1; ///< TRUE to request a memory
> clean
> + UINT32 OcSupport:1; ///< TRUE if Overclocking is
> enabled in BIOS
> + UINT32 RsvdBits5:30;
> + /**
> + Sets the serial debug message level\n
> + 0x00 = Disabled\n
> + 0x01 = Errors only\n
> + 0x02 = Errors and Warnings\n
> + <b>0x03 = Errors, Warnings, and Info</b>\n
> + 0x04 = Errors, Warnings, Info, and Events\n
> + 0x05 = Displays Memory Init Execution Time Summary only\n
> + **/
> + UINT8 SerialDebugLevel;
> +} MrcInput;
> +
> +typedef struct {
> + UINT32 Size; ///< The size of this structure, in bytes. Must be the first
> entry in this structure.
> + MrcSaveHeader Header; ///< The header portion of the MRC saved data.
> + MrcSaveData Data; ///< The data portion of the MRC saved data.
> +} MrcSave;
> +
> +typedef struct {
> + // Global variables that will be copied to the HOB follow.
> + UINT8 MrcDataString[4]; ///< Beginning of global data marker, starts
> with "MRC". Must be the first entry in this structure.
> + UINT32 MrcDataSize; ///< The size of the MRC global data area, in
> bytes. Must be the second entry in this structure.
> + MrcSave Save; ///< System specific save variables.
> + MrcInput Inputs; ///< System specific input variables.
> + MrcOutput Outputs; ///< System specific output variables.
> +
> + // Global variables that will remain internal to the MRC library follow.
> + union {
> + void *Internal; ///< System specific output variables that remain internal
> to the library.
> + UINT64 Data;
> + } IntOutputs;
> +} MrcParameters;
> +
> +#pragma pack (pop)
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcRmtData.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcRmtData.h
> new file mode 100644
> index 0000000000..9dd9b096ba
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcRmtData.h
> @@ -0,0 +1,203 @@
> +/** @file
> + Copies the memory related timing and configuration information into the
> + Compatible BIOS data (BDAT) table.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MrcRmtData_h_
> +#define _MrcRmtData_h_
> +
> +#include "MrcTypes.h"
> +
> +#define VDD_1_350 1350 ///< VDD in millivolts
> +#define VDD_1_500 1500 ///< VDD in millivolts
> +#define PI_STEP_BASE 2048 ///< Magic number from
> spec
> +#define PI_STEP_INTERVAL 128 ///< tCK is split into this
> amount of intervals
> +#define PI_STEP ((PI_STEP_BASE) / (PI_STEP_INTERVAL))
> +#define VREF_STEP_BASE 100 ///< Magic number from
> spec
> +#define TX_VREF_STEP 7800 ///< TX Vref step in
> microvolts
> +#define TX_VREF(VDD) (((TX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD))
> ///< VDD passed in is in millivolts
> +#define RX_VREF_STEP 8000 ///< TX Vref step in
> microvolts
> +#define RX_VREF(VDD) (((RX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD))
> ///< VDD passed in is in millivolts
> +#define CA_VREF_STEP 8000 ///< TX Vref step in
> microvolts
> +#define CA_VREF(VDD) (((CA_VREF_STEP) * (VREF_STEP_BASE)) / (VDD))
> ///< VDD passed in is in millivolts
> +
> +#define MAX_SPD_RMT 512 ///< The maximum
> amount of data, in bytes, in an SPD structure.
> +#define RMT_PRIMARY_VERSION 4 ///< The BDAT
> structure that is currently supported.
> +#define RMT_SECONDARY_VERSION 0 ///< The BDAT
> structure that is currently supported.
> +#define MAX_MODE_REGISTER 7 ///< Number of mode
> registers
> +#define MAX_DRAM_DEVICE 9 ///< Maximum number
> of memory devices
> +#define MAX_2D_EYE_TYPE 2 ///< Maximum number
> of supported Margin 2D Eye Types
> +#define MAX_2D_EYE_OFFSETS 7 ///< Number of 2D Eye
> Offsets
> +
> +//
> +// Warning: Bdat4.h has its own copy of this #define
> +// make sure to change it in both places
> +//
> +#define MAX_SCHEMA_LIST_LENGTH (10)
> +
> +
> +#ifdef BDAT_SUPPORT
> +/*
> + BSSA result Memory Schema GUID
> + {8F4E928-0F5F-46D4-8410-479FDA279DB6}
> +*/
> +extern EFI_GUID gSsaBiosResultsGuid;
> +/*
> + RMT Results Metadata GUID
> + {02CB1552-D659-4232-B51F-CAB1E11FCA87}
> +*/
> +extern EFI_GUID gRmtResultMetadataGuid;
> +/*
> + RMT Results Columns GUID
> + {0E60A1EB-331F-42A1-9DE7-453E84761154}
> +*/
> +extern EFI_GUID gRmtResultColumnsGuid;
> +
> +/*
> +Margin2D Results Metadata GUID
> +{48265582-8E49-4AC7-AA06-E1B9A74C9716}
> +*/
> +extern EFI_GUID gMargin2DResultMetadataGuid;
> +/*
> +Margin2D Results Columns GUID
> +{91A449EC-8A4A-4736-AD71-A3F6F6D752D9}
> +*/
> +extern EFI_GUID gMargin2DResultColumnsGuid;
> +
> +#endif
> +/*
> + GUID for Schema List HOB
> + This is private GUID used by MemoryInit internally.
> + {3047C2AC-5E8E-4C55-A1CB-EAAD0A88861B}
> +*/
> +extern EFI_GUID gMrcSchemaListHobGuid;
> +
> +#pragma pack(push, 1)
> +
> +
> +///
> +/// SSA results buffer header.
> +///
> +typedef struct {
> + UINT32 Revision;
> + BOOLEAN TransferMode;
> + struct {
> + UINT32 Reserved;
> + UINT32 MetadataSize;
> + EFI_GUID MetadataType;
> + } MdBlock;
> + struct {
> + UINT32 Reserved;
> + EFI_GUID ResultType;
> + UINT32 ResultElementSize;
> + INT32 ResultCapacity;
> + INT32 ResultElementCount;
> + } RsBlock;
> +} RESULTS_DATA_HDR;
> +
> +// start auto-generated by the BSSA CCK sourced from the result xml files.
> +typedef enum {
> + DisableScrambler = 0,
> + EnableScrambler = 1,
> + DontTouchScrambler = 2,
> + SCRAMBLER_OVERRIDE_MODE_DELIM = MRC_INT32_MAX
> +} SCRAMBLER_OVERRIDE_MODE;
> +
> +typedef struct _RMT_RESULT_METADATA {
> + BOOLEAN EnableCtlAllMargin;
> + UINT16 SinglesBurstLength;
> + UINT32 SinglesLoopCount;
> + UINT16 TurnaroundsBurstLength;
> + UINT32 TurnaroundsLoopCount;
> + SCRAMBLER_OVERRIDE_MODE ScramblerOverrideMode;
> + UINT8 PiStepUnit[2];
> + UINT16 RxVrefStepUnit[2];
> + UINT16 TxVrefStepUnit[2][2];
> + UINT16 CmdVrefStepUnit[2][2];
> + UINT8 MajorVer;
> + UINT8 MinorVer;
> + UINT8 RevVer;
> + UINT32 BuildVer;
> + UINT16 ResultEleCount;
> +} RMT_RESULT_METADATA;
> +
> +
> +typedef struct _RMT_RESULT_ROW_HEADER {
> + UINT32 ResultType : 5;
> + UINT32 Socket : 3;
> + UINT32 Controller : 2;
> + UINT32 Channel : 3;
> + UINT32 DimmA : 1;
> + UINT32 RankA : 3;
> + UINT32 DimmB : 1;
> + UINT32 RankB : 3;
> + UINT32 Lane : 8;
> + UINT32 IoLevel : 1;
> + UINT32 Reserved : 2;
> +} RMT_RESULT_ROW_HEADER;
> +
> +typedef struct _RMT_RESULT_COLUMNS {
> + RMT_RESULT_ROW_HEADER Header;
> + UINT8 Margin[4][2];
> +} RMT_RESULT_COLUMNS;
> +
> +// end of auto-generated by the BSSA CCK sourced from the result xml files.
> +
> +typedef struct _BASE_RMT_RESULT {
> + RESULTS_DATA_HDR ResultsHeader;
> + RMT_RESULT_METADATA Metadata;
> + RMT_RESULT_COLUMNS Rows[1];
> +} BASE_RMT_RESULT;
> +
> +
> +typedef struct {
> + UINT32 Data1;
> + UINT16 Data2;
> + UINT16 Data3;
> + UINT8 Data4[8];
> +} BDAT_EFI_GUID;
> +
> +typedef struct {
> + UINT16 HobType;
> + UINT16 HobLength;
> + UINT32 Reserved;
> +} BDAT_HOB_GENERIC_HEADER;
> +
> +typedef struct {
> + BDAT_HOB_GENERIC_HEADER Header;
> + BDAT_EFI_GUID Name;
> + ///
> + /// Guid specific data goes here
> + ///
> +} BDAT_HOB_GUID_TYPE;
> +
> +typedef struct {
> + BDAT_EFI_GUID SchemaId; ///< The GUID
> uniquely identifies the format of the data contained within the structure.
> + UINT32 DataSize; ///< The total size of the
> memory block, including both the header as well as the schema specific data.
> + UINT16 Crc16; ///< Crc16 is computed in
> the same manner as the field in the BDAT_HEADER_STRUCTURE.
> +} MRC_BDAT_SCHEMA_HEADER_STRUCTURE;
> +
> +typedef struct {
> + MRC_BDAT_SCHEMA_HEADER_STRUCTURE SchemaHeader;
> ///< The schema header.
> + BASE_RMT_RESULT RMT_RESULTS_WITH_META_COLUMNS;
> +} BDAT_MEMORY_DATA_STRUCTURE;
> +
> +typedef struct {
> + BDAT_HOB_GUID_TYPE HobGuidType;
> + BDAT_MEMORY_DATA_STRUCTURE MemorySchema;
> +} BDAT_MEMORY_DATA_HOB;
> +
> +#pragma pack (pop)
> +
> +typedef struct {
> + BDAT_HOB_GUID_TYPE HobGuidType;
> + UINT16 SchemaHobCount;
> + UINT16 Reserved;
> + BDAT_EFI_GUID
> SchemaHobGuids[MAX_SCHEMA_LIST_LENGTH];
> +} MRC_BDAT_SCHEMA_LIST_HOB;
> +
> +#endif //_MrcRmtData_h_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcSpdData.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcSpdData.h
> new file mode 100644
> index 0000000000..45de5084c0
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcSpdData.h
> @@ -0,0 +1,1167 @@
> +/** @file
> + SPD data format header file.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MrcSpdData_h_
> +#define _MrcSpdData_h_
> +#pragma pack (push, 1)
> +
> +#include "MrcTypes.h"
> +
> +#define MAX_XMP_PROFILES (2)
> +#define SPD3_MANUF_SIZE (SPD3_MANUF_END - SPD3_MANUF_START + 1)
> ///< The size of the SPD manufacturing data.
> +#define SPD4_MANUF_SIZE (SPD4_MANUF_END - SPD4_MANUF_START + 1)
> ///< The size of the SPD manufacturing data.
> +#define SPDLP_MANUF_SIZE (SPDLP_MANUF_END - SPDLP_MANUF_START +
> 1) ///< The size of the SPD manufacturing data
> +
> +typedef union {
> + struct {
> + UINT8 BytesUsed : 4; ///< Bits 3:0
> + UINT8 BytesTotal : 3; ///< Bits 6:4
> + UINT8 CrcCoverage : 1; ///< Bits 7:7
> + } Bits;
> + UINT8 Data;
> +} SPD_DEVICE_DESCRIPTION_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 Minor : 4; ///< Bits 3:0
> + UINT8 Major : 4; ///< Bits 7:4
> + } Bits;
> + UINT8 Data;
> +} SPD_REVISION_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 Type : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_DRAM_DEVICE_TYPE_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 ModuleType : 4; ///< Bits 3:0
> + UINT8 : 4; ///< Bits 7:4
> + } Bits;
> + UINT8 Data;
> +} SPD_MODULE_TYPE_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 Density : 4; ///< Bits 3:0
> + UINT8 BankAddress : 3; ///< Bits 6:4
> + UINT8 : 1; ///< Bits 7:7
> + } Bits;
> + UINT8 Data;
> +} SPD_SDRAM_DENSITY_BANKS_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 ColumnAddress : 3; ///< Bits 2:0
> + UINT8 RowAddress : 3; ///< Bits 5:3
> + UINT8 : 2; ///< Bits 7:6
> + } Bits;
> + UINT8 Data;
> +} SPD_SDRAM_ADDRESSING_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 OperationAt1_50 : 1; ///< Bits 0:0
> + UINT8 OperationAt1_35 : 1; ///< Bits 1:1
> + UINT8 OperationAt1_25 : 1; ///< Bits 2:2
> + UINT8 : 5; ///< Bits 7:3
> + } Bits;
> + UINT8 Data;
> +} SPD_MODULE_NOMINAL_VOLTAGE_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 SdramDeviceWidth : 3; ///< Bits 2:0
> + UINT8 RankCount : 3; ///< Bits 5:3
> + UINT8 : 2; ///< Bits 7:6
> + } Bits;
> + UINT8 Data;
> +} SPD_MODULE_ORGANIZATION_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 PrimaryBusWidth : 3; ///< Bits 2:0
> + UINT8 BusWidthExtension : 2; ///< Bits 4:3
> + UINT8 : 3; ///< Bits 7:5
> + } Bits;
> + UINT8 Data;
> +} SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 Divisor : 4; ///< Bits 3:0
> + UINT8 Dividend : 4; ///< Bits 7:4
> + } Bits;
> + UINT8 Data;
> +} SPD_FINE_TIMEBASE_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 Dividend : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 Divisor : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT;
> +
> +typedef struct {
> + SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT Dividend; ///< Medium
> Timebase (MTB) Dividend
> + SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT Divisor; ///< Medium
> Timebase (MTB) Divisor
> +} SPD_MEDIUM_TIMEBASE;
> +
> +typedef union {
> + struct {
> + UINT8 tCKmin : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TCK_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT16 CL4 : 1; ///< Bits 0:0
> + UINT16 CL5 : 1; ///< Bits 1:1
> + UINT16 CL6 : 1; ///< Bits 2:2
> + UINT16 CL7 : 1; ///< Bits 3:3
> + UINT16 CL8 : 1; ///< Bits 4:4
> + UINT16 CL9 : 1; ///< Bits 5:5
> + UINT16 CL10 : 1; ///< Bits 6:6
> + UINT16 CL11 : 1; ///< Bits 7:7
> + UINT16 CL12 : 1; ///< Bits 8:8
> + UINT16 CL13 : 1; ///< Bits 9:9
> + UINT16 CL14 : 1; ///< Bits 10:10
> + UINT16 CL15 : 1; ///< Bits 11:11
> + UINT16 CL16 : 1; ///< Bits 12:12
> + UINT16 CL17 : 1; ///< Bits 13:13
> + UINT16 CL18 : 1; ///< Bits 14:14
> + UINT16 : 1; ///< Bits 15:15
> + } Bits;
> + UINT16 Data;
> + UINT8 Data8[2];
> +} SPD_CAS_LATENCIES_SUPPORTED_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tAAmin : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TAA_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tWRmin : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TWR_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tRCDmin : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TRCD_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tRRDmin : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TRRD_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tRPmin : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TRP_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tRPab : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TRP_AB_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + INT8 tRPabFine : 8; ///< Bits 7:0
> + } Bits;
> + INT8 Data;
> +} SPD_TRP_AB_FTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tRPpb : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TRP_PB_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + INT8 tRPpbFine : 8; ///< Bits 7:0
> + } Bits;
> + INT8 Data;
> +} SPD_TRP_PB_FTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT16 tRFCab : 16; ///< Bits 15:0
> + } Bits;
> + UINT16 Data;
> + UINT8 Data8[2];
> +} SPD_TRFC_AB_MTB_STRUCT;
> +
> +typedef union {
> +struct {
> + UINT16 tRFCpb : 16; ///< Bits 15:0
> + } Bits;
> + UINT16 Data;
> + UINT8 Data8[2];
> +} SPD_TRFC_PB_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tRASminUpper : 4; ///< Bits 3:0
> + UINT8 tRCminUpper : 4; ///< Bits 7:4
> + } Bits;
> + UINT8 Data;
> +} SPD_TRAS_TRC_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tRASmin : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TRAS_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tRCmin : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TRC_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT16 tRFCmin : 16; ///< Bits 15:0
> + } Bits;
> + UINT16 Data;
> + UINT8 Data8[2];
> +} SPD_TRFC_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tWTRmin : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TWTR_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tRTPmin : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TRTP_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tFAWminUpper : 4; ///< Bits 3:0
> + UINT8 : 4; ///< Bits 7:4
> + } Bits;
> + UINT8 Data;
> +} SPD_TFAW_MIN_MTB_UPPER_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tFAWmin : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TFAW_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tCWLmin : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_TCWL_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 NMode : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_SYSTEM_COMMAND_RATE_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT16 tREFImin : 16; ///< Bits 15:0
> + } Bits;
> + UINT16 Data;
> + UINT8 Data8[2];
> +} SPD_TREFI_MIN_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 RZQ6 : 1; ///< Bits 0:0
> + UINT8 RZQ7 : 1; ///< Bits 1:1
> + UINT8 : 5; ///< Bits 6:2
> + UINT8 DllOff : 1; ///< Bits 7:7
> + } Bits;
> + UINT8 Data;
> +} SPD_SDRAM_OPTIONAL_FEATURES_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 ExtendedTemperatureRange : 1; ///< Bits 0:0
> + UINT8 ExtendedTemperatureRefreshRate : 1; ///< Bits 1:1
> + UINT8 AutoSelfRefresh : 1; ///< Bits 2:2
> + UINT8 OnDieThermalSensor : 1; ///< Bits 3:3
> + UINT8 : 3; ///< Bits 6:4
> + UINT8 PartialArraySelfRefresh : 1; ///< Bits 7:7
> + } Bits;
> + UINT8 Data;
> +} SPD_SDRAM_THERMAL_REFRESH_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 ThermalSensorAccuracy : 7; ///< Bits 6:0
> + UINT8 ThermalSensorPresence : 1; ///< Bits 7:7
> + } Bits;
> + UINT8 Data;
> +} SPD_MODULE_THERMAL_SENSOR_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 NonStandardDeviceDescription : 7; ///< Bits 6:0
> + UINT8 SdramDeviceType : 1; ///< Bits 7:7
> + } Bits;
> + UINT8 Data;
> +} SPD_SDRAM_DEVICE_TYPE_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_AUTO_SELF_REFRESH_PERF_STRUCT;
> +
> +typedef union {
> + struct {
> + INT8 tCKminFine : 8; ///< Bits 7:0
> + } Bits;
> + INT8 Data;
> +} SPD_TCK_MIN_FTB_STRUCT;
> +
> +typedef union {
> + struct {
> + INT8 tAAminFine : 8; ///< Bits 7:0
> + } Bits;
> + INT8 Data;
> +} SPD_TAA_MIN_FTB_STRUCT;
> +
> +typedef union {
> + struct {
> + INT8 tRCDminFine : 8; ///< Bits 7:0
> + } Bits;
> + INT8 Data;
> +} SPD_TRCD_MIN_FTB_STRUCT;
> +
> +typedef union {
> + struct {
> + INT8 tRPminFine : 8; ///< Bits 7:0
> + } Bits;
> + INT8 Data;
> +} SPD_TRP_MIN_FTB_STRUCT;
> +
> +typedef union {
> + struct {
> + INT8 tRCminFine : 8; ///< Bits 7:0
> + } Bits;
> + INT8 Data;
> +} SPD_TRC_MIN_FTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tMACencoding : 4; ///< Bits 3:0
> + UINT8 tMAWencoding : 2; ///< Bits 5:4
> + UINT8 Reserved : 2; ///< Bits 7:6
> + } Bits;
> + UINT8 Data;
> +} SPD_PTRR_SUPPORT_STRUCT;
> +
> +typedef union {
> + struct {
> + INT8 tRRDminFine : 8; ///< Bits 7:0
> + } Bits;
> + INT8 Data;
> +} SPD_TRRD_MIN_FTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 Height : 5; ///< Bits 4:0
> + UINT8 RawCardExtension : 3; ///< Bits 7:5
> + } Bits;
> + UINT8 Data;
> +} SPD_UNBUF_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> + struct {
> + UINT8 FrontThickness : 4; ///< Bits 3:0
> + UINT8 BackThickness : 4; ///< Bits 7:4
> + } Bits;
> + UINT8 Data;
> +} SPD_UNBUF_MODULE_NOMINAL_THICKNESS;
> +
> +typedef union {
> + struct {
> + UINT8 Card : 5; ///< Bits 4:0
> + UINT8 Revision : 2; ///< Bits 6:5
> + UINT8 Extension : 1; ///< Bits 7:7
> + } Bits;
> + UINT8 Data;
> +} SPD_UNBUF_REFERENCE_RAW_CARD;
> +
> +typedef union {
> + struct {
> + UINT8 MappingRank1 : 1; ///< Bits 0:0
> + UINT8 : 7; ///< Bits 7:1
> + } Bits;
> + UINT8 Data;
> +} SPD_UNBUF_ADDRESS_MAPPING;
> +
> +typedef union {
> + struct {
> + UINT8 Height : 5; ///< Bits 4:0
> + UINT8 : 3; ///< Bits 7:5
> + } Bits;
> + UINT8 Data;
> +} SPD_RDIMM_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> + struct {
> + UINT8 FrontThickness : 4; ///< Bits 3:0
> + UINT8 BackThickness : 4; ///< Bits 7:4
> + } Bits;
> + UINT8 Data;
> +} SPD_RDIMM_MODULE_NOMINAL_THICKNESS;
> +
> +typedef union {
> + struct {
> + UINT8 Card : 5; ///< Bits 4:0
> + UINT8 Revision : 2; ///< Bits 6:5
> + UINT8 Extension : 1; ///< Bits 7:7
> + } Bits;
> + UINT8 Data;
> +} SPD_RDIMM_REFERENCE_RAW_CARD;
> +
> +typedef union {
> + struct {
> + UINT8 RegisterCount : 2; ///< Bits 1:0
> + UINT8 DramRowCount : 2; ///< Bits 3:2
> + UINT8 : 4; ///< Bits 7:4
> + } Bits;
> + UINT8 Data;
> +} SPD_RDIMM_MODULE_ATTRIBUTES;
> +
> +typedef union {
> + struct {
> + UINT16 ContinuationCount : 7; ///< Bits 6:0
> + UINT16 ContinuationParity : 1; ///< Bits 7:7
> + UINT16 LastNonZeroByte : 8; ///< Bits 15:8
> + } Bits;
> + UINT16 Data;
> + UINT8 Data8[2];
> +} SPD_MANUFACTURER_ID_CODE;
> +
> +typedef struct {
> + UINT8 Year; ///< Year represented in BCD (00h =
> 2000)
> + UINT8 Week; ///< Year represented in BCD (47h =
> week 47)
> +} SPD_MANUFACTURING_DATE;
> +
> +typedef union {
> + UINT32 Data;
> + UINT16 SerialNumber16[2];
> + UINT8 SerialNumber8[4];
> +} SPD_MANUFACTURER_SERIAL_NUMBER;
> +
> +typedef struct {
> + UINT8 Location; ///< Module Manufacturing Location
> +} SPD_MANUFACTURING_LOCATION;
> +
> +typedef struct {
> + SPD_MANUFACTURER_ID_CODE IdCode; ///< Module
> Manufacturer ID Code
> + SPD_MANUFACTURING_LOCATION Location; ///<
> Module Manufacturing Location
> + SPD_MANUFACTURING_DATE Date; ///< Module
> Manufacturing Year, in BCD (range: 2000-2255)
> + SPD_MANUFACTURER_SERIAL_NUMBER SerialNumber; ///<
> Module Serial Number
> +} SPD_UNIQUE_MODULE_ID;
> +
> +typedef union {
> + UINT16 Crc[1];
> + UINT8 Data8[2];
> +} SPD_CYCLIC_REDUNDANCY_CODE;
> +
> +typedef union {
> + struct {
> + UINT8 ProfileEnable1 : 1; ///< Bits 0:0
> + UINT8 ProfileEnable2 : 1; ///< Bits 1:1
> + UINT8 ProfileConfig1 : 2; ///< Bits 3:2
> + UINT8 ProfileConfig2 : 2; ///< Bits 5:4
> + UINT8 : 2; ///< Bits 7:6
> + } Bits;
> + UINT8 Data;
> +} SPD_XMP_ORG_CONFIG;
> +
> +typedef struct {
> + UINT16 XmpId; ///< 176-177 XMP
> Identification String
> + SPD_XMP_ORG_CONFIG XmpOrgConf; ///< 178 XMP
> Organization & Configuration
> + SPD_REVISION_STRUCT XmpRevision; ///< 179 XMP
> Revision
> + SPD_MEDIUM_TIMEBASE
> MediumTimeBase[MAX_XMP_PROFILES]; ///< 180-183 Medium Timebase
> (MTB)
> + SPD_FINE_TIMEBASE_STRUCT FineTimeBase; ///< 184
> Fine Timebase (FTB) Dividend / Divisor
> +} SPD_EXTREME_MEMORY_PROFILE_HEADER;
> +
> +typedef union {
> + struct {
> + UINT8 Decimal : 5;
> + UINT8 Integer : 2;
> + UINT8 : 1;
> + } Bits;
> + UINT8 Data;
> +} SPD_VDD_VOLTAGE_LEVEL_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 Decimal : 7;
> + UINT8 Integer : 1;
> + } Bits;
> + UINT8 Data;
> +} SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0;
> +
> +typedef union {
> + struct {
> + UINT8 Fine : 2; ///< Bits 1:0
> + UINT8 Medium : 2; ///< Bits 3:2
> + UINT8 : 4; ///< Bits 7:4
> + } Bits;
> + UINT8 Data;
> +} SPD4_TIMEBASE_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT32 CL7 : 1; ///< Bits 0:0
> + UINT32 CL8 : 1; ///< Bits 1:1
> + UINT32 CL9 : 1; ///< Bits 2:2
> + UINT32 CL10 : 1; ///< Bits 3:3
> + UINT32 CL11 : 1; ///< Bits 4:4
> + UINT32 CL12 : 1; ///< Bits 5:5
> + UINT32 CL13 : 1; ///< Bits 6:6
> + UINT32 CL14 : 1; ///< Bits 7:7
> + UINT32 CL15 : 1; ///< Bits 8:8
> + UINT32 CL16 : 1; ///< Bits 9:9
> + UINT32 CL17 : 1; ///< Bits 10:10
> + UINT32 CL18 : 1; ///< Bits 11:11
> + UINT32 CL19 : 1; ///< Bits 12:12
> + UINT32 CL20 : 1; ///< Bits 13:13
> + UINT32 CL21 : 1; ///< Bits 14:14
> + UINT32 CL22 : 1; ///< Bits 15:15
> + UINT32 CL23 : 1; ///< Bits 16:16
> + UINT32 CL24 : 1; ///< Bits 17:17
> + UINT32 : 14; ///< Bits 31:18
> + } Bits;
> + UINT32 Data;
> + UINT16 Data16[2];
> + UINT8 Data8[4];
> +} SPD4_CAS_LATENCIES_SUPPORTED_STRUCT;
> +
> +typedef struct {
> + SPD_VDD_VOLTAGE_LEVEL_STRUCT Vdd; ///< 185, 220
> XMP Module VDD Voltage Level
> + SPD_TCK_MIN_MTB_STRUCT tCKmin; ///< 186, 221
> XMP SDRAM Minimum Cycle Time (tCKmin)
> + SPD_TAA_MIN_MTB_STRUCT tAAmin; ///< 187, 222
> XMP Minimum CAS Latency Time (tAAmin)
> + SPD_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies; ///<
> 188-189, 223-224 XMP CAS Latencies Supported, Least Significant Byte
> + SPD_TCWL_MIN_MTB_STRUCT tCWLmin; ///< 190,
> 225 XMP Minimum CAS Write Latency Time (tCWLmin)
> + SPD_TRP_MIN_MTB_STRUCT tRPmin; ///< 191, 226
> XMP Minimum Row Precharge Delay Time (tRPmin)
> + SPD_TRCD_MIN_MTB_STRUCT tRCDmin; ///< 192,
> 227 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
> + SPD_TWR_MIN_MTB_STRUCT tWRmin; ///< 193,
> 228 XMP Minimum Write Recovery Time (tWRmin)
> + SPD_TRAS_TRC_MIN_MTB_STRUCT tRASMintRCMinUpper; ///<
> 194, 229 XMP Upper Nibbles for tRAS and tRC
> + SPD_TRAS_MIN_MTB_STRUCT tRASmin; ///< 195, 230
> XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
> + SPD_TRC_MIN_MTB_STRUCT tRCmin; ///< 196, 231
> XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant
> Byte
> + SPD_TREFI_MIN_MTB_STRUCT tREFImin; ///< 197-198,
> 232-233 XMP Maximum tREFI Time (Average Periodic Refresh Interval), Least
> Significant Byte
> + SPD_TRFC_MIN_MTB_STRUCT tRFCmin; ///< 199-200,
> 234-235 XMP Minimum Refresh Recovery Delay Time (tRFCmin), Least
> Significant Byte
> + SPD_TRTP_MIN_MTB_STRUCT tRTPmin; ///< 201, 236
> XMP Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
> + SPD_TRRD_MIN_MTB_STRUCT tRRDmin; ///< 202,
> 237 XMP Minimum Row Active to Row Active Delay Time (tRRDmin)
> + SPD_TFAW_MIN_MTB_UPPER_STRUCT tFAWMinUpper; ///<
> 203, 238 XMP Upper Nibble for tFAW
> + SPD_TFAW_MIN_MTB_STRUCT tFAWmin; ///< 204,
> 239 XMP Minimum Four Activate Window Delay Time (tFAWmin)
> + SPD_TWTR_MIN_MTB_STRUCT tWTRmin; ///< 205,
> 240 XMP Minimum Internal Write to Read Command Delay Time (tWTRmin)
> + UINT8 Reserved1[207 - 206 + 1]; ///< 206-207, 241-242
> XMP Reserved
> + SPD_SYSTEM_COMMAND_RATE_STRUCT SystemCmdRate; ///<
> 208, 243 XMP System ADD/CMD Rate (1N or 2N mode)
> + SPD_AUTO_SELF_REFRESH_PERF_STRUCT AsrPerf; ///< 209,
> 244 XMP SDRAM Auto Self Refresh Performance (Sub 1x Refresh and IDD6
> impact)
> + UINT8 VoltageLevel; ///< 210, 245 XMP
> Memory Controller Voltage Level
> + SPD_TCK_MIN_FTB_STRUCT tCKminFine; ///< 211, 246
> XMP Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
> + SPD_TAA_MIN_FTB_STRUCT tAAminFine; ///< 212, 247
> XMP Fine Offset for Minimum CAS Latency Time (tAAmin)
> + SPD_TRP_MIN_FTB_STRUCT tRPminFine; ///< 213, 248
> XMP Minimum Row Precharge Delay Time (tRPmin)
> + SPD_TRCD_MIN_FTB_STRUCT tRCDminFine; ///< 214,
> 249 XMP Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> + SPD_TRC_MIN_FTB_STRUCT tRCminFine; ///< 215, 250
> XMP Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
> + UINT8 Reserved2[218 - 216 + 1]; ///< 216-218, 251-253
> XMP Reserved
> + UINT8 VendorPersonality; ///< 219, 254 XMP
> Vendor Personality
> +} SPD_EXTREME_MEMORY_PROFILE_DATA;
> +
> +typedef struct {
> + SPD_EXTREME_MEMORY_PROFILE_HEADER Header; ///<
> 176-184 XMP header
> + SPD_EXTREME_MEMORY_PROFILE_DATA Data[MAX_XMP_PROFILES];
> ///< 185-254 XMP profiles
> +} SPD_EXTREME_MEMORY_PROFILE;
> +
> +typedef struct {
> + UINT16 XmpId; ///< 384-385 XMP
> Identification String
> + SPD_XMP_ORG_CONFIG XmpOrgConf; ///< 386
> XMP Organization & Configuration
> + SPD_REVISION_STRUCT XmpRevision; ///< 387
> XMP Revision
> + SPD4_TIMEBASE_STRUCT TimeBase[MAX_XMP_PROFILES];
> ///< 388-389 Medium and Fine Timebase
> + UINT8 Reserved[392 - 390 + 1]; ///< 390-392
> Reserved
> +} SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0;
> +
> +typedef struct {
> + SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0 Vdd; ///< 393,
> 440 XMP Module VDD Voltage Level
> + UINT8 Reserved1[395 - 394 + 1]; ///< 394-395, 441-442
> XMP Reserved
> + SPD_TCK_MIN_MTB_STRUCT tCKAVGmin; ///< 396,
> 443 XMP SDRAM Minimum Cycle Time (tCKAVGmin)
> + SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies; ///<
> 397-400, 444-447 XMP CAS Latencies Supported
> + SPD_TAA_MIN_MTB_STRUCT tAAmin; ///< 401, 448
> XMP Minimum CAS Latency Time (tAAmin)
> + SPD_TRCD_MIN_MTB_STRUCT tRCDmin; ///< 402,
> 449 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
> + SPD_TRP_MIN_MTB_STRUCT tRPmin; ///< 403, 450
> XMP Minimum Row Precharge Delay Time (tRPmin)
> + SPD_TRAS_TRC_MIN_MTB_STRUCT tRASMintRCMinUpper; ///<
> 404, 451 XMP Upper Nibbles for tRAS and tRC
> + SPD_TRAS_MIN_MTB_STRUCT tRASmin; ///< 405, 452
> XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
> + SPD_TRC_MIN_MTB_STRUCT tRCmin; ///< 406, 453
> XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant
> Byte
> + SPD_TRFC_MIN_MTB_STRUCT tRFC1min; ///< 407-408,
> 454-455 XMP Minimum Refresh Recovery Delay Time (tRFC1min)
> + SPD_TRFC_MIN_MTB_STRUCT tRFC2min; ///< 409-410,
> 456-457 XMP Minimum Refresh Recovery Delay Time (tRFC2min)
> + SPD_TRFC_MIN_MTB_STRUCT tRFC4min; ///< 411-412,
> 458-459 XMP Minimum Refresh Recovery Delay Time (tRFC4min)
> + SPD_TFAW_MIN_MTB_UPPER_STRUCT tFAWMinUpper; ///<
> 413, 460 Upper Nibble for tFAW
> + SPD_TFAW_MIN_MTB_STRUCT tFAWmin; ///< 414,
> 461 Minimum Four Activate Window Delay Time (tFAWmin)
> + SPD_TRRD_MIN_MTB_STRUCT tRRD_Smin; ///< 415,
> 462 Minimum Activate to Activate Delay Time (tRRD_Smin), different bank
> group
> + SPD_TRRD_MIN_MTB_STRUCT tRRD_Lmin; ///< 416,
> 463 Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
> + UINT8 Reserved2[424 - 417 + 1]; ///< 417-424, 464-471
> XMP Reserved
> + SPD_TRRD_MIN_FTB_STRUCT tRRD_LminFine; ///< 425,
> 472 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin),
> different bank group
> + SPD_TRRD_MIN_FTB_STRUCT tRRD_SminFine; ///< 426,
> 473 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin),
> same bank group
> + SPD_TRC_MIN_FTB_STRUCT tRCminFine; ///< 427, 474
> Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
> + SPD_TRP_MIN_FTB_STRUCT tRPminFine; ///< 428, 475
> Minimum Row Precharge Delay Time (tRPmin)
> + SPD_TRCD_MIN_FTB_STRUCT tRCDminFine; ///< 429,
> 476 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> + SPD_TAA_MIN_FTB_STRUCT tAAminFine; ///< 430, 477
> Fine Offset for Minimum CAS Latency Time (tAAmin)
> + SPD_TCK_MIN_FTB_STRUCT tCKAVGminFine; ///< 431,
> 478 Fine Offset for SDRAM Maximum Cycle Time (tCKAVGmin)
> + UINT8 Reserved3[439 - 432 + 1]; ///< 432-439, 479-486
> XMP Reserved
> +} SPD_EXTREME_MEMORY_PROFILE_DATA_2_0;
> +
> +typedef struct {
> + SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0 Header;
> ///< 384-392 XMP header
> + SPD_EXTREME_MEMORY_PROFILE_DATA_2_0
> Data[MAX_XMP_PROFILES]; ///< 393-486 XMP profiles
> +} SPD_EXTREME_MEMORY_PROFILE_2_0;
> +
> +typedef struct {
> + SPD_DEVICE_DESCRIPTION_STRUCT Description; ///< 0
> Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
> + SPD_REVISION_STRUCT Revision; ///< 1 SPD
> Revision
> + SPD_DRAM_DEVICE_TYPE_STRUCT DramDeviceType; ///< 2
> DRAM Device Type
> + SPD_MODULE_TYPE_STRUCT ModuleType; ///< 3
> Module Type
> + SPD_SDRAM_DENSITY_BANKS_STRUCT SdramDensityAndBanks;
> ///< 4 SDRAM Density and Banks
> + SPD_SDRAM_ADDRESSING_STRUCT SdramAddressing; ///< 5
> SDRAM Addressing
> + SPD_MODULE_NOMINAL_VOLTAGE_STRUCT ModuleNominalVoltage;
> ///< 6 Module Nominal Voltage, VDD
> + SPD_MODULE_ORGANIZATION_STRUCT ModuleOrganization; ///<
> 7 Module Organization
> + SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT ModuleMemoryBusWidth;
> ///< 8 Module Memory Bus Width
> + SPD_FINE_TIMEBASE_STRUCT FineTimebase; ///< 9 Fine
> Timebase (FTB) Dividend / Divisor
> + SPD_MEDIUM_TIMEBASE MediumTimebase; ///< 10-11
> Medium Timebase (MTB) Dividend
> + SPD_TCK_MIN_MTB_STRUCT tCKmin; ///< 12
> SDRAM Minimum Cycle Time (tCKmin)
> + UINT8 Reserved1; ///< 13 Reserved
> + SPD_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies; ///<
> 14-15 CAS Latencies Supported
> + SPD_TAA_MIN_MTB_STRUCT tAAmin; ///< 16
> Minimum CAS Latency Time (tAAmin)
> + SPD_TWR_MIN_MTB_STRUCT tWRmin; ///< 17
> Minimum Write Recovery Time (tWRmin)
> + SPD_TRCD_MIN_MTB_STRUCT tRCDmin; ///< 18
> Minimum RAS# to CAS# Delay Time (tRCDmin)
> + SPD_TRRD_MIN_MTB_STRUCT tRRDmin; ///< 19
> Minimum Row Active to Row Active Delay Time (tRRDmin)
> + SPD_TRP_MIN_MTB_STRUCT tRPmin; ///< 20
> Minimum Row Precharge Delay Time (tRPmin)
> + SPD_TRAS_TRC_MIN_MTB_STRUCT tRASMintRCMinUpper; ///<
> 21 Upper Nibbles for tRAS and tRC
> + SPD_TRAS_MIN_MTB_STRUCT tRASmin; ///< 22
> Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
> + SPD_TRC_MIN_MTB_STRUCT tRCmin; ///< 23
> Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
> + SPD_TRFC_MIN_MTB_STRUCT tRFCmin; ///< 24-25
> Minimum Refresh Recovery Delay Time (tRFCmin)
> + SPD_TWTR_MIN_MTB_STRUCT tWTRmin; ///< 26
> Minimum Internal Write to Read Command Delay Time (tWTRmin)
> + SPD_TRTP_MIN_MTB_STRUCT tRTPmin; ///< 27
> Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
> + SPD_TFAW_MIN_MTB_UPPER_STRUCT tFAWMinUpper; ///<
> 28 Upper Nibble for tFAW
> + SPD_TFAW_MIN_MTB_STRUCT tFAWmin; ///< 29
> Minimum Four Activate Window Delay Time (tFAWmin)
> + SPD_SDRAM_OPTIONAL_FEATURES_STRUCT SdramOptionalFeatures;
> ///< 30 SDRAM Optional Features
> + SPD_SDRAM_THERMAL_REFRESH_STRUCT ThermalAndRefreshOptions;
> ///< 31 SDRAMThermalAndRefreshOptions
> + SPD_MODULE_THERMAL_SENSOR_STRUCT ModuleThermalSensor;
> ///< 32 Module Thermal Sensor
> + SPD_SDRAM_DEVICE_TYPE_STRUCT SdramDeviceType; ///< 33
> SDRAM Device Type
> + SPD_TCK_MIN_FTB_STRUCT tCKminFine; ///< 34 Fine
> Offset for SDRAM Minimum Cycle Time (tCKmin)
> + SPD_TAA_MIN_FTB_STRUCT tAAminFine; ///< 35 Fine
> Offset for Minimum CAS Latency Time (tAAmin)
> + SPD_TRCD_MIN_FTB_STRUCT tRCDminFine; ///< 36
> Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> + SPD_TRP_MIN_FTB_STRUCT tRPminFine; ///< 37
> Minimum Row Precharge Delay Time (tRPmin)
> + SPD_TRC_MIN_FTB_STRUCT tRCminFine; ///< 38 Fine
> Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
> + SPD_TRP_AB_MTB_STRUCT tRPab; ///< 39
> Minimum Row Precharge Delay Time for all banks (tRPab)
> + SPD_TRP_AB_FTB_STRUCT tRPabFine; ///< 40 Fine
> Offset for Minimum Row Precharge Delay Time for all banks (tRPab)
> + SPD_PTRR_SUPPORT_STRUCT pTRRsupport; ///< 41 -
> pTRR support with TMAC value
> + UINT8 Reserved3[59 - 42 + 1]; ///< 42 - 59 Reserved
> +} SPD_GENERAL_SECTION;
> +
> +typedef struct {
> + SPD_UNBUF_MODULE_NOMINAL_HEIGHT ModuleNominalHeight;
> ///< 60 Module Nominal Height
> + SPD_UNBUF_MODULE_NOMINAL_THICKNESS ModuleMaximumThickness;
> ///< 61 Module Maximum Thickness
> + SPD_UNBUF_REFERENCE_RAW_CARD ReferenceRawCardUsed;
> ///< 62 Reference Raw Card Used
> + SPD_UNBUF_ADDRESS_MAPPING AddressMappingEdgeConn;
> ///< 63 Address Mapping from Edge Connector to DRAM
> + UINT8 Reserved[116 - 64 + 1]; ///< 64-116 Reserved
> +} SPD_MODULE_UNBUFFERED;
> +
> +typedef struct {
> + SPD_RDIMM_MODULE_NOMINAL_HEIGHT ModuleNominalHeight;
> ///< 60 Module Nominal Height
> + SPD_RDIMM_MODULE_NOMINAL_THICKNESS ModuleMaximumThickness;
> ///< 61 Module Maximum Thickness
> + SPD_RDIMM_REFERENCE_RAW_CARD ReferenceRawCardUsed;
> ///< 62 Reference Raw Card Used
> + SPD_RDIMM_MODULE_ATTRIBUTES DimmModuleAttributes; ///<
> 63 DIMM Module Attributes
> + UINT8 Reserved[116 - 64 + 1]; ///< 64-116 Reserved
> +} SPD_MODULE_REGISTERED;
> +
> +typedef union {
> + SPD_MODULE_UNBUFFERED Unbuffered;
> + SPD_MODULE_REGISTERED Registered;
> +} SPD_MODULE_SPECIFIC;
> +
> +typedef struct {
> + UINT8 ModulePartNumber[145 - 128 + 1]; ///<
> 128-145 Module Part Number
> +} SPD_MODULE_PART_NUMBER;
> +
> +typedef struct {
> + UINT8 ModuleRevisionCode[147 - 146 + 1]; ///<
> 146-147 Module Revision Code
> +} SPD_MODULE_REVISION_CODE;
> +
> +typedef struct {
> + UINT8 ManufactureSpecificData[175 - 150 + 1]; ///<
> 150-175 Manufacturer's Specific Data
> +} SPD_MANUFACTURE_SPECIFIC;
> +
> +///
> +/// DDR3 Serial Presence Detect structure
> +///
> +typedef struct {
> + SPD_GENERAL_SECTION General; ///< 0-59
> General Section
> + SPD_MODULE_SPECIFIC Module; ///< 60-116
> Module-Specific Section
> + SPD_UNIQUE_MODULE_ID ModuleId; ///<
> 117-125 Unique Module ID
> + SPD_CYCLIC_REDUNDANCY_CODE Crc; ///<
> 126-127 Cyclical Redundancy Code (CRC)
> + SPD_MODULE_PART_NUMBER ModulePartNumber;
> ///< 128-145 Module Part Number
> + SPD_MODULE_REVISION_CODE ModuleRevisionCode;
> ///< 146-147 Module Revision Code
> + SPD_MANUFACTURER_ID_CODE DramIdCode; ///<
> 148-149 Dram Manufacturer ID Code
> + SPD_MANUFACTURE_SPECIFIC ManufactureSpecificData; ///<
> 150-175 Manufacturer's Specific Data
> + SPD_EXTREME_MEMORY_PROFILE Xmp; ///<
> 176-254 Intel(r) Extreme Memory Profile support
> + UINT8 Reserved; ///< 255 Reserved
> +} MrcSpdDdr3;
> +
> +typedef union {
> + struct {
> + UINT8 Density : 4; ///< Bits 3:0
> + UINT8 BankAddress : 2; ///< Bits 5:4
> + UINT8 BankGroup : 2; ///< Bits 7:6
> + } Bits;
> + UINT8 Data;
> +} SPD4_SDRAM_DENSITY_BANKS_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 SignalLoading : 2; ///< Bits 1:0
> + UINT8 : 2; ///< Bits 3:2
> + UINT8 DieCount : 3; ///< Bits 6:4
> + UINT8 SdramDeviceType : 1; ///< Bits 7:7
> + } Bits;
> + UINT8 Data;
> +} SPD4_SDRAM_DEVICE_TYPE_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 OperationAt1_20 : 1; ///< Bits 0:0
> + UINT8 EndurantAt1_20 : 1; ///< Bits 1:1
> + UINT8 : 6; ///< Bits 7:2
> + } Bits;
> + UINT8 Data;
> +} SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tCKmax : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD4_TCK_MAX_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + INT8 tCKmaxFine : 8; ///< Bits 7:0
> + } Bits;
> + INT8 Data;
> +} SPD4_TCK_MAX_FTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD4_SDRAM_THERMAL_REFRESH_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 Height : 5; ///< Bits 4:0
> + UINT8 RawCardExtension : 3; ///< Bits 7:5
> + } Bits;
> + UINT8 Data;
> +} SPD4_UNBUF_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> + struct {
> + UINT8 Height : 5; ///< Bits 4:0
> + UINT8 RawCardExtension : 3; ///< Bits 7:5
> + } Bits;
> + UINT8 Data;
> +} SPD4_RDIMM_MODULE_NOMINAL_HEIGHT;
> +
> +typedef struct {
> + SPD_DEVICE_DESCRIPTION_STRUCT Description; ///< 0
> Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
> + SPD_REVISION_STRUCT Revision; ///< 1 SPD
> Revision
> + SPD_DRAM_DEVICE_TYPE_STRUCT DramDeviceType; ///< 2
> DRAM Device Type
> + SPD_MODULE_TYPE_STRUCT ModuleType; ///< 3
> Module Type
> + SPD4_SDRAM_DENSITY_BANKS_STRUCT SdramDensityAndBanks;
> ///< 4 SDRAM Density and Banks
> + SPD_SDRAM_ADDRESSING_STRUCT SdramAddressing; ///< 5
> SDRAM Addressing
> + SPD4_SDRAM_DEVICE_TYPE_STRUCT SdramDeviceType; ///< 6
> SDRAM Device Type
> + SPD_PTRR_SUPPORT_STRUCT pTRRsupport; ///< 7
> pTRR support with TMAC value
> + SPD4_SDRAM_THERMAL_REFRESH_STRUCT ThermalAndRefreshOptions;
> ///< 8 SDRAM Thermal and Refresh Options
> + UINT8 Reserved0[10 - 9 + 1]; ///< 9-10 Reserved
> + SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT ModuleNominalVoltage;
> ///< 11 Module Nominal Voltage, VDD
> + SPD_MODULE_ORGANIZATION_STRUCT ModuleOrganization; ///<
> 12 Module Organization
> + SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT ModuleMemoryBusWidth;
> ///< 13 Module Memory Bus Width
> + SPD_MODULE_THERMAL_SENSOR_STRUCT ModuleThermalSensor;
> ///< 14 Module Thermal Sensor
> + UINT8 Reserved1[16 - 15 + 1]; ///< 15-16 Reserved
> + SPD4_TIMEBASE_STRUCT Timebase; ///< 17
> Timebases
> + SPD_TCK_MIN_MTB_STRUCT tCKmin; ///< 18
> SDRAM Minimum Cycle Time (tCKmin)
> + SPD4_TCK_MAX_MTB_STRUCT tCKmax; ///< 19
> SDRAM Maximum Cycle Time (tCKmax)
> + SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies; ///<
> 20-23 CAS Latencies Supported
> + SPD_TAA_MIN_MTB_STRUCT tAAmin; ///< 24
> Minimum CAS Latency Time (tAAmin)
> + SPD_TRCD_MIN_MTB_STRUCT tRCDmin; ///< 25
> Minimum RAS# to CAS# Delay Time (tRCDmin)
> + SPD_TRP_MIN_MTB_STRUCT tRPmin; ///< 26
> Minimum Row Precharge Delay Time (tRPmin)
> + SPD_TRAS_TRC_MIN_MTB_STRUCT tRASMintRCMinUpper; ///<
> 27 Upper Nibbles for tRAS and tRC
> + SPD_TRAS_MIN_MTB_STRUCT tRASmin; ///< 28
> Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
> + SPD_TRC_MIN_MTB_STRUCT tRCmin; ///< 29
> Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
> + SPD_TRFC_MIN_MTB_STRUCT tRFC1min; ///< 30-31
> Minimum Refresh Recovery Delay Time (tRFC1min)
> + SPD_TRFC_MIN_MTB_STRUCT tRFC2min; ///< 32-33
> Minimum Refresh Recovery Delay Time (tRFC2min)
> + SPD_TRFC_MIN_MTB_STRUCT tRFC4min; ///< 34-35
> Minimum Refresh Recovery Delay Time (tRFC4min)
> + SPD_TFAW_MIN_MTB_UPPER_STRUCT tFAWMinUpper; ///<
> 36 Upper Nibble for tFAW
> + SPD_TFAW_MIN_MTB_STRUCT tFAWmin; ///< 37
> Minimum Four Activate Window Delay Time (tFAWmin)
> + SPD_TRRD_MIN_MTB_STRUCT tRRD_Smin; ///< 38
> Minimum Activate to Activate Delay Time (tRRD_Smin), different bank group
> + SPD_TRRD_MIN_MTB_STRUCT tRRD_Lmin; ///< 39
> Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
> + UINT8 Reserved2[117 - 40 + 1]; ///< 40-117
> Reserved
> + SPD_TRRD_MIN_FTB_STRUCT tRRD_LminFine; ///< 118
> Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin),
> different bank group
> + SPD_TRRD_MIN_FTB_STRUCT tRRD_SminFine; ///< 119
> Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin), same
> bank group
> + SPD_TRC_MIN_FTB_STRUCT tRCminFine; ///< 120
> Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
> + SPD_TRP_MIN_FTB_STRUCT tRPminFine; ///< 121
> Minimum Row Precharge Delay Time (tRPmin)
> + SPD_TRCD_MIN_FTB_STRUCT tRCDminFine; ///< 122
> Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> + SPD_TAA_MIN_FTB_STRUCT tAAminFine; ///< 123
> Fine Offset for Minimum CAS Latency Time (tAAmin)
> + SPD4_TCK_MAX_FTB_STRUCT tCKmaxFine; ///< 124
> Fine Offset for SDRAM Minimum Cycle Time (tCKmax)
> + SPD_TCK_MIN_FTB_STRUCT tCKminFine; ///< 125
> Fine Offset for SDRAM Maximum Cycle Time (tCKmin)
> + SPD_CYCLIC_REDUNDANCY_CODE Crc; ///< 126-127
> Cyclical Redundancy Code (CRC)
> +} SPD4_BASE_SECTION;
> +
> +typedef struct {
> + SPD4_UNBUF_MODULE_NOMINAL_HEIGHT ModuleNominalHeight;
> ///< 128 Module Nominal Height
> + SPD_UNBUF_MODULE_NOMINAL_THICKNESS ModuleMaximumThickness;
> ///< 129 Module Maximum Thickness
> + SPD_UNBUF_REFERENCE_RAW_CARD ReferenceRawCardUsed;
> ///< 130 Reference Raw Card Used
> + SPD_UNBUF_ADDRESS_MAPPING AddressMappingEdgeConn;
> ///< 131 Address Mapping from Edge Connector to DRAM
> + UINT8 Reserved[253 - 132 + 1]; ///< 132-253
> Reserved
> + SPD_CYCLIC_REDUNDANCY_CODE Crc; ///< 254-255
> Cyclical Redundancy Code (CRC)
> +} SPD4_MODULE_UNBUFFERED;
> +
> +typedef struct {
> + SPD4_RDIMM_MODULE_NOMINAL_HEIGHT ModuleNominalHeight;
> ///< 128 Module Nominal Height
> + SPD_RDIMM_MODULE_NOMINAL_THICKNESS ModuleMaximumThickness;
> ///< 129 Module Maximum Thickness
> + SPD_RDIMM_REFERENCE_RAW_CARD ReferenceRawCardUsed;
> ///< 130 Reference Raw Card Used
> + SPD_RDIMM_MODULE_ATTRIBUTES DimmModuleAttributes; ///<
> 131 DIMM Module Attributes
> + UINT8 Reserved[253 - 132 + 1]; ///< 253-132
> Reserved
> + SPD_CYCLIC_REDUNDANCY_CODE Crc; ///< 254-255
> Cyclical Redundancy Code (CRC)
> +} SPD4_MODULE_REGISTERED;
> +
> +typedef union {
> + SPD4_MODULE_UNBUFFERED Unbuffered; ///<
> 128-255 Unbuffered Memory Module Types
> + SPD4_MODULE_REGISTERED Registered; ///< 128-255
> Registered Memory Module Types
> +} SPD4_MODULE_SPECIFIC;
> +
> +typedef struct {
> + UINT8 ModulePartNumber[348 - 329 + 1]; ///<
> 329-348 Module Part Number
> +} SPD4_MODULE_PART_NUMBER;
> +
> +typedef struct {
> + UINT8 ManufactureSpecificData[381 - 353 + 1]; ///<
> 353-381 Manufacturer's Specific Data
> +} SPD4_MANUFACTURE_SPECIFIC;
> +
> +typedef UINT8 SPD4_MODULE_REVISION_CODE;///< 349
> Module Revision Code
> +typedef UINT8 SPD4_DRAM_STEPPING; ///< 352
> Dram Stepping
> +
> +typedef struct {
> + SPD_UNIQUE_MODULE_ID ModuleId; ///< 320-328
> Unique Module ID
> + SPD4_MODULE_PART_NUMBER ModulePartNumber; ///<
> 329-348 Module Part Number
> + SPD4_MODULE_REVISION_CODE ModuleRevisionCode; ///<
> 349 Module Revision Code
> + SPD_MANUFACTURER_ID_CODE DramIdCode; ///<
> 350-351 Dram Manufacturer ID Code
> + SPD4_DRAM_STEPPING DramStepping; ///< 352
> Dram Stepping
> + SPD4_MANUFACTURE_SPECIFIC ManufactureSpecificData; ///<
> 353-381 Manufacturer's Specific Data
> + SPD_CYCLIC_REDUNDANCY_CODE Crc; ///< 382-383
> Cyclical Redundancy Code (CRC)
> +} SPD4_MANUFACTURING_DATA;
> +
> +typedef union {
> + SPD_EXTREME_MEMORY_PROFILE_2_0 Xmp; ///<
> 384-463 Intel(r) Extreme Memory Profile support
> + UINT8 Reserved0[511 - 384 + 1]; ///< 384-511
> Unbuffered Memory Module Types
> +} SPD4_END_USER_SECTION;
> +
> +///
> +/// DDR4 Serial Presence Detect structure
> +///
> +typedef struct {
> + SPD4_BASE_SECTION Base; ///< 0-127 Base
> Configuration and DRAM Parameters
> + SPD4_MODULE_SPECIFIC Module; ///< 128-255
> Module-Specific Section
> + UINT8 Reserved0[319 - 256 + 1]; ///< 256-319
> Reserved
> + SPD4_MANUFACTURING_DATA ManufactureInfo; ///<
> 320-383 Manufacturing Information
> + SPD4_END_USER_SECTION EndUser; ///< 384-511
> End User Programmable
> +} MrcSpdDdr4;
> +
> +typedef union {
> + struct {
> + UINT8 Fine : 2; ///< Bits 1:0
> + UINT8 Medium : 2; ///< Bits 3:2
> + UINT8 : 4; ///< Bits 7:4
> + } Bits;
> + UINT8 Data;
> +} SPD_LPDDR_TIMEBASE_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT32 CL3 : 1; ///< Bits 0:0
> + UINT32 CL6 : 1; ///< Bits 1:1
> + UINT32 CL8 : 1; ///< Bits 2:2
> + UINT32 CL9 : 1; ///< Bits 3:3
> + UINT32 CL10 : 1; ///< Bits 4:4
> + UINT32 CL11 : 1; ///< Bits 5:5
> + UINT32 CL12 : 1; ///< Bits 6:6
> + UINT32 CL14 : 1; ///< Bits 7:7
> + UINT32 CL16 : 1; ///< Bits 8:8
> + UINT32 : 1; ///< Bits 9:9
> + UINT32 CL20 : 1; ///< Bits 10:10
> + UINT32 CL22 : 1; ///< Bits 11:11
> + UINT32 CL24 : 1; ///< Bits 12:12
> + UINT32 : 1; ///< Bits 13:13
> + UINT32 CL28 : 1; ///< Bits 14:14
> + UINT32 : 1; ///< Bits 15:15
> + UINT32 CL32 : 1; ///< Bits 16:16
> + UINT32 : 1; ///< Bits 17:17
> + UINT32 CL36 : 1; ///< Bits 18:18
> + UINT32 : 1; ///< Bits 19:19
> + UINT32 CL40 : 1; ///< Bits 20:20
> + UINT32 : 11; ///< Bits 31:21
> + } Bits;
> + UINT32 Data;
> + UINT16 Data16[2];
> + UINT8 Data8[4];
> +} SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 Density : 4; ///< Bits 3:0
> + UINT8 BankAddress : 2; ///< Bits 5:4
> + UINT8 BankGroup : 2; ///< Bits 7:6
> + } Bits;
> + UINT8 Data;
> +} SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 SignalLoading : 2; ///< Bits 1:0
> + UINT8 ChannelsPerDie : 2; ///< Bits 3:2
> + UINT8 DieCount : 3; ///< Bits 6:4
> + UINT8 SdramPackageType : 1; ///< Bits 7:7
> + } Bits;
> + UINT8 Data;
> +} SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 OperationAt1_20 : 1; ///< Bits 0:0
> + UINT8 EndurantAt1_20 : 1; ///< Bits 1:1
> + UINT8 OperationAt1_10 : 1; ///< Bits 2:2
> + UINT8 EndurantAt1_10 : 1; ///< Bits 3:3
> + UINT8 OperationAtTBD2V : 1; ///< Bits 4:4
> + UINT8 EndurantAtTBD2V : 1; ///< Bits 5:5
> + UINT8 : 2; ///< Bits 7:6
> + } Bits;
> + UINT8 Data;
> +} SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 tCKmax : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_LPDDR_TCK_MAX_MTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 ReadLatencyMode : 2; ///< Bits 1:0
> + UINT8 WriteLatencySet : 2; ///< Bits 3:2
> + UINT8 : 4; ///< Bits 7:4
> + } Bits;
> + UINT8 Data;
> +} SPD_LPDDR_RW_LATENCY_OPTION_STRUCT;
> +
> +typedef union {
> + struct {
> + INT8 tCKmaxFine : 8; ///< Bits 7:0
> + } Bits;
> + INT8 Data;
> +} SPD_LPDDR_TCK_MAX_FTB_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 : 8; ///< Bits 7:0
> + } Bits;
> + UINT8 Data;
> +} SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT;
> +
> +typedef union {
> + struct {
> + UINT8 Height : 5; ///< Bits 4:0
> + UINT8 RawCardExtension : 3; ///< Bits 7:5
> + } Bits;
> + UINT8 Data;
> +} SPD_LPDDR_UNBUF_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> + struct {
> + UINT8 Height : 5; ///< Bits 4:0
> + UINT8 RawCardExtension : 3; ///< Bits 7:5
> + } Bits;
> + UINT8 Data;
> +} SPD_LPDDR_RDIMM_MODULE_NOMINAL_HEIGHT;
> +
> +typedef struct {
> + SPD_DEVICE_DESCRIPTION_STRUCT Description; ///< 0
> Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
> + SPD_REVISION_STRUCT Revision; ///< 1
> SPD Revision
> + SPD_DRAM_DEVICE_TYPE_STRUCT DramDeviceType; ///<
> 2 DRAM Device Type
> + SPD_MODULE_TYPE_STRUCT ModuleType; ///< 3
> Module Type
> + SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT SdramDensityAndBanks;
> ///< 4 SDRAM Density and Banks
> + SPD_SDRAM_ADDRESSING_STRUCT SdramAddressing;
> ///< 5 SDRAM Addressing
> + SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT SdramPackageType;
> ///< 6 SDRAM Package Type
> + SPD_PTRR_SUPPORT_STRUCT pTRRsupport; ///< 7
> pTRR support with TMAC value - SDRAM Optional Features
> + SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT
> ThermalAndRefreshOptions; ///< 8 SDRAM Thermal and Refresh Options
> + UINT8 Reserved0[10 - 9 + 1]; ///< 9-10
> Reserved
> + SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT
> ModuleNominalVoltage; ///< 11 Module Nominal Voltage, VDD
> + SPD_MODULE_ORGANIZATION_STRUCT ModuleOrganization;
> ///< 12 Module Organization
> + SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT
> ModuleMemoryBusWidth; ///< 13 Module Memory Bus Width
> + SPD_MODULE_THERMAL_SENSOR_STRUCT ModuleThermalSensor;
> ///< 14 Module Thermal Sensor
> + UINT8 Reserved1[16 - 15 + 1]; ///< 15-16
> Reserved
> + SPD_LPDDR_TIMEBASE_STRUCT Timebase; ///< 17
> Timebases
> + SPD_TCK_MIN_MTB_STRUCT tCKmin; ///< 18
> SDRAM Minimum Cycle Time (tCKmin)
> + SPD_LPDDR_TCK_MAX_MTB_STRUCT tCKmax; ///<
> 19 SDRAM Maximum Cycle Time (tCKmax)
> + SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies;
> ///< 20-23 CAS Latencies Supported
> + SPD_TAA_MIN_MTB_STRUCT tAAmin; ///< 24
> Minimum CAS Latency Time (tAAmin)
> + SPD_LPDDR_RW_LATENCY_OPTION_STRUCT LatencySetOptions;
> ///< 25 Read and Write Latency Set Options
> + SPD_TRCD_MIN_MTB_STRUCT tRCDmin; ///< 26
> Minimum RAS# to CAS# Delay Time (tRCDmin)
> + SPD_TRP_AB_MTB_STRUCT tRPab; ///< 27
> Minimum Row Precharge Delay Time (tRPab), all banks
> + SPD_TRP_PB_MTB_STRUCT tRPpb; ///< 28
> Minimum Row Precharge Delay Time (tRPpb), per bank
> + SPD_TRFC_AB_MTB_STRUCT tRFCab; ///< 29-30
> Minimum Refresh Recovery Delay Time (tRFCab), all banks
> + SPD_TRFC_PB_MTB_STRUCT tRFCpb; ///< 31-32
> Minimum Refresh Recovery Delay Time (tRFCpb), per bank
> + UINT8 Reserved2[119 - 33 + 1]; ///< 33-119
> Reserved
> + SPD_TRP_PB_FTB_STRUCT tRPpbFine; ///< 120
> Fine Offset for Minimum Row Precharge Delay Time (tRPpbFine), per bank
> + SPD_TRP_AB_FTB_STRUCT tRPabFine; ///< 121
> Fine Offset for Minimum Row Precharge Delay Time (tRPabFine), all ranks
> + SPD_TRCD_MIN_FTB_STRUCT tRCDminFine; ///<
> 122 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> + SPD_TAA_MIN_FTB_STRUCT tAAminFine; ///< 123
> Fine Offset for Minimum CAS Latency Time (tAAmin)
> + SPD_LPDDR_TCK_MAX_FTB_STRUCT tCKmaxFine; ///<
> 124 Fine Offset for SDRAM Maximum Cycle Time (tCKmax)
> + SPD_TCK_MIN_FTB_STRUCT tCKminFine; ///< 125
> Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
> + SPD_CYCLIC_REDUNDANCY_CODE Crc; ///<
> 126-127 Cyclical Redundancy Code (CRC)
> +} SPD_LPDDR_BASE_SECTION;
> +
> +typedef union {
> + struct {
> + UINT8 FrontThickness : 4; ///< Bits 3:0
> + UINT8 BackThickness : 4; ///< Bits 7:4
> + } Bits;
> + UINT8 Data;
> +} SPD_LPDDR_MODULE_MAXIMUM_THICKNESS;
> +
> +typedef union {
> + struct {
> + UINT8 Height : 5; ///< Bits 4:0
> + UINT8 RawCardExtension : 3; ///< Bits 7:5
> + } Bits;
> + UINT8 Data;
> +} SPD_LPDDR_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> + struct {
> + UINT8 Card : 5; ///< Bits 4:0
> + UINT8 Revision : 2; ///< Bits 6:5
> + UINT8 Extension : 1; ///< Bits 7:7
> + } Bits;
> + UINT8 Data;
> +} SPD_LPDDR_REFERENCE_RAW_CARD;
> +
> +typedef struct {
> + SPD_LPDDR_MODULE_NOMINAL_HEIGHT ModuleNominalHeight;
> ///< 128 Module Nominal Height
> + SPD_LPDDR_MODULE_MAXIMUM_THICKNESS
> ModuleMaximumThickness; ///< 129 Module Maximum Thickness
> + SPD_LPDDR_REFERENCE_RAW_CARD ReferenceRawCardUsed;
> ///< 130 Reference Raw Card Used
> + UINT8 Reserved[253 - 131 + 1]; ///< 131-253
> Reserved
> + SPD_CYCLIC_REDUNDANCY_CODE Crc; ///<
> 254-255 Cyclical Redundancy Code (CRC)
> +} SPD_LPDDR_MODULE_LPDIMM;
> +
> +typedef union {
> + SPD_LPDDR_MODULE_LPDIMM LpDimm; ///<
> 128-255 Unbuffered Memory Module Types
> +} SPD_LPDDR_MODULE_SPECIFIC;
> +
> +typedef struct {
> + UINT8 ModulePartNumber[348 - 329 + 1]; ///<
> 329-348 Module Part Number
> +} SPD_LPDDR_MODULE_PART_NUMBER;
> +
> +typedef struct {
> + UINT8 ManufactureSpecificData[381 - 353 + 1];
> ///< 353-381 Manufacturer's Specific Data
> +} SPD_LPDDR_MANUFACTURE_SPECIFIC;
> +
> +typedef UINT8
> SPD_LPDDR_MODULE_REVISION_CODE;///< 349 Module Revision Code
> +typedef UINT8 SPD_LPDDR_DRAM_STEPPING; ///<
> 352 Dram Stepping
> +
> +typedef struct {
> + SPD_UNIQUE_MODULE_ID ModuleId; ///<
> 320-328 Unique Module ID
> + SPD_LPDDR_MODULE_PART_NUMBER ModulePartNumber;
> ///< 329-348 Module Part Number
> + SPD_LPDDR_MODULE_REVISION_CODE ModuleRevisionCode;
> ///< 349 Module Revision Code
> + SPD_MANUFACTURER_ID_CODE DramIdCode; ///<
> 350-351 Dram Manufacturer ID Code
> + SPD_LPDDR_DRAM_STEPPING DramStepping; ///< 352
> Dram Stepping
> + SPD_LPDDR_MANUFACTURE_SPECIFIC ManufactureSpecificData;
> ///< 353-381 Manufacturer's Specific Data
> + UINT8 Reserved[383 - 382 + 1]; ///< 382-383
> Reserved
> +} SPD_LPDDR_MANUFACTURING_DATA;
> +
> +typedef union {
> + UINT8 Reserved0[511 - 384 + 1]; ///< 384-511 End
> User Programmable
> +} SPD_LPDDR_END_USER_SECTION;
> +
> +typedef struct {
> + SPD_LPDDR_BASE_SECTION Base; ///< 0-127
> Base Configuration and DRAM Parameters
> + SPD_LPDDR_MODULE_SPECIFIC Module; ///<
> 128-255 Module-Specific Section
> + UINT8 Reserved0[319 - 256 + 1]; ///< 256-319
> Reserved
> + SPD_LPDDR_MANUFACTURING_DATA ManufactureInfo; ///<
> 320-383 Manufacturing Information
> + SPD_LPDDR_END_USER_SECTION EndUser; ///<
> 384-511 End User Programmable
> +} MrcSpdLpDdr;
> +
> +typedef union {
> + MrcSpdDdr3 Ddr3;
> + MrcSpdDdr4 Ddr4;
> + MrcSpdLpDdr Lpddr;
> +} MrcSpd;
> +
> +#ifndef MAX_SPD_SAVE
> +#define MAX_SPD_SAVE (sizeof (SPD_MANUFACTURER_ID_CODE) + \
> + sizeof (SPD_MANUFACTURING_LOCATION) + \
> + sizeof (SPD_MANUFACTURING_DATE) + \
> + sizeof (SPD_MANUFACTURER_SERIAL_NUMBER) + \
> + sizeof (SPD4_MODULE_PART_NUMBER))
> +#endif
> +
> +#pragma pack (pop)
> +#endif // _MrcSpdData_h_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcTypes.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcTypes.h
> new file mode 100644
> index 0000000000..b267315f36
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcTypes.h
> @@ -0,0 +1,237 @@
> +/** @file
> + Include the the general MRC types
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MRC_TYPES_H
> +#define _MRC_TYPES_H
> +
> +#ifdef MRC_MINIBIOS_BUILD
> +#include "MrcMiniBiosEfiDefs.h"
> +#else
> +#include <Base.h>
> +#endif // MRC_MINIBIOS_BUILD
> +
> +//
> +// Data Types
> +//
> +typedef union {
> + struct {
> + UINT32 Low;
> + UINT32 High;
> + } Data32;
> + UINT64 Data;
> +} UINT64_STRUCT;
> +
> +typedef union {
> + struct {
> + INT32 Low;
> + INT32 High;
> + } Data32;
> + INT64 Data;
> +} INT64_STRUCT;
> +
> +typedef union {
> + VOID *Ptr;
> + UINTN DataN;
> + UINT64 Data64;
> +} POINTER_STRUCT;
> +
> +#define UNSUPPORT 0
> +#define SUPPORT 1
> +
> +typedef enum {
> + mrcSuccess,
> + mrcFail,
> + mrcWrongInputParameter,
> + mrcCasError,
> + mrcTimingError,
> + mrcSenseAmpErr,
> + mrcReadMPRErr,
> + mrcReadLevelingError,
> + mrcWriteLevelingError,
> + mrcDataTimeCentering1DErr,
> + mrcWriteVoltage2DError,
> + mrcReadVoltage2DError,
> + mrcMiscTrainingError,
> + mrcWrError,
> + mrcDimmNotSupport,
> + mrcChannelNotSupport,
> + mrcPiSettingError,
> + mrcDqsPiSettingError,
> + mrcDeviceBusy,
> + mrcFrequencyChange,
> + mrcReutSequenceError,
> + mrcCrcError,
> + mrcFrequencyError,
> + mrcDimmNotExist,
> + mrcColdBootRequired,
> + mrcRoundTripLatencyError,
> + mrcMixedDimmSystem,
> + mrcAliasDetected,
> + mrcRetrain,
> + mrcRtpError,
> + mrcUnsupportedTechnology,
> + mrcMappingError,
> + mrcSocketNotSupported,
> + mrcControllerNotSupported,
> + mrcRankNotSupported,
> + mrcTurnAroundTripError
> +} MrcStatus;
> +
> +//
> +// general macros
> +//
> +#ifndef MIN
> +#define MIN(a, b) (((a) < (b)) ? (a) : (b))
> +#endif
> +
> +#ifndef MAX
> +#define MAX(a, b) (((a) > (b)) ? (a) : (b))
> +#endif
> +
> +#ifndef ABS
> +#define ABS(x) (((x) < 0) ? (-(x)) : (x))
> +#endif
> +
> +//
> +// Make sure x is inside the range of [a..b]
> +//
> +#ifndef RANGE
> +#define RANGE(x, a, b) (MIN ((b), MAX ((x), (a))))
> +#endif
> +
> +#ifndef DIVIDECEIL
> +#define DIVIDECEIL(a, b) (((a) + (b) - 1) / (b))
> +#endif
> +
> +#ifndef DIVIDEROUND
> +#define DIVIDEROUND(a, b) (((a) * (b) > 0) ? ((a) + (b) / 2) / (b) : ((a) - (b) / 2)
> / (b))
> +#endif
> +
> +#ifndef DIVIDEFLOOR
> +#define DIVIDEFLOOR(a, b) ((a) / (b))
> +#endif
> +
> +//
> +// Number of elements in a 1D array
> +//
> +#ifndef ARRAY_COUNT
> +#define ARRAY_COUNT(a) (sizeof (a) / sizeof (a[0]))
> +#endif
> +
> +//
> +// use for ignore parames
> +//
> +// #define MRC_IGNORE_PARAM(x) ((x) = (x))
> +//
> +#if _MSC_EXTENSIONS
> +//
> +// Disable warning that make it impossible to compile at /W4
> +// This only works for Microsoft* tools
> +//
> +//
> +// Disabling bitfield type checking warnings.
> +//
> +#pragma warning (disable : 4214)
> +//
> +// Unreferenced formal parameter - We are object oriented, so we pass
> parameters even
> +// if we don't need them.
> +//
> +#pragma warning (disable : 4100)
> +//
> +// ASSERT(FALSE) or while (TRUE) are legal constructs so supress this warning
> +//
> +#pragma warning(disable : 4127)
> +//
> +// The given function was selected for inline expansion, but the compiler did
> not perform the inlining.
> +//
> +#pragma warning(disable : 4710)
> +
> +#endif // _MSC_EXTENSIONS
> +#define MRC_BIT0 0x00000001
> +#define MRC_BIT1 0x00000002
> +#define MRC_BIT2 0x00000004
> +#define MRC_BIT3 0x00000008
> +#define MRC_BIT4 0x00000010
> +#define MRC_BIT5 0x00000020
> +#define MRC_BIT6 0x00000040
> +#define MRC_BIT7 0x00000080
> +#define MRC_BIT8 0x00000100
> +#define MRC_BIT9 0x00000200
> +#define MRC_BIT10 0x00000400
> +#define MRC_BIT11 0x00000800
> +#define MRC_BIT12 0x00001000
> +#define MRC_BIT13 0x00002000
> +#define MRC_BIT14 0x00004000
> +#define MRC_BIT15 0x00008000
> +#define MRC_BIT16 0x00010000
> +#define MRC_BIT17 0x00020000
> +#define MRC_BIT18 0x00040000
> +#define MRC_BIT19 0x00080000
> +#define MRC_BIT20 0x00100000
> +#define MRC_BIT21 0x00200000
> +#define MRC_BIT22 0x00400000
> +#define MRC_BIT23 0x00800000
> +#define MRC_BIT24 0x01000000
> +#define MRC_BIT25 0x02000000
> +#define MRC_BIT26 0x04000000
> +#define MRC_BIT27 0x08000000
> +#define MRC_BIT28 0x10000000
> +#define MRC_BIT29 0x20000000
> +#define MRC_BIT30 0x40000000
> +#define MRC_BIT31 0x80000000
> +#define MRC_BIT32 0x100000000ULL
> +#define MRC_BIT33 0x200000000ULL
> +#define MRC_BIT34 0x400000000ULL
> +#define MRC_BIT35 0x800000000ULL
> +#define MRC_BIT36 0x1000000000ULL
> +#define MRC_BIT37 0x2000000000ULL
> +#define MRC_BIT38 0x4000000000ULL
> +#define MRC_BIT39 0x8000000000ULL
> +#define MRC_BIT40 0x10000000000ULL
> +#define MRC_BIT41 0x20000000000ULL
> +#define MRC_BIT42 0x40000000000ULL
> +#define MRC_BIT43 0x80000000000ULL
> +#define MRC_BIT44 0x100000000000ULL
> +#define MRC_BIT45 0x200000000000ULL
> +#define MRC_BIT46 0x400000000000ULL
> +#define MRC_BIT47 0x800000000000ULL
> +#define MRC_BIT48 0x1000000000000ULL
> +#define MRC_BIT49 0x2000000000000ULL
> +#define MRC_BIT50 0x4000000000000ULL
> +#define MRC_BIT51 0x8000000000000ULL
> +#define MRC_BIT52 0x10000000000000ULL
> +#define MRC_BIT53 0x20000000000000ULL
> +#define MRC_BIT54 0x40000000000000ULL
> +#define MRC_BIT55 0x80000000000000ULL
> +#define MRC_BIT56 0x100000000000000ULL
> +#define MRC_BIT57 0x200000000000000ULL
> +#define MRC_BIT58 0x400000000000000ULL
> +#define MRC_BIT59 0x800000000000000ULL
> +#define MRC_BIT60 0x1000000000000000ULL
> +#define MRC_BIT61 0x2000000000000000ULL
> +#define MRC_BIT62 0x4000000000000000ULL
> +#define MRC_BIT63 0x8000000000000000ULL
> +
> +#define MRC_DEADLOOP() { volatile int __iii; __iii = 1; while (__iii); }
> +
> +#ifndef ASM
> +#define ASM __asm
> +#endif
> +
> +///
> +/// Type Max/Min Values
> +///
> +#define MRC_INT32_MAX (0x7FFFFFFF)
> +#define MRC_INT32_MIN (0x80000000)
> +#define MRC_INT64_MAX (0x7FFFFFFFFFFFFFFFLL)
> +#define MRC_INT64_MIN (0x8000000000000000LL)
> +#define MRC_UINT32_MAX (0xFFFFFFFF)
> +#define MRC_UINT64_MAX (0xFFFFFFFFFFFFFFFFULL)
> +#define MRC_UINT_MIN (0x0)
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcI
> nterface.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcI
> nterface.h
> new file mode 100644
> index 0000000000..d444e937d6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcI
> nterface.h
> @@ -0,0 +1,15 @@
> +/** @file
> + This file includes all the data structures that the MRC considers "global
> data".
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _UNIFIED_MrcInterface_h_
> +#define _UNIFIED_MrcInterface_h_
> +
> +#include "Coffeelake/MrcInterface.h"
> +
> +#endif
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
> new file mode 100644
> index 0000000000..82d798b783
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
> @@ -0,0 +1,50 @@
> +/** @file
> + Header file for initialization of GT PowerManagement
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GRAPHICS_INIT_H_
> +#define _GRAPHICS_INIT_H_
> +
> +#include <Library/DxeServicesTableLib.h>
> +#include <Guid/DxeServices.h>
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Library/PciSegmentLib.h>
> +#include <SaAccess.h>
> +#include <Protocol/SaPolicy.h>
> +#include "SaInitDxe.h"
> +#include "SaInit.h"
> +#include <PchAccess.h>
> +#include <CpuRegs.h>
> +#include <Library/CpuPlatformLib.h>
> +
> +
> +/**
> + Initialize GT ACPI tables
> +
> + @param[in] ImageHandle - Handle for the image of this driver
> + @param[in] SaPolicy - SA DXE Policy protocol
> +
> + @retval EFI_SUCCESS - GT ACPI initialization complete
> + @retval EFI_NOT_FOUND - Dxe System Table not found.
> + @retval EFI_OUT_OF_RESOURCES - Mmio not allocated successfully.
> +**/
> +EFI_STATUS
> +GraphicsInit (
> + IN EFI_HANDLE ImageHandle,
> + IN SA_POLICY_PROTOCOL *SaPolicy
> + );
> +
> +/**
> + Do Post GT PM Init Steps after VBIOS Initialization.
> +
> + @retval EFI_SUCCESS Succeed.
> +**/
> +EFI_STATUS
> +PostPmInitEndOfDxe (
> + VOID
> + );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.h
> new file mode 100644
> index 0000000000..0e95db3d02
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.h
> @@ -0,0 +1,193 @@
> +/** @file
> + This is part of the implementation of an Intel Graphics drivers OpRegion /
> + Software SCI interface between system BIOS, ASL code, and Graphics drivers.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _IGD_OPREGION_INIT_H_
> +#define _IGD_OPREGION_INIT_H_
> +
> +///
> +/// Statements that include other header files.
> +///
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <PchAccess.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PmcLib.h>
> +#include <SaAccess.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <CpuRegs.h>
> +#include <SaInit.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <SiConfigHob.h>
> +
> +///
> +/// Driver Consumed Protocol Prototypes
> +///
> +#include <Protocol/PciIo.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/LegacyBios.h>
> +#include <Protocol/SaPolicy.h>
> +
> +
> +#include <Private/Protocol/SaNvsArea.h>
> +
> +///
> +/// Driver Produced Protocol Prototypes
> +///
> +#include <Protocol/IgdOpRegion.h>
> +
> +///
> +///
> +/// OpRegion (Miscellaneous) defines.
> +///
> +/// OpRegion Header defines.
> +///
> +typedef UINT16 STRING_REF;
> +#define HEADER_SIGNATURE "IntelGraphicsMem"
> +#define HEADER_SIZE 0x2000
> +#define HEADER_OPREGION_VER 0x0200
> +#define HEADER_OPREGION_REV 0x00
> +#define HEADER_MBOX_SUPPORT (HD_MBOX5 + HD_MBOX4 +
> HD_MBOX3 + HD_MBOX2 + HD_MBOX1)
> +#define HD_MBOX1 BIT0
> +#define HD_MBOX2 BIT1
> +#define HD_MBOX3 BIT2
> +#define HD_MBOX4 BIT3
> +#define HD_MBOX5 BIT4
> +#define SVER_SIZE 32
> +
> +///
> +/// OpRegion Mailbox 1 EQUates.
> +///
> +/// OpRegion Mailbox 3 EQUates.
> +///
> +#define ALS_ENABLE BIT0
> +#define BLC_ENABLE BIT1
> +#define BACKLIGHT_BRIGHTNESS 0xFF
> +#define FIELD_VALID_BIT BIT31
> +#define PFIT_ENABLE BIT2
> +#define PFIT_OPRN_AUTO 0x00000000
> +#define PFIT_OPRN_SCALING 0x00000007
> +#define PFIT_OPRN_OFF 0x00000000
> +#define PFIT_SETUP_AUTO 0
> +#define PFIT_SETUP_SCALING 1
> +#define PFIT_SETUP_OFF 2
> +#define INIT_BRIGHT_LEVEL 0x64
> +#define PFIT_STRETCH 6
> +
> +///
> +/// Video BIOS / VBT defines
> +///
> +#define OPTION_ROM_SIGNATURE 0xAA55
> +#define VBIOS_LOCATION_PRIMARY 0xC0000
> +
> +#define VBT_SIGNATURE SIGNATURE_32 ('$', 'V', 'B', 'T')
> +///
> +/// Typedef stuctures
> +///
> +#pragma pack(1)
> +typedef struct {
> + UINT16 Signature; /// 0xAA55
> + UINT8 Size512;
> + UINT8 Reserved[21];
> + UINT16 PcirOffset;
> + UINT16 VbtOffset;
> +} INTEL_VBIOS_OPTION_ROM_HEADER;
> +#pragma pack()
> +
> +#pragma pack(1)
> +typedef struct {
> + UINT32 Signature; /// "PCIR"
> + UINT16 VendorId; /// 0x8086
> + UINT16 DeviceId;
> + UINT16 Reserved0;
> + UINT16 Length;
> + UINT8 Revision;
> + UINT8 ClassCode[3];
> + UINT16 ImageLength;
> + UINT16 CodeRevision;
> + UINT8 CodeType;
> + UINT8 Indicator;
> + UINT16 Reserved1;
> +} INTEL_VBIOS_PCIR_STRUCTURE;
> +#pragma pack()
> +
> +#pragma pack(1)
> +typedef struct {
> + UINT8 HeaderSignature[20];
> + UINT16 HeaderVersion;
> + UINT16 HeaderSize;
> + UINT16 HeaderVbtSize;
> + UINT8 HeaderVbtCheckSum;
> + UINT8 HeaderReserved;
> + UINT32 HeaderOffsetVbtDataBlock;
> + UINT32 HeaderOffsetAim1;
> + UINT32 HeaderOffsetAim2;
> + UINT32 HeaderOffsetAim3;
> + UINT32 HeaderOffsetAim4;
> + UINT8 DataHeaderSignature[16];
> + UINT16 DataHeaderVersion;
> + UINT16 DataHeaderSize;
> + UINT16 DataHeaderDataBlockSize;
> + UINT8 CoreBlockId;
> + UINT16 CoreBlockSize;
> + UINT16 CoreBlockBiosSize;
> + UINT8 CoreBlockBiosType;
> + UINT8 CoreBlockReleaseStatus;
> + UINT8 CoreBlockHWSupported;
> + UINT8 CoreBlockIntegratedHW;
> + UINT8 CoreBlockBiosBuild[4];
> + UINT8 CoreBlockBiosSignOn[155];
> +} VBIOS_VBT_STRUCTURE;
> +#pragma pack()
> +///
> +/// Driver Private Function definitions
> +///
> +
> +/**
> + Graphics OpRegion / Software SCI driver installation function.
> +
> + @retval EFI_SUCCESS - The driver installed without error.
> + @retval EFI_ABORTED - The driver encountered an error and could not
> complete
> + installation of the ACPI tables.
> +**/
> +EFI_STATUS
> +IgdOpRegionInit (
> + VOID
> + );
> +
> +/**
> + Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
> + The VBT (Video BIOS Table) is a block of customizable data that is built
> + within the video BIOS and edited by customers.
> +
> + @retval EFI_SUCCESS - Video BIOS VBT information returned.
> + @exception EFI_UNSUPPORTED - Could not find VBT information
> (*VBiosVbtPtr = NULL).
> +**/
> +EFI_STATUS
> +GetVBiosVbtEndOfDxe (
> + VOID
> + );
> +
> +/**
> + Update Graphics OpRegion after PCI enumeration.
> +
> + @retval EFI_SUCCESS - The function completed successfully.
> +**/
> +EFI_STATUS
> +UpdateIgdOpRegionEndOfDxe (
> + VOID
> + );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.
> h
> new file mode 100644
> index 0000000000..34a2809f80
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.
> h
> @@ -0,0 +1,91 @@
> +/** @file
> + Header file for PciExpress Initialization Driver.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCIEXPRESS_INITIALIZATION_DRIVER_H_
> +#define _PCIEXPRESS_INITIALIZATION_DRIVER_H_
> +
> +#include <Library/HobLib.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Register/Msr.h>
> +#include <SaAccess.h>
> +#include <PchAccess.h>
> +#include <Private/SaConfigHob.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Private/Protocol/SaNvsArea.h>
> +
> +#define GEN1 1
> +#define GEN2 2
> +
> +///
> +/// Function prototypes
> +///
> +/**
> + PCI Express Dxe Initialization.
> + Run before PCI Bus Init, where assignment of Bus, Memory,
> + and I/O Resources are assigned.
> +
> + @param[in] SaPolicy - SA DXE Policy protocol
> +
> + @retval EFI_SUCCESS - Pci Express successfully started and ready to be
> used
> + @exception EFI_UNSUPPORTED - Pci Express can't be initialized
> +**/
> +EFI_STATUS
> +PciExpressInit (
> + IN SA_POLICY_PROTOCOL *SaPolicy
> + );
> +
> +/**
> + Find the Offset to a given Capabilities ID
> +
> + @param[in] Segment - Pci Segment Number
> + @param[in] Bus - Pci Bus Number
> + @param[in] Device - Pci Device Number
> + @param[in] Function - Pci Function Number
> + @param[in] CapId - CAPID to search fo
> +
> + @retval 0 - CAPID not found
> + @retval Other - CAPID found, Offset of desired CAPID
> +**/
> +UINT32
> +PcieFindCapId (
> + IN UINT8 Segment,
> + IN UINT8 Bus,
> + IN UINT8 Device,
> + IN UINT8 Function,
> + IN UINT8 CapId
> + );
> +
> +/**
> + Search and return the offset of desired Pci Express Capability ID
> +
> + @param[in] Segment - Pci Segment Number
> + @param[in] Bus - Pci Bus Number
> + @param[in] Device - Pci Device Number
> + @param[in] Function - Pci Function Number
> + @param[in] CapId - Extended CAPID to search for
> +
> + @retval 0 - CAPID not found
> + @retval Other - CAPID found, Offset of desired CAPID
> +**/
> +UINT32
> +PcieFindExtendedCapId (
> + IN UINT8 Segment,
> + IN UINT8 Bus,
> + IN UINT8 Device,
> + IN UINT8 Function,
> + IN UINT16 CapId
> + );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
> new file mode 100644
> index 0000000000..73af27e9d7
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
> @@ -0,0 +1,23 @@
> +/** @file
> + This is header file for SA PCIE Root Complex initialization.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +EFI_STATUS
> +PegInitBeforeEndOfDxe (
> + VOID
> + );
> +
> +/**
> + This function performs SA registers Saving/Restoring in EndOfDxe callback
> +
> + @retval EFI_SUCCESS - Save/restore has done
> + @retval EFI_UNSUPPORTED - Save/restore not done successfully
> +**/
> +EFI_STATUS
> +SaSaveRestore (
> + VOID
> + );
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
> new file mode 100644
> index 0000000000..d7e2423ffd
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
> @@ -0,0 +1,71 @@
> +/** @file
> + Header file for SA Common Initialization Driver.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_INITIALIZATION_DRIVER_H_
> +#define _SA_INITIALIZATION_DRIVER_H_
> +
> +#include <Uefi.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Pci.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciCf8Lib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/SaPlatformLib.h>
> +#include <Guid/EventGroup.h>
> +#include <CpuRegs.h>
> +#include <SaAccess.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Private/SaConfigHob.h>
> +
> +extern SA_POLICY_PROTOCOL *mSaPolicy;
> +extern SA_CONFIG_HOB *SaConfigHob;
> +
> +typedef struct {
> + UINT64 BaseAddr;
> + UINT32 Offset;
> + UINT32 AndMask;
> + UINT32 OrMask;
> +} BOOT_SCRIPT_REGISTER_SETTING;
> +
> +/**
> + SystemAgent Initialization Common Function.
> +
> + @retval EFI_SUCCESS - Always.
> +**/
> +VOID
> +SaInitEntryPoint (
> + VOID
> + );
> +
> +/**
> + Common function locks the PAM register as part of the SA Security
> requirements.
> +
> + @retval EFI_SUCCESS - Always.
> +**/
> +VOID
> +SaPamLock (
> + VOID
> + );
> +/**
> + This function performs SA Security locking in EndOfDxe callback
> +
> + @retval EFI_SUCCESS - Security lock has done
> + @retval EFI_UNSUPPORTED - Security lock not done successfully
> +**/
> +EFI_STATUS
> +SaSecurityInit (
> + VOID
> + );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
> new file mode 100644
> index 0000000000..1991fd82c4
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
> @@ -0,0 +1,139 @@
> +/** @file
> + Header file for SA Initialization Driver.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_INITIALIZATION_DXE_DRIVER_H_
> +#define _SA_INITIALIZATION_DXE_DRIVER_H_
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/AcpiTable.h>
> +#include "VTd.h"
> +#include "PcieComplex.h"
> +#include "IgdOpRegionInit.h"
> +#include <Private/Library/LegacyRegion.h>
> +#include "GraphicsInit.h"
> +#include "PciExpressInit.h"
> +#include "SwitchableGraphicsInit.h"
> +#include <Library/CpuPlatformLib.h>
> +
> +///
> +/// Driver Consumed Protocol Prototypes
> +///
> +#include <Protocol/SaPolicy.h>
> +
> +extern EFI_GUID gSaAcpiTableStorageGuid;
> +extern EFI_GUID gSaSsdtAcpiTableStorageGuid;
> +extern EFI_GUID gPegSsdtAcpiTableStorageGuid;
> +
> +typedef struct {
> + UINT64 Address;
> + EFI_BOOT_SCRIPT_WIDTH Width;
> + UINT32 Value;
> +} BOOT_SCRIPT_PCI_REGISTER_SAVE;
> +
> +///
> +/// Function Prototype
> +///
> +/**
> + This function gets registered as a callback to perform SA initialization before
> ExitPmAuth
> +
> + @param[in] Event - A pointer to the Event that triggered the callback.
> + @param[in] Context - A pointer to private data registered with the
> callback function.
> +
> + @retval EFI_SUCCESS - Always.
> +
> +**/
> +VOID
> +EFIAPI
> +SaPciEnumCompleteCallback (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + );
> +
> +/**
> + <b>System Agent Initialization DXE Driver Entry Point</b>
> + - <b>Introduction</b> \n
> + Based on the information/data in SA_POLICY_PROTOCOL, this module
> performs further SA initialization in DXE phase,
> + e.g. internal devices enable/disable, SSVID/SID programming, graphic
> power-management, VT-d, IGD OpRegion initialization.
> + From the perspective of a PCI Express hierarchy, the Broadwell System
> Agent and PCH together appear as a Root Complex with root ports the number
> of which depends on how the 8 PCH ports and 4 System Agent PCIe ports are
> configured [4x1, 2x8, 1x16].
> + There is an internal link (DMI or OPI) that connects the System Agent to the
> PCH component. This driver includes initialization of SA DMI, PCI Express, SA &
> PCH Root Complex Topology.
> + For iGFX, this module implements the initialization of the Graphics
> Technology Power Management from the Broadwell System Agent BIOS
> Specification and the initialization of the IGD OpRegion/Software SCI - BIOS
> Specification.
> + The ASL files that go along with the driver define the IGD OpRegion
> mailboxes in ACPI space and implement the software SCI interrupt mechanism.
> + The IGD OpRegion/Software SCI code serves as a communication interface
> between system BIOS, ASL, and Intel graphics driver including making a block of
> customizable data (VBT) from the Intel video BIOS available.
> + Reference Code for the SCI service functions "Get BIOS Data" and "System
> BIOS Callback" can be found in the ASL files, those functions can be platform
> specific, the sample provided in the reference code are implemented for Intel
> CRB.
> + This module implements the VT-d functionality described in the Broadwell
> System Agent BIOS Specification.
> + This module publishes the LegacyRegion protocol to control the read and
> write accesses to the Legacy BIOS ranges.
> + E000 and F000 segments are the legacy BIOS ranges and contain pointers
> to the ACPI regions, SMBIOS tables and so on. This is a private protocol used by
> Intel Framework.
> + This module registers CallBack function that performs SA security registers
> lockdown at end of post as required from Broadwell Bios Spec.
> + In addition, this module publishes the SaInfo Protocol with information
> such as current System Agent reference code version#.
> +
> + - @pre
> + - EFI_FIRMWARE_VOLUME_PROTOCOL: Documented in Firmware Volume
> Specification, available at the URL:
> http://www.intel.com/technology/framework/spec.htm
> + - SA_POLICY_PROTOCOL: A protocol published by a platform DXE module
> executed earlier; this is documented in this document as well.
> + - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL: Documented in the Unified
> Extensible Firmware Interface Specification, version 2.0, available at the URL:
> http://www.uefi.org/specs/
> + - EFI_BOOT_SCRIPT_SAVE_PROTOCOL: A protocol published by a platform
> DXE module executed earlier; refer to the Sample Code section of the
> Framework PCH Reference Code.
> + - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL:
> Documented in the Unified Extensible Firmware Interface Specification,
> version 2.0, available at the URL: http://www.uefi.org/specs/
> + - EFI_ACPI_TABLE_PROTOCOL : Documented in PI Specification 1.2
> + - EFI_CPU_IO_PROTOCOL: Documented in CPU I/O Protocol Specification,
> available at the URL: http://www.intel.com/technology/framework/spec.htm
> + - EFI_DATA_HUB_PROTOCOL: Documented in EFI Data Hub Infrastructure
> Specification, available at the URL:
> http://www.intel.com/technology/framework/spec.htm
> + - EFI_HII_PROTOCOL (or EFI_HII_DATABASE_PROTOCOL for UEFI 2.1):
> Documented in Human Interface Infrastructure Specification, available at the
> URL: http://www.intel.com/technology/framework/spec.htm
> + (For EFI_HII_DATABASE_PROTOCOL, refer to UEFI Specification Version 2.1
> available at the URL: http://www.uefi.org/)
> +
> + - @result
> + IGD power-management functionality is initialized; VT-d is initialized
> (meanwhile, the DMAR table is updated); IGD OpRegion is initialized -
> IGD_OPREGION_PROTOCOL installed, IGD OpRegion allocated and mailboxes
> initialized, chipset initialized and ready to generate Software SCI for Internal
> graphics events. Publishes the SA_INFO_PROTOCOL with current SA reference
> code version #. Publishes the EFI_LEGACY_REGION_PROTOCOL documented in
> the Compatibility Support Module Specification, version 0.9, available at the
> URL: http://www.intel.com/technology/framework/spec.htm
> +
> + - <b>References</b> \n
> + IGD OpRegion/Software SCI for Broadwell
> + Advanced Configuration and Power Interface Specification Revision 4.0a.
> +
> + - <b>Porting Recommendations</b> \n
> + No modification of the DXE driver should be typically necessary.
> + This driver should be executed after all related devices (audio, video, ME,
> etc.) are initialized to ensure correct data in DMAR table and DMA-remapping
> registers.
> +
> + @param[in] ImageHandle Handle for the image of this driver
> + @param[in] SystemTable Pointer to the EFI System Table
> +
> + @retval EFI_SUCCESS The function completed successfully
> + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
> +**/
> +EFI_STATUS
> +EFIAPI
> +SaInitEntryPointDxe (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + );
> +
> +/**
> + SystemAgent Acpi Initialization.
> +
> + @param[in] ImageHandle Handle for the image of this driver
> +
> + @retval EFI_SUCCESS The function completed successfully
> + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
> +**/
> +EFI_STATUS
> +EFIAPI
> +SaAcpiInit (
> + IN EFI_HANDLE ImageHandle
> + );
> +
> +/**
> + This function locks the PAM register as part of the SA Security requirements.
> +
> + @param[in] Event - A pointer to the Event that triggered the callback.
> + @param[in] Context - A pointer to private data registered with the
> callback function.
> +
> + @retval EFI_SUCCESS - Always.
> +**/
> +VOID
> +EFIAPI
> +SaPamLockDxe (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGra
> phicsInit.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGra
> phicsInit.h
> new file mode 100644
> index 0000000000..2b1b4c5880
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGra
> phicsInit.h
> @@ -0,0 +1,17 @@
> +/** @file
> + Header file for the SwitchableGraphics Dxe driver.
> + This driver loads SwitchableGraphics ACPI tables.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SWITCHABLE_GRAPHICS_DXE_H_
> +#define _SWITCHABLE_GRAPHICS_DXE_H_
> +
> +
> +#include <Protocol/FirmwareVolume2.h>
> +
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
> new file mode 100644
> index 0000000000..c4bc47f7fe
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
> @@ -0,0 +1,53 @@
> +/** @file
> + This code provides a initialization of intel VT-d (Virtualization Technology
> for Directed I/O).
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _VT_D_H_
> +#define _VT_D_H_
> +
> +///
> +/// Include files
> +///
> +#include <DmaRemappingTable.h>
> +#include <SaAccess.h>
> +#include <PchAccess.h>
> +#include <Uefi.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> +#include <Protocol/AcpiTable.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Private/PchConfigHob.h>
> +#include <CpuRegs.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +
> +#define VTD_ECAP_REG 0x10
> +#define IR BIT3
> +
> +/**
> + Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
> + Publish the appropriate SSDT based on current configuration and
> capabilities.
> +
> + @param[in] SaPolicy SA DXE Policy protocol
> +
> + @retval EFI_SUCCESS - Vtd initialization complete
> + @retval Other - No Vtd function initiated
> +**/
> +EFI_STATUS
> +VtdInit (
> + IN SA_POLICY_PROTOCOL *SaPolicy
> + );
> +
> +/**
> + PciEnumerationComplete routine for update DMAR
> +**/
> +VOID
> +UpdateDmarPciEnumCompleteCallback (
> + VOID
> + );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.h
> new file mode 100644
> index 0000000000..02c74c0672
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.h
> @@ -0,0 +1,162 @@
> +/** @file
> + Header file for SMM Access Driver.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SMM_ACCESS_DRIVER_H_
> +#define _SMM_ACCESS_DRIVER_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Uefi/UefiBaseType.h>
> +
> +#include <Guid/SmramMemoryReserve.h>
> +#include <Protocol/SmmAccess2.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <SaAccess.h>
> +
> +#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5', 's',
> 'a')
> +
> +///
> +/// Private data
> +///
> +typedef struct {
> + UINTN Signature;
> + EFI_HANDLE Handle;
> + EFI_SMM_ACCESS2_PROTOCOL SmmAccess;
> +
> + ///
> + /// Local Data for SMM Access interface goes here
> + ///
> + UINTN NumberRegions;
> + EFI_SMRAM_DESCRIPTOR *SmramDesc;
> +} SMM_ACCESS_PRIVATE_DATA;
> +
> +#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
> + CR (a, \
> + SMM_ACCESS_PRIVATE_DATA, \
> + SmmAccess, \
> + SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
> + )
> +
> +//
> +// Prototypes
> +// Driver model protocol interface
> +//
> +/**
> + <b>SMM Access Driver Entry Point</b>
> + This driver installs an SMM Access Protocol
> + - <b>Introduction</b> \n
> + This module publishes the SMM access protocol. The protocol is used by
> the SMM Base driver to access the SMRAM region when the processor is not in
> SMM.
> + The SMM Base driver uses the services provided by the SMM access
> protocol to open SMRAM during post and copy the SMM handler.
> + SMM access protocol is also used to close the SMRAM region once the
> copying is done.
> + Finally, the SMM access protocol provides services to "Lock" the SMRAM
> region.
> + Please refer the SMM Protocols section in the attached SMM CIS
> Specification version 0.9 for further details.
> + This driver is required if SMM is supported. Proper configuration of SMM
> registers is recommended even if SMM is not supported.
> +
> + - @result
> + Publishes the _EFI_SMM_ACCESS_PROTOCOL: Documented in the System
> Management Mode Core Interface Specification, available at the URL:
> http://www.intel.com/technology/framework/spec.htm
> +
> + - <b>Porting Recommendations</b> \n
> + No modification of this module is recommended. Any modification
> should be done in compliance with the _EFI_SMM_ACCESS_PROTOCOL
> protocol definition.
> +
> + @param[in] ImageHandle - Handle for the image of this driver
> + @param[in] SystemTable - Pointer to the EFI System Table
> +
> + @retval EFI_SUCCESS - Protocol was installed successfully
> + @exception EFI_UNSUPPORTED - Protocol was not installed
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmAccessDriverEntryPoint (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + );
> +
> +/**
> + This routine accepts a request to "open" a region of SMRAM. The
> + region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> + The use of "open" means that the memory is visible from all boot-service
> + and SMM agents.
> +
> + @param[in] This - Pointer to the SMM Access Interface.
> +
> + @retval EFI_SUCCESS - The region was successfully opened.
> + @retval EFI_DEVICE_ERROR - The region could not be opened because
> locked by
> + chipset.
> + @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Open (
> + IN EFI_SMM_ACCESS2_PROTOCOL *This
> + );
> +
> +/**
> + This routine accepts a request to "close" a region of SMRAM. The
> + region could be legacy AB or TSEG near top of physical memory.
> + The use of "close" means that the memory is only visible from SMM agents,
> + not from BS or RT code.
> +
> + @param[in] This - Pointer to the SMM Access Interface.
> +
> + @retval EFI_SUCCESS - The region was successfully closed.
> + @retval EFI_DEVICE_ERROR - The region could not be closed because
> locked by
> + chipset.
> + @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Close (
> + IN EFI_SMM_ACCESS2_PROTOCOL *This
> + );
> +
> +/**
> + This routine accepts a request to "lock" SMRAM. The
> + region could be legacy AB or TSEG near top of physical memory.
> + The use of "lock" means that the memory can no longer be opened
> + to BS state..
> +
> + @param[in] This - Pointer to the SMM Access Interface.
> +
> + @retval EFI_SUCCESS - The region was successfully locked.
> + @retval EFI_DEVICE_ERROR - The region could not be locked because at
> least
> + one range is still open.
> + @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Lock (
> + IN EFI_SMM_ACCESS2_PROTOCOL *This
> + );
> +
> +/**
> + This routine services a user request to discover the SMRAM
> + capabilities of this platform. This will report the possible
> + ranges that are possible for SMRAM access, based upon the
> + memory controller capabilities.
> +
> + @param[in] This - Pointer to the SMRAM Access Interface.
> + @param[in] SmramMapSize - Pointer to the variable containing size
> of the
> + buffer to contain the description information.
> + @param[in] SmramMap - Buffer containing the data describing
> the Smram
> + region descriptors.
> +
> + @retval EFI_BUFFER_TOO_SMALL - The user did not provide a sufficient
> buffer.
> + @retval EFI_SUCCESS - The user provided a sufficiently-sized buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetCapabilities (
> + IN CONST EFI_SMM_ACCESS2_PROTOCOL *This,
> + IN OUT UINTN *SmramMapSize,
> + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
> + );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
> new file mode 100644
> index 0000000000..5daa2367e6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
> @@ -0,0 +1,157 @@
> +/** @file
> + DXE driver for Initializing SystemAgent Graphics ACPI table initialization.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "GraphicsInit.h"
> +#include "SaInit.h"
> +#include <Protocol/LegacyBios.h>
> +#include <Protocol/GopComponentName2.h>
> +#include <SiConfigHob.h>
> +
> +typedef union {
> + struct {
> + UINT32 Low;
> + UINT32 High;
> + } Data32;
> + UINT64 Data;
> +} UINT64_STRUCT;
> +
> +extern SYSTEM_AGENT_NVS_AREA_PROTOCOL mSaNvsAreaProtocol;
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT64
> mGttMmAdr;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT64_STRUCT
> mMchBarBase;
> +GLOBAL_REMOVE_IF_UNREFERENCED
> GOP_COMPONENT_NAME2_PROTOCOL *GopComponentName2Protocol =
> NULL;
> +
> +/**
> + Do Post GT PM Init Steps after VBIOS Initialization.
> +
> + @retval EFI_SUCCESS Succeed.
> +**/
> +EFI_STATUS
> +PostPmInitEndOfDxe (
> + VOID
> + )
> +{
> + CHAR16 *DriverVersion;
> + UINTN Index;
> + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
> + EFI_STATUS Status;
> + GRAPHICS_DXE_CONFIG *GraphicsDxeConfig;
> + EFI_PEI_HOB_POINTERS HobPtr;
> + SI_CONFIG_HOB_DATA *SiConfigHobData;
> +
> + ///
> + /// Get the platform setup policy.
> + ///
> + DriverVersion = NULL;
> + LegacyBios = NULL;
> + Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **)
> &mSaPolicy);
> + ASSERT_EFI_ERROR (Status);
> +
> + Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> + ASSERT_EFI_ERROR (Status);
> +
> + //
> + // Get Silicon Config data HOB
> + //
> + HobPtr.Guid = GetFirstGuidHob (&gSiConfigHobGuid);
> + SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA
> (HobPtr.Guid);
> +
> + if (SiConfigHobData->CsmFlag == 1) {
> + Status = gBS->LocateProtocol (
> + &gEfiLegacyBiosProtocolGuid,
> + NULL,
> + (VOID **) &LegacyBios
> + );
> + }
> +
> + if (LegacyBios == NULL) {
> + Status = gBS->LocateProtocol (&gGopComponentName2ProtocolGuid,
> NULL, (VOID **)&GopComponentName2Protocol);
> + if (!EFI_ERROR (Status)) {
> + Status = GopComponentName2Protocol->GetDriverVersion (
> + GopComponentName2Protocol,
> + "en-US",
> + &DriverVersion
> + );
> + if (!EFI_ERROR (Status)) {
> + for (Index = 0; (DriverVersion[Index] != '\0'); Index++) {
> + }
> + Index = (Index+1)*2;
> + CopyMem (GraphicsDxeConfig->GopVersion, DriverVersion, Index);
> + }
> + }
> + }
> +
> + ///
> + /// Return final status
> + ///
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +Initialize GT ACPI tables
> +
> + @param[in] ImageHandle - Handle for the image of this driver
> + @param[in] SaPolicy - SA DXE Policy protocol
> +
> + @retval EFI_SUCCESS - GT ACPI initialization complete
> + @retval EFI_NOT_FOUND - Dxe System Table not found.
> + @retval EFI_OUT_OF_RESOURCES - Mmio not allocated successfully.
> +**/
> +EFI_STATUS
> +GraphicsInit (
> + IN EFI_HANDLE ImageHandle,
> + IN SA_POLICY_PROTOCOL *SaPolicy
> + )
> +{
> + EFI_STATUS Status;
> + GRAPHICS_DXE_CONFIG *GraphicsDxeConfig;
> +
> + mGttMmAdr = 0;
> + Status = EFI_SUCCESS;
> + mMchBarBase.Data32.High = PciSegmentRead32
> (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0,
> R_SA_MCHBAR + 4));
> + mMchBarBase.Data32.Low = PciSegmentRead32
> (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0,
> R_SA_MCHBAR));
> + mMchBarBase.Data &= (UINT64) ~BIT0;
> +
> + Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> + ASSERT_EFI_ERROR (Status);
> +
> + ///
> + /// Update IGD SA Global NVS
> + ///
> + DEBUG ((DEBUG_INFO, " Update Igd SA Global NVS Area.\n"));
> +
> + mSaNvsAreaProtocol.Area->AlsEnable =
> GraphicsDxeConfig->AlsEnable;
> + ///
> + /// Initialize IGD state by checking if IGD Device 2 Function 0 is enabled in the
> chipset
> + ///
> + if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 0, 0, R_SA_DEVEN)) & B_SA_DEVEN_D2EN_MASK) {
> + mSaNvsAreaProtocol.Area->IgdState = 1;
> + } else {
> + mSaNvsAreaProtocol.Area->IgdState = 0;
> + }
> +
> + mSaNvsAreaProtocol.Area->BrightnessPercentage = 100;
> + mSaNvsAreaProtocol.Area->IgdBootType =
> GraphicsDxeConfig->IgdBootType;
> + mSaNvsAreaProtocol.Area->IgdPanelType =
> GraphicsDxeConfig->IgdPanelType;
> + mSaNvsAreaProtocol.Area->IgdPanelScaling =
> GraphicsDxeConfig->IgdPanelScaling;
> + ///
> + /// Get SFF power mode platform data for the IGD driver. Flip the bit
> (bitwise xor)
> + /// since Setup value is opposite of NVS and IGD OpRegion value.
> + ///
> + mSaNvsAreaProtocol.Area->IgdDvmtMemSize =
> GraphicsDxeConfig->IgdDvmtMemSize;
> + mSaNvsAreaProtocol.Area->IgdFunc1Enable = 0;
> + mSaNvsAreaProtocol.Area->IgdHpllVco = MmioRead8
> (mMchBarBase.Data + 0xC0F) & 0x07;
> + mSaNvsAreaProtocol.Area->IgdSciSmiMode = 0;
> + mSaNvsAreaProtocol.Area->GfxTurboIMON =
> GraphicsDxeConfig->GfxTurboIMON;
> +
> + mSaNvsAreaProtocol.Area->EdpValid = 0;
> +
> + return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.c
> new file mode 100644
> index 0000000000..6ec0691074
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.c
> @@ -0,0 +1,570 @@
> +/** @file
> + This is part of the implementation of an Intel Graphics drivers OpRegion /
> + Software SCI interface between system BIOS, ASL code, and Graphics drivers.
> + The code in this file will load the driver and initialize the interface
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "IgdOpRegionInit.h"
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED IGD_OPREGION_PROTOCOL
> mIgdOpRegion;
> +
> +/**
> + Get VBT data using SaPlaformPolicy
> +
> + @param[out] VbtFileBuffer Pointer to VBT data buffer.
> +
> + @retval EFI_SUCCESS VBT data was returned.
> + @retval EFI_NOT_FOUND VBT data not found.
> + @exception EFI_UNSUPPORTED Invalid signature in VBT data.
> +**/
> +EFI_STATUS
> +GetIntegratedIntelVbtPtr (
> + OUT VBIOS_VBT_STRUCTURE **VbtFileBuffer
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS VbtAddress;
> + UINT32 Size;
> + GRAPHICS_DXE_CONFIG *GraphicsDxeConfig;
> +
> + ///
> + /// Get the SA policy.
> + ///
> + Status = gBS->LocateProtocol (
> + &gSaPolicyProtocolGuid,
> + NULL,
> + (VOID **) &mSaPolicy
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> + ASSERT_EFI_ERROR (Status);
> +
> + VbtAddress = GraphicsDxeConfig->VbtAddress;
> + Size = GraphicsDxeConfig->Size;
> +
> + if (VbtAddress == 0x00000000) {
> + return EFI_NOT_FOUND;
> + } else {
> + ///
> + /// Check VBT signature
> + ///
> + *VbtFileBuffer = NULL;
> + *VbtFileBuffer = (VBIOS_VBT_STRUCTURE *) (UINTN) VbtAddress;
> + if ((*((UINT32 *) ((*VbtFileBuffer)->HeaderSignature))) != VBT_SIGNATURE)
> {
> + FreePool (*VbtFileBuffer);
> + *VbtFileBuffer = NULL;
> + return EFI_UNSUPPORTED;
> + }
> + }
> + if (Size == 0) {
> + return EFI_NOT_FOUND;
> + } else {
> + ///
> + /// Check VBT size
> + ///
> + if ((*VbtFileBuffer)->HeaderVbtSize > Size) {
> + (*VbtFileBuffer)->HeaderVbtSize = (UINT16) Size;
> + }
> + }
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Get a pointer to an uncompressed image of the Intel video BIOS.
> +
> + @Note: This function would only be called if the video BIOS at 0xC000 is
> + missing or not an Intel video BIOS. It may not be an Intel video BIOS
> + if the Intel graphic contoller is considered a secondary adapter.
> +
> + @param[out] VBiosImage - Pointer to an uncompressed Intel video BIOS.
> This pointer must
> + be set to NULL if an uncompressed image of the Intel
> Video BIOS
> + is not obtainable.
> +
> + @retval EFI_SUCCESS - VBiosPtr is updated.
> + @exception EFI_UNSUPPORTED - No Intel video BIOS found.
> +**/
> +EFI_STATUS
> +GetIntegratedIntelVBiosPtr (
> + OUT INTEL_VBIOS_OPTION_ROM_HEADER **VBiosImage
> + )
> +{
> + EFI_HANDLE *HandleBuffer;
> + UINTN HandleCount;
> + UINTN Index;
> + INTEL_VBIOS_PCIR_STRUCTURE *PcirBlockPtr;
> + EFI_STATUS Status;
> + EFI_PCI_IO_PROTOCOL *PciIo;
> + INTEL_VBIOS_OPTION_ROM_HEADER *VBiosRomImage;
> +
> + ///
> + /// Set as if an umcompressed Intel video BIOS image was not obtainable.
> + ///
> + VBiosRomImage = NULL;
> +
> + ///
> + /// Get all PCI IO protocols
> + ///
> + Status = gBS->LocateHandleBuffer (
> + ByProtocol,
> + &gEfiPciIoProtocolGuid,
> + NULL,
> + &HandleCount,
> + &HandleBuffer
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + ///
> + /// Find the video BIOS by checking each PCI IO handle for an Intel video
> + /// BIOS OPROM.
> + ///
> + for (Index = 0; Index < HandleCount; Index++) {
> + Status = gBS->HandleProtocol (
> + HandleBuffer[Index],
> + &gEfiPciIoProtocolGuid,
> + (VOID **) &PciIo
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + VBiosRomImage = PciIo->RomImage;
> +
> + ///
> + /// If this PCI device doesn't have a ROM image, skip to the next device.
> + ///
> + if (!VBiosRomImage) {
> + continue;
> + }
> + ///
> + /// Get pointer to PCIR structure
> + ///
> + PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *)
> VBiosRomImage + VBiosRomImage->PcirOffset);
> +
> + ///
> + /// Check if we have an Intel video BIOS OPROM.
> + ///
> + if ((VBiosRomImage->Signature == OPTION_ROM_SIGNATURE) &&
> + (PcirBlockPtr->VendorId == V_SA_MC_VID) &&
> + (PcirBlockPtr->ClassCode[0] == 0x00) &&
> + (PcirBlockPtr->ClassCode[1] == 0x00) &&
> + (PcirBlockPtr->ClassCode[2] == 0x03)
> + ) {
> + ///
> + /// Found Intel video BIOS.
> + ///
> + *VBiosImage = VBiosRomImage;
> + return EFI_SUCCESS;
> + }
> + }
> + ///
> + /// No Intel video BIOS found.
> + ///
> + ///
> + /// Free any allocated buffers
> + ///
> + FreePool (HandleBuffer);
> + return EFI_UNSUPPORTED;
> +}
> +
> +/**
> + Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
> + The VBT (Video BIOS Table) is a block of customizable data that is built
> + within the video BIOS and edited by customers.
> +
> + @retval EFI_SUCCESS - Video BIOS VBT information returned.
> + @exception EFI_UNSUPPORTED - Could not find VBT information
> (*VBiosVbtPtr = NULL).
> +**/
> +EFI_STATUS
> +GetVBiosVbtEndOfDxe (
> + VOID
> + )
> +{
> + INTEL_VBIOS_PCIR_STRUCTURE *PcirBlockPtr;
> + UINT32 PcirBlockAddress;
> + UINT16 PciVenderId;
> + INTEL_VBIOS_OPTION_ROM_HEADER *VBiosPtr;
> + VBIOS_VBT_STRUCTURE *VBiosVbtPtr;
> + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
> + EFI_STATUS Status;
> + VBIOS_VBT_STRUCTURE *VbtFileBuffer;
> + UINTN Index;
> + UINT8 LegacyVbtFound;
> + GRAPHICS_DXE_CONFIG *GraphicsDxeConfig;
> + EFI_PEI_HOB_POINTERS HobPtr;
> + SI_CONFIG_HOB_DATA *SiConfigHobData;
> +
> + VbtFileBuffer = NULL;
> + LegacyVbtFound = 1;
> +
> + ///
> + /// Get the SA policy.
> + ///
> + Status = gBS->LocateProtocol (
> + &gSaPolicyProtocolGuid,
> + NULL,
> + (VOID **) &mSaPolicy
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> + ASSERT_EFI_ERROR (Status);
> +
> + LegacyBios = NULL;
> + VBiosPtr = NULL;
> + //
> + // Get Silicon Config data HOB
> + //
> + HobPtr.Guid = GetFirstGuidHob (&gSiConfigHobGuid);
> + SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA
> (HobPtr.Guid);
> + if (SiConfigHobData->CsmFlag == 1) {
> + Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID
> **) &LegacyBios);
> +
> + if (LegacyBios) {
> + VBiosPtr = (INTEL_VBIOS_OPTION_ROM_HEADER *) (UINTN)
> (VBIOS_LOCATION_PRIMARY);
> + PcirBlockAddress = VBIOS_LOCATION_PRIMARY + VBiosPtr->PcirOffset;
> + PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *) (UINTN)
> (PcirBlockAddress);
> + PciVenderId = PcirBlockPtr->VendorId;
> + ///
> + /// If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get
> + /// the integrated Intel video BIOS (must be uncompressed).
> + ///
> + if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId !=
> V_SA_MC_VID)) {
> + GetIntegratedIntelVBiosPtr (&VBiosPtr);
> + if (VBiosPtr != NULL) {
> + ///
> + /// Video BIOS found.
> + ///
> + PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *) VBiosPtr
> + VBiosPtr->PcirOffset);
> + PciVenderId = PcirBlockPtr->VendorId;
> +
> + if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) ||
> (PciVenderId != V_SA_MC_VID)) {
> + ///
> + /// Intel video BIOS not found.
> + ///
> + VBiosVbtPtr = NULL;
> + LegacyVbtFound = 0;
> + }
> + }
> + }
> + }
> + }
> + if ((LegacyBios == NULL) || (LegacyVbtFound == 0)) {
> + ///
> + /// No Video BIOS found, try to get VBT from FV.
> + ///
> + GetIntegratedIntelVbtPtr (&VbtFileBuffer);
> + if (VbtFileBuffer != NULL) {
> + ///
> + /// Video BIOS not found, use VBT from SaPolicy
> + ///
> + DEBUG ((DEBUG_INFO, "VBT data found\n"));
> + for (Index = 0; (GraphicsDxeConfig->GopVersion[Index] != '\0'); Index++) {
> + }
> + Index = (Index+1)*2;
> + CopyMem (mIgdOpRegion.OpRegion->Header.DVER,
> GraphicsDxeConfig->GopVersion, Index);
> + CopyMem (mIgdOpRegion.OpRegion->MBox4.RVBT, VbtFileBuffer,
> VbtFileBuffer->HeaderVbtSize);
> + return EFI_SUCCESS;
> + }
> + }
> +
> + if (VBiosPtr == NULL) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + DEBUG ((DEBUG_INFO, "VBIOS found at 0x%X\n", VBiosPtr));
> + VBiosVbtPtr = (VBIOS_VBT_STRUCTURE *) ((UINT8 *) VBiosPtr +
> VBiosPtr->VbtOffset);
> +
> + if ((*((UINT32 *) (VBiosVbtPtr->HeaderSignature))) != VBT_SIGNATURE) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + ///
> + /// Initialize Video BIOS version with its build number.
> + ///
> + mIgdOpRegion.OpRegion->Header.VVER[0] =
> VBiosVbtPtr->CoreBlockBiosBuild[0];
> + mIgdOpRegion.OpRegion->Header.VVER[1] =
> VBiosVbtPtr->CoreBlockBiosBuild[1];
> + mIgdOpRegion.OpRegion->Header.VVER[2] =
> VBiosVbtPtr->CoreBlockBiosBuild[2];
> + mIgdOpRegion.OpRegion->Header.VVER[3] =
> VBiosVbtPtr->CoreBlockBiosBuild[3];
> + CopyMem (mIgdOpRegion.OpRegion->MBox4.RVBT, VBiosVbtPtr,
> VBiosVbtPtr->HeaderVbtSize);
> +
> + ///
> + /// Return final status
> + ///
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Graphics OpRegion / Software SCI driver installation function.
> +
> + @param[in] void - None
> + @retval EFI_SUCCESS - The driver installed without error.
> + @retval EFI_ABORTED - The driver encountered an error and could not
> complete
> + installation of the ACPI tables.
> +**/
> +EFI_STATUS
> +IgdOpRegionInit (
> + VOID
> + )
> +{
> + EFI_HANDLE Handle;
> + EFI_STATUS Status;
> + UINT32 DwordData;
> + UINT64 IgdBaseAddress;
> + SA_POLICY_PROTOCOL *SaPolicy;
> + GRAPHICS_DXE_CONFIG *GraphicsDxeConfig;
> + UINT8 Index;
> + SYSTEM_AGENT_NVS_AREA_PROTOCOL *SaNvsAreaProtocol;
> +
> + ///
> + /// Get the SA policy.
> + ///
> + Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID
> **)&SaPolicy);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> + ASSERT_EFI_ERROR (Status);
> + ///
> + /// Locate the SA Global NVS Protocol.
> + ///
> + Status = gBS->LocateProtocol (
> + &gSaNvsAreaProtocolGuid,
> + NULL,
> + (VOID **) &SaNvsAreaProtocol
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + ///
> + /// Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize
> + /// the first 1K, and set the IGD OpRegion pointer in the Global NVS
> + /// area structure.
> + ///
> + Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof
> (IGD_OPREGION_STRUCTURE), (VOID **) &mIgdOpRegion.OpRegion);
> + ASSERT_EFI_ERROR (Status);
> +
> + SetMem (mIgdOpRegion.OpRegion, sizeof (IGD_OPREGION_STRUCTURE),
> 0);
> + SaNvsAreaProtocol->Area->IgdOpRegionAddress = (UINT32) (UINTN)
> (mIgdOpRegion.OpRegion);
> +
> + ///
> + /// If IGD is disabled return
> + ///
> + IgdBaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0);
> + if (PciSegmentRead32 (IgdBaseAddress + 0) == 0xFFFFFFFF) {
> + return EFI_SUCCESS;
> + }
> + ///
> + /// Initialize OpRegion Header
> + ///
> + CopyMem (mIgdOpRegion.OpRegion->Header.SIGN, HEADER_SIGNATURE,
> sizeof (HEADER_SIGNATURE));
> + ///
> + /// Set OpRegion Size in KBs
> + ///
> + mIgdOpRegion.OpRegion->Header.SIZE = HEADER_SIZE / 1024;
> + mIgdOpRegion.OpRegion->Header.OVER = (UINT32) (LShiftU64
> (HEADER_OPREGION_VER, 16) + LShiftU64 (HEADER_OPREGION_REV, 8));
> +
> + ///
> + /// All Mailboxes are supported.
> + ///
> + mIgdOpRegion.OpRegion->Header.MBOX = HEADER_MBOX_SUPPORT;
> +
> + ///
> + /// Initialize OpRegion Mailbox 1 (Public ACPI Methods).
> + ///
> + /// Note - The initial setting of mailbox 1 fields is implementation specific.
> + /// Adjust them as needed many even coming from user setting in setup.
> + ///
> + ///
> + /// Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservation).
> + ///
> + /// Note - The initial setting of mailbox 3 fields is implementation specific.
> + /// Adjust them as needed many even coming from user setting in setup.
> + ///
> + ///
> + /// Do not initialize TCHE. This field is written by the graphics driver only.
> + ///
> + ///
> + /// The ALSI field is generally initialized by ASL code by reading the
> embedded controller.
> + ///
> + mIgdOpRegion.OpRegion->Header.PCON =
> GraphicsDxeConfig->PlatformConfig;
> + mIgdOpRegion.OpRegion->Header.PCON =
> mIgdOpRegion.OpRegion->Header.PCON | 0x2;
> +
> + mIgdOpRegion.OpRegion->MBox3.BCLP = BACKLIGHT_BRIGHTNESS;
> +
> + mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT |
> PFIT_STRETCH);
> +
> + ///
> + /// Reporting to driver for VR IMON Calibration. Bits [5-1] values supported
> 14A to 31A.
> + ///
> + mIgdOpRegion.OpRegion->MBox3.PCFT =
> (SaNvsAreaProtocol->Area->GfxTurboIMON << 1) & 0x003E;
> +
> + ///
> + /// Set Initial current Brightness
> + ///
> + mIgdOpRegion.OpRegion->MBox3.CBLV = (INIT_BRIGHT_LEVEL |
> FIELD_VALID_BIT);
> +
> + ///
> + /// Static Backlight Brightness Level Duty cycle Mapping Table
> + ///
> + for (Index = 0; Index < MAX_BCLM_ENTRIES; Index++) {
> + mIgdOpRegion.OpRegion->MBox3.BCLM[Index] =
> GraphicsDxeConfig->BCLM[Index];
> + }
> +
> + mIgdOpRegion.OpRegion->MBox3.IUER = 0x00;
> +
> + if (!EFI_ERROR (Status)) {
> + mIgdOpRegion.OpRegion->MBox3.IUER =
> GraphicsDxeConfig->IuerStatusVal;
> + }
> +
> + ///
> + /// Initialize hardware state:
> + /// Set ASLS Register to the OpRegion physical memory address.
> + /// Set SWSCI register bit 15 to a "1" to activate SCI interrupts.
> + ///
> + PciSegmentWrite32 (IgdBaseAddress + R_SA_IGD_ASLS_OFFSET, (UINT32)
> (UINTN) (mIgdOpRegion.OpRegion));
> + PciSegmentAndThenOr16 (IgdBaseAddress + R_SA_IGD_SWSCI_OFFSET,
> (UINT16) ~(BIT0), BIT15);
> +
> + DwordData = PciSegmentRead32 (IgdBaseAddress +
> R_SA_IGD_ASLS_OFFSET);
> + S3BootScriptSaveMemWrite (
> + S3BootScriptWidthUint32,
> + (UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (IgdBaseAddress +
> R_SA_IGD_ASLS_OFFSET),
> + 1,
> + &DwordData
> + );
> + DwordData = PciSegmentRead32 (IgdBaseAddress +
> R_SA_IGD_SWSCI_OFFSET);
> + S3BootScriptSaveMemWrite (
> + S3BootScriptWidthUint32,
> + (UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (IgdBaseAddress +
> R_SA_IGD_SWSCI_OFFSET),
> + 1,
> + &DwordData
> + );
> +
> + ///
> + /// Install OpRegion / Software SCI protocol
> + ///
> + Handle = NULL;
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &Handle,
> + &gIgdOpRegionProtocolGuid,
> + &mIgdOpRegion,
> + NULL
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + ///
> + /// Return final status
> + ///
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Update Graphics OpRegion after PCI enumeration.
> +
> + @param[in] void - None
> + @retval EFI_SUCCESS - The function completed successfully.
> +**/
> +EFI_STATUS
> +UpdateIgdOpRegionEndOfDxe (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + UINTN HandleCount;
> + EFI_HANDLE *HandleBuffer;
> + UINTN Index;
> + EFI_PCI_IO_PROTOCOL *PciIo;
> + PCI_TYPE00 Pci;
> + UINTN Segment;
> + UINTN Bus;
> + UINTN Device;
> + UINTN Function;
> +
> + Bus = 0;
> + Device = 0;
> + Function = 0;
> +
> + DEBUG ((DEBUG_INFO, "UpdateIgdOpRegionEndOfDxe\n"));
> +
> + mIgdOpRegion.OpRegion->Header.PCON |= BIT8; //Set External Gfx
> Adapter field is valid
> + mIgdOpRegion.OpRegion->Header.PCON &= (UINT32) (~BIT7); //Assume No
> External Gfx Adapter
> +
> + ///
> + /// Get all PCI IO protocols handles
> + ///
> + Status = gBS->LocateHandleBuffer (
> + ByProtocol,
> + &gEfiPciIoProtocolGuid,
> + NULL,
> + &HandleCount,
> + &HandleBuffer
> + );
> +
> + if (!EFI_ERROR (Status)) {
> + for (Index = 0; Index < HandleCount; Index++) {
> + ///
> + /// Get the PCI IO Protocol Interface corresponding to each handle
> + ///
> + Status = gBS->HandleProtocol (
> + HandleBuffer[Index],
> + &gEfiPciIoProtocolGuid,
> + (VOID **) &PciIo
> + );
> +
> + if (!EFI_ERROR (Status)) {
> + ///
> + /// Read the PCI configuration space
> + ///
> + Status = PciIo->Pci.Read (
> + PciIo,
> + EfiPciIoWidthUint32,
> + 0,
> + sizeof (Pci) / sizeof (UINT32),
> + &Pci
> + );
> +
> + ///
> + /// Find the display controllers devices
> + ///
> + if (!EFI_ERROR (Status) && IS_PCI_DISPLAY (&Pci)) {
> + Status = PciIo->GetLocation (
> + PciIo,
> + &Segment,
> + &Bus,
> + &Device,
> + &Function
> + );
> +
> + //
> + // Assumption: Onboard devices will be sits on Bus no 0, while
> external devices will be sits on Bus no > 0
> + //
> + if (!EFI_ERROR (Status) && (Bus > 0)) {
> + //External Gfx Adapter Detected and Available
> + DEBUG ((DEBUG_INFO, "PCON - External Gfx Adapter Detected and
> Available\n"));
> + mIgdOpRegion.OpRegion->Header.PCON |= BIT7;
> + break;
> + }
> + }
> + }
> + }
> + }
> +
> + ///
> + /// Free any allocated buffers
> + ///
> + if (HandleBuffer != NULL) {
> + FreePool (HandleBuffer);
> + }
> +
> + ///
> + /// Return final status
> + ///
> + return Status;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
> new file mode 100644
> index 0000000000..bbdf0d0fab
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
> @@ -0,0 +1,171 @@
> +/** @file
> + This driver does SA PCI Express ACPI table initialization.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PciExpressInit.h"
> +
> +extern SYSTEM_AGENT_NVS_AREA_PROTOCOL mSaNvsAreaProtocol;
> +extern SA_CONFIG_HOB *mSaConfigHob;
> +
> +/**
> + PCI Express Dxe Initialization.
> + Run before PCI Bus Init, where assignment of Bus, Memory,
> + and I/O Resources are assigned.
> +
> + @param[in] SaPolicy - SA DXE Policy protocol
> +
> + @retval EFI_SUCCESS - Pci Express successfully started and ready to be
> used
> +**/
> +EFI_STATUS
> +PciExpressInit (
> + IN SA_POLICY_PROTOCOL *SaPolicy
> + )
> +{
> + EFI_STATUS Status;
> + PCIE_DXE_CONFIG *PcieDxeConfig;
> + MSR_BROADWELL_PKG_CST_CONFIG_CONTROL_REGISTER Msr;
> +
> + Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID
> *)&PcieDxeConfig);
> + ASSERT_EFI_ERROR (Status);
> +
> +
> + Msr.Uint64 = AsmReadMsr64
> (MSR_BROADWELL_PKG_CST_CONFIG_CONTROL);
> + mSaNvsAreaProtocol.Area->PackageCstateLimit = (UINT8) Msr.Bits.Limit;
> +
> + mSaNvsAreaProtocol.Area->PwrDnBundlesGlobalEnable = 0;
> +
> + if (mSaConfigHob != NULL) {
> + mSaNvsAreaProtocol.Area->Peg0PowerDownUnusedBundles =
> mSaConfigHob->PowerDownUnusedBundles[0];
> + mSaNvsAreaProtocol.Area->Peg1PowerDownUnusedBundles =
> mSaConfigHob->PowerDownUnusedBundles[1];
> + mSaNvsAreaProtocol.Area->Peg2PowerDownUnusedBundles =
> mSaConfigHob->PowerDownUnusedBundles[2];
> + if (SA_PEG_MAX_FUN > 3) {
> + mSaNvsAreaProtocol.Area->Peg3PowerDownUnusedBundles =
> mSaConfigHob->PowerDownUnusedBundles[3];
> + }
> + }
> + ///
> + /// LTR/OBFF
> + ///
> + mSaNvsAreaProtocol.Area->Peg0LtrEnable =
> PcieDxeConfig->PegPwrOpt[0].LtrEnable;
> + mSaNvsAreaProtocol.Area->Peg0ObffEnable =
> PcieDxeConfig->PegPwrOpt[0].ObffEnable;
> + mSaNvsAreaProtocol.Area->Peg1LtrEnable =
> PcieDxeConfig->PegPwrOpt[1].LtrEnable;
> + mSaNvsAreaProtocol.Area->Peg1ObffEnable =
> PcieDxeConfig->PegPwrOpt[1].ObffEnable;
> + mSaNvsAreaProtocol.Area->Peg2LtrEnable =
> PcieDxeConfig->PegPwrOpt[2].LtrEnable;
> + mSaNvsAreaProtocol.Area->Peg2ObffEnable =
> PcieDxeConfig->PegPwrOpt[2].ObffEnable;
> + mSaNvsAreaProtocol.Area->PegLtrMaxSnoopLatency =
> LTR_MAX_SNOOP_LATENCY_VALUE;
> + mSaNvsAreaProtocol.Area->PegLtrMaxNoSnoopLatency =
> LTR_MAX_NON_SNOOP_LATENCY_VALUE;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Find the Offset to a given Capabilities ID
> + CAPID list:
> + 0x01 = PCI Power Management Interface
> + 0x04 = Slot Identification
> + 0x05 = MSI Capability
> + 0x10 = PCI Express Capability
> +
> + @param[in] Segment - Pci Segment Number
> + @param[in] Bus - Pci Bus Number
> + @param[in] Device - Pci Device Number
> + @param[in] Function - Pci Function Number
> + @param[in] CapId - CAPID to search for
> +
> + @retval 0 - CAPID not found
> + @retval Other - CAPID found, Offset of desired CAPID
> +**/
> +UINT32
> +PcieFindCapId (
> + IN UINT8 Segment,
> + IN UINT8 Bus,
> + IN UINT8 Device,
> + IN UINT8 Function,
> + IN UINT8 CapId
> + )
> +{
> + UINT64 DeviceBaseAddress;
> + UINT8 CapHeader;
> +
> + ///
> + /// Always start at Offset 0x34
> + ///
> + DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device,
> Function, 0);
> + CapHeader = PciSegmentRead8 (DeviceBaseAddress +
> PCI_CAPBILITY_POINTER_OFFSET);
> + if (CapHeader == 0xFF) {
> + return 0;
> + }
> +
> + while (CapHeader != 0) {
> + ///
> + /// Bottom 2 bits of the pointers are reserved per PCI Local Bus Spec 2.2
> + ///
> + CapHeader &= ~(BIT1 + BIT0);
> + ///
> + /// Search for desired CapID
> + ///
> + if (PciSegmentRead8 (DeviceBaseAddress + CapHeader) == CapId) {
> + return CapHeader;
> + }
> +
> + CapHeader = PciSegmentRead8 (DeviceBaseAddress + CapHeader + 1);
> + }
> +
> + return 0;
> +}
> +
> +/**
> + Search and return the offset of desired Pci Express Capability ID
> + CAPID list:
> + 0x0001 = Advanced Error Rreporting Capability
> + 0x0002 = Virtual Channel Capability
> + 0x0003 = Device Serial Number Capability
> + 0x0004 = Power Budgeting Capability
> +
> + @param[in] Segment - Pci Segment Number
> + @param[in] Bus - Pci Bus Number
> + @param[in] Device - Pci Device Number
> + @param[in] Function - Pci Function Number
> + @param[in] CapId - Extended CAPID to search for
> +
> + @retval 0 - CAPID not found
> + @retval Other - CAPID found, Offset of desired CAPID
> +**/
> +UINT32
> +PcieFindExtendedCapId (
> + IN UINT8 Segment,
> + IN UINT8 Bus,
> + IN UINT8 Device,
> + IN UINT8 Function,
> + IN UINT16 CapId
> + )
> +{
> + UINT64 DeviceBaseAddress;
> + UINT16 CapHeaderOffset;
> + UINT16 CapHeaderId;
> +
> + ///
> + /// Start to search at Offset 0x100
> + /// Get Capability Header
> + ///
> + DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device,
> Function, 0);
> + CapHeaderId = 0;
> + CapHeaderOffset = 0x100;
> +
> + while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
> + ///
> + /// Search for desired CapID
> + ///
> + CapHeaderId = PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffset);
> + if (CapHeaderId == CapId) {
> + return CapHeaderOffset;
> + }
> +
> + CapHeaderOffset = (PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffset + 2) >> 4);
> + }
> +
> + return 0;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
> new file mode 100644
> index 0000000000..1dc37334ae
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
> @@ -0,0 +1,171 @@
> +/** @file
> + This file will perform SA PCIE Root Complex initialization.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PciExpressInit.h"
> +#include <Private/Library/SaPcieLib.h>
> +#include "PcieComplex.h"
> +#include <Private/Protocol/SaIotrapSmi.h>
> +#include "SaInit.h"
> +
> +///
> +/// Global variables
> +///
> +UINT16 mSaIotrapSmiAddress;
> +extern SA_CONFIG_HOB *mSaConfigHob;
> +
> +///
> +/// Functions
> +///
> +/**
> + This function gets registered as a callback to perform all SA late
> initialization
> +
> + @param[in] Event - A pointer to the Event that triggered the callback.
> + @param[in] Context - A pointer to private data registered with the
> callback function.
> +**/
> +VOID
> +EFIAPI
> +SaLateInitSmiCallback (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + EFI_STATUS Status;
> + SA_IOTRAP_SMI_PROTOCOL *SaIotrapSmiProtocol;
> +
> + if (mSaIotrapSmiAddress == 0) {
> + //
> + // Use global variable instead of protocol data since it maybe tampered in
> unsecure environment
> + // Get IOTrap address when first time this routine calling
> (gEfiPciEnumerationCompleteProtocolGuid callback)
> + //
> + SaIotrapSmiProtocol = NULL;
> + Status = gBS->LocateProtocol (&gSaIotrapSmiProtocolGuid, NULL, (VOID **)
> &SaIotrapSmiProtocol);
> + ASSERT_EFI_ERROR (Status);
> + if (SaIotrapSmiProtocol != NULL) {
> + mSaIotrapSmiAddress = SaIotrapSmiProtocol->SaIotrapSmiAddress;
> + }
> + }
> +
> + ASSERT (mSaIotrapSmiAddress != 0);
> + if (mSaIotrapSmiAddress != 0) {
> + //
> + // Generate IOTRAP SMI immediately
> + //
> + DEBUG ((DEBUG_INFO, "[SA] Issue IOTRAP SMI %X\n",
> mSaIotrapSmiAddress));
> + IoWrite8 (mSaIotrapSmiAddress, 0);
> + }
> + if (Event != NULL) {
> + gBS->CloseEvent (Event);
> + }
> + return;
> +}
> +
> +/**
> + This function performs Peg initialization before EndOfDxe.
> + @note This function will be executed as
> gEfiPciEnumerationCompleteProtocolGuid protocol callback and assumed SA
> DXE/SMM drivers have been dispatched.
> +
> + @retval EFI_SUCCESS - Always.
> +**/
> +EFI_STATUS
> +PegInitBeforeEndOfDxe (
> + VOID
> + )
> +{
> + EFI_EVENT ReadyToBoot;
> + EFI_STATUS Status;
> + BOOLEAN AspmHasBeenHandled;
> +
> + DEBUG ((DEBUG_INFO, "[SA] Pcie before EndOfDxe callback.\n"));
> + AspmHasBeenHandled = FALSE;
> + ///
> + /// SMM mode ASPM handling
> + /// Check if supported and enabled
> + ///
> + if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom
> == TRUE)) {
> + ///
> + /// Do the Phase 1 SMI callback
> + /// This will enumerate PCIe downstream devices
> + ///
> + SaLateInitSmiCallback (NULL, NULL);
> +
> + if (mSaIotrapSmiAddress != 0) {
> + ///
> + /// Create an ReadyToBoot call back event to do the Phase 3 SMI callback
> + /// This will handle PEG ASPM programming after OROM execution
> + /// Note: Phase 2 SMI callback will be triggered in EndOfDxe callback
> + /// to initialize rest of PCIe settings prior to OPROM
> + ///
> + Status = EfiCreateEventReadyToBootEx (
> + TPL_NOTIFY,
> + (EFI_EVENT_NOTIFY) SaLateInitSmiCallback,
> + NULL,
> + &ReadyToBoot
> + );
> + ASSERT_EFI_ERROR (Status);
> + AspmHasBeenHandled = TRUE;
> + }
> + }
> +
> + ///
> + /// DXE mode ASPM handling
> + /// Check if SMM mode already taken care all things
> + /// TRUE to skip DXE mode task. Otherwise do DXE mode ASPM initialization
> + ///
> + if (AspmHasBeenHandled == FALSE) {
> +
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This function performs SA registers Saving/Restoring in EndOfDxe callback
> +
> + @retval EFI_SUCCESS - Save/restore has done
> + @retval EFI_UNSUPPORTED - Save/restore not done successfully
> +**/
> +EFI_STATUS
> +SaSaveRestore (
> + VOID
> + )
> +{
> + BOOLEAN SaveRestoreHasBeenHandled;
> + UINT8 SmiData;
> +
> + SaveRestoreHasBeenHandled = FALSE;
> +
> + if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom
> == TRUE)) {
> + ///
> + /// Generate the Phase 2 of SA SMI to do SA chipset save/restore and
> security lock
> + ///
> + SaLateInitSmiCallback (NULL, NULL);
> +
> + if (mSaIotrapSmiAddress != 0) {
> + ///
> + /// Store IOTRAP SMI address into Boot Script save table
> + /// This is required to trigger this IOTRAP during S3 resume to restore all
> settings
> + ///
> + SmiData = 0;
> + S3BootScriptSaveIoWrite (
> + S3BootScriptWidthUint8,
> + (UINTN) mSaIotrapSmiAddress,
> + 1,
> + &SmiData
> + );
> + SaveRestoreHasBeenHandled = TRUE;
> + }
> + }
> +
> + ///
> + /// Check if SMM mode already taken care this task
> + ///
> + if (SaveRestoreHasBeenHandled == TRUE) {
> + return EFI_SUCCESS;
> + } else {
> + return EFI_UNSUPPORTED;
> + }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
> new file mode 100644
> index 0000000000..d5a63785b4
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
> @@ -0,0 +1,496 @@
> +/** @file
> + This is the driver that initializes the Intel System Agent.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaInitDxe.h"
> +#include "SaInit.h"
> +#include <Private/SaConfigHob.h>
> +#include <Private/Protocol/SaNvsArea.h>
> +#include <Library/PchInfoLib.h>
> +
> +///
> +/// Global Variables
> +///
> +GLOBAL_REMOVE_IF_UNREFERENCED
> SYSTEM_AGENT_NVS_AREA_PROTOCOL mSaNvsAreaProtocol;
> +GLOBAL_REMOVE_IF_UNREFERENCED SA_POLICY_PROTOCOL
> *mSaPolicy;
> +extern SA_CONFIG_HOB *mSaConfigHob;
> +
> +/**
> + Initialize System Agent SSDT ACPI tables
> +
> + @retval EFI_SUCCESS ACPI tables are initialized successfully
> + @retval EFI_NOT_FOUND ACPI tables not found
> +**/
> +EFI_STATUS
> +InitializeSaSsdtAcpiTables (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + EFI_HANDLE *HandleBuffer;
> + UINTN NumberOfHandles;
> + EFI_FV_FILETYPE FileType;
> + UINT32 FvStatus;
> + EFI_FV_FILE_ATTRIBUTES Attributes;
> + UINTN Size;
> + UINTN i;
> + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
> + INTN Instance;
> + EFI_ACPI_COMMON_HEADER *CurrentTable;
> + UINTN AcpiTableKey;
> + UINT8 *CurrPtr;
> + UINT8 *EndPtr;
> + UINT32 *Signature;
> + EFI_ACPI_DESCRIPTION_HEADER *SaAcpiTable;
> + EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
> +
> + FwVol = NULL;
> + SaAcpiTable = NULL;
> +
> + ///
> + /// Locate ACPI Table protocol
> + ///
> + DEBUG ((DEBUG_INFO, "Init SA SSDT table\n"));
> + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)
> &AcpiTable);
> + if (Status != EFI_SUCCESS) {
> + DEBUG ((DEBUG_WARN, "Fail to locate EfiAcpiTableProtocol.\n"));
> + return EFI_NOT_FOUND;
> + }
> +
> + ///
> + /// Locate protocol.
> + /// There is little chance we can't find an FV protocol
> + ///
> + Status = gBS->LocateHandleBuffer (
> + ByProtocol,
> + &gEfiFirmwareVolume2ProtocolGuid,
> + NULL,
> + &NumberOfHandles,
> + &HandleBuffer
> + );
> + ASSERT_EFI_ERROR (Status);
> + ///
> + /// Looking for FV with ACPI storage file
> + ///
> + for (i = 0; i < NumberOfHandles; i++) {
> + ///
> + /// Get the protocol on this handle
> + /// This should not fail because of LocateHandleBuffer
> + ///
> + Status = gBS->HandleProtocol (
> + HandleBuffer[i],
> + &gEfiFirmwareVolume2ProtocolGuid,
> + (VOID **) &FwVol
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + ///
> + /// See if it has the ACPI storage file
> + ///
> + Size = 0;
> + FvStatus = 0;
> + Status = FwVol->ReadFile (
> + FwVol,
> + &gSaSsdtAcpiTableStorageGuid,
> + NULL,
> + &Size,
> + &FileType,
> + &Attributes,
> + &FvStatus
> + );
> +
> + ///
> + /// If we found it, then we are done
> + ///
> + if (Status == EFI_SUCCESS) {
> + break;
> + }
> + }
> + ///
> + /// Free any allocated buffers
> + ///
> + FreePool (HandleBuffer);
> +
> + ///
> + /// Sanity check that we found our data file
> + ///
> + ASSERT (FwVol != NULL);
> + if (FwVol == NULL) {
> + DEBUG ((DEBUG_INFO, "SA Global NVS table not found\n"));
> + return EFI_NOT_FOUND;
> + }
> + ///
> + /// Our exit status is determined by the success of the previous operations
> + /// If the protocol was found, Instance already points to it.
> + /// Read tables from the storage file.
> + ///
> + Instance = 0;
> + CurrentTable = NULL;
> + while (Status == EFI_SUCCESS) {
> + Status = FwVol->ReadSection (
> + FwVol,
> + &gSaSsdtAcpiTableStorageGuid,
> + EFI_SECTION_RAW,
> + Instance,
> + (VOID **) &CurrentTable,
> + &Size,
> + &FvStatus
> + );
> +
> + if (!EFI_ERROR (Status)) {
> + ///
> + /// Check the table ID to modify the table
> + ///
> + if (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->OemTableId ==
> SIGNATURE_64 ('S', 'a', 'S', 's', 'd', 't', ' ', 0)) {
> + SaAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
> + ///
> + /// Locate the SSDT package
> + ///
> + CurrPtr = (UINT8 *) SaAcpiTable;
> + EndPtr = CurrPtr + SaAcpiTable->Length;
> +
> + for (; CurrPtr <= EndPtr; CurrPtr++) {
> + Signature = (UINT32 *) (CurrPtr + 3);
> + if (*Signature == SIGNATURE_32 ('S', 'A', 'N', 'V')) {
> + ASSERT (*(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) ==
> 0xFFFF0000);
> + ASSERT (*(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof
> (UINT32) + 1) == 0xAA55);
> + ///
> + /// SA Global NVS Area address
> + ///
> + *(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) = (UINT32) (UINTN)
> mSaNvsAreaProtocol.Area;
> + ///
> + /// SA Global NVS Area size
> + ///
> + *(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) +
> 1) =
> + sizeof (SYSTEM_AGENT_NVS_AREA);
> +
> + AcpiTableKey = 0;
> + Status = AcpiTable->InstallAcpiTable (
> + AcpiTable,
> + SaAcpiTable,
> + SaAcpiTable->Length,
> + &AcpiTableKey
> + );
> + ASSERT_EFI_ERROR (Status);
> + return EFI_SUCCESS;
> + }
> + }
> + }
> + ///
> + /// Increment the instance
> + ///
> + Instance++;
> + CurrentTable = NULL;
> + }
> + }
> +
> + return Status;
> +
> +}
> +
> +/**
> + Install SSDT Table
> +
> + @retval EFI_SUCCESS - SSDT Table load successful.
> +**/
> +EFI_STATUS
> +InstallSsdtAcpiTable (
> + IN GUID SsdtTableGuid,
> + IN UINT64 Signature
> + )
> +{
> + EFI_STATUS Status;
> + EFI_HANDLE *HandleBuffer;
> + BOOLEAN LoadTable;
> + UINTN NumberOfHandles;
> + UINTN Index;
> + INTN Instance;
> + UINTN Size;
> + UINT32 FvStatus;
> + UINTN TableHandle;
> + EFI_FV_FILETYPE FileType;
> + EFI_FV_FILE_ATTRIBUTES Attributes;
> + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
> + EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
> + EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
> + EFI_ACPI_COMMON_HEADER *Table;
> +
> + FwVol = NULL;
> + Table = NULL;
> +
> + DEBUG ((DEBUG_INFO, "Loading SSDT Table GUID: %g\n", SsdtTableGuid));
> +
> + ///
> + /// Locate FV protocol.
> + ///
> + Status = gBS->LocateHandleBuffer (
> + ByProtocol,
> + &gEfiFirmwareVolume2ProtocolGuid,
> + NULL,
> + &NumberOfHandles,
> + &HandleBuffer
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + ///
> + /// Look for FV with ACPI storage file
> + ///
> + for (Index = 0; Index < NumberOfHandles; Index++) {
> + ///
> + /// Get the protocol on this handle
> + /// This should not fail because of LocateHandleBuffer
> + ///
> + Status = gBS->HandleProtocol (
> + HandleBuffer[Index],
> + &gEfiFirmwareVolume2ProtocolGuid,
> + (VOID **) &FwVol
> + );
> + ASSERT_EFI_ERROR (Status);
> + if (FwVol == NULL) {
> + return EFI_NOT_FOUND;
> + }
> + ///
> + /// See if it has the ACPI storage file
> + ///
> + Size = 0;
> + FvStatus = 0;
> + Status = FwVol->ReadFile (
> + FwVol,
> + &SsdtTableGuid,
> + NULL,
> + &Size,
> + &FileType,
> + &Attributes,
> + &FvStatus
> + );
> +
> + ///
> + /// If we found it, then we are done
> + ///
> + if (!EFI_ERROR (Status)) {
> + break;
> + }
> + }
> + ///
> + /// Our exit status is determined by the success of the previous operations
> + /// If the protocol was found, Instance already points to it.
> + ///
> + ///
> + /// Free any allocated buffers
> + ///
> + FreePool (HandleBuffer);
> +
> + ///
> + /// Sanity check that we found our data file
> + ///
> + ASSERT (FwVol);
> +
> + ///
> + /// Locate ACPI tables
> + ///
> + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)
> &AcpiTable);
> +
> + ///
> + /// Read tables from the storage file.
> + ///
> + if (FwVol == NULL) {
> + ASSERT_EFI_ERROR (EFI_NOT_FOUND);
> + return EFI_NOT_FOUND;
> + }
> + Instance = 0;
> +
> + while (Status == EFI_SUCCESS) {
> + ///
> + /// Read the ACPI tables
> + ///
> + Status = FwVol->ReadSection (
> + FwVol,
> + &SsdtTableGuid,
> + EFI_SECTION_RAW,
> + Instance,
> + (VOID **) &Table,
> + &Size,
> + &FvStatus
> + );
> + if (!EFI_ERROR (Status)) {
> + ///
> + /// check and load SwitchableGraphics SSDT table
> + ///
> + LoadTable = FALSE;
> + TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
> +
> + if (((EFI_ACPI_DESCRIPTION_HEADER *) TableHeader)->OemTableId ==
> Signature) {
> + ///
> + /// This is the SSDT table that match the Signature
> + ///
> + DEBUG ((DEBUG_INFO, "Found out SSDT Table GUID: %g\n",
> SsdtTableGuid));
> + LoadTable = TRUE;
> + }
> +
> + ///
> + /// Add the table
> + ///
> + if (LoadTable) {
> + TableHandle = 0;
> + Status = AcpiTable->InstallAcpiTable (
> + AcpiTable,
> + TableHeader,
> + TableHeader->Length,
> + &TableHandle
> + );
> + }
> + ///
> + /// Increment the instance
> + ///
> + Instance++;
> + Table = NULL;
> + }
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This function gets registered as a callback to perform Dmar Igd
> +
> + @param[in] Event - A pointer to the Event that triggered the callback.
> + @param[in] Context - A pointer to private data registered with the
> callback function.
> +**/
> +VOID
> +EFIAPI
> +SaAcpiEndOfDxeCallback (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + EFI_STATUS Status;
> +
> + if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 0xFFFF) {
> + Status = PostPmInitEndOfDxe ();
> + if (EFI_SUCCESS != Status) {
> + DEBUG ((DEBUG_WARN, "[SA] EndOfDxe GraphicsInit Error, Status = %r
> \n", Status));
> + ASSERT_EFI_ERROR (Status);
> + }
> + }
> +
> + if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 0xFFFF) {
> + Status = GetVBiosVbtEndOfDxe ();
> + if (EFI_SUCCESS != Status) {
> + DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Op Region Error, Status = %r \n",
> Status));
> + }
> +
> + Status = UpdateIgdOpRegionEndOfDxe ();
> + if (EFI_SUCCESS != Status) {
> + DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Update Op Region Error, Status
> = %r \n", Status));
> + }
> + }
> +
> + return;
> +}
> +
> +/**
> + SystemAgent Acpi Initialization.
> +
> + @param[in] ImageHandle Handle for the image of this driver
> +
> + @retval EFI_SUCCESS The function completed successfully
> + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
> +**/
> +EFI_STATUS
> +EFIAPI
> +SaAcpiInit (
> + IN EFI_HANDLE ImageHandle
> + )
> +{
> + EFI_STATUS Status;
> + EFI_CPUID_REGISTER CpuidRegs;
> + CPU_FAMILY CpuFamilyId;
> + EFI_EVENT EndOfDxeEvent;
> +
> + CpuFamilyId = GetCpuFamily();
> + AsmCpuid (1, &CpuidRegs.RegEax, 0, 0, 0);
> + ///
> + /// Get the platform setup policy.
> + ///
> + Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **)
> &mSaPolicy);
> + ASSERT_EFI_ERROR (Status);
> +
> + ///
> + /// Install System Agent Global NVS protocol
> + ///
> + DEBUG ((DEBUG_INFO, "Install SA GNVS protocol\n"));
> + Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof
> (SYSTEM_AGENT_NVS_AREA), (VOID **) &mSaNvsAreaProtocol.Area);
> + ASSERT_EFI_ERROR (Status);
> + ZeroMem ((VOID *) mSaNvsAreaProtocol.Area, sizeof
> (SYSTEM_AGENT_NVS_AREA));
> + mSaNvsAreaProtocol.Area->XPcieCfgBaseAddress = (UINT32) (PcdGet64
> (PcdPciExpressBaseAddress));
> + mSaNvsAreaProtocol.Area->CpuIdInfo = CpuidRegs.RegEax;
> + if (mSaConfigHob != NULL) {
> + mSaNvsAreaProtocol.Area->IpuAcpiMode =
> mSaConfigHob->IpuAcpiMode;
> + }
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &ImageHandle,
> + &gSaNvsAreaProtocolGuid,
> + &mSaNvsAreaProtocol,
> + NULL
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + ///
> + /// PciExpress Dxe Initialization
> + ///
> + DEBUG ((DEBUG_INFO, "Initializing PciExpress (Dxe)\n"));
> + PciExpressInit (mSaPolicy);
> +
> + ///
> + /// GtPostInit Initialization
> + ///
> + DEBUG ((DEBUG_INFO, "Initializing GT ACPI tables\n"));
> +
> + GraphicsInit (ImageHandle, mSaPolicy);
> +
> + /// Vtd Initialization
> + ///
> + DEBUG ((DEBUG_INFO, "Initializing VT-d ACPI tables\n"));
> + VtdInit (mSaPolicy);
> +
> + ///
> + /// IgdOpRegion Install Initialization
> + ///
> + DEBUG ((DEBUG_INFO, "Initializing IGD OpRegion\n"));
> + IgdOpRegionInit ();
> +
> + ///
> + /// Register an end of DXE event for SA ACPI to do tasks before invoking any
> UEFI drivers,
> + /// applications, or connecting consoles,...
> + ///
> + Status = gBS->CreateEventEx (
> + EVT_NOTIFY_SIGNAL,
> + TPL_CALLBACK,
> + SaAcpiEndOfDxeCallback,
> + NULL,
> + &gEfiEndOfDxeEventGroupGuid,
> + &EndOfDxeEvent
> + );
> +
> + ///
> + /// Install System Agent Global NVS ACPI table
> + ///
> + Status = InitializeSaSsdtAcpiTables ();
> +
> + ///
> + /// Install PEG SSDT table only if PEG port is present
> + ///
> + if (IsPchLinkDmi (CpuFamilyId)) {
> + if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, SA_PEG0_FUN_NUM,
> R_SA_PEG_DID_OFFSET)) != V_SA_DEVICE_ID_INVALID) {
> + Status = InstallSsdtAcpiTable (gPegSsdtAcpiTableStorageGuid,
> SIGNATURE_64 ('P','e','g','S','s','d','t',0));
> + ASSERT_EFI_ERROR (Status);
> + }
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
> new file mode 100644
> index 0000000000..40bb107ad0
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
> @@ -0,0 +1,179 @@
> +/** @file
> + This is the Common driver that initializes the Intel System Agent.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaInit.h"
> +#include <Library/PciSegmentLib.h>
> +#include <Private/SaConfigHob.h>
> +#include <Protocol/PciEnumerationComplete.h>
> +
> +//
> +// Declare I/O Ports used to perform PCI Confguration Cycles
> +//
> +#define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8
> +#define PCI_CONFIGURATION_DATA_PORT 0xCFC
> +
> +/**
> + Convert a PCI Library address to PCI CF8 formatted address.
> +
> + Declare macro to convert PCI Library address to PCI CF8 formatted address.
> + Bit fields of PCI Library and CF8 formatted address is as follows:
> + PCI Library formatted address CF8 Formatted Address
> + ============================= ======================
> + Bits 00..11 Register Bits 00..07 Register
> + Bits 12..14 Function Bits 08..10 Function
> + Bits 15..19 Device Bits 11..15 Device
> + Bits 20..27 Bus Bits 16..23 Bus
> + Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)
> + Bits 31..31 Must be 1
> +
> + @param A The address to convert.
> +
> + @retval The coverted address.
> +
> +**/
> +#define PCI_TO_CF8_ADDRESS(A) \
> + ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
> +
> +///
> +/// Global Variables
> +///
> +GLOBAL_REMOVE_IF_UNREFERENCED SA_CONFIG_HOB
> *mSaConfigHob;
> +BOOLEAN mSkipPamLock =
> FALSE;
> +
> +/*
> + Intel(R) Core Processor Skylake BWG version 0.4.0
> +
> + 18.6 System Agent Configuration Locking
> + For reliable operation and security, System BIOS must set the following bits:
> + 1. For all modern Intel processors, Intel strongly recommends that BIOS
> should set
> + the D_LCK bit. Set B0:D0:F0.R088h [4] = 1b to lock down SMRAM space.
> + BaseAddr values for mSaSecurityRegisters that uses PciExpressBaseAddress
> will be initialized at
> + Runtime inside function SaPcieInitPolicy().
> +*/
> +GLOBAL_REMOVE_IF_UNREFERENCED BOOT_SCRIPT_REGISTER_SETTING
> mSaSecurityRegisters[] = {
> + {0, R_SA_SMRAMC, 0xFFFFFFFF, BIT4}
> +};
> +
> +/**
> + SystemAgent Initialization Common Function.
> +
> + @retval EFI_SUCCESS - Always.
> +**/
> +
> +VOID
> +SaInitEntryPoint (
> + VOID
> + )
> +{
> + ///
> + /// Get SaConfigHob HOB
> + ///
> + mSaConfigHob = NULL;
> + mSaConfigHob = (SA_CONFIG_HOB *) GetFirstGuidHob
> (&gSaConfigHobGuid);
> + if (mSaConfigHob != NULL) {
> + mSkipPamLock = mSaConfigHob->SkipPamLock;
> + }
> +
> + return;
> +}
> +
> +
> +
> +/**
> + Common function locks the PAM register as part of the SA Security
> requirements.
> +
> + @retval EFI_SUCCESS - Always.
> +**/
> +
> +VOID
> +SaPamLock (
> + VOID
> + )
> +{
> + UINT64 BaseAddress;
> + UINT32 Data32Or;
> +
> + if (mSkipPamLock == FALSE) {
> + //
> + // Lock PAM by PAM Lock Bit
> + //
> + BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, 0, 0, 0);
> + Data32Or = BIT0;
> + DEBUG ((DEBUG_INFO, "PAM_LOCK!!\n"));
> + PciSegmentOr32 (BaseAddress + R_SA_PAM0, Data32Or);
> + }
> +}
> +
> +/**
> + This function does SA security lock
> +**/
> +VOID
> +SaSecurityLock (
> + VOID
> + )
> +{
> + UINT8 Index;
> + UINT32 RegOffset;
> + UINT32 Data32Or;
> + UINT32 Data32;
> + UINT8 Data8;
> +
> + ///
> + /// 17.2 System Agent Security Lock configuration
> + ///
> + DEBUG ((DEBUG_INFO, "DXE SaSecurityLock\n"));
> + for (Index = 0; Index < (sizeof (mSaSecurityRegisters) / sizeof
> (BOOT_SCRIPT_REGISTER_SETTING)); Index++) {
> + RegOffset = mSaSecurityRegisters[Index].Offset;
> + Data32Or = mSaSecurityRegisters[Index].OrMask;
> +
> + if (RegOffset == R_SA_SMRAMC) {
> + ///
> + /// SMRAMC LOCK must use CF8/CFC access
> + ///
> + PciCf8Or8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV,
> SA_MC_FUN, R_SA_SMRAMC), (UINT8) Data32Or);
> + Data8 = PciCf8Read8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV,
> SA_MC_FUN, R_SA_SMRAMC));
> + Data32 = PCI_TO_CF8_ADDRESS (PCI_CF8_LIB_ADDRESS (SA_MC_BUS,
> SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC));
> + S3BootScriptSaveIoWrite (
> + S3BootScriptWidthUint32,
> + (UINTN) (PCI_CONFIGURATION_ADDRESS_PORT),
> + 1,
> + &Data32
> + );
> + S3BootScriptSaveIoWrite (
> + S3BootScriptWidthUint8,
> + (UINTN) (PCI_CONFIGURATION_DATA_PORT),
> + 1,
> + &Data8
> + );
> + }
> + }
> +}
> +
> +/**
> + This function performs SA Security locking in EndOfDxe callback
> +
> + @retval EFI_SUCCESS - Security lock has done
> + @retval EFI_UNSUPPORTED - Security lock not done successfully
> +**/
> +EFI_STATUS
> +SaSecurityInit (
> + VOID
> + )
> +{
> +
> + UINT8 Index;
> +
> + for (Index = 0; Index < (sizeof (mSaSecurityRegisters) / sizeof
> (BOOT_SCRIPT_REGISTER_SETTING)); Index++) {
> + if (mSaSecurityRegisters[Index].BaseAddr != PcdGet64
> (PcdMchBaseAddress)) {
> + mSaSecurityRegisters[Index].BaseAddr = PcdGet64
> (PcdPciExpressBaseAddress);
> + }
> + }
> + SaSecurityLock ();
> +
> + return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
> new file mode 100644
> index 0000000000..d646e60618
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
> @@ -0,0 +1,122 @@
> +/** @file
> + This is the driver that initializes the Intel System Agent.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaInitDxe.h"
> +#include "SaInit.h"
> +#include <Private/SaConfigHob.h>
> +#include <Protocol/PciEnumerationComplete.h>
> +#include <MemInfoHob.h>
> +
> +///
> +/// Global Variables
> +///
> +extern SA_CONFIG_HOB *mSaConfigHob;
> +
> +/**
> + SystemAgent Dxe Initialization.
> +
> + @param[in] ImageHandle Handle for the image of this driver
> + @param[in] SystemTable Pointer to the EFI System Table
> +
> + @retval EFI_SUCCESS The function completed successfully
> + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
> +**/
> +EFI_STATUS
> +EFIAPI
> +SaInitEntryPointDxe (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> + VOID *Registration;
> +
> + DEBUG ((DEBUG_INFO, "SaInitDxe Start\n"));
> +
> + SaInitEntryPoint ();
> +
> + Status = SaAcpiInit (ImageHandle);
> +
> + ///
> + /// Create PCI Enumeration Completed callback for SA
> + ///
> + EfiCreateProtocolNotifyEvent (
> + &gEfiPciEnumerationCompleteProtocolGuid,
> + TPL_CALLBACK,
> + SaPciEnumCompleteCallback,
> + NULL,
> + &Registration
> + );
> +
> + DEBUG ((DEBUG_INFO, "SaInitDxe End\n"));
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This function gets registered as a callback to perform SA initialization before
> EndOfDxe
> +
> + @param[in] Event - A pointer to the Event that triggered the callback.
> + @param[in] Context - A pointer to private data registered with the
> callback function.
> +**/
> +VOID
> +EFIAPI
> +SaPciEnumCompleteCallback (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + EFI_STATUS Status;
> + VOID *ProtocolPointer;
> +
> + DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback Start\n"));
> + ///
> + /// Check if this is first time called by EfiCreateProtocolNotifyEvent() or not,
> + /// if it is, we will skip it until real event is triggered
> + ///
> + Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid,
> NULL, (VOID **) &ProtocolPointer);
> + if (EFI_SUCCESS != Status) {
> + return;
> + }
> +
> + gBS->CloseEvent (Event);
> +
> + Status = PegInitBeforeEndOfDxe ();
> + if (EFI_SUCCESS != Status) {
> + DEBUG ((DEBUG_WARN, "[SA] Pcie initialization before EndOfDxe Error,
> Status = %r \n", Status));
> + ASSERT_EFI_ERROR (Status);
> + }
> +
> + SaSaveRestore ();
> + SaSecurityInit ();
> + UpdateDmarPciEnumCompleteCallback ();
> +
> + DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback End\n"));
> + return;
> +}
> +
> +/**
> + This function locks the PAM register as part of the SA Security requirements.
> +
> + @param[in] Event - A pointer to the Event that triggered the callback.
> + @param[in] Context - A pointer to private data registered with the
> callback function.
> +
> +**/
> +VOID
> +EFIAPI
> +SaPamLockDxe (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + DEBUG ((DEBUG_INFO, "SaPamLockDxe Start\n"));
> +
> + SaPamLock ();
> +
> + DEBUG ((DEBUG_INFO, "SaPamLockDxe End\n"));
> +}
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
> new file mode 100644
> index 0000000000..acbf6b7aab
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
> @@ -0,0 +1,717 @@
> +/** @file
> + This code provides a initialization of intel VT-d (Virtualization Technology
> for Directed I/O).
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaInitDxe.h"
> +#include "SaInit.h"
> +#include "VTd.h"
> +#include <CpuRegs.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PchSerialIoLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <PchInfoHob.h>
> +#include <PchAccess.h>
> +
> +
> +extern SA_CONFIG_HOB *mSaConfigHob;
> +
> +/**
> + For device that specified by Device Num and Function Num,
> + mDevEnMap is used to check device presence.
> + 0x80 means use Device ID to detemine presence
> + 0x8F means force to update
> +
> + The structure is used to check if device scope is valid when update DMAR
> table
> +**/
> +UINT16 mDevEnMap[][2] = {{0x0200, 0x80}, {0x1400, 0x80}, {0x1401, 0x80},
> {0x1607, 0x8F}};
> +
> +BOOLEAN mInterruptRemappingSupport;
> +
> +/**
> + Get the corresponding device Enable/Disable bit according DevNum and
> FunNum
> +
> + @param[in] DevNum - Device Number
> + @param[in] FunNum - Function Number
> +
> + @retval If the device is found, return disable/Enable bit in FD/Deven
> reigster
> + @retval If not found return 0xFF
> +**/
> +UINT16
> +GetFunDisableBit (
> + UINT8 DevNum,
> + UINT8 FunNum
> + )
> +{
> + UINTN Index;
> +
> + for (Index = 0; Index < sizeof (mDevEnMap) / 4; Index++) {
> + if (mDevEnMap[Index][0] == ((DevNum << 0x08) | FunNum)) {
> + return mDevEnMap[Index][1];
> + }
> + }
> +
> + return 0xFF;
> +}
> +
> +/**
> + Update the DRHD structure
> +
> + @param[in, out] DrhdEnginePtr - A pointer to DRHD structure
> +**/
> +VOID
> +UpdateDrhd (
> + IN OUT VOID *DrhdEnginePtr
> + )
> +{
> + UINT16 Length;
> + UINT16 DisableBit;
> + BOOLEAN NeedRemove;
> + EFI_ACPI_DRHD_ENGINE1_STRUCT *DrhdEngine;
> +
> + //
> + // Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE1_STRUCT Pointer
> + //
> + DrhdEngine = (EFI_ACPI_DRHD_ENGINE1_STRUCT *) DrhdEnginePtr;
> + Length = DrhdEngine->DrhdHeader.Header.Length;
> + DisableBit = GetFunDisableBit (
> + DrhdEngine->DeviceScope[0].PciPath.Device,
> + DrhdEngine->DeviceScope[0].PciPath.Function
> + );
> + NeedRemove = FALSE;
> +
> + if ((DisableBit == 0xFF) ||
> + (DrhdEngine->DrhdHeader.RegisterBaseAddress == 0) ||
> + ((DisableBit == 0x80) &&
> + (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0,
> DrhdEngine->DeviceScope[0].PciPath.Device,
> DrhdEngine->DeviceScope[0].PciPath.Function, 0x00)) == 0xFFFFFFFF))
> + ) {
> + NeedRemove = TRUE;
> + }
> + if (NeedRemove) {
> + Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> + }
> + ///
> + /// If no devicescope is left, we set the structure length as 0x00
> + ///
> + if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) ||
> (DrhdEngine->DrhdHeader.Flags == 0x01)) {
> + DrhdEngine->DrhdHeader.Header.Length = Length;
> + } else {
> + DrhdEngine->DrhdHeader.Header.Length = 0;
> + }
> +}
> +
> +/**
> + Get IOAPIC ID from LPC
> +
> + @retval APIC ID
> +**/
> +UINT8
> +GetIoApicId (
> + VOID
> + )
> +{
> + UINT32 IoApicAddress;
> + UINT32 IoApicId;
> +
> + IoApicAddress = PcdGet32 (PcdIoApicBaseAddress);
> + ///
> + /// Get current IO APIC ID
> + ///
> + MmioWrite8 ((UINTN) (IoApicAddress + R_IO_APIC_INDEX_OFFSET), 0);
> + IoApicId = MmioRead32 ((UINTN) (IoApicAddress +
> R_IO_APIC_DATA_OFFSET)) >> 24;
> +
> + return (UINT8) IoApicId;
> +}
> +
> +/**
> + Update the second DRHD structure
> +
> + @param[in, out] DrhdEnginePtr - A pointer to DRHD structure
> +**/
> +VOID
> +UpdateDrhd2 (
> + IN OUT VOID *DrhdEnginePtr
> + )
> +{
> + UINT16 Length;
> + UINTN DeviceScopeNum;
> + UINTN ValidDeviceScopeNum;
> + UINT16 Index;
> + UINT8 Bus;
> + UINT8 Path[2];
> + BOOLEAN NeedRemove;
> + EFI_ACPI_DRHD_ENGINE3_STRUCT *DrhdEngine;
> + VOID *HobPtr;
> + PCH_INFO_HOB *PchInfoHob;
> +
> + ///
> + /// Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE3_STRUCT Pointer
> + ///
> + DrhdEngine = (EFI_ACPI_DRHD_ENGINE3_STRUCT *) DrhdEnginePtr;
> +
> + Length = DrhdEngine->DrhdHeader.Header.Length;
> + DeviceScopeNum = (DrhdEngine->DrhdHeader.Header.Length -
> EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) / sizeof
> (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> + Bus = 0;
> + ValidDeviceScopeNum = 0;
> + Path[0] = 0;
> + Path[1] = 0;
> +
> + HobPtr = GetFirstGuidHob (&gPchInfoHobGuid);
> + ASSERT (HobPtr != NULL);
> + if (HobPtr == NULL) {
> + return;
> + }
> + PchInfoHob = (PCH_INFO_HOB *) GET_GUID_HOB_DATA (HobPtr);
> + ASSERT (PchInfoHob != NULL);
> + if (PchInfoHob == NULL) {
> + return;
> + }
> +
> + for (Index = 0; Index < DeviceScopeNum; Index++) {
> + NeedRemove = FALSE;
> + /**
> + For HPET and APIC, update device scope if Interrupt remapping is
> supported. remove device scope
> + if interrupt remapping is not supported.
> + - Index = 0 - IOAPIC
> + - Index = 1 - HPET
> + **/
> + if (mInterruptRemappingSupport) {
> + if (Index == 0) {
> + ///
> + /// Update source id for IoApic's device scope entry
> + ///
> + Bus = (UINT8) PchInfoHob->IoApicBusNum;
> + Path[0] = (UINT8) PchInfoHob->IoApicDevNum;
> + Path[1] = (UINT8) PchInfoHob->IoApicFuncNum;
> +
> DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNum
> ber = Bus;
> + DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
> + DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
> + //
> + // Update APIC ID
> + //
> +
> DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.EnumerationI
> d = GetIoApicId ();
> + }
> + if (Index == 1) {
> + ///
> + /// Update source id for HPET's device scope entry
> + ///
> + Bus = (UINT8) PchInfoHob->HpetBusNum;
> + Path[0] = (UINT8) PchInfoHob->HpetDevNum;
> + Path[1] = (UINT8) PchInfoHob->HpetFuncNum;
> +
> DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNum
> ber = Bus;
> + DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
> + DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
> + }
> + } else {
> + if ((Index == 0) || (Index == 1)) {
> + NeedRemove = TRUE;
> + }
> + }
> +
> + CopyMem (
> + &DrhdEngine->DeviceScope[ValidDeviceScopeNum],
> + &DrhdEngine->DeviceScope[Index],
> + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
> + );
> + if (NeedRemove) {
> + Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> + } else {
> + ValidDeviceScopeNum++;
> + }
> + }
> + ///
> + /// If no devicescope is left, we set the structure length as 0x00
> + ///
> + if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) ||
> (DrhdEngine->DrhdHeader.Flags == 0x01)) {
> + DrhdEngine->DrhdHeader.Header.Length = Length;
> + } else {
> + DrhdEngine->DrhdHeader.Header.Length = 0;
> + }
> +}
> +
> +/**
> + Update the RMRR structure
> +
> + @param[in, out] RmrrPtr - A pointer to RMRR structure
> +**/
> +VOID
> +UpdateRmrr (
> + IN OUT VOID *RmrrPtr
> + )
> +{
> + UINT16 Length;
> + UINT16 DisableBit;
> + UINTN DeviceScopeNum;
> + UINTN ValidDeviceScopeNum;
> + UINTN Index;
> + BOOLEAN NeedRemove;
> + EFI_ACPI_RMRR_USB_STRUC *Rmrr;
> +
> + ///
> + /// To make sure all devicescope can be checked,
> + /// we convert the RmrrPtr to EFI_ACPI_RMRR_USB_STRUC pointer
> + ///
> + Rmrr = (EFI_ACPI_RMRR_USB_STRUC *) RmrrPtr;
> +
> + Length = Rmrr->RmrrHeader.Header.Length;
> + ValidDeviceScopeNum = 0;
> + DeviceScopeNum = (Rmrr->RmrrHeader.Header.Length -
> EFI_ACPI_RMRR_HEADER_LENGTH) / sizeof
> (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> + for (Index = 0; Index < DeviceScopeNum; Index++) {
> + DisableBit = GetFunDisableBit (
> + Rmrr->DeviceScope[Index].PciPath.Device,
> + Rmrr->DeviceScope[Index].PciPath.Function
> + );
> + NeedRemove = FALSE;
> + if ((DisableBit == 0xFF) ||
> + ((DisableBit == 0x80) &&
> + (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0,
> Rmrr->DeviceScope[Index].PciPath.Device,
> Rmrr->DeviceScope[Index].PciPath.Function, 0x00)) == 0xFFFFFFFF))
> + ) {
> + NeedRemove = TRUE;
> + } else if (DisableBit == 0x8F) {
> + NeedRemove = FALSE;
> + }
> + CopyMem (
> + &Rmrr->DeviceScope[ValidDeviceScopeNum],
> + &Rmrr->DeviceScope[Index],
> + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
> + );
> +
> + if (Rmrr->RmrrHeader.ReservedMemoryRegionLimitAddress == 0x0) {
> + NeedRemove = TRUE;
> + }
> +
> + if (NeedRemove) {
> + Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> + } else {
> + ValidDeviceScopeNum++;
> + }
> + }
> + ///
> + /// If No deviceScope is left, set length as 0x00
> + ///
> + if (Length > EFI_ACPI_RMRR_HEADER_LENGTH) {
> + Rmrr->RmrrHeader.Header.Length = Length;
> + } else {
> + Rmrr->RmrrHeader.Header.Length = 0;
> + }
> +}
> +
> +/**
> + Update the DMAR table
> +
> + @param[in, out] TableHeader - The table to be set
> + @param[in, out] Version - Version to publish
> +**/
> +VOID
> +DmarTableUpdate (
> + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader,
> + IN OUT EFI_ACPI_TABLE_VERSION *Version
> + )
> +{
> + EFI_ACPI_DMAR_TABLE *DmarTable;
> + EFI_ACPI_DMAR_TABLE TempDmarTable;
> + UINTN Offset;
> + UINTN StructureLen;
> + UINT64 McD0BaseAddress;
> + UINTN MchBar;
> + UINT16 IgdMode;
> + UINT16 GttMode;
> + UINT32 IgdMemSize;
> + UINT32 GttMemSize;
> + EFI_STATUS Status;
> + MISC_DXE_CONFIG *MiscDxeConfig;
> +
> + IgdMemSize = 0;
> + GttMemSize = 0;
> + DmarTable = (EFI_ACPI_DMAR_TABLE *) TableHeader;
> +
> + Status = GetConfigBlock ((VOID *) mSaPolicy, &gMiscDxeConfigGuid, (VOID
> *)&MiscDxeConfig);
> + ASSERT_EFI_ERROR (Status);
> +
> + ///
> + /// Set INTR_REMAP bit (BIT 0) if interrupt remapping is supported
> + ///
> + if (mInterruptRemappingSupport) {
> + DmarTable->DmarHeader.Flags |= BIT0;
> + }
> +
> + if (mSaConfigHob->VtdData.X2ApicOptOut == 1) {
> + DmarTable->DmarHeader.Flags |= BIT1;
> + } else {
> + DmarTable->DmarHeader.Flags &= 0xFD;
> + }
> +
> + ///
> + /// Get OemId
> + ///
> + CopyMem (DmarTable->DmarHeader.Header.OemId, PcdGetPtr
> (PcdAcpiDefaultOemId), sizeof (DmarTable->DmarHeader.Header.OemId));
> + DmarTable->DmarHeader.Header.OemTableId = PcdGet64
> (PcdAcpiDefaultOemTableId);
> + DmarTable->DmarHeader.Header.OemRevision = PcdGet32
> (PcdAcpiDefaultOemRevision);
> + DmarTable->DmarHeader.Header.CreatorId = PcdGet32
> (PcdAcpiDefaultCreatorId);
> + DmarTable->DmarHeader.Header.CreatorRevision = PcdGet32
> (PcdAcpiDefaultCreatorRevision);
> +
> + ///
> + /// Calculate IGD memsize
> + ///
> + McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 0, 0, 0);
> + MchBar = PciSegmentRead32 (McD0BaseAddress + R_SA_MCHBAR)
> & ~BIT0;
> + IgdMode = ((PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) &
> B_SA_GGC_GMS_MASK) >> N_SA_GGC_GMS_OFFSET) & 0xFF;
> + if (IgdMode < 0xF0) {
> + IgdMemSize = IgdMode * 32 * (1024) * (1024);
> + } else {
> + IgdMemSize = 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024);
> + }
> + ///
> + /// Calculate GTT mem size
> + ///
> + GttMemSize = 0;
> + GttMode = (PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) &
> B_SA_GGC_GGMS_MASK) >> N_SA_GGC_GGMS_OFFSET;
> + if (GttMode <= V_SA_GGC_GGMS_8MB) {
> + GttMemSize = (1 << GttMode) * (1024) * (1024);
> + }
> +
> + DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress =
> (PciSegmentRead32 (McD0BaseAddress + R_SA_TOLUD) & ~(0x01)) -
> IgdMemSize - GttMemSize;
> + DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress =
> DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress +
> IgdMemSize + GttMemSize - 1;
> + DEBUG ((DEBUG_INFO, "RMRR Base address IGD %016lX\n",
> DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress));
> + DEBUG ((DEBUG_INFO, "RMRR Limit address IGD %016lX\n",
> DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress));
> +
> + DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress
> = MiscDxeConfig->RmrrUsbBaseAddress[0];
> + DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress
> = MiscDxeConfig->RmrrUsbBaseAddress[1];
> +
> + ///
> + /// Convert to 4KB alignment.
> + ///
> + if
> (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress !=
> 0x0) {
> + DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress
> &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
> + DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress
> &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
> + DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress
> += 0x1000-1;
> + }
> +
> + DEBUG ((DEBUG_INFO, "RMRR Base address USB %016lX\n",
> DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress));
> + DEBUG ((DEBUG_INFO, "RMRR Limit address USB %016lX\n",
> DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress));
> +
> + if (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress
> == 0) {
> + DEBUG ((DEBUG_WARN, "WARNING:
> RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress is 0.\n"));
> + }
> +
> + DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress
> = MiscDxeConfig->RmrrCsmeBaseAddress[0];
> + DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress
> = MiscDxeConfig->RmrrCsmeBaseAddress[1];
> + DEBUG ((DEBUG_INFO, "RMRR Base address CSME %016lX\n",
> DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress));
> + DEBUG ((DEBUG_INFO, "RMRR Limit address CSME %016lX\n",
> DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress));
> + ///
> + /// Update DRHD structures of DmarTable
> + ///
> + DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress =
> (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
> + DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress =
> (MmioRead32 (MchBar + R_SA_MCHBAR_VTD3_OFFSET) &~1);
> +
> + DEBUG ((DEBUG_INFO, "VTD base address1 %x\n",
> DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress));
> + DEBUG ((DEBUG_INFO, "VTD base address3 %x\n",
> DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress));
> + ///
> + /// copy DmarTable to TempDmarTable to be processed
> + ///
> + CopyMem (&TempDmarTable, DmarTable, sizeof (EFI_ACPI_DMAR_TABLE));
> +
> + ///
> + /// Update DRHD structures of temp DMAR table
> + ///
> + UpdateDrhd (&TempDmarTable.DrhdEngine1);
> + UpdateDrhd2 (&TempDmarTable.DrhdEngine3);
> +
> + ///
> + /// Update RMRR structures of temp DMAR table
> + ///
> + UpdateRmrr ((VOID *) &TempDmarTable.RmrrUsb);
> + UpdateRmrr ((VOID *) &TempDmarTable.RmrrIgd);
> + UpdateRmrr ((VOID *) &TempDmarTable.RmrrCsme);
> +
> + ///
> + /// Remove unused device scope or entire DRHD structures
> + ///
> + Offset = (UINTN) (&TempDmarTable.DrhdEngine1);
> + if (TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length != 0) {
> + Offset += TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length;
> + }
> + if (TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length != 0) {
> + StructureLen = TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length;
> + CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.DrhdEngine3,
> TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length);
> + Offset += StructureLen;
> + }
> + ///
> + /// Remove unused device scope or entire RMRR structures
> + ///
> + if (TempDmarTable.RmrrUsb.RmrrHeader.Header.Length != 0) {
> + StructureLen = TempDmarTable.RmrrUsb.RmrrHeader.Header.Length;
> + CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrUsb,
> TempDmarTable.RmrrUsb.RmrrHeader.Header.Length);
> + Offset += StructureLen;
> + }
> + if (TempDmarTable.RmrrIgd.RmrrHeader.Header.Length != 0) {
> + StructureLen = TempDmarTable.RmrrIgd.RmrrHeader.Header.Length;
> + CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrIgd,
> TempDmarTable.RmrrIgd.RmrrHeader.Header.Length);
> + Offset += StructureLen;
> + }
> + if (TempDmarTable.RmrrCsme.RmrrHeader.Header.Length != 0) {
> + StructureLen = TempDmarTable.RmrrCsme.RmrrHeader.Header.Length;
> + CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrCsme,
> TempDmarTable.RmrrCsme.RmrrHeader.Header.Length);
> + Offset += StructureLen;
> + }
> +
> + Offset = Offset - (UINTN) &TempDmarTable;
> + ///
> + /// Re-calculate DMAR table check sum
> + ///
> + TempDmarTable.DmarHeader.Header.Checksum = (UINT8)
> (TempDmarTable.DmarHeader.Header.Checksum +
> TempDmarTable.DmarHeader.Header.Length - Offset);
> + ///
> + /// Set DMAR table length
> + ///
> + TempDmarTable.DmarHeader.Header.Length = (UINT32) Offset;
> + ///
> + /// Replace DMAR table with rebuilt table TempDmarTable
> + ///
> + CopyMem ((VOID *) DmarTable, (VOID *) &TempDmarTable,
> TempDmarTable.DmarHeader.Header.Length);
> +}
> +
> +/**
> + PciEnumerationComplete routine for update DMAR
> +**/
> +VOID
> +UpdateDmarPciEnumCompleteCallback (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + EFI_HANDLE *HandleBuffer;
> + UINTN NumberOfHandles;
> + EFI_FV_FILETYPE FileType;
> + UINT32 FvStatus;
> + EFI_FV_FILE_ATTRIBUTES Attributes;
> + UINTN Size;
> + UINTN i;
> + INTN Instance;
> + EFI_ACPI_TABLE_VERSION Version;
> + EFI_ACPI_COMMON_HEADER *CurrentTable;
> + UINTN AcpiTableHandle;
> + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
> + EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
> + EFI_ACPI_DESCRIPTION_HEADER *VtdAcpiTable;
> + STATIC BOOLEAN Triggered = FALSE;
> +
> +
> + if (Triggered) {
> + return;
> + }
> +
> + Triggered = TRUE;
> +
> + FwVol = NULL;
> + AcpiTable = NULL;
> + VtdAcpiTable = NULL;
> +
> + DEBUG ((DEBUG_INFO, "UpdateDmarPciEnumCompleteCallback \n"));
> +
> +
> + ///
> + /// Fix DMAR Table always created, skip install when disabled
> + ///
> + if ((mSaConfigHob->VtdData.VtdDisable == TRUE) || (PciSegmentRead32
> (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0,
> R_SA_MC_CAPID0_A_OFFSET)) & BIT23)) {
> + DEBUG ((DEBUG_INFO, "Vtd Disabled, skip DMAR Table install\n"));
> + return;
> + }
> +
> +
> + ///
> + /// Locate ACPI support protocol
> + ///
> + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)
> &AcpiTable);
> +
> + ///
> + /// Locate protocol.
> + /// There is little chance we can't find an FV protocol
> + ///
> + Status = gBS->LocateHandleBuffer (
> + ByProtocol,
> + &gEfiFirmwareVolume2ProtocolGuid,
> + NULL,
> + &NumberOfHandles,
> + &HandleBuffer
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + ///
> + /// Looking for FV with ACPI storage file
> + ///
> + for (i = 0; i < NumberOfHandles; i++) {
> + ///
> + /// Get the protocol on this handle
> + /// This should not fail because of LocateHandleBuffer
> + ///
> + Status = gBS->HandleProtocol (
> + HandleBuffer[i],
> + &gEfiFirmwareVolume2ProtocolGuid,
> + (VOID **) &FwVol
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + ///
> + /// See if it has the ACPI storage file
> + ///
> + Size = 0;
> + FvStatus = 0;
> + Status = FwVol->ReadFile (
> + FwVol,
> + &gSaAcpiTableStorageGuid,
> + NULL,
> + &Size,
> + &FileType,
> + &Attributes,
> + &FvStatus
> + );
> +
> + ///
> + /// If we found it, then we are done
> + ///
> + if (Status == EFI_SUCCESS) {
> + break;
> + }
> + }
> + ///
> + /// Our exit status is determined by the success of the previous operations
> + /// If the protocol was found, Instance already points to it.
> + ///
> + ///
> + /// Free any allocated buffers
> + ///
> + FreePool (HandleBuffer);
> +
> + ///
> + /// Sanity check that we found our data file
> + ///
> + ASSERT (FwVol);
> + if (FwVol == NULL) {
> + return;
> + }
> + ///
> + /// By default, a table belongs in all ACPI table versions published.
> + ///
> + Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0
> | EFI_ACPI_TABLE_VERSION_3_0;
> +
> + ///
> + /// Read tables from the storage file.
> + ///
> + Instance = 0;
> + CurrentTable = NULL;
> +
> + while (Status == EFI_SUCCESS) {
> + Status = FwVol->ReadSection (
> + FwVol,
> + &gSaAcpiTableStorageGuid,
> + EFI_SECTION_RAW,
> + Instance,
> + (VOID **) &CurrentTable,
> + &Size,
> + &FvStatus
> + );
> +
> + if (!EFI_ERROR (Status)) {
> + ///
> + /// Check the Signature ID to modify the table
> + ///
> + switch (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Signature) {
> +
> + case EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE:
> + VtdAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
> + DmarTableUpdate (VtdAcpiTable, &Version);
> + break;
> +
> + default:
> + break;
> + }
> + ///
> + /// Increment the instance
> + ///
> + Instance++;
> + CurrentTable = NULL;
> + }
> + }
> + ///
> + /// Update the VTD table in the ACPI tables.
> + ///
> + AcpiTableHandle = 0;
> + if (VtdAcpiTable != NULL) {
> + Status = AcpiTable->InstallAcpiTable (
> + AcpiTable,
> + VtdAcpiTable,
> + VtdAcpiTable->Length,
> + &AcpiTableHandle
> + );
> + FreePool (VtdAcpiTable);
> + }
> +}
> +
> +/**
> + Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
> + Publish the appropriate SSDT based on current configuration and
> capabilities.
> +
> + @param[in] SaPolicy - SA DXE Policy protocol
> +
> + @retval EFI_SUCCESS - Vtd initialization complete
> + @exception EFI_UNSUPPORTED - Vtd is not enabled by policy
> +**/
> +EFI_STATUS
> +VtdInit (
> + IN SA_POLICY_PROTOCOL *SaPolicy
> + )
> +{
> + EFI_STATUS Status;
> + UINT64 McD0BaseAddress;
> + UINT64 McD2BaseAddress;
> + UINTN MchBar;
> + SYSTEM_AGENT_NVS_AREA_PROTOCOL *SaNvsAreaProtocol;
> +
> + mInterruptRemappingSupport = FALSE;
> + mSaConfigHob = NULL;
> + mSaConfigHob = GetFirstGuidHob (&gSaConfigHobGuid);
> + if (mSaConfigHob != NULL) {
> + mInterruptRemappingSupport =
> mSaConfigHob->VtdData.InterruptRemappingSupport;
> + }
> +
> + ///
> + /// Locate the SA Global NVS Protocol.
> + ///
> + Status = gBS->LocateProtocol (
> + &gSaNvsAreaProtocolGuid,
> + NULL,
> + (VOID **) &SaNvsAreaProtocol
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 0, 0, 0);
> + McD2BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0);
> + mSaPolicy = SaPolicy;
> + MchBar = PciSegmentRead32(McD0BaseAddress + R_SA_MCHBAR)
> & ~BIT0;
> +
> + if (mSaConfigHob != NULL) {
> + SaNvsAreaProtocol->Area->VtdDisable =
> mSaConfigHob->VtdData.VtdDisable;
> + }
> + SaNvsAreaProtocol->Area->VtdBaseAddress1 = (MmioRead32(MchBar +
> R_SA_MCHBAR_VTD1_OFFSET) &~1);
> + SaNvsAreaProtocol->Area->VtdBaseAddress3 = (MmioRead32(MchBar +
> R_SA_MCHBAR_VTD3_OFFSET) &~1);
> + SaNvsAreaProtocol->Area->VtdEngine1Vid =
> PciSegmentRead16(McD2BaseAddress + PCI_VENDOR_ID_OFFSET);
> +
> + if (mSaConfigHob != NULL) {
> + if ((mSaConfigHob->VtdData.VtdDisable) || (PciSegmentRead32
> (McD0BaseAddress + R_SA_MC_CAPID0_A_OFFSET) & BIT23)) {
> + DEBUG ((DEBUG_WARN, "VTd disabled or no capability!\n"));
> + return EFI_UNSUPPORTED;
> + }
> + }
> + ///
> + /// Check SA supports VTD and VTD is enabled in setup menu
> + ///
> + DEBUG ((DEBUG_INFO, "VTd enabled\n"));
> +
> + return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.c
> new file mode 100644
> index 0000000000..08fd9266c6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.c
> @@ -0,0 +1,356 @@
> +/** @file
> + This is the driver that publishes the SMM Access Protocol
> + instance for System Agent.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SmmAccessDriver.h"
> +
> +static SMM_ACCESS_PRIVATE_DATA mSmmAccess;
> +
> +
> +/**
> + This is the standard EFI driver point that
> + installs an SMM Access Protocol
> +
> + @param[in] ImageHandle - Handle for the image of this driver
> + @param[in] SystemTable - Pointer to the EFI System Table
> +
> + @retval EFI_SUCCESS - Protocol was installed successfully
> + @exception EFI_UNSUPPORTED - Protocol was not installed
> + @retval EFI_NOT_FOUND - Protocol can't be found.
> + @retval EFI_OUT_OF_RESOURCES - Protocol does not have enough
> resources to initialize the driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmAccessDriverEntryPoint (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> + UINTN Index;
> + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock;
> + EFI_PEI_HOB_POINTERS *Hob;
> +
> + ///
> + /// --cr-- INITIALIZE_SCRIPT (ImageHandle, SystemTable);
> + ///
> + /// Initialize Global variables
> + ///
> + ZeroMem (&mSmmAccess, sizeof (mSmmAccess));
> +
> + mSmmAccess.Signature = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
> + mSmmAccess.Handle = NULL;
> +
> + ///
> + /// Get Hob list
> + ///
> + Hob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
> + if (Hob == NULL) {
> + DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
> + return EFI_NOT_FOUND;
> + }
> +
> + DescriptorBlock = (VOID *) ((UINT8 *) Hob + sizeof (EFI_HOB_GUID_TYPE));
> +
> + ///
> + /// Alloc space for mSmmAccess.SmramDesc
> + ///
> + mSmmAccess.SmramDesc = AllocateZeroPool
> ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof
> (EFI_SMRAM_DESCRIPTOR));
> + if (mSmmAccess.SmramDesc == NULL) {
> + DEBUG ((DEBUG_WARN, "Alloc mSmmAccess.SmramDesc fail.\n"));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + DEBUG ((DEBUG_INFO, "Alloc mSmmAccess.SmramDesc success.\n"));
> +
> + ///
> + /// Use the HOB to publish SMRAM capabilities
> + ///
> + for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions;
> Index++) {
> + mSmmAccess.SmramDesc[Index].PhysicalStart =
> DescriptorBlock->Descriptor[Index].PhysicalStart;
> + mSmmAccess.SmramDesc[Index].CpuStart =
> DescriptorBlock->Descriptor[Index].CpuStart;
> + mSmmAccess.SmramDesc[Index].PhysicalSize =
> DescriptorBlock->Descriptor[Index].PhysicalSize;
> + mSmmAccess.SmramDesc[Index].RegionState =
> DescriptorBlock->Descriptor[Index].RegionState;
> + }
> +
> + mSmmAccess.NumberRegions = Index;
> + mSmmAccess.SmmAccess.Open = Open;
> + mSmmAccess.SmmAccess.Close = Close;
> + mSmmAccess.SmmAccess.Lock = Lock;
> + mSmmAccess.SmmAccess.GetCapabilities = GetCapabilities;
> + mSmmAccess.SmmAccess.LockState = FALSE;
> + mSmmAccess.SmmAccess.OpenState = FALSE;
> +
> + ///
> + /// Install our protocol interfaces on the device's handle
> + ///
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &mSmmAccess.Handle,
> + &gEfiSmmAccess2ProtocolGuid,
> + &mSmmAccess.SmmAccess,
> + NULL
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_WARN, "InstallMultipleProtocolInterfaces returned
> %r\n", Status));
> + return EFI_UNSUPPORTED;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This routine accepts a request to "open" a region of SMRAM. The
> + region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> + The use of "open" means that the memory is visible from all boot-service
> + and SMM agents.
> +
> + @param[in] This - Pointer to the SMM Access Interface.
> +
> + @retval EFI_SUCCESS - The region was successfully opened.
> + @retval EFI_DEVICE_ERROR - The region could not be opened because
> locked by
> + chipset.
> + @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Open (
> + IN EFI_SMM_ACCESS2_PROTOCOL *This
> + )
> +{
> + SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> + UINT64 Address;
> + UINT8 SmramControl;
> + UINTN DescriptorIndex;
> +
> + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> + for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> + if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> + DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
> + return EFI_DEVICE_ERROR;
> + }
> + }
> +
> + ///
> + /// BEGIN CHIPSET SPECIFIC CODE
> + ///
> + ///
> + /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
> + ///
> + Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN,
> R_SA_SMRAMC);
> +
> + SmramControl = PciRead8 (Address);
> + ///
> + /// Is SMRAM locked?
> + ///
> + for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> + if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
> + ///
> + /// Cannot Open a locked region
> + ///
> + SmmAccess->SmramDesc[DescriptorIndex].RegionState |=
> EFI_SMRAM_LOCKED;
> + DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
> + return EFI_DEVICE_ERROR;
> + }
> + }
> + ///
> + /// Open SMRAM region
> + ///
> + SmramControl |= B_SA_SMRAMC_D_OPEN_MASK;
> + SmramControl &= ~(B_SA_SMRAMC_D_CLS_MASK);
> +
> + PciWrite8 (Address, SmramControl);
> + ///
> + /// END CHIPSET SPECIFIC CODE
> + ///
> + for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> + SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> + SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> EFI_SMRAM_OPEN;
> + }
> + SmmAccess->SmmAccess.OpenState = TRUE;
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This routine accepts a request to "close" a region of SMRAM. The
> + region could be legacy AB or TSEG near top of physical memory.
> + The use of "close" means that the memory is only visible from SMM agents,
> + not from BS or RT code.
> +
> + @param[in] This - Pointer to the SMM Access Interface.
> +
> + @retval EFI_SUCCESS - The region was successfully closed.
> + @retval EFI_DEVICE_ERROR - The region could not be closed because
> locked by chipset.
> + @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Close (
> + IN EFI_SMM_ACCESS2_PROTOCOL *This
> + )
> +{
> + SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> + UINT64 Address;
> + UINT8 SmramControl;
> + BOOLEAN OpenState;
> + UINT8 Index;
> + UINTN DescriptorIndex;
> +
> + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> + for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> + if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> + DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
> + continue;
> + }
> +
> + ///
> + /// BEGIN CHIPSET SPECIFIC CODE
> + ///
> + ///
> + /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
> + ///
> + Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN,
> R_SA_SMRAMC);
> +
> + SmramControl = PciRead8 (Address);
> + ///
> + /// Is SMRAM locked?
> + ///
> + if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
> + ///
> + /// Cannot Close a locked region
> + ///
> + SmmAccess->SmramDesc[DescriptorIndex].RegionState |=
> EFI_SMRAM_LOCKED;
> + DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
> + return EFI_DEVICE_ERROR;
> + }
> + ///
> + /// Close SMRAM region
> + ///
> + SmramControl &= ~(B_SA_SMRAMC_D_OPEN_MASK);
> +
> + PciWrite8 (Address, SmramControl);
> + ///
> + /// END CHIPSET SPECIFIC CODE
> + ///
> + SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> ~EFI_SMRAM_OPEN;
> + SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> + }
> +
> + ///
> + /// Find out if any regions are still open
> + ///
> + OpenState = FALSE;
> + for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
> + if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) ==
> EFI_SMRAM_OPEN) {
> + OpenState = TRUE;
> + }
> + }
> +
> + SmmAccess->SmmAccess.OpenState = OpenState;
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This routine accepts a request to "lock" SMRAM. The
> + region could be legacy AB or TSEG near top of physical memory.
> + The use of "lock" means that the memory can no longer be opened
> + to BS state..
> +
> + @param[in] This - Pointer to the SMM Access Interface.
> +
> + @retval EFI_SUCCESS - The region was successfully locked.
> + @retval EFI_DEVICE_ERROR - The region could not be locked because at
> least
> + one range is still open.
> + @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Lock (
> + IN EFI_SMM_ACCESS2_PROTOCOL *This
> + )
> +{
> + SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> + UINT64 Address;
> + UINT8 SmramControl;
> + UINTN DescriptorIndex;
> +
> + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> + if (SmmAccess->SmmAccess.OpenState) {
> + DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are
> still open\n"));
> + return EFI_DEVICE_ERROR;
> + }
> + for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> + SmmAccess->SmramDesc[DescriptorIndex].RegionState |=
> EFI_SMRAM_LOCKED;
> + }
> + SmmAccess->SmmAccess.LockState = TRUE;
> +
> + ///
> + /// BEGIN CHIPSET SPECIFIC CODE
> + ///
> + ///
> + /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
> + ///
> + Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN,
> R_SA_SMRAMC);
> +
> + SmramControl = PciRead8 (Address);
> + ///
> + /// Lock the SMRAM
> + ///
> + SmramControl |= B_SA_SMRAMC_D_LCK_MASK;
> +
> + PciWrite8 (Address, SmramControl);
> + ///
> + /// END CHIPSET SPECIFIC CODE
> + ///
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This routine services a user request to discover the SMRAM
> + capabilities of this platform. This will report the possible
> + ranges that are possible for SMRAM access, based upon the
> + memory controller capabilities.
> +
> + @param[in] This - Pointer to the SMRAM Access Interface.
> + @param[in] SmramMapSize - Pointer to the variable containing size
> of the
> + buffer to contain the description information.
> + @param[in] SmramMap - Buffer containing the data describing
> the Smram
> + region descriptors.
> +
> + @retval EFI_BUFFER_TOO_SMALL - The user did not provide a sufficient
> buffer.
> + @retval EFI_SUCCESS - The user provided a sufficiently-sized buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetCapabilities (
> + IN CONST EFI_SMM_ACCESS2_PROTOCOL *This,
> + IN OUT UINTN *SmramMapSize,
> + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
> + )
> +{
> + EFI_STATUS Status;
> + SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> + UINTN NecessaryBufferSize;
> +
> + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> + NecessaryBufferSize = SmmAccess->NumberRegions * sizeof
> (EFI_SMRAM_DESCRIPTOR);
> +
> + if (*SmramMapSize < NecessaryBufferSize) {
> + DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
> + Status = EFI_BUFFER_TOO_SMALL;
> + } else {
> + CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
> + Status = EFI_SUCCESS;
> + }
> +
> + *SmramMapSize = NecessaryBufferSize;
> +
> + return Status;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.asl
> c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.asl
> c
> new file mode 100644
> index 0000000000..c864a0ca8f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.asl
> c
> @@ -0,0 +1,250 @@
> +/** @file
> + This file describes the contents of the ACPI DMA address Remapping
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "Dmar.h"
> +#include <Register/PchRegsP2sb.h>
> +
> +EFI_ACPI_DMAR_TABLE DmarTable = {
> + //
> + // EFI_ACPI_DMAR_HEADER
> + //
> + {
> + //
> + // EFI_ACPI_DESCRIPTION_HEADER
> + //
> + {
> + EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE,
> + sizeof (EFI_ACPI_DMAR_TABLE),
> + EFI_ACPI_DMAR_TABLE_REVISION,
> +
> + //
> + // Checksum will be updated at runtime
> + //
> + 0x00,
> +
> + //
> + // It is expected that these values will be programmed at runtime
> + //
> + { 'I', 'N', 'T', 'E', 'L', ' ' },
> + EFI_ACPI_DMAR_OEM_TABLE_ID,
> + 0x1,
> + EFI_ACPI_DMAR_OEM_CREATOR_ID,
> + 1
> + },
> +
> + //
> + // DMAR table specific entries below:
> + //
> +
> + //
> + // 39-bit addressing Host Address Width
> + //
> + 38,
> +
> + //
> + // Flags
> + //
> + 0,
> +
> + //
> + // Reserved fields
> + //
> + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
> + },
> +
> + //
> + // First DRHD structure, VT-d Engine #1
> + //
> + {
> + //
> + // EFI_ACPI_DMAR_DRHD_HEADER
> + //
> + {
> + {0, // Type = 0 (DRHD)
> + sizeof (EFI_ACPI_DRHD_ENGINE1_STRUCT)}, // Length of structure
> + 0, // Flag - Do not include all
> + 0, // Reserved fields
> + 0, // Segment
> + 0 // Base address of DMA-remapping
> hardware - Updated at boot time
> + },
> + //
> + // Device Scopes
> + //
> + {
> + {
> + {1, // Type
> + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> + 0, // Segment number
> + 0, // Reserved
> + 0}, // Start bus number
> + {2, 0} // PCI path
> + }
> + }
> + },
> +
> + //
> + //Third DRHD structure VT-d Engine# 3
> + //
> + {
> + //
> + // EFI_ACPI_DMAR_DRHD_HEADER
> + //
> + {
> + {0, // Type = 0 (DRHD)
> + sizeof (EFI_ACPI_DRHD_ENGINE3_STRUCT)}, // Length of strucure.
> + 1, // Flag - Include all
> + 0, // Reserved
> + 0, // Segment Number
> + 0 // Base address of DMA-remapping
> hardware.
> + },
> + {
> + //
> + // Device Scopes
> + //
> + {
> + {3, // Type=IO APIC
> + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> + 0, // Reserved
> + 2, // Enumeration ID
> + V_P2SB_CFG_IBDF_BUS}, // Start bus number
> + {V_P2SB_CFG_IBDF_DEV, V_P2SB_CFG_IBDF_FUNC} // PCI path
> + },
> + //
> + // Device Scopes
> + //
> + {
> + {4, // Type=HPET
> + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> + 0, // Reserved
> + 0, // Enumeration ID
> + V_P2SB_CFG_HBDF_BUS}, // Start bus number
> + {V_P2SB_CFG_HBDF_DEV, V_P2SB_CFG_HBDF_FUNC} // PCI path
> + }
> + }
> + },
> + //RMRR structure for USB devices.
> + {
> + //
> + // EFI_ACPI_DMAR_RMRR_HEADER
> + //
> + {
> + {
> + 0x1, // Type 1 - RMRR structure
> + sizeof(EFI_ACPI_RMRR_USB_STRUC) // Length
> + },
> + { 0x00, 0x00 }, // Reserved
> + 0x0000, // Segment Num
> + 0x00000000000E0000, // RMRR Base address - Updated
> in runtime.
> + 0x00000000000EFFFF // RMRR Limit address - Updated
> in runtime.
> + },
> + //
> + // Device Scopes
> + //
> + {
> + {
> + {1, // Type
> + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> + 0, // Reserved
> + 0, // Enum ID
> + 0}, // Start bus number
> + {20, 0} // PCI path
> + },
> + {
> + {1, // Type
> + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> + 0, // Reserved
> + 0, // Enum ID
> + 0}, // Start bus number
> + {20, 1} // PCI path
> + }
> + }
> + },
> +
> + //RMRR structure for IGD device.
> + {
> + //
> + // EFI_ACPI_DMAR_RMRR_HEADER
> + //
> + {
> + {1, // Type 1 - RMRR structure
> + sizeof (EFI_ACPI_RMRR_IGD_STRUC)}, // Length
> + {0x0000}, // Reserved
> + 0x0000, // Segment Num
> + 0x0000000000000000, // RMRR Base address - Updated
> in runtime.
> + 0x0000000000000000 // RMRR Limit address - Updated
> in runtime.
> + },
> + //
> + // Device Scopes
> + //
> + {
> + {
> + {1, // Type
> + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> + 0, // Reserved
> + 0, // Enum ID
> + 0}, // Start bus number
> + {2, 0} // PCI path
> + }
> + }
> + },
> +
> + // RMRR structure for WiAMT DMA access.
> + // Keep this device in end of RMRR queue.
> + {
> + //
> + // EFI_ACPI_DMAR_RMRR_HEADER
> + //
> + {
> + {1, // Type 1 - RMRR structure
> + sizeof (EFI_ACPI_RMRR_CSME_STRUC)}, // Length
> + {0x0000}, // Reserved
> + 0x0000, // Segment Num
> + 0x0000000000000000, // RMRR Base address - Updated
> in runtime.
> + 0x0000000000000000 // RMRR Limit address - Updated
> in runtime.
> + },
> + //
> + // Device Scopes
> + //
> + {
> + {
> + {1, // Type
> + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> + 0, // Reserved
> + 0, // Enum ID
> + 0}, // Start bus number
> + {22, 7} // PCI path
> + }
> + }
> + }
> +};
> +
> +//
> +// Dummy function required for build tools
> +//
> +#if defined (__GNUC__)
> +VOID*
> +ReferenceAcpiTable (
> + VOID
> + )
> +
> +{
> + //
> + // Reference the table being generated to prevent the optimizer from
> removing the
> + // data structure from the exeutable
> + //
> + return (VOID*)&DmarTable;
> +}
> +#else
> +int
> +main (
> + VOID
> + )
> +{
> + return 0;
> +}
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
> new file mode 100644
> index 0000000000..b431a77f05
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
> @@ -0,0 +1,794 @@
> +/** @file
> + This file contains the SystemAgent PCI Configuration space
> + definition.
> + It defines various System Agent PCI Configuration Space registers
> + which will be used to dynamically produce all resources in the Host Bus.
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +External(M64B)
> +External(M64L)
> +External(M32B)
> +External(M32L)
> +
> +//
> +// Define various System Agent (SA) PCI Configuration Space
> +// registers which will be used to dynamically produce all
> +// resources in the Host Bus _CRS.
> +//
> +OperationRegion (HBUS, PCI_Config, 0x00, 0x100)
> +Field (HBUS, DWordAcc, NoLock, Preserve)
> +{
> + Offset(0x40), // EPBAR (0:0:0:40)
> + EPEN, 1, // Enable
> + , 11,
> + EPBR, 20, // EPBAR [31:12]
> +
> + Offset(0x48), // MCHBAR (0:0:0:48)
> + MHEN, 1, // Enable
> + , 14,
> + MHBR, 17, // MCHBAR [31:15]
> +
> + Offset(0x50), // GGC (0:0:0:50)
> + GCLK, 1, // GGCLCK
> +
> + Offset(0x54), // DEVEN (0:0:0:54)
> + D0EN, 1, // DEV0 Enable
> + D1F2, 1, // DEV1 FUN2 Enable
> + D1F1, 1, // DEV1 FUN1 Enable
> + D1F0, 1, // DEV1 FUN0 Enable
> +
> + Offset(0x60), // PCIEXBAR (0:0:0:60)
> + PXEN, 1, // Enable
> + PXSZ, 2, // PCI Express Size
> + , 23,
> + PXBR, 6, // PCI Express BAR [31:26]
> +
> + Offset(0x68), // DMIBAR (0:0:0:68)
> + DIEN, 1, // Enable
> + , 11,
> + DIBR, 20, // DMIBAR [31:12]
> +
> + Offset(0x70), // MESEG_BASE (0:0:0:70)
> + , 20,
> + MEBR, 12, // MESEG_BASE [31:20]
> +
> + Offset(0x80), // PAM0 Register (0:0:0:80)
> + PMLK, 1, // PAM Lock bit.
> + , 3,
> + PM0H, 2, // PAM 0, High Nibble
> + , 2,
> +
> + Offset(0x81), // PAM1 Register (0:0:0:81)
> + PM1L, 2, // PAM1, Low Nibble
> + , 2,
> + PM1H, 2, // PAM1, High Nibble
> + , 2,
> +
> + Offset(0x82), // PAM2 Register (0:0:0:82)
> + PM2L, 2, // PAM2, Low Nibble
> + , 2,
> + PM2H, 2, // PAM2, High Nibble
> + , 2,
> +
> + Offset(0x83), // PAM3 Register (0:0:0:83)
> + PM3L, 2, // PAM3, Low Nibble
> + , 2,
> + PM3H, 2, // PAM3, High Nibble
> + , 2,
> +
> + Offset(0x84), // PAM4 Register (0:0:0:84)
> + PM4L, 2, // PAM4, Low Nibble
> + , 2,
> + PM4H, 2, // PAM4, High Nibble
> + , 2,
> +
> + Offset(0x85), // PAM5 Register (0:0:0:85)
> + PM5L, 2, // PAM5, Low Nibble
> + , 2,
> + PM5H, 2, // PAM5, High Nibble
> + , 2,
> +
> + Offset(0x86), // PAM6 Register (0:0:0:86)
> + PM6L, 2, // PAM6, Low Nibble
> + , 2,
> + PM6H, 2, // PAM6, High Nibble
> + , 2,
> +
> + Offset(0xA8), // Top of Upper Usable DRAM Register (0:0:0:A8)
> + , 20,
> + TUUD, 19, // TOUUD [38:20]
> +
> + Offset(0xBC), // Top of Lower Usable DRAM Register (0:0:0:BC)
> + , 20,
> + TLUD, 12, // TOLUD [31:20]
> +
> + Offset(0xC8), // ERRSTS register (0:0:0:C8)
> + , 7,
> + HTSE, 1 // Host Thermal Sensor Event for SMI/SCI/SERR
> +}
> +//
> +// Define a buffer that will store all the bus, memory, and IO information
> +// relating to the Host Bus. This buffer will be dynamically altered in
> +// the _CRS and passed back to the OS.
> +//
> +Name(BUF0,ResourceTemplate()
> +{
> + //
> + // Bus Number Allocation: Bus 0 to 0xFF
> + //
> + WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00,
> + 0x0000,0x00FF,0x00,0x0100,,,PB00)
> +
> + //
> + // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 )
> + //
> + DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
> + 0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00)
> +
> + //
> + // PCI Configuration Registers ( 0x0CF8 - 0x0CFF )
> + //
> + Io(Decode16,0x0CF8,0x0CF8,1,0x08)
> +
> + //
> + // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF )
> + //
> + DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
> + 0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01)
> +
> + //
> + // Video Buffer Area ( 0xA0000 - 0xBFFFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000)
> +
> + //
> + // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000)
> +
> + //
> + // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400)
> +
> + //
> + // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800)
> +
> + //
> + // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00)
> +
> + //
> + // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000)
> +
> + //
> + // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400)
> +
> + //
> + // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800)
> +
> + //
> + // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00)
> +
> + //
> + // BIOS Extension Area ( 0xE0000 - 0xE3FFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000)
> +
> + //
> + // BIOS Extension Area ( 0xE4000 - 0xE7FFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400)
> +
> + //
> + // BIOS Extension Area ( 0xE8000 - 0xEBFFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800)
> +
> + //
> + // BIOS Extension Area ( 0xEC000 - 0xEFFFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00)
> +
> + //
> + // BIOS Area ( 0xF0000 - 0xFFFFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> + ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000)
> +
> +// //
> +// // Memory Hole Region ( 0xF00000 - 0xFFFFFF )
> +// //
> +//
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +// ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE)
> +
> + //
> + // PCI Memory Region ( TOLUD - 0xDFFFFFFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> + ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01)
> +
> + //
> + // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) )
> + // (This is dummy range for OS compatibility, will patch it in _CRS)
> + //
> +
> QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> + ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
> +
> + //
> + // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
> + //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> + ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03)
> +})
> +
> + //
> + // SA reserved resources
> + //
> + Device(SRRE) {
> + Name(_HID,EISAID("PNP0C02")) // motherboard resource
> + Name(_UID,"SARESV")
> + Method(_STA,0,Serialized) // device present and decodes its resources,
> but not to be displayed in OSPM
> + {
> + If(LGreaterEqual(TLUD, 0x404)) {
> + Return (3)
> + } Else {
> + Return (0)
> + }
> + }
> +
> + Method(_CRS,0,Serialized)
> + {
> + Name(BUF0,ResourceTemplate(){
> + //
> + // Reserve the 0x40000000 ~ 0x403FFFFF to prevent other driver use this
> memory range
> + //
> + Memory32Fixed(ReadOnly,0x40000000,0x400000)
> + })
> + If(LGreaterEqual(TLUD, 0x404)) {
> + Return (BUF0)
> + } Else {
> + Return (Buffer(){})
> + }
> + }
> + }
> +
> +Name(EP_B, 0) // to store EP BAR
> +Name(MH_B, 0) // to store MCH BAR
> +Name(PC_B, 0) // to store PCIe BAR
> +Name(PC_L, 0) // to store PCIe BAR Length
> +Name(DM_B, 0) // to store DMI BAR
> +
> +//
> +// Get EP BAR
> +//
> +Method(GEPB,0,Serialized)
> +{
> + if(LEqual(EP_B,0))
> + {
> + ShiftLeft(\_SB.PCI0.EPBR,12,EP_B)
> + }
> + Return(EP_B)
> +}
> +
> +//
> +// Get MCH BAR
> +//
> +Method(GMHB,0,Serialized)
> +{
> + if(LEqual(MH_B,0))
> + {
> + ShiftLeft(\_SB.PCI0.MHBR,15,MH_B)
> + }
> + Return(MH_B)
> +}
> +
> +//
> +// Get PCIe BAR
> +//
> +Method(GPCB,0,Serialized)
> +{
> + if(LEqual(PC_B,0))
> + {
> + ShiftLeft(\_SB.PCI0.PXBR,26,PC_B)
> + }
> + Return(PC_B)
> +}
> +
> +//
> +// Get PCIe Length
> +//
> +Method(GPCL,0,Serialized)
> +{
> + if(LEqual(PC_L,0)) {
> + ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L)
> + }
> + Return(PC_L)
> +}
> +
> +//
> +// Get DMI BAR
> +//
> +Method(GDMB,0,Serialized)
> +{
> + if(LEqual(DM_B,0))
> + {
> + ShiftLeft(\_SB.PCI0.DIBR,12,DM_B)
> + }
> + Return(DM_B)
> +}
> +
> +
> +Method(_CRS,0,Serialized)
> +{
> + //
> + // Fix up Max Bus Number and Length
> + //
> + Store(\_SB.PCI0.GPCL(),Local0)
> + CreateWordField(BUF0, ^PB00._MAX, PBMX)
> + Store(Subtract(ShiftRight(Local0,20),2), PBMX)
> + CreateWordField(BUF0, ^PB00._LEN, PBLN)
> + Store(Subtract(ShiftRight(Local0,20),1), PBLN)
> + //
> + // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF.
> + //
> + If(PM1L) // \_SB.PCI0
> + {
> + // PAMx != 0. Set length = 0.
> +
> + CreateDwordField(BUF0, ^C000._LEN,C0LN)
> + Store(Zero,C0LN)
> + }
> +
> + If(LEqual(PM1L,1))
> + {
> + CreateBitField(BUF0, ^C000._RW,C0RW)
> + Store(Zero,C0RW)
> + }
> +
> + If(PM1H)
> + {
> + CreateDwordField(BUF0, ^C400._LEN,C4LN)
> + Store(Zero,C4LN)
> + }
> +
> + If(LEqual(PM1H,1))
> + {
> + CreateBitField(BUF0, ^C400._RW,C4RW)
> + Store(Zero,C4RW)
> + }
> +
> + If(PM2L)
> + {
> + CreateDwordField(BUF0, ^C800._LEN,C8LN)
> + Store(Zero,C8LN)
> + }
> +
> + If(LEqual(PM2L,1))
> + {
> + CreateBitField(BUF0, ^C800._RW,C8RW)
> + Store(Zero,C8RW)
> + }
> +
> + If(PM2H)
> + {
> + CreateDwordField(BUF0, ^CC00._LEN,CCLN)
> + Store(Zero,CCLN)
> + }
> +
> + If(LEqual(PM2H,1))
> + {
> + CreateBitField(BUF0, ^CC00._RW,CCRW)
> + Store(Zero,CCRW)
> + }
> +
> + If(PM3L)
> + {
> + CreateDwordField(BUF0, ^D000._LEN,D0LN)
> + Store(Zero,D0LN)
> + }
> +
> + If(LEqual(PM3L,1))
> + {
> + CreateBitField(BUF0, ^D000._RW,D0RW)
> + Store(Zero,D0RW)
> + }
> +
> + If(PM3H)
> + {
> + CreateDwordField(BUF0, ^D400._LEN,D4LN)
> + Store(Zero,D4LN)
> + }
> +
> + If(LEqual(PM3H,1))
> + {
> + CreateBitField(BUF0, ^D400._RW,D4RW)
> + Store(Zero,D4RW)
> + }
> +
> + If(PM4L)
> + {
> + CreateDwordField(BUF0, ^D800._LEN,D8LN)
> + Store(Zero,D8LN)
> + }
> +
> + If(LEqual(PM4L,1))
> + {
> + CreateBitField(BUF0, ^D800._RW,D8RW)
> + Store(Zero,D8RW)
> + }
> +
> + If(PM4H)
> + {
> + CreateDwordField(BUF0, ^DC00._LEN,DCLN)
> + Store(Zero,DCLN)
> + }
> +
> + If(LEqual(PM4H,1))
> + {
> + CreateBitField(BUF0, ^DC00._RW,DCRW)
> + Store(Zero,DCRW)
> + }
> +
> + If(PM5L)
> + {
> + CreateDwordField(BUF0, ^E000._LEN,E0LN)
> + Store(Zero,E0LN)
> + }
> +
> + If(LEqual(PM5L,1))
> + {
> + CreateBitField(BUF0, ^E000._RW,E0RW)
> + Store(Zero,E0RW)
> + }
> +
> + If(PM5H)
> + {
> + CreateDwordField(BUF0, ^E400._LEN,E4LN)
> + Store(Zero,E4LN)
> + }
> +
> + If(LEqual(PM5H,1))
> + {
> + CreateBitField(BUF0, ^E400._RW,E4RW)
> + Store(Zero,E4RW)
> + }
> +
> + If(PM6L)
> + {
> + CreateDwordField(BUF0, ^E800._LEN,E8LN)
> + Store(Zero,E8LN)
> + }
> +
> + If(LEqual(PM6L,1))
> + {
> + CreateBitField(BUF0, ^E800._RW,E8RW)
> + Store(Zero,E8RW)
> + }
> +
> + If(PM6H)
> + {
> + CreateDwordField(BUF0, ^EC00._LEN,ECLN)
> + Store(Zero,ECLN)
> + }
> +
> + If(LEqual(PM6H,1))
> + {
> + CreateBitField(BUF0, ^EC00._RW,ECRW)
> + Store(Zero,ECRW)
> + }
> +
> + If(PM0H)
> + {
> + CreateDwordField(BUF0, ^F000._LEN,F0LN)
> + Store(Zero,F0LN)
> + }
> +
> + If(LEqual(PM0H,1))
> + {
> + CreateBitField(BUF0, ^F000._RW,F0RW)
> + Store(Zero,F0RW)
> + }
> +
> + // Enable the 1MB region between 15-16MB if HENA = 1.
> + //
> + // If( MCHC.HENA)
> + // {
> + // CreateDwordField(BUF0, HOLE._LEN,H0LN)
> + // Store(0x100000,H0LN)
> + // }
> +
> + //
> + // Create pointers to Memory Sizing values.
> + //
> + CreateDwordField(BUF0, ^PM01._MIN,M1MN)
> + CreateDwordField(BUF0, ^PM01._MAX,M1MX)
> + CreateDwordField(BUF0, ^PM01._LEN,M1LN)
> +
> + //
> + // Set Memory Size Values. TLUD represents bits 31:20 of phyical
> + // TOM, so shift these bits into the correct position and fix up
> + // the Memory Region available to PCI.
> + //
> + Store (M32L, M1LN)
> + Store (M32B, M1MN)
> + Subtract (Add (M1MN, M1LN), 1, M1MX)
> +
> + //
> + // Create pointers to Memory Sizing values.
> + // Patch PM02 range basing on memory size and OS type
> + //
> + If (LEqual(M64L, 0)) {
> + CreateQwordField(BUF0, ^PM02._LEN,MSLN)
> + //
> + // Set resource length to 0
> + //
> + Store (0, MSLN)
> + }
> + Else {
> + CreateQwordField(BUF0, ^PM02._LEN,M2LN)
> + CreateQwordField(BUF0, ^PM02._MIN,M2MN)
> + CreateQwordField(BUF0, ^PM02._MAX,M2MX)
> + //
> + // Set 64bit MMIO resource Base and Length
> + //
> + Store (M64L, M2LN)
> + Store (M64B, M2MN)
> + Subtract (Add (M2MN, M2LN), 1, M2MX)
> + }
> + Return(BUF0)
> +}
> +
> +//
> +//Name(GUID,UUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))
> +//
> +Name(GUID,Buffer(){0x5b, 0x4d, 0xdb, 0x33,
> + 0xf7, 0x1f,
> + 0x1c, 0x40,
> + 0x96, 0x57,
> + 0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66})
> +
> +
> +Name(SUPP,0) // PCI _OSC Support Field value
> +Name(CTRL,0) // PCI _OSC Control Field value
> +Name(XCNT, 0) // Variable used in _OSC for counting
> +
> +Method(_OSC,4,Serialized)
> +{
> + //
> + // Check for proper UUID
> + // Save the capabilities buffer
> + //
> + Store(Arg3,Local0)
> +
> + //
> + // Create DWord-adressable fields from the Capabilties Buffer
> + //
> + CreateDWordField(Local0,0,CDW1)
> + CreateDWordField(Local0,4,CDW2)
> + CreateDWordField(Local0,8,CDW3)
> +
> +
> + //
> + // Check for proper UUID
> + //
> + If(LEqual(Arg0,GUID))
> + {
> + // Save Capabilities DWord2 & 3
> + Store(CDW2,SUPP)
> + Store(CDW3,CTRL)
> +
> + //
> + // You can clear bits in CTRL here if you don't want OS to take
> + // control
> + //
> + If(LNot(NEXP))
> + {
> + And(CTRL, 0xFFFFFFF8, CTRL) // disable Native hot plug, PME
> + }
> +
> + If(LEqual(TBTS, 1)) {
> + // \_OSC disallow only Advanced Error Reporting control
> + And(CTRL, 0xFFFFFFF7, CTRL)
> + }
> +
> + If(Not(And(CDW1,1))) // Query flag clear?
> + { // Disable GPEs for features granted native control.
> + If(And(CTRL,0x01))
> + {
> + NHPG()
> + }
> + If(And(CTRL,0x04)) // PME control granted?
> + {
> + NPME()
> + }
> + }
> +
> + If(LNotEqual(Arg1,One))
> + {
> + //
> + // Unknown revision
> + //
> + Or(CDW1,0x08,CDW1)
> + }
> +
> + If(LNotEqual(CDW3,CTRL))
> + {
> + //
> + // Capabilities bits were masked
> + //
> + Or(CDW1,0x10,CDW1)
> + }
> + //
> + // Update DWORD3 in the buffer
> + //
> + Store(CTRL,CDW3)
> + Store(CTRL,OSCC)
> + Return(Local0)
> + } Else {
> + Or(CDW1,4,CDW1) // Unrecognized UUID
> + Return(Local0)
> + }
> +} // End _OSC
> +
> +//
> +// Added code for Dual IRQ support. Two set of ACPI IRQ tables were
> generated.
> +// Code has been added to select the appropriate IRQ table by checking the
> CPUID.
> +//
> +Scope(\_SB.PCI0)
> +{
> + Method(AR00) {
> + Return(\_SB.AR00)
> + }
> +
> + Method(PD00) {
> + Return(\_SB.PD00)
> + }
> +
> + Method(AR02) {
> + Return(\_SB.AR02)
> + }
> +
> + Method(PD02) {
> + Return(\_SB.PD02)
> + }
> +
> + Method(AR04) {
> + Return(\_SB.AR04)
> + }
> +
> + Method(PD04) {
> + Return(\_SB.PD04)
> + }
> +
> + Method(AR05) {
> + Return(\_SB.AR05)
> + }
> +
> + Method(PD05) {
> + Return(\_SB.PD05)
> + }
> +
> + Method(AR06) {
> + Return(\_SB.AR06)
> + }
> +
> + Method(PD06) {
> + Return(\_SB.PD06)
> + }
> +
> + Method(AR07) {
> + Return(\_SB.AR07)
> + }
> +
> + Method(PD07) {
> + Return(\_SB.PD07)
> + }
> +
> + Method(AR08) {
> + Return(\_SB.AR08)
> + }
> +
> + Method(PD08) {
> + Return(\_SB.PD08)
> + }
> +
> + Method(AR09) {
> + Return(\_SB.AR09)
> + }
> +
> + Method(PD09) {
> + Return(\_SB.PD09)
> + }
> +
> + Method(AR0A) {
> + Return(\_SB.AR0A)
> + }
> +
> + Method(PD0A) {
> + Return(\_SB.PD0A)
> + }
> +
> + Method(AR0B) {
> + Return(\_SB.AR0B)
> + }
> +
> + Method(PD0B) {
> + Return(\_SB.PD0B)
> + }
> +
> + //
> + // Add device scope definition for System Agent
> + // P.E.G. Root Port D1F0
> + //
> + Device(PEG0) {
> + Name(_ADR, 0x00010000)
> + Device(PEGP) { // P.E.G. Port Slot x16
> + Name(_ADR, 0x00000000)
> + }
> + }
> + //
> + // P.E.G. Root Port D1F1
> + //
> + Device(PEG1) {
> + Name(_ADR, 0x00010001)
> + Device(PEGP) { // P.E.G. Port Slot x8
> + Name(_ADR, 0x00000000)
> + }
> + }
> + //
> + // P.E.G. Root Port D1F2
> + //
> + Device(PEG2) {
> + Name(_ADR, 0x00010002)
> + Device(PEGP) { // P.E.G. Port Slot x4
> + Name(_ADR, 0x00000000)
> + }
> + }
> + //
> + // I.G.D
> + //
> + Device(GFX0) {
> + Name(_ADR, 0x00020000)
> + }
> + //
> + // SA Thermal Device
> + //
> + Device(B0D4) {
> + Method(_DSM,4,serialized){if(PCIC(Arg0))
> { return(PCID(Arg0,Arg1,Arg2,Arg3)) }; Return(Buffer() {0})}
> + Name(_ADR, 0x00040000)
> + }
> + //
> + // Device IPU0 is the IPU PCI device
> + //
> + Device(IPU0) {
> + Name(_ADR, 0x00050000)
> + }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
> new file mode 100644
> index 0000000000..e7a797c973
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
> @@ -0,0 +1,1666 @@
> +/** @file
> + This file contains the IGD OpRegion/Software ACPI Reference
> + Code.
> + It defines the methods to enable/disable output switching,
> + store display switching and LCD brightness BIOS control
> + and return valid addresses for all display device encoders
> + present in the system, etc.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +External(\ECST, MethodObj)
> +External(\PBCL, MethodObj)
> +External(HDOS, MethodObj)
> +External(\ECON, IntObj)
> +External(\PNHM, IntObj)
> +External(OSYS, IntObj)
> +External(CPSC)
> +External(\GUAM, MethodObj)
> +External(DSEN)
> +External(S0ID)
> +
> +Name(TMP1,Package() {0xFFFFFFFF})
> +Name(TMP2,Package() {0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP3,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP4,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP5,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF})
> +Name(TMP6,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP7,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP8,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> + 0xFFFFFFFF})
> +Name(TMP9,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> + 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMPA,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF })
> +Name(TMPB,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMPC,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMPD,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF})
> +Name(TMPE,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMPF,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF,
> + 0xFFFFFFFF})
> +Name(TMPG,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF,
> + 0xFFFFFFFF, 0xFFFFFFFF})
> +
> +// Enable/Disable Output Switching. In WIN2K/WINXP, _DOS = 0 will
> +// get called during initialization to prepare for an ACPI Display
> +// Switch Event. During an ACPI Display Switch, the OS will call
> +// _DOS = 2 immediately after a Notify=0x80 to temporarily disable
> +// all Display Switching. After ACPI Display Switching is complete,
> +// the OS will call _DOS = 0 to re-enable ACPI Display Switching.
> +Method(_DOS,1)
> +{
> + //
> + // Store Display Switching and LCD brightness BIOS control bit
> + //
> + Store(And(Arg0,7),DSEN)
> +
> + If(LEqual(And(Arg0, 0x3), 0)) // If _DOS[1:0]=0
> + {
> + If(CondRefOf(HDOS))
> + {
> + HDOS()
> + }
> + }
> +}
> +
> +//
> +// Enumerate the Display Environment. This method will return
> +// valid addresses for all display device encoders present in the
> +// system. The Miniport Driver will reject the addresses for every
> +// encoder that does not have an attached display device. After
> +// enumeration is complete, the OS will call the _DGS methods
> +// during a display switch only for the addresses accepted by the
> +// Miniport Driver. For hot-insertion and removal of display
> +// devices, a re-enumeration notification will be required so the
> +// address of the newly present display device will be accepted by
> +// the Miniport Driver.
> +//
> +Method(_DOD,0)
> +{
> + If (LEqual(IPTP,1)) {
> + //
> + // Increment number of devices if IPU is enabled
> + //
> + Store(1, NDID)
> + } Else {
> + Store(0, NDID)
> + }
> +
> + If(LNotEqual(DIDL, Zero))
> + {
> + Store(SDDL(DIDL),DID1)
> + }
> + If(LNotEqual(DDL2, Zero))
> + {
> + Store(SDDL(DDL2),DID2)
> + }
> + If(LNotEqual(DDL3, Zero))
> + {
> + Store(SDDL(DDL3),DID3)
> + }
> + If(LNotEqual(DDL4, Zero))
> + {
> + Store(SDDL(DDL4),DID4)
> + }
> + If(LNotEqual(DDL5, Zero))
> + {
> + Store(SDDL(DDL5),DID5)
> + }
> + If(LNotEqual(DDL6, Zero))
> + {
> + Store(SDDL(DDL6),DID6)
> + }
> + If(LNotEqual(DDL7, Zero))
> + {
> + Store(SDDL(DDL7),DID7)
> + }
> + If(LNotEqual(DDL8, Zero))
> + {
> + Store(SDDL(DDL8),DID8)
> + }
> + If(LNotEqual(DDL9, Zero))
> + {
> + Store(SDDL(DDL9),DID9)
> + }
> + If(LNotEqual(DD10, Zero))
> + {
> + Store(SDDL(DD10),DIDA)
> + }
> + If(LNotEqual(DD11, Zero))
> + {
> + Store(SDDL(DD11),DIDB)
> + }
> + If(LNotEqual(DD12, Zero))
> + {
> + Store(SDDL(DD12),DIDC)
> + }
> + If(LNotEqual(DD13, Zero))
> + {
> + Store(SDDL(DD13),DIDD)
> + }
> + If(LNotEqual(DD14, Zero))
> + {
> + Store(SDDL(DD14),DIDE)
> + }
> + If(LNotEqual(DD15, Zero))
> + {
> + Store(SDDL(DD15),DIDF)
> + }
> +
> + //
> + // Enumerate the encoders. Note that for
> + // current silicon, the maximum number of encoders
> + // possible is 15.
> + //
> + If(LEqual(NDID,1))
> + {
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMP1,0))
> + } Else {
> + Store(Or(0x10000,DID1),Index(TMP1,0))
> + }
> + Return(TMP1)
> + }
> +
> + If(LEqual(NDID,2))
> + {
> + Store(Or(0x10000,DID1),Index(TMP2,0))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMP2,1))
> + } Else {
> + Store(Or(0x10000,DID2),Index(TMP2,1))
> + }
> + Return(TMP2)
> + }
> +
> + If(LEqual(NDID,3))
> + {
> + Store(Or(0x10000,DID1),Index(TMP3,0))
> + Store(Or(0x10000,DID2),Index(TMP3,1))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMP3,2))
> + } Else {
> + Store(Or(0x10000,DID3),Index(TMP3,2))
> + }
> + Return(TMP3)
> + }
> +
> + If(LEqual(NDID,4))
> + {
> + Store(Or(0x10000,DID1),Index(TMP4,0))
> + Store(Or(0x10000,DID2),Index(TMP4,1))
> + Store(Or(0x10000,DID3),Index(TMP4,2))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMP4,3))
> + } Else {
> + Store(Or(0x10000,DID4),Index(TMP4,3))
> + }
> + Return(TMP4)
> + }
> +
> + If(LEqual(NDID,5))
> + {
> + Store(Or(0x10000,DID1),Index(TMP5,0))
> + Store(Or(0x10000,DID2),Index(TMP5,1))
> + Store(Or(0x10000,DID3),Index(TMP5,2))
> + Store(Or(0x10000,DID4),Index(TMP5,3))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMP5,4))
> + } Else {
> + Store(Or(0x10000,DID5),Index(TMP5,4))
> + }
> + Return(TMP5)
> + }
> +
> + If(LEqual(NDID,6))
> + {
> + Store(Or(0x10000,DID1),Index(TMP6,0))
> + Store(Or(0x10000,DID2),Index(TMP6,1))
> + Store(Or(0x10000,DID3),Index(TMP6,2))
> + Store(Or(0x10000,DID4),Index(TMP6,3))
> + Store(Or(0x10000,DID5),Index(TMP6,4))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMP6,5))
> + } Else {
> + Store(Or(0x10000,DID6),Index(TMP6,5))
> + }
> + Return(TMP6)
> + }
> +
> + If(LEqual(NDID,7))
> + {
> + Store(Or(0x10000,DID1),Index(TMP7,0))
> + Store(Or(0x10000,DID2),Index(TMP7,1))
> + Store(Or(0x10000,DID3),Index(TMP7,2))
> + Store(Or(0x10000,DID4),Index(TMP7,3))
> + Store(Or(0x10000,DID5),Index(TMP7,4))
> + Store(Or(0x10000,DID6),Index(TMP7,5))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMP7,6))
> + } Else {
> + Store(Or(0x10000,DID7),Index(TMP7,6))
> + }
> + Return(TMP7)
> + }
> +
> + If(LEqual(NDID,8))
> + {
> + Store(Or(0x10000,DID1),Index(TMP8,0))
> + Store(Or(0x10000,DID2),Index(TMP8,1))
> + Store(Or(0x10000,DID3),Index(TMP8,2))
> + Store(Or(0x10000,DID4),Index(TMP8,3))
> + Store(Or(0x10000,DID5),Index(TMP8,4))
> + Store(Or(0x10000,DID6),Index(TMP8,5))
> + Store(Or(0x10000,DID7),Index(TMP8,6))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMP8,7))
> + } Else {
> + Store(Or(0x10000,DID8),Index(TMP8,7))
> + }
> + Return(TMP8)
> + }
> +
> + If(LEqual(NDID,9))
> + {
> + Store(Or(0x10000,DID1),Index(TMP9,0))
> + Store(Or(0x10000,DID2),Index(TMP9,1))
> + Store(Or(0x10000,DID3),Index(TMP9,2))
> + Store(Or(0x10000,DID4),Index(TMP9,3))
> + Store(Or(0x10000,DID5),Index(TMP9,4))
> + Store(Or(0x10000,DID6),Index(TMP9,5))
> + Store(Or(0x10000,DID7),Index(TMP9,6))
> + Store(Or(0x10000,DID8),Index(TMP9,7))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMP9,8))
> + } Else {
> + Store(Or(0x10000,DID9),Index(TMP9,8))
> + }
> + Return(TMP9)
> + }
> +
> + If(LEqual(NDID,0x0A))
> + {
> + Store(Or(0x10000,DID1),Index(TMPA,0))
> + Store(Or(0x10000,DID2),Index(TMPA,1))
> + Store(Or(0x10000,DID3),Index(TMPA,2))
> + Store(Or(0x10000,DID4),Index(TMPA,3))
> + Store(Or(0x10000,DID5),Index(TMPA,4))
> + Store(Or(0x10000,DID6),Index(TMPA,5))
> + Store(Or(0x10000,DID7),Index(TMPA,6))
> + Store(Or(0x10000,DID8),Index(TMPA,7))
> + Store(Or(0x10000,DID9),Index(TMPA,8))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMPA,9))
> + } Else {
> + Store(Or(0x10000,DIDA),Index(TMPA,9))
> + }
> + Return(TMPA)
> + }
> +
> + If(LEqual(NDID,0x0B))
> + {
> + Store(Or(0x10000,DID1),Index(TMPB,0))
> + Store(Or(0x10000,DID2),Index(TMPB,1))
> + Store(Or(0x10000,DID3),Index(TMPB,2))
> + Store(Or(0x10000,DID4),Index(TMPB,3))
> + Store(Or(0x10000,DID5),Index(TMPB,4))
> + Store(Or(0x10000,DID6),Index(TMPB,5))
> + Store(Or(0x10000,DID7),Index(TMPB,6))
> + Store(Or(0x10000,DID8),Index(TMPB,7))
> + Store(Or(0x10000,DID9),Index(TMPB,8))
> + Store(Or(0x10000,DIDA),Index(TMPB,9))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMPB,10))
> + } Else {
> + Store(Or(0x10000,DIDB),Index(TMPB,10))
> + }
> + Return(TMPB)
> + }
> +
> + If(LEqual(NDID,0x0C))
> + {
> + Store(Or(0x10000,DID1),Index(TMPC,0))
> + Store(Or(0x10000,DID2),Index(TMPC,1))
> + Store(Or(0x10000,DID3),Index(TMPC,2))
> + Store(Or(0x10000,DID4),Index(TMPC,3))
> + Store(Or(0x10000,DID5),Index(TMPC,4))
> + Store(Or(0x10000,DID6),Index(TMPC,5))
> + Store(Or(0x10000,DID7),Index(TMPC,6))
> + Store(Or(0x10000,DID8),Index(TMPC,7))
> + Store(Or(0x10000,DID9),Index(TMPC,8))
> + Store(Or(0x10000,DIDA),Index(TMPC,9))
> + Store(Or(0x10000,DIDB),Index(TMPC,10))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMPC,11))
> + } Else {
> + Store(Or(0x10000,DIDC),Index(TMPC,11))
> + }
> + Return(TMPC)
> + }
> +
> + If(LEqual(NDID,0x0D))
> + {
> + Store(Or(0x10000,DID1),Index(TMPD,0))
> + Store(Or(0x10000,DID2),Index(TMPD,1))
> + Store(Or(0x10000,DID3),Index(TMPD,2))
> + Store(Or(0x10000,DID4),Index(TMPD,3))
> + Store(Or(0x10000,DID5),Index(TMPD,4))
> + Store(Or(0x10000,DID6),Index(TMPD,5))
> + Store(Or(0x10000,DID7),Index(TMPD,6))
> + Store(Or(0x10000,DID8),Index(TMPD,7))
> + Store(Or(0x10000,DID9),Index(TMPD,8))
> + Store(Or(0x10000,DIDA),Index(TMPD,9))
> + Store(Or(0x10000,DIDB),Index(TMPD,10))
> + Store(Or(0x10000,DIDC),Index(TMPD,11))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMPD,12))
> + } Else {
> + Store(Or(0x10000,DIDD),Index(TMPD,12))
> + }
> + Return(TMPD)
> + }
> +
> + If(LEqual(NDID,0x0E))
> + {
> + Store(Or(0x10000,DID1),Index(TMPE,0))
> + Store(Or(0x10000,DID2),Index(TMPE,1))
> + Store(Or(0x10000,DID3),Index(TMPE,2))
> + Store(Or(0x10000,DID4),Index(TMPE,3))
> + Store(Or(0x10000,DID5),Index(TMPE,4))
> + Store(Or(0x10000,DID6),Index(TMPE,5))
> + Store(Or(0x10000,DID7),Index(TMPE,6))
> + Store(Or(0x10000,DID8),Index(TMPE,7))
> + Store(Or(0x10000,DID9),Index(TMPE,8))
> + Store(Or(0x10000,DIDA),Index(TMPE,9))
> + Store(Or(0x10000,DIDB),Index(TMPE,10))
> + Store(Or(0x10000,DIDC),Index(TMPE,11))
> + Store(Or(0x10000,DIDD),Index(TMPE,12))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMPE,13))
> + } Else {
> + Store(Or(0x10000,DIDE),Index(TMPE,13))
> + }
> + Return(TMPE)
> + }
> +
> + If(LEqual(NDID,0x0F))
> + {
> + Store(Or(0x10000,DID1),Index(TMPF,0))
> + Store(Or(0x10000,DID2),Index(TMPF,1))
> + Store(Or(0x10000,DID3),Index(TMPF,2))
> + Store(Or(0x10000,DID4),Index(TMPF,3))
> + Store(Or(0x10000,DID5),Index(TMPF,4))
> + Store(Or(0x10000,DID6),Index(TMPF,5))
> + Store(Or(0x10000,DID7),Index(TMPF,6))
> + Store(Or(0x10000,DID8),Index(TMPF,7))
> + Store(Or(0x10000,DID9),Index(TMPF,8))
> + Store(Or(0x10000,DIDA),Index(TMPF,9))
> + Store(Or(0x10000,DIDB),Index(TMPF,10))
> + Store(Or(0x10000,DIDC),Index(TMPF,11))
> + Store(Or(0x10000,DIDD),Index(TMPF,12))
> + Store(Or(0x10000,DIDE),Index(TMPF,13))
> + If (LEqual(IPTP,1)) {
> + //
> + // IGFX need report IPUA as GFX0 child
> + //
> + Store(0x00023480,Index(TMPF,14))
> + } Else {
> + Store(Or(0x10000,DIDF),Index(TMPF,14))
> + }
> + Return(TMPF)
> + }
> +
> + If(LEqual(NDID,0x10))
> + {
> + Store(Or(0x10000,DID1),Index(TMPG,0))
> + Store(Or(0x10000,DID2),Index(TMPG,1))
> + Store(Or(0x10000,DID3),Index(TMPG,2))
> + Store(Or(0x10000,DID4),Index(TMPG,3))
> + Store(Or(0x10000,DID5),Index(TMPG,4))
> + Store(Or(0x10000,DID6),Index(TMPG,5))
> + Store(Or(0x10000,DID7),Index(TMPG,6))
> + Store(Or(0x10000,DID8),Index(TMPG,7))
> + Store(Or(0x10000,DID9),Index(TMPG,8))
> + Store(Or(0x10000,DIDA),Index(TMPG,9))
> + Store(Or(0x10000,DIDB),Index(TMPG,10))
> + Store(Or(0x10000,DIDC),Index(TMPG,11))
> + Store(Or(0x10000,DIDD),Index(TMPG,12))
> + Store(Or(0x10000,DIDE),Index(TMPG,13))
> + Store(Or(0x10000,DIDF),Index(TMPG,14))
> + //
> + // IGFX need report IPUA as GFX0 child
> + // NDID can only be 0x10 if IPU is enabled
> + //
> + Store(0x00023480,Index(TMPG,15))
> + Return(TMPG)
> + }
> +
> + //
> + // If nothing else, return Unknown LFP.
> + // (Prevents compiler warning.)
> + //
> + Return(Package() {0x00000400})
> +}
> +
> +Device(DD01)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DID1),0x400))
> + {
> + Store(0x1, EDPV)
> + Store(NXD1, NXDX)
> + Store(DID1, DIDX)
> + Return(1)
> + }
> + If(LEqual(DID1,0))
> + {
> + Return(1)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DID1))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + Return(CDDS(DID1))
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD1)
> + }
> + Return(NDDS(DID1))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD02)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DID2),0x400))
> + {
> + Store(0x2, EDPV)
> + Store(NXD2, NXDX)
> + Store(DID2, DIDX)
> + Return(2)
> + }
> + If(LEqual(DID2,0))
> + {
> + Return(2)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DID2))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(LIDS,0))
> + {
> + Return(0x0)
> + }
> + Return(CDDS(DID2))
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + //
> + // Return the Next State.
> + //
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD2)
> + }
> + Return(NDDS(DID2))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD03)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DID3),0x400))
> + {
> + Store(0x3, EDPV)
> + Store(NXD3, NXDX)
> + Store(DID3, DIDX)
> + Return(3)
> + }
> + If(LEqual(DID3,0))
> + {
> + Return(3)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DID3))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DID3,0))
> + {
> + Return(0x0B)
> + }
> + Else
> + {
> + Return(CDDS(DID3))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD3)
> + }
> + Return(NDDS(DID3))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD04)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DID4),0x400))
> + {
> + Store(0x4, EDPV)
> + Store(NXD4, NXDX)
> + Store(DID4, DIDX)
> + Return(4)
> + }
> + If(LEqual(DID4,0))
> + {
> + Return(4)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DID4))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DID4,0))
> + {
> + Return(0x0B)
> + }
> + Else
> + {
> + Return(CDDS(DID4))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD4)
> + }
> + Return(NDDS(DID4))
> + }
> +
> + //
> + // Device Set State. (See table above.)
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD05)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DID5),0x400))
> + {
> + Store(0x5, EDPV)
> + Store(NXD5, NXDX)
> + Store(DID5, DIDX)
> + Return(5)
> + }
> + If(LEqual(DID5,0))
> + {
> + Return(5)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DID5))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DID5,0))
> + {
> + Return(0x0B)
> + }
> + Else
> + {
> + Return(CDDS(DID5))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD5)
> + }
> + Return(NDDS(DID5))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD06)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DID6),0x400))
> + {
> + Store(0x6, EDPV)
> + Store(NXD6, NXDX)
> + Store(DID6, DIDX)
> + Return(6)
> + }
> + If(LEqual(DID6,0))
> + {
> + Return(6)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DID6))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DID6,0))
> + {
> + Return(0x0B)
> + }
> + Else
> + {
> + Return(CDDS(DID6))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD6)
> + }
> + Return(NDDS(DID6))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD07)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DID7),0x400))
> + {
> + Store(0x7, EDPV)
> + Store(NXD7, NXDX)
> + Store(DID7, DIDX)
> + Return(7)
> + }
> + If(LEqual(DID7,0))
> + {
> + Return(7)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DID7))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DID7,0))
> + {
> + Return(0x0B)
> + }
> + Else
> + {
> + Return(CDDS(DID7))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD7)
> + }
> + Return(NDDS(DID7))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD08)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DID8),0x400))
> + {
> + Store(0x8, EDPV)
> + Store(NXD8, NXDX)
> + Store(DID8, DIDX)
> + Return(8)
> + }
> + If(LEqual(DID8,0))
> + {
> + Return(8)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DID8))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DID8,0))
> + {
> + Return(0x0B)
> + }
> + Else
> + {
> + Return(CDDS(DID8))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD8)
> + }
> + Return(NDDS(DID8))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD09)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DID9),0x400))
> + {
> + Store(0x9, EDPV)
> + Store(NXD8, NXDX)
> + Store(DID9, DIDX)
> + Return(9)
> + }
> + If(LEqual(DID9,0))
> + {
> + Return(9)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DID9))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DID9,0))
> + {
> + Return(0x0B)
> + }
> + Else
> + {
> + Return(CDDS(DID9))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD8)
> + }
> + Return(NDDS(DID9))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD0A)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DIDA),0x400))
> + {
> + Store(0xA, EDPV)
> + Store(NXD8, NXDX)
> + Store(DIDA, DIDX)
> + Return(0x0A)
> + }
> + If(LEqual(DIDA,0))
> + {
> + Return(0x0A)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DIDA))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DIDA,0))
> + {
> + Return(0x0B)
> + }
> + Else
> + {
> + Return(CDDS(DIDA))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD8)
> + }
> + Return(NDDS(DIDA))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD0B)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DIDB),0x400))
> + {
> + Store(0xB, EDPV)
> + Store(NXD8, NXDX)
> + Store(DIDB, DIDX)
> + Return(0X0B)
> + }
> + If(LEqual(DIDB,0))
> + {
> + Return(0x0B)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DIDB))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DIDB,0))
> + {
> + Return(0x0B)
> + }
> + Else
> + {
> + Return(CDDS(DIDB))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD8)
> + }
> + Return(NDDS(DIDB))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD0C)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DIDC),0x400))
> + {
> + Store(0xC, EDPV)
> + Store(NXD8, NXDX)
> + Store(DIDC, DIDX)
> + Return(0X0C)
> + }
> + If(LEqual(DIDC,0))
> + {
> + Return(0x0C)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DIDC))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DIDC,0))
> + {
> + Return(0x0C)
> + }
> + Else
> + {
> + Return(CDDS(DIDC))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD8)
> + }
> + Return(NDDS(DIDC))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD0D)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DIDD),0x400))
> + {
> + Store(0xD, EDPV)
> + Store(NXD8, NXDX)
> + Store(DIDD, DIDX)
> + Return(0X0D)
> + }
> + If(LEqual(DIDD,0))
> + {
> + Return(0x0D)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DIDD))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DIDD,0))
> + {
> + Return(0x0D)
> + }
> + Else
> + {
> + Return(CDDS(DIDD))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD8)
> + }
> + Return(NDDS(DIDD))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD0E)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DIDE),0x400))
> + {
> + Store(0xE, EDPV)
> + Store(NXD8, NXDX)
> + Store(DIDE, DIDX)
> + Return(0X0E)
> + }
> + If(LEqual(DIDE,0))
> + {
> + Return(0x0E)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DIDE))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DIDE,0))
> + {
> + Return(0x0E)
> + }
> + Else
> + {
> + Return(CDDS(DIDE))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD8)
> + }
> + Return(NDDS(DIDE))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +Device(DD0F)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(And(0x0F00,DIDF),0x400))
> + {
> + Store(0xF, EDPV)
> + Store(NXD8, NXDX)
> + Store(DIDF, DIDX)
> + Return(0X0F)
> + }
> + If(LEqual(DIDF,0))
> + {
> + Return(0x0F)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DIDF))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(DIDC,0))
> + {
> + Return(0x0F)
> + }
> + Else
> + {
> + Return(CDDS(DIDF))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXD8)
> + }
> + Return(NDDS(DIDF))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +}
> +
> +//
> +//Device for eDP
> +//
> +Device(DD1F)
> +{
> + //
> + // Return Unique ID.
> + //
> + Method(_ADR,0,Serialized)
> + {
> + If(LEqual(EDPV, 0x0))
> + {
> + Return(0x1F)
> + }
> + Else
> + {
> + Return(And(0xFFFF,DIDX))
> + }
> + }
> +
> + //
> + // Return the Current Status.
> + //
> + Method(_DCS,0)
> + {
> + If(LEqual(EDPV, 0x0))
> + {
> + Return(0x00)
> + }
> + Else
> + {
> + Return(CDDS(DIDX))
> + }
> + }
> +
> + //
> + // Query Graphics State (active or inactive).
> + //
> + Method(_DGS,0)
> + {
> + If(LAnd(LEqual(And(SGMD,0x7F),0x01),CondRefOf(SNXD)))
> + {
> + Return (NXDX)
> + }
> + Return(NDDS(DIDX))
> + }
> +
> + //
> + // Device Set State.
> + //
> + Method(_DSS,1)
> + {
> + DSST(Arg0)
> + }
> +
> + //
> + // Query List of Brightness Control Levels Supported.
> + //
> + Method(_BCL,0)
> + {
> + //
> + // List of supported brightness levels in the following sequence.
> + // Level when machine has full power.
> + // Level when machine is on batteries.
> + // Other supported levels.
> + //
> + If(CondRefOf(\PBCL)) {
> + Return (PBCL())
> + } Else {
> + Return(Package(){80, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
> 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
> 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
> 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
> 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100})
> + }
> + }
> +
> + //
> + // Set the Brightness Level.
> + //
> + Method (_BCM,1)
> + {
> + //
> + // Set the requested level if it is between 0 and 100%.
> + //
> + If(LAnd(LGreaterEqual(Arg0,0),LLessEqual(Arg0,100)))
> + {
> + \_SB.PCI0.GFX0.AINT(1, Arg0)
> + Store(Arg0,BRTL) // Store Brightness Level.
> + }
> + }
> +
> + //
> + // Brightness Query Current level.
> + //
> + Method (_BQC,0)
> + {
> + Return(BRTL)
> + }
> +}
> +
> +Method(SDDL,1)
> +{
> + Increment(NDID)
> + Store(And(Arg0,0xF0F),Local0)
> + Or(0x80000000,Local0, Local1)
> + If(LEqual(DIDL,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DDL2,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DDL3,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DDL4,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DDL5,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DDL6,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DDL7,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DDL8,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DDL9,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DD10,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DD11,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DD12,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DD13,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DD14,Local0))
> + {
> + Return(Local1)
> + }
> + If(LEqual(DD15,Local0))
> + {
> + Return(Local1)
> + }
> + Return(0)
> +}
> +
> +Method(CDDS,1)
> +{
> + Store(And(Arg0,0xF0F),Local0)
> +
> + If(LEqual(0, Local0))
> + {
> + Return(0x1D)
> + }
> + If(LEqual(CADL, Local0))
> + {
> + Return(0x1F)
> + }
> + If(LEqual(CAL2, Local0))
> + {
> + Return(0x1F)
> + }
> + If(LEqual(CAL3, Local0))
> + {
> + Return(0x1F)
> + }
> + If(LEqual(CAL4, Local0))
> + {
> + Return(0x1F)
> + }
> + If(LEqual(CAL5, Local0))
> + {
> + Return(0x1F)
> + }
> + If(LEqual(CAL6, Local0))
> + {
> + Return(0x1F)
> + }
> + If(LEqual(CAL7, Local0))
> + {
> + Return(0x1F)
> + }
> + If(LEqual(CAL8, Local0))
> + {
> + Return(0x1F)
> + }
> + Return(0x1D)
> +}
> +
> +Method(NDDS,1)
> +{
> + Store(And(Arg0,0xF0F),Local0)
> +
> + If(LEqual(0, Local0))
> + {
> + Return(0)
> + }
> + If(LEqual(NADL, Local0))
> + {
> + Return(1)
> + }
> + If(LEqual(NDL2, Local0))
> + {
> + Return(1)
> + }
> + If(LEqual(NDL3, Local0))
> + {
> + Return(1)
> + }
> + If(LEqual(NDL4, Local0))
> + {
> + Return(1)
> + }
> + If(LEqual(NDL5, Local0))
> + {
> + Return(1)
> + }
> + If(LEqual(NDL6, Local0))
> + {
> + Return(1)
> + }
> + If(LEqual(NDL7, Local0))
> + {
> + Return(1)
> + }
> + If(LEqual(NDL8, Local0))
> + {
> + Return(1)
> + }
> + Return(0)
> +}
> +
> +//
> +// Device Set State Table
> +// BIT31 BIT30 Execution
> +// 0 0 Don't implement.
> +// 0 1 Cache change. Nothing to Implement.
> +// 1 0 Don't Implement.
> +// 1 1 Display Switch Complete. Implement.
> +//
> +Method(DSST,1)
> +{
> + If(LEqual(And(Arg0,0xC0000000),0xC0000000))
> + {
> + //
> + // State change was performed by the
> + // Video Drivers. Simply update the
> + // New State.
> + //
> + Store(NSTE,CSTE)
> + }
> +}
> +
> +//
> +// Include IGD OpRegion/Software SCI interrupt handler/DSM which is used
> by
> +// the graphics drivers to request data from system BIOS.
> +//
> +include ("IgfxOpRn.asl")
> +include ("IgfxDsm.asl")
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCo
> mmon.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCo
> mmon.asl
> new file mode 100644
> index 0000000000..7edbe45e2e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCo
> mmon.asl
> @@ -0,0 +1,472 @@
> +/** @file
> + IGD OpRegion/Software SCI Reference Code.
> + This file contains ASL code with the purpose of handling events
> + i.e. hotkeys and other system interrupts.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +/**************************************************************
> **********;
> +;* ACPI Notification Methods
> +;**************************************************************
> **********/
> +
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name: PDRD
> +;*
> +;* Description: Check if the graphics driver is ready to process
> +;* notifications and video extensions.
> +;*
> +;* Usage: This method is to be called prior to performing any
> +;* notifications or handling video extensions.
> +;* Ex: If (PDRD()) {Return (FAIL)}
> +;*
> +;* Input: None
> +;*
> +;* Output: None
> +;*
> +;* References: DRDY (Driver ready status), ASLP (Driver recommended
> +;* sleep timeout value).
> +;*
> +;**************************************************************
> **********/
> +
> +External(HNOT, MethodObj)
> +
> +Method(PDRD)
> +{
> + //
> + // If DRDY is clear, the driver is not ready. If the return value is
> + // !=0, do not perform any notifications or video extension handling.
> + //
> + Return(LNot(DRDY))
> +}
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name: PSTS
> +;*
> +;* Description: Check if the graphics driver has completed the previous
> +;* "notify" command.
> +;*
> +;* Usage: This method is called before every "notify" command. A
> +;* "notify" should only be set if the driver has completed the
> +;* previous command. Else, ignore the event and exit the parent
> +;* method.
> +;* Ex: If (PSTS()) {Return (FAIL)}
> +;*
> +;* Input: None
> +;*
> +;* Output: None
> +;*
> +;* References: CSTS (Notification status), ASLP (Driver recommended sleep
> +;* timeout value).
> +;*
> +;**************************************************************
> **********/
> +
> +Method(PSTS)
> +{
> + If(LGreater(CSTS, 2))
> + {
> + //
> + // Sleep for ASLP milliseconds if the status is not "success,
> + // failure, or pending"
> + //
> + Sleep(ASLP)
> + }
> +
> + Return(LEqual(CSTS, 3)) // Return True if still Dispatched
> +}
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name: GNOT
> +;*
> +;* Description: Call the appropriate methods to query the graphics driver
> +;* status. If all methods return success, do a notification of
> +;* the graphics device.
> +;*
> +;* Usage: This method is to be called when a graphics device
> +;* notification is required (display switch hotkey, etc).
> +;*
> +;* Input: Arg0 = Current event type:
> +;* 1 = display switch
> +;* 2 = lid
> +;* 3 = dock
> +;* Arg1 = Notification type:
> +;* 0 = Re-enumeration
> +;* 0x80 = Display switch
> +;*
> +;* Output: Returns 0 = success, 1 = failure
> +;*
> +;* References: PDRD and PSTS methods. OSYS (OS version)
> +;*
> +;**************************************************************
> **********/
> +
> +Method(GNOT, 2)
> +{
> + //
> + // Check for 1. Driver loaded, 2. Driver ready.
> + // If any of these cases is not met, skip this event and return failure.
> + //
> + If(PDRD())
> + {
> + Return(0x1) // Return failure if driver not loaded.
> + }
> +
> + Store(Arg0, CEVT) // Set up the current event value
> + Store(3, CSTS) // CSTS=BIOS dispatched an event
> +
> + If(LAnd(LEqual(CHPD, 0), LEqual(Arg1, 0))) // Do not re-enum if driver
> supports hotplug
> + {
> + //
> + // Re-enumerate the Graphics Device for non-XP operating systems.
> + //
> + Notify(\_SB.PCI0.GFX0, Arg1)
> + }
> +
> + If(CondRefOf(HNOT))
> + {
> + HNOT(Arg0) //Notification handler for Switchable graphics
> + }
> + Else
> + {
> + Notify(\_SB.PCI0.GFX0,0x80)
> + }
> +
> + Return(0x0) // Return success
> +}
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name: GHDS
> +;*
> +;* Description: Handle a hotkey display switching event (performs a
> +;* Notify(GFX0, 0).
> +;*
> +;* Usage: This method must be called when a hotkey event occurs and
> the
> +;* purpose of that hotkey is to do a display switch.
> +;*
> +;* Input: Arg0 = Toggle table number.
> +;*
> +;* Output: Returns 0 = success, 1 = failure.
> +;* CEVT and TIDX are indirect outputs.
> +;*
> +;* References: TIDX, GNOT
> +;*
> +;**************************************************************
> **********/
> +
> +Method(GHDS, 1)
> +{
> + Store(Arg0, TIDX) // Store the table number
> + //
> + // Call GNOT for CEVT = 1 = hotkey, notify value = 0
> + //
> + Return(GNOT(1, 0)) // Return stats from GNOT
> +}
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name: GLID
> +;*
> +;* Description: Handle a lid event (performs the Notify(GFX0, 0), but not the
> +;* lid notify).
> +;*
> +;* Usage: This method must be called when a lid event occurs. A
> +;* Notify(LID0, 0x80) must follow the call to this method.
> +;*
> +;* Input: Arg0 = Lid state:
> +;* 0 = All closed
> +;* 1 = internal LFP lid open
> +;* 2 = external lid open
> +;* 3 = both external and internal open
> +;*
> +;* Output: Returns 0=success, 1=failure.
> +;* CLID and CEVT are indirect outputs.
> +;*
> +;* References: CLID, GNOT
> +;*
> +;**************************************************************
> **********/
> +
> +Method(GLID, 1)
> +{
> +
> + If (LEqual(Arg0,1))
> + {
> + Store(3,CLID)
> + }
> + Else
> + {
> + Store(Arg0, CLID)
> + }
> + //
> + //Store(Arg0, CLID) // Store the current lid state
> + // Call GNOT for CEVT=2=Lid, notify value = 0
> + //
> + if (GNOT(2, 0)) {
> + Or (CLID, 0x80000000, CLID)
> + Return (1) // Return Fail
> + }
> +
> + Return (0) // Return Pass
> +}
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name: GDCK
> +;*
> +;* Description: Handle a docking event by updating the current docking status
> +;* and doing a notification.
> +;*
> +;* Usage: This method must be called when a docking event occurs.
> +;*
> +;* Input: Arg0 = Docking state:
> +;* 0 = Undocked
> +;* 1 = Docked
> +;*
> +;* Output: Returns 0=success, 1=failure.
> +;* CDCK and CEVT are indirect outputs.
> +;*
> +;* References: CDCK, GNOT
> +;*
> +;**************************************************************
> **********/
> +
> +Method(GDCK, 1)
> +{
> + Store(Arg0, CDCK) // Store the current dock state
> + //
> + // Call GNOT for CEVT=4=Dock, notify value = 0
> + //
> + Return(GNOT(4, 0)) // Return stats from GNOT
> +}
> +
> +/**************************************************************
> **********;
> +;* ASLE Interrupt Methods
> +;**************************************************************
> **********/
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name: PARD
> +;*
> +;* Description: Check if the driver is ready to handle ASLE interrupts
> +;* generate by the system BIOS.
> +;*
> +;* Usage: This method must be called before generating each ASLE
> +;* interrupt.
> +;*
> +;* Input: None
> +;*
> +;* Output: Returns 0 = success, 1 = failure.
> +;*
> +;* References: ARDY (Driver readiness), ASLP (Driver recommended sleep
> +;* timeout value)
> +;*
> +;**************************************************************
> **********/
> +
> +Method(PARD)
> +{
> + If(LNot(ARDY))
> + {
> + //
> + // Sleep for ASLP milliseconds if the driver is not ready.
> + //
> + Sleep(ASLP)
> + }
> + //
> + // If ARDY is clear, the driver is not ready. If the return value is
> + // !=0, do not generate the ASLE interrupt.
> + //
> + Return(LNot(ARDY))
> +}
> +
> +//
> +// Intel Ultrabook Event Handler. Arg0 represents the Ultrabook Event Bit #
> to pass
> +// to the Intel Graphics Driver. Note that this is a serialized method, meaning
> +// sumultaneous events are not allowed.
> +//
> +Method(IUEH,1,Serialized)
> +{
> + And(IUER,0xC0,IUER) // Clear all button events on entry.
> + XOr(IUER,Shiftleft(1,Arg0),IUER) // Toggle status.
> +
> + If(LLessEqual(Arg0,4)) // Button Event?
> + {
> + Return(AINT(5,0)) // Generate event and return status.
> +
> + }
> + Else // Indicator Event.
> + {
> + Return(AINT(Arg0,0)) // Generate event and return status.
> + }
> +}
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name: AINT
> +;*
> +;* Description: Call the appropriate methods to generate an ASLE interrupt.
> +;* This process includes ensuring the graphics driver is ready
> +;* to process the interrupt, ensuring the driver supports the
> +;* interrupt of interest, and passing information about the event
> +;* to the graphics driver.
> +;*
> +;* Usage: This method must called to generate an ASLE interrupt.
> +;*
> +;* Input: Arg0 = ASLE command function code:
> +;* 0 = Set ALS illuminance
> +;* 1 = Set backlight brightness
> +;* 2 = Do Panel Fitting
> +;* 4 = Reserved
> +;* 5 = Button Indicator Event
> +;* 6 = Convertible Indicator Event
> +;* 7 = Docking Indicator Event
> +;* Arg1 = If Arg0 = 0, current ALS reading:
> +;* 0 = Reading below sensor range
> +;* 1-0xFFFE = Current sensor reading
> +;* 0xFFFF = Reading above sensor range
> +;* Arg1 = If Arg0 = 1, requested backlight percentage
> +;*
> +;* Output: Returns 0 = success, 1 = failure
> +;*
> +;* References: PARD method.
> +;*
> +;**************************************************************
> **********/
> +
> +Method(AINT, 2)
> +{
> + //
> + // Return failure if the requested feature is not supported by the
> + // driver.
> + //
> + If(LNot(And(TCHE, ShiftLeft(1, Arg0))))
> + {
> + Return(0x1)
> + }
> + //
> + // Return failure if the driver is not ready to handle an ASLE
> + // interrupt.
> + //
> + If(PARD())
> + {
> + Return(0x1)
> + }
> + //
> + // Handle Intel Ultrabook Events.
> + //
> + If(LAnd(LGreaterEqual(Arg0,5),LLessEqual(Arg0,7)))
> + {
> + Store(ShiftLeft(1,Arg0), ASLC) // Set Ultrbook Event [6:4].
> + Store(0x01, ASLE) // Generate ASLE interrupt
> +
> + Store(0,Local2) // Use Local2 as a timeout counter. Intialize to zero.
> +
> + While(LAnd(LLess(Local2,250),LNotEqual(ASLC,0))) // Wait 1 second or
> until Driver ACKs a success.
> + {
> + Sleep(4) // Delay 4 ms.
> + Increment(Local2) // Increment Timeout.
> + }
> +
> + Return(0) // Return success
> + }
> + //
> + // Evaluate the first argument (Panel fitting, backlight brightness, or ALS).
> + //
> + If(LEqual(Arg0, 2)) // Arg0 = 2, so request a panel fitting mode change.
> + {
> + If(CPFM) // If current mode field is non-zero use it.
> + {
> + And(CPFM, 0x0F, Local0) // Create variables without reserved
> + And(EPFM, 0x0F, Local1) // or valid bits.
> +
> + If(LEqual(Local0, 1)) // If current mode is centered,
> + {
> + If(And(Local1, 6)) // and if stretched is enabled,
> + {
> + Store(6, PFIT) // request stretched.
> + }
> + Else // Otherwise,
> + {
> + If(And(Local1, 8)) // if aspect ratio is enabled,
> + {
> + Store(8, PFIT) // request aspect ratio.
> + }
> + Else // Only centered mode is enabled
> + {
> + Store(1, PFIT) // so request centered. (No change.)
> + }
> + }
> + }
> + If(LEqual(Local0, 6)) // If current mode is stretched,
> + {
> + If(And(Local1, 8)) // and if aspect ratio is enabled,
> + {
> + Store(8, PFIT) // request aspect ratio.
> + }
> + Else // Otherwise,
> + {
> + If(And(Local1, 1)) // if centered is enabled,
> + {
> + Store(1, PFIT) // request centered.
> + }
> + Else // Only stretched mode is enabled
> + {
> + Store(6, PFIT) // so request stretched. (No change.)
> + }
> + }
> + }
> + If(LEqual(Local0, 8)) // If current mode is aspect ratio,
> + {
> + If(And(Local1, 1)) // and if centered is enabled,
> + {
> + Store(1, PFIT) // request centered.
> + }
> + Else // Otherwise,
> + {
> + If(And(Local1, 6)) // if stretched is enabled,
> + {
> + Store(6, PFIT) // request stretched.
> + }
> + Else // Only aspect ratio mode is enabled
> + {
> + Store(8, PFIT) // so request aspect ratio. (No change.)
> + }
> + }
> + }
> + }
> + //
> + // The following code for panel fitting (within the Else condition) is
> retained for backward compatiblity.
> + //
> + Else // If CFPM field is zero use PFIT and toggle the
> + {
> + Xor(PFIT,7,PFIT) // mode setting between stretched and centered
> only.
> + }
> + Or(PFIT,0x80000000,PFIT) // Set the valid bit for all cases.
> + Store(4, ASLC) // Store "Panel fitting event" to ASLC[31:1]
> + }
> + Else
> + {
> + If(LEqual(Arg0, 1)) // Arg0=1, so set the backlight brightness.
> + {
> + Store(Divide(Multiply(Arg1, 255), 100), BCLP) // Convert from percent to
> 0-255.
> + Or(BCLP, 0x80000000, BCLP) // Set the valid bit.
> + Store(2, ASLC) // Store "Backlight control event" to ASLC[31:1]
> + }
> + Else
> + {
> + If(LEqual(Arg0, 0)) // Arg0=0, so set the ALS illuminace
> + {
> + Store(Arg1, ALSI)
> + Store(1, ASLC) // Store "ALS event" to ASLC[31:1]
> + }
> + Else
> + {
> + Return(0x1) // Unsupported function
> + }
> + }
> + }
> +
> + Store(0x01, ASLE) // Generate ASLE interrupt
> + Return(0x0) // Return success
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDs
> m.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDs
> m.asl
> new file mode 100644
> index 0000000000..e7b3c92cda
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDs
> m.asl
> @@ -0,0 +1,369 @@
> +/** @file
> + IGD OpRegion/_DSM Reference Code.
> + This file contains Get BIOS Data and Callback functions for
> + the Integrated Graphics Device (IGD) OpRegion/DSM mechanism
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// _DSM Device Specific Method
> +//
> +// Arg0: UUID Unique function identifier
> +// Arg1: Integer Revision Level
> +// Arg2: Integer Function Index (1 = Return Supported Functions)
> +// Arg3: Additional Inputs/Package Parameters Bits [31:0] input as {Byte0,
> Byte1, Byte2, Byte3} to BIOS which is passed as 32 bit DWORD by Driver
> +//
> +Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj,
> PkgObj}) {
> +
> + If (LEqual(Arg0, ToUUID ("3E5B41C6-EB1D-4260-9D15-C71FBADAE414"))) {
> + //
> + // _DSM Definition for Igd functions
> + // Arguments:
> + // Arg0: UUID: 3E5B41C6-EB1D-4260-9D15-C71FBADAE414
> + // Arg1: Revision ID: 1
> + // Arg2: Function Index: 16
> + // Arg3: Additional Inputs Bits[31:0] Arg3 {Byte0, Byte1, Byte2, Byte3}
> + //
> + // Return:
> + // Success for simple notification, Opregion update for some routines and
> a Package for AKSV
> + //
> + //
> + // Switch by function index
> + //
> + Switch(ToInteger(Arg2)) {
> + //
> + // Function Index: 0
> + // Standard query - A bitmask of functions supported
> + //
> + // Return: A bitmask of functions supported
> + //
> + Case (0)
> + {
> + If (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
> + Store("iGfx Supported Functions Bitmap ", Debug)
> + Return (0x1E7FF) // bit 11 and 12 is not supported
> + }
> + }
> +
> + //
> + // Function Index: 1
> + // Adapter Power State Notification
> + // Arg3 Bits [7:0]: Adapter Power State bits [7:0] from Driver 00h = D0; 01h
> = D1; 02h = D2; 04h = D3 (Cold/Hot); 08h = D4 (Hibernate Notification)
> + // Return: Success
> + //
> + Case(1) {
> + If (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
> + Store(" Adapter Power State Notification ", Debug)
> +
> + //
> + // Handle Low Power S0 Idle Capability if enabled
> + //
> + If(LAnd(LEqual(S0ID, 1),LLess(OSYS, 2015))) {
> + //
> + // Call GUAM to trigger CS Entry
> + // If Adapter Power State Notification = D1 (Arg3[0]=0x01)
> + //
> + If (LEqual (And(DerefOf (Index (Arg3,0)), 0xFF), 0x01)) {
> + // GUAM - Global User Absent Mode Notification Method
> + \GUAM(One) // 0x01 - Power State Standby (CS Entry)
> + }
> + Store(And(DerefOf (Index (Arg3,1)), 0xFF), Local0)
> + //
> + // Call GUAM
> + // If Display Turn ON Notification (Arg3 [1] == 0) for CS Exit
> + //
> + If (LEqual (Local0, 0)) {
> + // GUAM - Global User Absent Mode Notification Method
> + \GUAM(0)
> + }
> + }
> +
> + // Upon notification from driver that the Adapter Power State = D0,
> + // check if previous lid event failed. If it did, retry the lid
> + // event here.
> + If(LEqual(DerefOf (Index (Arg3,0)), 0)) {
> + Store(CLID, Local0)
> + If(And(0x80000000,Local0)) {
> + And(CLID, 0x0000000F, CLID)
> + GLID(CLID)
> + }
> + }
> + Return(0x01)
> + }
> + }
> + //
> + // Function Index: 2
> + // Display Power State Notification
> + // Arg3: Display Power State Bits [15:8]
> + // 00h = On
> + // 01h = Standby
> + // 02h = Suspend
> + // 04h = Off
> + // 08h = Reduced On
> + // Return: Success
> + //
> + Case(2) {
> + if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
> +
> + Store("Display Power State Notification ", Debug)
> + Return(0x01)
> + }
> + }
> +
> + //
> + // Function Index: 3
> + // BIOS POST Completion Notification
> + // Return: Success
> + //
> + Case(3) {
> + if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
> + Store("BIOS POST Completion Notification ", Debug)
> + Return(0x01) // Not supported, but no failure
> + }
> + }
> +
> + //
> + // Function Index: 4
> + // Pre-Hires Set Mode
> + // Return: Success
> + //
> + Case(4) {
> + if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> + Store("Pre-Hires Set Mode ", Debug)
> + Return(0x01) // Not supported, but no failure
> + }
> + }
> +
> + //
> + // Function Index: 5
> + // Post-Hires Set Mode
> + // Return: Success
> + //
> + Case(5) {
> + if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> + Store("Post-Hires Set Mode ", Debug)
> + Return(0x01) // Not supported, but no failure
> + }
> + }
> +
> + //
> + // Function Index: 6
> + // SetDisplayDeviceNotification (Display Switch)
> + // Return: Success
> + //
> + Case(6) {
> + if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> + Store("SetDisplayDeviceNotification", Debug)
> + Return(0x01) // Not supported, but no failure
> + }
> + }
> +
> + //
> + // Function Index: 7
> + // SetBootDevicePreference
> + // Return: Success
> + //
> + Case(7) {
> + if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> + //<TODO> An OEM may elect to implement this method. In that case,
> + // the input values must be saved into non-volatile storage for
> + // parsing during the next boot. The following Sample code is Intel
> + // validated implementation.
> +
> + Store("SetBootDevicePreference ", Debug)
> + And(DerefOf (Index (Arg3,0)), 0xFF, IBTT) // Save the boot display to
> NVS
> + Return(0x01)
> + }
> + }
> +
> + //
> + // Function Index: 8
> + // SetPanelPreference
> + // Return: Success
> + //
> + Case(8) {
> + if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> + // An OEM may elect to implement this method. In that case,
> + // the input values must be saved into non-volatile storage for
> + // parsing during the next boot. The following Sample code is Intel
> + // validated implementation.
> +
> + Store("SetPanelPreference ", Debug)
> +
> + // Set the panel-related NVRAM variables based the input from the
> driver.
> + And(DerefOf (Index (Arg3,0)), 0xFF, IPSC)
> +
> + // Change panel type if a change is requested by the driver (Change if
> + // panel type input is non-zero). Zero=No change requested.
> + If(And(DerefOf (Index (Arg3,1)), 0xFF)) {
> + And(DerefOf (Index (Arg3,1)), 0xFF, IPAT)
> + Decrement(IPAT) // 0 = no change, so fit to CMOS map
> + }
> + And(ShiftRight(DerefOf (Index (Arg3,2)), 4), 0x7, IBIA)
> + Return(0x01) // Success
> + }
> + }
> +
> + //
> + // Function Index: 9
> + // FullScreenDOS
> + // Return: Success
> + //
> + Case(9) {
> + if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> + Store("FullScreenDOS ", Debug)
> + Return(0x01) // Not supported, but no failure
> + }
> + }
> +
> + //
> + // Function Index: 10
> + // APM Complete
> + // Return: Adjusted Lid State
> + //
> + Case(10) {
> + if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
> +
> + Store("APM Complete ", Debug)
> + Store(ShiftLeft(LIDS, 8), Local0) // Report the lid state
> + Add(Local0, 0x100, Local0) // Adjust the lid state, 0 = Unknown
> + Return(Local0)
> + }
> + }
> +
> + //
> + //
> + // Function Index: 13
> + // GetBootDisplayPreference
> + // Arg3 Bits [30:16] : Boot Device Ports
> + // Arg3 Bits [7:0] : Boot Device Type
> + // Return: Boot device port and Boot device type from saved
> configuration
> + //
> + Case(13) {
> + if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> +
> + Store("GetBootDisplayPreference ", Debug)
> + Or(ShiftLeft(DerefOf (Index (Arg3,3)), 24), ShiftLeft(DerefOf (Index
> (Arg3,2)), 16), Local0) // Combine Arg3 Bits [31:16]
> + And(Local0, 0xEFFF0000, Local0)
> + And(Local0, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), Local0)
> + Or(IBTT, Local0, Local0) // Arg3 Bits [7:0] = Boot device type
> + Return(Local0)
> + }
> + }
> +
> + //
> + // Function Index: 14
> + // GetPanelDetails
> + // Return: Different Panel Settings
> + //
> + Case(14) {
> + if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> + Store("GetPanelDetails ", Debug)
> +
> + // Report the scaling setting
> + // Bits [7:0] - Panel Scaling
> + // Bits contain the panel scaling user setting from CMOS
> + // 00h = On: Auto
> + // 01h = On: Force Scaling
> + // 02h = Off
> + // 03h = Maintain Aspect Ratio
> +
> + Store(IPSC, Local0)
> + Or(Local0, ShiftLeft(IPAT, 8), Local0)
> +
> + // Adjust panel type, 0 = VBT default
> + // Bits [15:8] - Panel Type
> + // Bits contain the panel type user setting from CMOS
> + // 00h = Not Valid, use default Panel Type & Timings from VBT
> + // 01h - 0Fh = Panel Number
> +
> + Add(Local0, 0x100, Local0)
> +
> + // Report the lid state and Adjust it
> + // Bits [16] - Lid State
> + // Bits contain the current panel lid state
> + // 0 = Lid Open
> + // 1 = Lid Closed
> +
> + Or(Local0, ShiftLeft(LIDS, 16), Local0)
> + Add(Local0, 0x10000, Local0)
> +
> + // Report the BIA setting
> + // Bits [22:20] - Backlight Image Adaptation (BIA) Control
> + // Bits contain the backlight image adaptation control user setting
> from CMOS
> + // 000 = VBT Default
> + // 001 = BIA Disabled (BLC may still be enabled)
> + // 010 - 110 = BIA Enabled at Aggressiveness Level [1 - 5]
> +
> + Or(Local0, ShiftLeft(IBIA, 20), Local0)
> + Return(Local0)
> + }
> + }
> +
> + //
> + // Function Index: 15
> + // GetInternalGraphics
> + // Return: Different Internal Grahics Settings
> + //
> +
> + Case(15) {
> + if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
> + Store("GetInternalGraphics ", Debug)
> +
> + Store(GIVD, Local0) // Local0[0] - VGA mode(1=VGA)
> + Xor(Local0, 1, Local0) // Invert the VGA mode polarity
> +
> + Or(Local0, ShiftLeft(GMFN, 1), Local0) // Local0[1] - # IGD PCI
> functions-1
> + // Local0[3:2] - Reserved
> + // Local0[4] - IGD D3 support(0=cold)
> + // Local0[10:5] - Reserved
> + Or(Local0, ShiftLeft(3, 11), Local0) // Local0[12:11] - DVMT version
> (11b = 5.0)
> +
> + //
> + // Report DVMT 5.0 Total Graphics memory size.
> + //
> + Or(Local0, ShiftLeft(IDMS, 17), Local0) // Bits 20:17 are for Gfx total
> memory size
> +
> + // If the "Set Internal Graphics" call is supported, the modified
> + // settings flag must be programmed per the specification. This
> means
> + // that the flag must be set to indicate that system BIOS requests
> + // these settings. Once "Set Internal Graphics" is called, the
> + // modified settings flag must be cleared on all subsequent calls to
> + // this function.
> +
> + // Report the graphics frequency based on B0:D2:F0:RF0h[12]. Must
> + // take into account the current VCO.
> +
> + Or(ShiftLeft(DeRefOf(Index(DeRefOf(Index(CDCT, HVCO)), CDVL)),
> 21),Local0, Local0)
> + Return(Local0)
> + }
> + }
> +
> + //
> + // Function Index: 16
> + // GetAKSV
> + // Retrun: 5 bytes of AKSV
> + //
> + Case(16) {
> + if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
> +
> + Store("GetAKSV ", Debug)
> + Name (KSVP, Package()
> + {
> + 0x80000000,
> + 0x8000
> + })
> + Store(KSV0, Index(KSVP,0)) // First four bytes of AKSV
> + Store(KSV1, Index(KSVP,1)) // Fifth byte of AKSV
> + Return(KSVP) // Success
> + }
> + }
> + } // End of switch(Arg2)
> +
> + } // End of if (ToUUID("3E5B41C6-EB1D-4260-9D15-C71FBADAE414D"))
> +
> + Return (Buffer () {0x00})
> +} // End of _DSM
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Gbda.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Gbda.asl
> new file mode 100644
> index 0000000000..26e560a358
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Gbda.asl
> @@ -0,0 +1,129 @@
> +/** @file
> + IGD OpRegion/Software SCI Reference Code.
> + This file contains Get BIOS Data Area funciton support for
> + the Integrated Graphics Device (IGD) OpRegion/Software SCI mechanism
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +Method (GBDA, 0, Serialized)
> +{
> + //
> + // Supported calls: Sub-function 0
> + //
> + If (LEqual(GESF, 0))
> + {
> + //
> + //<NOTE> Reference code is set to Intel's validated implementation.
> + //
> + Store(0x0000659, PARM)
> + Store(Zero, GESF) // Clear the exit parameter
> + Return(SUCC) // Success
> + }
> + //
> + // Requested callbacks: Sub-function 1
> + //
> + If (LEqual(GESF, 1))
> + {
> + //
> + //<NOTE> Call back functions are where the driver calls the
> + // system BIOS at function indicated event.
> + //
> + Store(0x300482, PARM)
> + If(LEqual(S0ID, One)){
> + Or(PARM, 0x100, PARM) //Request Fn 8 callback in CS systems
> + }
> + Store(Zero, GESF) // Clear the exit parameter
> + Return(SUCC) // Success
> + }
> + //
> + // Get Boot display Preferences: Sub-function 4
> + //
> + If (LEqual(GESF, 4))
> + {
> + //
> + //<NOTE> Get Boot Display Preferences function.
> + //
> + And(PARM, 0xEFFF0000, PARM) // PARM[30:16] = Boot device ports
> + And(PARM, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), PARM)
> + Or(IBTT, PARM, PARM) // PARM[7:0] = Boot device type
> + Store(Zero, GESF) // Clear the exit parameter
> + Return(SUCC) // Success
> + }
> + //
> + // Panel details: Sub-function 5
> + //
> + If (LEqual(GESF, 5))
> + {
> + //
> + //<NOTE> Get Panel Details function.
> + //
> + Store(IPSC, PARM) // Report the scaling setting
> + Or(PARM, ShiftLeft(IPAT, 8), PARM)
> + Add(PARM, 0x100, PARM) // Adjust panel type, 0 = VBT default
> + Or(PARM, ShiftLeft(LIDS, 16), PARM) // Report the lid state
> + Add(PARM, 0x10000, PARM) // Adjust the lid state, 0 = Unknown
> + Or(PARM, ShiftLeft(IBIA, 20), PARM) // Report the BIA setting
> + Store(Zero, GESF)
> + Return(SUCC)
> + }
> + //
> + // Internal graphics: Sub-function 7
> + //
> + If (LEqual(GESF, 7))
> + {
> + Store(GIVD, PARM) // PARM[0] - VGA mode(1=VGA)
> + Xor(PARM, 1, PARM) // Invert the VGA mode polarity
> + Or(PARM, ShiftLeft(GMFN, 1), PARM) // PARM[1] - # IGD PCI functions-1
> + // PARM[3:2] - Reserved
> + // PARM[4] - IGD D3 support(0=cold)
> + // PARM[10:5] - Reserved
> + Or(PARM, ShiftLeft(3, 11), PARM) // PARM[12:11] - DVMT mode(11b = 5.0)
> +
> + //
> + // Report DVMT 5.0 Total Graphics memory size.
> + //
> + Or(PARM, ShiftLeft(IDMS, 17), PARM) // Bits 20:17 are for Gfx total memory
> size
> + //
> + // If the "Set Internal Graphics" call is supported, the modified
> + // settings flag must be programmed per the specification. This means
> + // that the flag must be set to indicate that system BIOS requests
> + // these settings. Once "Set Internal Graphics" is called, the
> + // modified settings flag must be cleared on all subsequent calls to
> + // this function.
> + // Report the graphics frequency based on B0:D2:F0:RF0h[12]. Must
> + // take into account the current VCO.
> + //
> + Or(ShiftLeft(Derefof(Index(Derefof(Index(CDCT, HVCO)), CDVL)), 21),PARM,
> PARM)
> + Store(1, GESF) // Set the modified settings flag
> + Return(SUCC)
> + }
> + //
> + // Spread spectrum clocks: Sub-function 10
> + //
> + If (LEqual(GESF, 10))
> + {
> + Store(0, PARM) // Assume SSC is disabled
> + If(ISSC)
> + {
> + Or(PARM, 3, PARM) // If SSC enabled, return SSC1+Enabled
> + }
> + Store(0, GESF) // Set the modified settings flag
> + Return(SUCC) // Success
> + }
> +
> + If (LEqual(GESF, 11))
> + {
> + Store(KSV0, PARM) // First four bytes of AKSV
> + Store(KSV1, GESF) // Fifth byte of AKSV
> +
> + Return(SUCC) // Success
> + }
> + //
> + // A call to a reserved "Get BIOS data" function was received.
> + //
> + Store(Zero, GESF) // Clear the exit parameter
> + Return(CRIT) // Reserved, "Critical failure"
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpR
> n.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Rn.asl
> new file mode 100644
> index 0000000000..a26cbdb00c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Rn.asl
> @@ -0,0 +1,296 @@
> +/** @file
> + IGD OpRegion/Software SCI Reference Code.
> + This file contains the interrupt handler code for the Integrated
> + Graphics Device (IGD) OpRegion/Software SCI mechanism.
> + It defines OperationRegions to cover the IGD PCI configuration space
> + as described in the IGD OpRegion specification.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +// Define an OperationRegion to cover the GMCH PCI configuration space as
> +// described in the IGD OpRegion specificiation.
> +//
> +Scope(\_SB.PCI0)
> +{
> + OperationRegion(MCHP, PCI_Config, 0x40, 0xC0)
> + Field(MCHP, AnyAcc, NoLock, Preserve)
> + {
> + Offset(0x14),
> + AUDE, 8,
> +
> + Offset(0x60), // Top of Memory register
> + TASM, 10, // Total system memory (64MB gran)
> + , 6,
> + }
> +}
> +
> +//
> +// Define an OperationRegion to cover the IGD PCI configuration space as
> +// described in the IGD OpRegion specificiation.
> +//
> +OperationRegion(IGDP, PCI_Config, 0x40, 0xC0)
> +Field(IGDP, AnyAcc, NoLock, Preserve)
> +{
> + Offset(0x10), // Mirror of gfx control reg
> + , 1,
> + GIVD, 1, // IGD VGA disable bit
> + , 2,
> + GUMA, 3, // Stolen memory size
> + , 9,
> + Offset(0x14),
> + , 4,
> + GMFN, 1, // Gfx function 1 enable
> + , 27,
> + Offset(0xA4),
> + ASLE, 8, // Reg 0xE4, ASLE interrupt register
> + , 24, // Only use first byte of ASLE reg
> + Offset(0xA8), // Reg 0xE8, SWSCI control register
> + GSSE, 1, // Graphics SCI event (1=event pending)
> + GSSB, 14, // Graphics SCI scratchpad bits
> + GSES, 1, // Graphics event select (1=SCI)
> + Offset(0xB0), // Gfx Clk Frequency and Gating Control
> + , 12,
> + CDVL, 1, // Core display clock value
> + , 3, // Graphics Core Display Clock Select
> + Offset(0xB5),
> + LBPC, 8, // Legacy brightness control
> + Offset(0xBC),
> + ASLS, 32, // Reg 0xFC, Address of the IGD OpRegion
> +}
> +
> +//
> +// Define an OperationRegion to cover the IGD OpRegion layout.
> +//
> +OperationRegion(IGDM, SystemMemory, ASLB, 0x2000)
> +Field(IGDM, AnyAcc, NoLock, Preserve)
> +{
> + //
> + // OpRegion Header
> + //
> + SIGN, 128, // Signature-"IntelGraphicsMem"
> + SIZE, 32, // OpRegion Size
> + OVER, 32, // OpRegion Version
> + SVER, 256, // System BIOS Version
> + VVER, 128, // VBIOS Version
> + GVER, 128, // Driver version
> + MBOX, 32, // Mailboxes supported
> + DMOD, 32, // Driver Model
> + PCON, 32, // Platform Configuration
> + DVER, 64, // GOP Version
> + //
> + // OpRegion Mailbox 1 (Public ACPI Methods)
> + // Note: Mailbox 1 is normally reserved for desktop platforms.
> + //
> + Offset(0x100),
> + DRDY, 32, // Driver readiness (ACPI notification)
> + CSTS, 32, // Notification status
> + CEVT, 32, // Current event
> + Offset(0x120),
> + DIDL, 32, // Supported display device ID list
> + DDL2, 32, // Allows for 8 devices
> + DDL3, 32,
> + DDL4, 32,
> + DDL5, 32,
> + DDL6, 32,
> + DDL7, 32,
> + DDL8, 32,
> + CPDL, 32, // Currently present display list
> + CPL2, 32, // Allows for 8 devices
> + CPL3, 32,
> + CPL4, 32,
> + CPL5, 32,
> + CPL6, 32,
> + CPL7, 32,
> + CPL8, 32,
> + CADL, 32, // Currently active display list
> + CAL2, 32, // Allows for 8 devices
> + CAL3, 32,
> + CAL4, 32,
> + CAL5, 32,
> + CAL6, 32,
> + CAL7, 32,
> + CAL8, 32,
> + NADL, 32, // Next active display list
> + NDL2, 32, // Allows for 8 devices
> + NDL3, 32,
> + NDL4, 32,
> + NDL5, 32,
> + NDL6, 32,
> + NDL7, 32,
> + NDL8, 32,
> + ASLP, 32, // ASL sleep timeout
> + TIDX, 32, // Toggle table index
> + CHPD, 32, // Current hot plug enable indicator
> + CLID, 32, // Current lid state indicator
> + CDCK, 32, // Current docking state indicator
> + SXSW, 32, // Display switch notify on resume
> + EVTS, 32, // Events supported by ASL (diag only)
> + CNOT, 32, // Current OS notifications (diag only)
> + NRDY, 32,
> + //
> + //Extended DIDL list
> + //
> + DDL9, 32,
> + DD10, 32,
> + DD11, 32,
> + DD12, 32,
> + DD13, 32,
> + DD14, 32,
> + DD15, 32,
> + //
> + //Extended Currently attached Display Device List CPD2
> + //
> + CPL9, 32,
> + CP10, 32,
> + CP11, 32,
> + CP12, 32,
> + CP13, 32,
> + CP14, 32,
> + CP15, 32,
> + //
> + // OpRegion Mailbox 2 (Software SCI Interface)
> + //
> + Offset(0x200), // SCIC
> + SCIE, 1, // SCI entry bit (1=call unserviced)
> + GEFC, 4, // Entry function code
> + GXFC, 3, // Exit result
> + GESF, 8, // Entry/exit sub-function/parameter
> + , 16, // SCIC[31:16] reserved
> + Offset(0x204), // PARM
> + PARM, 32, // PARM register (extra parameters)
> + DSLP, 32, // Driver sleep time out
> + //
> + // OpRegion Mailbox 3 (BIOS to Driver Notification)
> + // Note: Mailbox 3 is normally reserved for desktop platforms.
> + //
> + Offset(0x300),
> + ARDY, 32, // Driver readiness (power conservation)
> + ASLC, 32, // ASLE interrupt command/status
> + TCHE, 32, // Technology enabled indicator
> + ALSI, 32, // Current ALS illuminance reading
> + BCLP, 32, // Backlight brightness
> + PFIT, 32, // Panel fitting state or request
> + CBLV, 32, // Current brightness level
> + BCLM, 320, // Backlight brightness level duty cycle mapping table
> + CPFM, 32, // Current panel fitting mode
> + EPFM, 32, // Enabled panel fitting modes
> + PLUT, 592, // Optional. 74-byte Panel LUT Table
> + PFMB, 32, // Optional. PWM Frequency and Minimum Brightness
> + CCDV, 32, // Optional. Gamma, Brightness, Contrast values.
> + PCFT, 32, // Optional. Power Conservation Features
> + SROT, 32, // Supported rotation angle.
> + IUER, 32, // Optional. Intel Ultrabook Event Register.
> + FDSS, 64, // Optional. FFS Display Physical address
> + FDSP, 32, // Optional. FFS Display Size
> + STAT, 32, // State Indicator
> + //
> + // OpRegion Mailbox 4 (VBT)
> + //
> + Offset(0x400),
> + RVBT, 0xC000, // 6K bytes maximum VBT image
> + //
> + // OpRegion Mailbox 5 (BIOS to Driver Notification Extension)
> + //
> + Offset(0x1C00),
> + PHED, 32, // Panel Header
> + BDDC, 2048, // Panel EDID (Max 256 bytes)
> +
> +}
> +
> +//
> +// Convert boot display type into a port mask.
> +//
> +Name (DBTB, Package()
> +{
> + 0x0000, // Automatic
> + 0x0007, // Port-0 : Integrated CRT
> + 0x0038, // Port-1 : DVO-A, or Integrated LVDS
> + 0x01C0, // Port-2 : SDVO-B, or SDVO-B/C
> + 0x0E00, // Port-3 : SDVO-C
> + 0x003F, // [CRT + DVO-A / Integrated LVDS]
> + 0x01C7, // [CRT + SDVO-B] or [CRT + SDVO-B/C]
> + 0x0E07, // [CRT + SDVO-C]
> + 0x01F8, // [DVO-A / Integrated LVDS + SDVO-B]
> + 0x0E38, // [DVO-A / Integrated LVDS + SDVO-C]
> + 0x0FC0, // [SDVO-B + SDVO-C]
> + 0x0000, // Reserved
> + 0x0000, // Reserved
> + 0x0000, // Reserved
> + 0x0000, // Reserved
> + 0x0000, // Reserved
> + 0x7000, // Port-4: Integrated TV
> + 0x7007, // [Integrated TV + CRT]
> + 0x7038, // [Integrated TV + LVDS]
> + 0x71C0, // [Integrated TV + DVOB]
> + 0x7E00 // [Integrated TV + DVOC]
> +})
> +
> +//
> +// Core display clock value table.
> +//
> +Name (CDCT, Package()
> +{
> + Package() {228, 320},
> + Package() {222, 333},
> + Package() {222, 333},
> + Package() { 0, 0},
> + Package() {222, 333},
> +})
> +
> +//
> +// Defined exit result values:
> +//
> +Name (SUCC, 1) // Exit result: Success
> +Name (NVLD, 2) // Exit result: Invalid parameter
> +Name (CRIT, 4) // Exit result: Critical failure
> +Name (NCRT, 6) // Exit result: Non-critical failure
> +
> +/**************************************************************
> **********;
> +;*
> +;* Name: GSCI
> +;*
> +;* Description: Handles an SCI generated by the graphics driver. The
> +;* PARM and SCIC input fields are parsed to determine the
> +;* functionality requested by the driver. GBDA or SBCB
> +;* is called based on the input data in SCIC.
> +;*
> +;* Usage: The method must be called in response to a GPE 06 event
> +;* which will be generated by the graphics driver.
> +;* Ex: Method(\_GPE._L06) {Return(\_SB.PCI0.GFX0.GSCI())}
> +;*
> +;* Input: PARM and SCIC are indirect inputs
> +;*
> +;* Output: PARM and SIC are indirect outputs
> +;*
> +;* References: GBDA (Get BIOS Data method), SBCB (System BIOS Callback
> +;* method)
> +;*
> +;**************************************************************
> **********/
> +
> +Method (GSCI, 0, Serialized)
> +{
> + Include("IgfxOpGbda.asl") // "Get BIOS Data" Functions
> + Include("IgfxOpSbcb.asl") // "System BIOS CallBacks"
> +
> + If (LEqual(GEFC, 4))
> + {
> + Store(GBDA(), GXFC) // Process Get BIOS Data functions
> + }
> +
> + If (LEqual(GEFC, 6))
> + {
> + Store(SBCB(), GXFC) // Process BIOS Callback functions
> + }
> +
> + Store(0, GEFC) // Wipe out the entry function code
> + Store(1, CPSC) // Clear CPUSCI_STS to clear the PCH TCO SCI status
> + Store(0, GSSE) // Clear the SCI generation bit in PCI space.
> + Store(0, SCIE) // Clr SCI serviced bit to signal completion
> +
> + Return(Zero)
> +}
> +
> +Include("IgfxCommon.asl") // IGD SCI mobile features
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpS
> bcb.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpS
> bcb.asl
> new file mode 100644
> index 0000000000..0167d922ff
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpS
> bcb.asl
> @@ -0,0 +1,262 @@
> +/** @file
> + This file contains the system BIOS call back functionality for the
> + OpRegion/Software SCI mechanism.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +Method (SBCB, 0, Serialized)
> +{
> + //
> + // Supported Callbacks: Sub-function 0
> + //
> + If (LEqual(GESF, 0x0))
> + {
> + //
> + //<NOTE> An OEM may support the driver->SBIOS status callbacks, but
> + // the supported callbacks value must be modified. The code that is
> + // executed upon reception of the callbacks must be also be updated
> + // to perform the desired functionality.
> + //
> + Store(0x00000000, PARM) // No callbacks supported
> + //Store(0x000787FD, PARM) // Used for Intel test implementaion
> + Store(0x000F87DD, PARM)
> + Store(Zero, GESF) // Clear the exit parameter
> + Return(SUCC) // "Success"
> + }
> + //
> + // BIOS POST Completion: Sub-function 1
> + //
> + If (LEqual(GESF, 1))
> + {
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Not supported, but no failure
> + }
> + //
> + // Pre-Hires Set Mode: Sub-function 3
> + //
> + If (LEqual(GESF, 3))
> + {
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Not supported, but no failure
> + }
> + //
> + // Post-Hires Set Mode: Sub-function 4
> + //
> + If (LEqual(GESF, 4))
> + {
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Not supported, but no failure
> + }
> + //
> + // Display Switch: Sub-function 5
> + //
> + If (LEqual(GESF, 5))
> + {
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Not supported, but no failure
> + }
> + //
> + // Adapter Power State: Sub-function 7
> + //
> + If (LEqual(GESF, 7))
> + {
> + //
> + // Handle Low Power S0 Idle Capability if enabled
> + //
> + If(LAnd(LEqual(S0ID, 1),LLess(OSYS, 2015))) {
> + //
> + // Call GUAM to trigger CS Entry
> + // If Adapter Power State Notification = D1 (PARM[7:0]=0x01)
> + //
> + If (LEqual (And(PARM,0xFF), 0x01)) {
> + // GUAM - Global User Absent Mode Notification Method
> + \GUAM(One) // 0x01 - Power State Standby (CS Entry)
> + }
> + If (LEqual (And(PARM,0xFF), 0x00)) {
> + // GUAM - Global User Absent Mode Notification Method
> + \GUAM(0)
> + }
> + }
> + //
> + // Upon notification from driver that the Adapter Power State = D0,
> + // check if previous lid event failed. If it did, retry the lid
> + // event here.
> + //
> + If(LEqual(PARM, 0))
> + {
> + Store(CLID, Local0)
> + If(And(0x80000000,Local0))
> + {
> + And(CLID, 0x0000000F, CLID)
> + GLID(CLID)
> + }
> + }
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Not supported, but no failure
> + }
> + //
> + // Display Power State: Sub-function 8
> + //
> + If (LEqual(GESF, 8))
> + {
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Not supported, but no failure
> + }
> + //
> + // Set Boot Display: Sub-function 9
> + //
> + If (LEqual(GESF, 9))
> + {
> + //
> + //<NOTE> An OEM may elect to implement this method. In that case,
> + // the input values must be saved into non-volatile storage for
> + // parsing during the next boot. The following Sample code is Intel
> + // validated implementation.
> + //
> + And(PARM, 0xFF, IBTT) // Save the boot display to NVS
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Reserved, "Critical failure"
> + }
> + //
> + // Set Panel Details: Sub-function 10 (0Ah)
> + //
> + If (LEqual(GESF, 10))
> + {
> + //
> + //<NOTE> An OEM may elect to implement this method. In that case,
> + // the input values must be saved into non-volatile storage for
> + // parsing during the next boot. The following Sample code is Intel
> + // validated implementation.
> + // Set the panel-related NVRAM variables based the input from the driver.
> + //
> + And(PARM, 0xFF, IPSC)
> + //
> + // Change panel type if a change is requested by the driver (Change if
> + // panel type input is non-zero). Zero=No change requested.
> + //
> + If(And(ShiftRight(PARM, 8), 0xFF))
> + {
> + And(ShiftRight(PARM, 8), 0xFF, IPAT)
> + Decrement(IPAT) // 0 = no change, so fit to CMOS map
> + }
> + And(ShiftRight(PARM, 20), 0x7, IBIA)
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Success
> + }
> + //
> + // Set Internal Graphics: Sub-function 11 (0Bh)
> + //
> + If (LEqual(GESF, 11))
> + {
> + //
> + //<NOTE> An OEM may elect to implement this method. In that case,
> + // the input values must be saved into non-volatile storage for
> + // parsing during the next boot. The following Sample code is Intel
> + // validated implementation.
> + //
> + And(ShiftRight(PARM, 1), 1, IF1E) // Program the function 1 option
> + If(And(PARM, ShiftLeft(0xF, 13))) // Use fixed memory if fixed size != 0
> + {
> + //
> + // Fixed memory
> + //
> + And(ShiftRight(PARM, 13), 0xF, IDMS) // Program fixed memory size
> + }
> + Else
> + {
> + //
> + // DVMT memory
> + //
> + And(ShiftRight(PARM, 17), 0xF, IDMS) // Program fixed memory size
> + }
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Success
> + }
> + //
> + // Post-Hires to DOS FS: Sub-function 16 (10h)
> + //
> + If (LEqual(GESF, 16))
> + {
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Not supported, but no failure
> + }
> + //
> + // APM Complete: Sub-function 17 (11h)
> + //
> + If (LEqual(GESF, 17))
> + {
> + Store(ShiftLeft(LIDS, 8), PARM) // Report the lid state
> + Add(PARM, 0x100, PARM) // Adjust the lid state, 0 = Unknown
> + Store(Zero, GESF) // Clear the exit parameter
> + Return(SUCC) // Not supported, but no failure
> + }
> + //
> + // Set Spread Spectrum Clocks: Sub-function 18 (12h)
> + //
> + If (LEqual(GESF, 18))
> + {
> + //
> + //<NOTE> An OEM may elect to implement this method. In that case,
> + // the input values must be saved into non-volatile storage for
> + // parsing during the next boot. The following Sample code is Intel
> + // validated implementation.
> + //
> + If(And(PARM, 1))
> + {
> + If(LEqual(ShiftRight(PARM, 1), 1))
> + {
> + Store(1, ISSC) // Enable HW SSC, only for clock 1
> + }
> + Else
> + {
> + Store(Zero, GESF)
> + Return(CRIT) // Failure, as the SSC clock must be 1
> + }
> + }
> + Else
> + {
> + Store(0, ISSC) // Disable SSC
> + }
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Success
> + }
> + //
> + // Post VBE/PM Callback: Sub-function 19 (13h)
> + //
> + If (LEqual(GESF, 19))
> + {
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Not supported, but no failure
> + }
> + //
> + // Set PAVP Data: Sub-function 20 (14h)
> + //
> + If (LEqual(GESF, 20))
> + {
> + And(PARM, 0xF, PAVP) // Store PAVP info
> + Store(Zero, GESF) // Clear the exit parameter
> + Store(Zero, PARM)
> + Return(SUCC) // Success
> + }
> +
> + //
> + // A call to a reserved "System BIOS callbacks" function was received
> + //
> + Store(Zero, GESF) // Clear the exit parameter
> + Return(SUCC) // Reserved, "Critical failure"
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
> new file mode 100644
> index 0000000000..e4e47ddf1e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
> @@ -0,0 +1,87 @@
> +/** @file
> + This file contains the device definition of the System Agent
> + ACPI reference code.
> + Currently defines the device objects for the
> + System Agent IPU device
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Device IPUA is the IPU AVStream virtual device and it appears under GFX0
> +//
> +Scope (\_SB.PCI0.GFX0)
> +{
> + Device(IPUA) // IPU AVStream virtual device name
> + {
> + /*
> + The identifier for this device (Same as in
> + _DOD above). This is required so GFX driver can
> + associate a matching device ID for the AVStream
> + driver and provide it to PnP (this device ID
> + should appear in the INF file of the AVStream
> + driver).
> + */
> + Name(_ADR, 0x00003480)
> + /*
> + The following is a technique that may be used (per OEM needs) to
> prevent
> + the load of the camera device in one of the following cases:
> + - Camera device is fused out
> + - If the platform setup requires that in a secured boot the camera device
> + should not be enabled
> + */
> + Method (_STA, 0, NotSerialized) {
> + If(LEqual(IPTP,1)){ // IGFX need report IPU AVStream virtual device as
> GFX0 child
> + Return (0xF)
> + } Else { // IGFX should NOT report IPU AVStream virtual device as GFX0
> child
> + Return (0x0)
> + }
> + }
> + } // End SKC0
> +} // end I.G.D
> +
> +Scope(\_SB.PCI0.IPU0)
> +{
> +//----------------------------------------------------------------------------------------
> +// Intel Proprietary Passing LTR information from BIOS to IPU Driver. DSM
> Method
> +//
> +// Method(_DSM, 0x4, Serialized, 0, {IntObj, BuffObj}, {BuffObj, IntObj,
> IntObj, PkgObj})
> +// Arguments:
> +// Arg0: GUID: "9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90"
> +// Arg1: Integer Revision Level (Current revision is 0)
> +// Arg2: Integer Function Index
> +// 0x1 - return UINT 32bit LTR values
> +// 0x2 - return UINT 32bit Fill Time
> +//
> +//-----------------------------------------------------------------------------------------
> +Method (_DSM, 4, NotSerialized) { // _DSM: Device-Specific Method
> + If (LEqual(Arg0, ToUUID("9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90")))
> + {
> + // Function 0 : Query Function
> + If (LEqual(Arg2, 0))
> + {
> + // Revision 0
> + If (LEqual(Arg1, 0)) // The current revision is 0
> + {
> + Return(Buffer() { 0x07 }) // There are 2 function defined other than
> Query.
> + } Else {
> + Return(0) // Revision mismatch
> + }
> + }
> + // Function 1 : Return UINT 32bit LTR values
> + If(LEqual(Arg2, 1))
> + {
> + Return(0x64503C19)
> + }
> + // Function 2 : Return UINT 32bit Fill Time
> + If(LEqual(Arg2, 2))
> + {
> + Return(0xFFF0783C)
> + }
> + }
> +
> + Return(0) // Function number or GUID mismatch but normal return.
> + }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
> new file mode 100644
> index 0000000000..4817968240
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
> @@ -0,0 +1,31 @@
> +/** @file
> + This file contains the device definition of the System Agent
> + ACPI reference code.
> + Currently defines the device objects for the
> + System Agent PCI Express* ports (PEG), iGfx and other devices.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +External(\_SB.PCI0, DeviceObj)
> +External(\_SB.PCI0.GFX0, DeviceObj)
> +External(\_SB.PCI0.IPU0, DeviceObj)
> +External(\_SB.PCI0.B0D3, DeviceObj)
> +External(\_SB.PCI0.PCIC, MethodObj)
> +External(\_SB.PCI0.PCID, MethodObj)
> +
> +
> +///
> +/// I.G.D
> +///
> +Scope (\_SB.PCI0.GFX0)
> +{
> + include("Igfx.asl")
> +} // end I.G.D
> +
> +///
> +/// IPU Device
> +///
> +include("Ipu.asl")
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.a
> sl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.
> asl
> new file mode 100644
> index 0000000000..09d36ade53
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.
> asl
> @@ -0,0 +1,147 @@
> +/** @file
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> + //
> + // Define SA NVS Area operatino region.
> + //
> +
> +
> +
> + OperationRegion(SANV,SystemMemory, 0xFFFF0000,0xAA55)
> + Field(SANV,AnyAcc,Lock,Preserve)
> + { Offset(0), ASLB, 32, // Offset(0), IGD OpRegion base address
> + Offset(4), IMON, 8, // Offset(4), IMON Current Value
> + Offset(5), IGDS, 8, // Offset(5), IGD State (Primary Display = 1)
> + Offset(6), IBTT, 8, // Offset(6), IGD Boot Display Device
> + Offset(7), IPAT, 8, // Offset(7), IGD Panel Type CMOS option
> + Offset(8), IPSC, 8, // Offset(8), IGD Panel Scaling
> + Offset(9), IBIA, 8, // Offset(9), IGD BIA Configuration
> + Offset(10), ISSC, 8, // Offset(10), IGD SSC Configuration
> + Offset(11), IDMS, 8, // Offset(11), IGD DVMT Memory Size
> + Offset(12), IF1E, 8, // Offset(12), IGD Function 1 Enable
> + Offset(13), HVCO, 8, // Offset(13), HPLL VCO
> + Offset(14), GSMI, 8, // Offset(14), GMCH SMI/SCI mode (0=SCI)
> + Offset(15), PAVP, 8, // Offset(15), IGD PAVP data
> + Offset(16), CADL, 8, // Offset(16), Current Attached Device List
> + Offset(17), CSTE, 16, // Offset(17), Current Display State
> + Offset(19), NSTE, 16, // Offset(19), Next Display State
> + Offset(21), NDID, 8, // Offset(21), Number of Valid Device IDs
> + Offset(22), DID1, 32, // Offset(22), Device ID 1
> + Offset(26), DID2, 32, // Offset(26), Device ID 2
> + Offset(30), DID3, 32, // Offset(30), Device ID 3
> + Offset(34), DID4, 32, // Offset(34), Device ID 4
> + Offset(38), DID5, 32, // Offset(38), Device ID 5
> + Offset(42), DID6, 32, // Offset(42), Device ID 6
> + Offset(46), DID7, 32, // Offset(46), Device ID 7
> + Offset(50), DID8, 32, // Offset(50), Device ID 8
> + Offset(54), DID9, 32, // Offset(54), Device ID 9
> + Offset(58), DIDA, 32, // Offset(58), Device ID 10
> + Offset(62), DIDB, 32, // Offset(62), Device ID 11
> + Offset(66), DIDC, 32, // Offset(66), Device ID 12
> + Offset(70), DIDD, 32, // Offset(70), Device ID 13
> + Offset(74), DIDE, 32, // Offset(74), Device ID 14
> + Offset(78), DIDF, 32, // Offset(78), Device ID 15
> + Offset(82), DIDX, 32, // Offset(82), Device ID for eDP device
> + Offset(86), NXD1, 32, // Offset(86), Next state DID1 for _DGS
> + Offset(90), NXD2, 32, // Offset(90), Next state DID2 for _DGS
> + Offset(94), NXD3, 32, // Offset(94), Next state DID3 for _DGS
> + Offset(98), NXD4, 32, // Offset(98), Next state DID4 for _DGS
> + Offset(102), NXD5, 32, // Offset(102), Next state DID5 for _DGS
> + Offset(106), NXD6, 32, // Offset(106), Next state DID6 for _DGS
> + Offset(110), NXD7, 32, // Offset(110), Next state DID7 for _DGS
> + Offset(114), NXD8, 32, // Offset(114), Next state DID8 for _DGS
> + Offset(118), NXDX, 32, // Offset(118), Next state DID for eDP
> + Offset(122), LIDS, 8, // Offset(122), Lid State (Lid Open = 1)
> + Offset(123), KSV0, 32, // Offset(123), First four bytes of AKSV
> (manufacturing mode)
> + Offset(127), KSV1, 8, // Offset(127), Fifth byte of AKSV (manufacturing
> mode)
> + Offset(128), BRTL, 8, // Offset(128), Brightness Level Percentage
> + Offset(129), ALSE, 8, // Offset(129), Ambient Light Sensor Enable
> + Offset(130), ALAF, 8, // Offset(130), Ambient Light Adjusment Factor
> + Offset(131), LLOW, 8, // Offset(131), LUX Low Value
> + Offset(132), LHIH, 8, // Offset(132), LUX High Value
> + Offset(133), ALFP, 8, // Offset(133), Active LFP
> + Offset(134), IPTP, 8, // Offset(134), IPU ACPI device type (0=Disabled,
> 1=AVStream virtual device as child of GFX)
> + Offset(135), EDPV, 8, // Offset(135), Check for eDP display device
> + Offset(136), SGMD, 8, // Offset(136), SG Mode (0=Disabled, 1=SG
> Muxed, 2=SG Muxless, 3=DGPU Only)
> + Offset(137), SGFL, 8, // Offset(137), SG Feature List
> + Offset(138), SGGP, 8, // Offset(138), PCIe0 GPIO Support (0=Disabled,
> 1=PCH Based, 2=I2C Based)
> + Offset(139), HRE0, 8, // Offset(139), PCIe0 HLD RST IO Expander
> Number
> + Offset(140), HRG0, 32, // Offset(140), PCIe0 HLD RST GPIO Number
> + Offset(144), HRA0, 8, // Offset(144), PCIe0 HLD RST GPIO Active
> Information
> + Offset(145), PWE0, 8, // Offset(145), PCIe0 PWR Enable IO Expander
> Number
> + Offset(146), PWG0, 32, // Offset(146), PCIe0 PWR Enable GPIO Number
> + Offset(150), PWA0, 8, // Offset(150), PCIe0 PWR Enable GPIO Active
> Information
> + Offset(151), P1GP, 8, // Offset(151), PCIe1 GPIO Support (0=Disabled,
> 1=PCH Based, 2=I2C Based)
> + Offset(152), HRE1, 8, // Offset(152), PCIe1 HLD RST IO Expander
> Number
> + Offset(153), HRG1, 32, // Offset(153), PCIe1 HLD RST GPIO Number
> + Offset(157), HRA1, 8, // Offset(157), PCIe1 HLD RST GPIO Active
> Information
> + Offset(158), PWE1, 8, // Offset(158), PCIe1 PWR Enable IO Expander
> Number
> + Offset(159), PWG1, 32, // Offset(159), PCIe1 PWR Enable GPIO Number
> + Offset(163), PWA1, 8, // Offset(163), PCIe1 PWR Enable GPIO Active
> Information
> + Offset(164), P2GP, 8, // Offset(164), PCIe2 GPIO Support (0=Disabled,
> 1=PCH Based, 2=I2C Based)
> + Offset(165), HRE2, 8, // Offset(165), PCIe2 HLD RST IO Expander
> Number
> + Offset(166), HRG2, 32, // Offset(166), PCIe2 HLD RST GPIO Number
> + Offset(170), HRA2, 8, // Offset(170), PCIe2 HLD RST GPIO Active
> Information
> + Offset(171), PWE2, 8, // Offset(171), PCIe2 PWR Enable IO Expander
> Number
> + Offset(172), PWG2, 32, // Offset(172), PCIe2 PWR Enable GPIO Number
> + Offset(176), PWA2, 8, // Offset(176), PCIe2 PWR Enable GPIO Active
> Information
> + Offset(177), DLPW, 16, // Offset(177), Delay after power enable for PCIe
> + Offset(179), DLHR, 16, // Offset(179), Delay after Hold Reset for PCIe
> + Offset(181), EECP, 8, // Offset(181), PCIe0 Endpoint Capability
> Structure Offset
> + Offset(182), XBAS, 32, // Offset(182), Any Device's PCIe Config Space
> Base Address
> + Offset(186), GBAS, 16, // Offset(186), GPIO Base Address
> + Offset(188), NVGA, 32, // Offset(188), NVIG opregion address
> + Offset(192), NVHA, 32, // Offset(192), NVHM opregion address
> + Offset(196), AMDA, 32, // Offset(196), AMDA opregion address
> + Offset(200), LTRX, 8, // Offset(200), Latency Tolerance Reporting Enable
> + Offset(201), OBFX, 8, // Offset(201), Optimized Buffer Flush and Fill
> + Offset(202), LTRY, 8, // Offset(202), Latency Tolerance Reporting Enable
> + Offset(203), OBFY, 8, // Offset(203), Optimized Buffer Flush and Fill
> + Offset(204), LTRZ, 8, // Offset(204), Latency Tolerance Reporting Enable
> + Offset(205), OBFZ, 8, // Offset(205), Optimized Buffer Flush and Fill
> + Offset(206), LTRW, 8, // Offset(206), Latency Tolerance Reporting
> Enable
> + Offset(207), OBFA, 8, // Offset(207), Optimized Buffer Flush and Fill
> + Offset(208), SMSL, 16, // Offset(208), SA Peg Latency Tolerance
> Reporting Max Snoop Latency
> + Offset(210), SNSL, 16, // Offset(210), SA Peg Latency Tolerance Reporting
> Max No Snoop Latency
> + Offset(212), P0UB, 8, // Offset(212), Peg0 Unused Bundle Control
> + Offset(213), P1UB, 8, // Offset(213), Peg1 Unused Bundle Control
> + Offset(214), P2UB, 8, // Offset(214), Peg2 Unused Bundle Control
> + Offset(215), P3UB, 8, // Offset(215), Peg3 Unused Bundle Control
> + Offset(216), PCSL, 8, // Offset(216), The lowest C-state for the package
> + Offset(217), PBGE, 8, // Offset(217), Pegx Unused Bundle Control
> Global Enable (0=Disabled, 1=Enabled)
> + Offset(218), M64B, 64, // Offset(218), Base of above 4GB MMIO resource
> + Offset(226), M64L, 64, // Offset(226), Length of above 4GB MMIO
> resource
> + Offset(234), CPEX, 32, // Offset(234), CPU ID info to get Family Id or
> Stepping
> + Offset(238), EEC1, 8, // Offset(238), PCIe1 Endpoint Capability
> Structure Offset
> + Offset(239), EEC2, 8, // Offset(239), PCIe2 Endpoint Capability
> Structure Offset
> + Offset(240), SBN0, 8, // Offset(240), PCIe0 Secondary Bus Number
> (PCIe0 Endpoint Bus Number)
> + Offset(241), SBN1, 8, // Offset(241), PCIe1 Secondary Bus Number
> (PCIe0 Endpoint Bus Number)
> + Offset(242), SBN2, 8, // Offset(242), PCIe2 Secondary Bus Number
> (PCIe0 Endpoint Bus Number)
> + Offset(243), M32B, 32, // Offset(243), Base of below 4GB MMIO resource
> + Offset(247), M32L, 32, // Offset(247), Length of below 4GB MMIO
> resource
> + Offset(251), P0WK, 32, // Offset(251), PCIe0 RTD3 Device Wake GPIO
> Number
> + Offset(255), P1WK, 32, // Offset(255), PCIe1 RTD3 Device Wake GPIO
> Number
> + Offset(259), P2WK, 32, // Offset(259), PCIe2 RTD3 Device Wake GPIO
> Number
> + Offset(263), VTDS, 8, // Offset(263), VT-d Enable/Disable
> + Offset(264), VTB1, 32, // Offset(264), VT-d Base Address 1
> + Offset(268), VTB2, 32, // Offset(268), VT-d Base Address 2
> + Offset(272), VTB3, 32, // Offset(272), VT-d Base Address 3
> + Offset(276), VE1V, 16, // Offset(276), VT-d Engine#1 Vendor ID
> + Offset(278), VE2V, 16, // Offset(278), VT-d Engine#2 Vendor ID
> + Offset(280), SBN3, 8, // Offset(280), PCIe3 Secondary Bus Number
> (PCIe3 Endpoint Bus Number)
> + Offset(281), P3GP, 8, // Offset(281), PCIe3 GPIO Support (0=Disabled,
> 1=PCH Based, 2=I2C Based)
> + Offset(282), HRE3, 8, // Offset(282), PCIe3 HLD RST IO Expander
> Number
> + Offset(283), HRG3, 32, // Offset(283), PCIe3 HLD RST GPIO Number
> + Offset(287), HRA3, 8, // Offset(287), PCIe3 HLD RST GPIO Active
> Information
> + Offset(288), PWE3, 8, // Offset(288), PCIe3 PWR Enable IO Expander
> Number
> + Offset(289), PWG3, 32, // Offset(289), PCIe3 PWR Enable GPIO Number
> + Offset(293), PWA3, 8, // Offset(293), PCIe3 PWR Enable GPIO Active
> Information
> + Offset(294), P3WK, 32, // Offset(294), PCIe3 RTD3 Device Wake GPIO
> Number
> + Offset(298), EEC3, 8, // Offset(298), PCIe3 Endpoint Capability
> Structure Offset
> + Offset(299), RPIN, 8, // Offset(299), RootPort Number
> + Offset(300), RPBA, 32, // Offset(300), RootPortAddress
> + Offset (500), // Offset(304) : Offset(499), Reserved bytes
> + }
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> asl
> new file mode 100644
> index 0000000000..0db354901d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> asl
> @@ -0,0 +1,22 @@
> +/** @file
> + This file contains the SystemAgent SSDT Table ASL code.
> + It defines a Global NVS table which exchanges datas between OS
> + and BIOS.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +DefinitionBlock (
> + "SaSsdt.aml",
> + "SSDT",
> + 0x02,
> + "SaSsdt",
> + "SaSsdt ",
> + 0x3000
> + )
> +{
> + include ("SaNvs.asl")
> + include ("Sa.asl")
> +}
> --
> 2.16.2.windows.1
next prev parent reply other threads:[~2019-08-17 1:15 UTC|newest]
Thread overview: 121+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-17 0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:08 ` Chiu, Chasel
2019-08-17 1:18 ` Chaganty, Rangasai V
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:08 ` Chiu, Chasel
2019-08-17 6:58 ` Chaganty, Rangasai V
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:08 ` Chiu, Chasel
2019-08-17 7:04 ` Chaganty, Rangasai V
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:08 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:09 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:09 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol " Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:09 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register " Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:09 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private " Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:12 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:09 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol " Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:10 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:12 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:12 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:12 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:15 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:12 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:13 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:13 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:13 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:13 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:13 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:14 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:14 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add " Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:14 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:14 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:15 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:15 ` Chiu, Chasel [this message]
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:14 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:15 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-19 18:09 ` Sinha, Ankit
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-17 0:16 ` [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: " Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:17 ` Chiu, Chasel
2019-08-17 20:08 ` Chaganty, Rangasai V
2019-08-17 0:16 ` [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:17 ` Chiu, Chasel
2019-08-17 7:50 ` Chaganty, Rangasai V
2019-08-17 0:16 ` [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-17 20:11 ` Chaganty, Rangasai V
2019-08-17 0:16 ` [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:17 ` Chiu, Chasel
2019-08-17 20:00 ` Chaganty, Rangasai V
2019-08-19 18:14 ` [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Sinha, Ankit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3C3EFB470A303B4AB093197B6777CCEC504623CD@PGSMSX111.gar.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox