From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.31, mailfrom: chasel.chiu@intel.com) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by groups.io with SMTP; Fri, 16 Aug 2019 18:15:19 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 18:15:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="352698107" Received: from pgsmsx112.gar.corp.intel.com ([10.108.55.201]) by orsmga005.jf.intel.com with ESMTP; 16 Aug 2019 18:15:12 -0700 Received: from pgsmsx111.gar.corp.intel.com ([169.254.2.22]) by PGSMSX112.gar.corp.intel.com ([169.254.3.188]) with mapi id 14.03.0439.000; Sat, 17 Aug 2019 09:15:11 +0800 From: "Chiu, Chasel" To: "Kubacki, Michael A" , "devel@edk2.groups.io" CC: "Chaganty, Rangasai V" , "Desimone, Nathaniel L" , "Gao, Liming" , "Kinney, Michael D" , "Sinha, Ankit" Subject: Re: [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Thread-Topic: [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Thread-Index: AQHVVJEdfrSksbC5CE6YodmOXyjQxab+iThw Date: Sat, 17 Aug 2019 01:15:10 +0000 Message-ID: <3C3EFB470A303B4AB093197B6777CCEC504623CD@PGSMSX111.gar.corp.intel.com> References: <20190817001603.30632-1-michael.a.kubacki@intel.com> <20190817001603.30632-29-michael.a.kubacki@intel.com> In-Reply-To: <20190817001603.30632-29-michael.a.kubacki@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMGVmYjkwOTktOTI1ZS00OTI3LWIzM2EtNTA0ZDA3YTk1OTRlIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiUVlEbFVzaGQyXC9XaVJBUDVQZWJQazJmWlRoV0w3cWhITmcwaFJOSzdmZ3VPYjBmUjJzTXp3c1lDVFNGbnJEcmMifQ== x-ctpclassification: CTP_NT x-originating-ip: [172.30.20.206] MIME-Version: 1.0 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Chasel Chiu > -----Original Message----- > From: Kubacki, Michael A > Sent: Saturday, August 17, 2019 8:16 AM > To: devel@edk2.groups.io > Cc: Chaganty, Rangasai V ; Chiu, Chasel > ; Desimone, Nathaniel L > ; Gao, Liming ; > Kinney, Michael D ; Sinha, Ankit > > Subject: [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgen= t: > Add modules >=20 > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D2082 >=20 > * SaAcpiTables - SA (DMAR) ACPI tables. > * SaSsdt - SA SSDT ACPI tables. > * SaInitDxe - Generic DXE SA initialization. > * SmmAccess - Produces an instance of EFI_SMM_ACCESS2_PROTOCOL. >=20 > Cc: Sai Chaganty > Cc: Chasel Chiu > Cc: Nate DeSimone > Cc: Liming Gao > Cc: Michael D Kinney > Cc: Ankit Sinha > Signed-off-by: Michael Kubacki > --- > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.i= nf > | 50 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.i= nf > | 49 + > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf > | 116 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess > .inf | 48 + > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h > | 25 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel > ake/MrcCommonTypes.h | 230 +++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel > ake/MrcInterface.h | 1567 ++++++++++++++++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel > ake/MrcRmtData.h | 203 +++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel > ake/MrcSpdData.h | 1167 ++++++++++++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel > ake/MrcTypes.h | 237 +++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInt > erface.h | 15 + > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h > | 50 + >=20 > 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 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraph > icsInit.h | 17 + > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h > | 53 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess > Driver.h | 162 ++ > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c > | 157 ++ >=20 > 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 +++++++++ >=20 > 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.as= l > | 1666 ++++++++++++++++++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCom > mon.asl | 472 ++++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.= a > sl | 369 +++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGb > da.asl | 129 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn= . > asl | 296 ++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSb= c > b.asl | 262 +++ > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl > | 87 + > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl > | 31 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.as= l > | 147 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.a= sl > | 22 + > 41 files changed, 11970 insertions(+) >=20 > 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.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010005 > +BASE_NAME =3D SaAcpiTables > +FILE_GUID =3D 3c0ed5e2-91ea-4b94-820d-9daf9a3bb4a2 > +MODULE_TYPE =3D USER_DEFINED > +VERSION_STRING =3D 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.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010005 > +BASE_NAME =3D SaSsdt > +FILE_GUID =3D ca89914d-2317-452e-b245-36c6fb77a9c6 > +MODULE_TYPE =3D USER_DEFINED > +VERSION_STRING =3D 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.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D SaInitDxe > +FILE_GUID =3D DE23ACEE-CF55-4fb6-AA77-984AB53DE811 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D DXE_DRIVER > +ENTRY_POINT =3D SaInitEntryPointDxe > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D 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.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D SmmAccess > +FILE_GUID =3D 1323C7F8-DAD5-4126-A54B-7A05FBF41515 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D DXE_DRIVER > +ENTRY_POINT =3D 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _SA_DMAR_H_ > +#define _SA_DMAR_H_ > + > +/// > +/// Include standard ACPI table definitions > +/// > +#include > +#include > + > +#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 API= s. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + 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 =3D 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 =3D 1, > + UDimmMemoryPackage =3D 2, > + SoDimmMemoryPackage =3D 3, > + MicroDimmMemoryPackageDdr3 =3D 4, > + LrDimmMemoryPackageDdr4 =3D 4, > + MiniRDimmMemoryPackage =3D 5, > + MiniUDimmMemoryPackage =3D 6, > + MiniCDimmMemoryPackage =3D 7, > + LpDimmMemoryPackage =3D 7, > + SoUDimmEccMemoryPackageDdr3 =3D 8, > + SoRDimmEccMemoryPackageDdr4 =3D 8, > + SoRDimmEccMemoryPackageDdr3 =3D 9, > + SoUDimmEccMemoryPackageDdr4 =3D 9, > + SoCDimmEccMemoryPackage =3D 10, > + LrDimmMemoryPackage =3D 11, > + SoDimm16bMemoryPackage =3D 12, > + SoDimm32bMemoryPackage =3D 13, > + NonDimmMemoryPackage =3D 14, > + MemoryPackageMax, ///< MEMORY_PACKAGE > enumeration maximum value. > + MemoryPackageDelim =3D 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 =3D 0, ///< Refers to frontside of = DIMM > + LrbufLevel =3D 1, ///< Refers to data level at= backside of > LRDIMM or AEP buffer > + RegALevel =3D 2, ///< Refers to cmd level at = backside of > register - side A > + RegBLevel =3D 3, ///< Refers to cmd level at = backside of > register - side B > + GsmLtMax, ///< GSM_LT enumeration maximu= m > value. > + GsmLtDelim =3D 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 =3D 0, ///< Linear delay (PI ticks)= , where the > positive increment moves the RCVEN sampling window later in time relative= to > the RX DQS strobes. > + RxDqsDelay =3D 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 =3D 2, ///< Linear delay (PI ticks)= , where the > positive increment moves the RX DQ byte/nibble/bitlane later in time rela= tive > to the RX DQS signal (i.e.closing the gap between DQ and DQS in the setup= side > of the eye). > + RxDqsPDelay =3D 3, ///< Linear delay (PI ticks)= , where the > positive increment moves the RX DQS strobe for "even" chunks later in tim= e > 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 =3D 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 =3D 5, ///< Linear increment (Vref = ticks), where the > positive increment moves the byte/nibble/bitlane RX Vref to a higher volt= age. > + RxEq =3D 6, ///< RX CTLE setting indicat= ing a set of > possible resistances, capacitance, current steering, etc. values, which m= ay be a > different set of values per product. The setting combinations are indexed= by > integer values. > + RxDqBitDelay =3D 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 e= ye). > + RxVoc =3D 8, ///< Monotonic increment (Se= nse Amp > setting), where the positive increment moves the byte/nibble/bitlane's > effective switching point to a lower Vref value. > + RxOdt =3D 9, ///< Resistance setting with= in a set of > possible resistances, which may be a different set of values per product. > Indexed by integer values. > + RxOdtUp =3D 10, ///< Resistance setting with= in a set of > possible resistances, which may be a different set of values per product. > Indexed by integer values. > + RxOdtDn =3D 11, ///< Resistance setting with= in a set of > possible resistances, which may be a different set of values per product. > Indexed by integer values. > + DramDrvStr =3D 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 =3D 13, ///< > + McOdtDuration =3D 14, ///< > + SenseAmpDelay =3D 15, ///< This may be used to ind= icate > CmdToDiffAmpEn for SoC's. > + SenseAmpDuration =3D 16, ///< > + RoundTripDelay =3D 17, ///< This may be used to ind= icate > CmdToRdDataValid for SoC's. > + RxDqsBitDelay =3D 18, ///< Linear delay (PI ticks)= , where the > positive increment moves the RX DQS within the bitlane later in time rela= tive > to the RX DQ signal (i.e.closing the gap between DQ and DQS in the hold s= ide of > the eye). > + RxDqDqsDelay =3D 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 th= e 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 DQDQ= S > timings. > + WrLvlDelay =3D 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 =3D 21, ///< Linear delay (PI ticks)= , where the > positive increment moves the TX DQS strobe later in time relative to all = other > bus signals. > + TxDqDelay =3D 22, ///< Linear delay (PI ticks)= , where the > positive increment moves the TX DQ byte/nibble/bitlane later in time rela= tive > to all other bus signals. > + TxVref =3D 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 D= DR4, for > example.) > + TxEq =3D 24, ///< TX EQ setting indicatin= g 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 =3D 25, ///< Linear delay (PI ticks)= , where the > positive increment moves the TX DQ bitlane later in time relative to all = other > bus signals. > + TxRon =3D 26, ///< Resistance setting with= in a set of > possible resistances, which may be a different set of values per product. > Indexed by integer values. > + TxRonUp =3D 27, ///< Resistance setting with= in a set of > possible resistances, which may be a different set of values per product. > Indexed by integer values. > + TxRonDn =3D 28, ///< Resistance setting with= in a set of > possible resistances, which may be a different set of values per product. > Indexed by integer values. > + TxSlewRate =3D 29, ///< Monotonic increment, wh= ere the > positive increment moves the byte/nibble/bitlane's effective slew rate to= a > higher slope. > + TxImode =3D 30, ///< TX I-Mode Boost setting= indicating a > set of possible current boost levels, which may be a different set of val= ues per > product. The setting combinations are indexed by integer values. > + WrOdt =3D 31, ///< Resistance setting with= in a set of > possible resistances, which may be a different set of values per product. > Indexed by integer values. > + NomOdt =3D 32, ///< Resistance setting with= in a set of > possible resistances, which may be a different set of values per product. > Indexed by integer values. > + ParkOdt =3D 33, ///< Resistance setting with= in a set of > possible resistances, which may be a different set of values per product. > Indexed by integer values. > + TxTco =3D 34, ///< > + RxCtleR =3D 36, ///< > + RxCtleC =3D 37, ///< > + RxDqsPBitDelay =3D 38, ///< Linear delay (PI ticks)= , where the > positive increment moves the RX DQS bitlane timing for "even" chunks late= r in > time relative to the RX DQ bitlane signal. Even chunks are 0, 2, 4, 6 wit= hin the > 0 to 7 chunks of an 8 burst length cacheline, for example. > + RxDqsNBitDelay =3D 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 with= in the 0 > to 7 chunks of an 8 burst length cacheline, for example. > + CmdAll =3D 40, ///< Linear delay (PI ticks)= , where the > positive increment moves all signals assigned to the CMD_ALL category lat= er in > time relative to all other signals on the bus. > + CmdGrp0 =3D 41, ///< Linear delay (PI ticks)= , where the > positive increment moves all signals assigned to the CMD_GRP0 category la= ter > in time relative to all other signals on the bus. > + CmdGrp1 =3D 42, ///< Linear delay (PI ticks)= , where the > positive increment moves all signals assigned to the CMD_GRP1 category la= ter > in time relative to all other signals on the bus. > + CmdGrp2 =3D 43, ///< Linear delay (PI ticks)= , where the > positive increment moves all signals assigned to the CMD_GRP2 category la= ter > in time relative to all other signals on the bus. > + CtlAll =3D 44, ///< Linear delay (PI ticks)= , where the > positive increment moves all signals assigned to the CTL_ALL category lat= er in > time relative to all other signals on the bus. > + CtlGrp0 =3D 45, ///< Linear delay (PI ticks)= , where the > positive increment moves all signals assigned to the CTL_GRP0 category la= ter > in time relative to all other signals on the bus. > + CtlGrp1 =3D 46, ///< Linear delay (PI ticks)= , where the > positive increment moves all signals assigned to the CTL_GRP1 category la= ter > in time relative to all other signals on the bus. > + CtlGrp2 =3D 47, ///< Linear delay (PI ticks)= , where the > positive increment moves all signals assigned to the CTL_GRP2 category la= ter > in time relative to all other signals on the bus. > + CtlGrp3 =3D 48, ///< Linear delay (PI ticks)= , where the > positive increment moves all signals assigned to the CTL_GRP3 category la= ter > in time relative to all other signals on the bus. > + CtlGrp4 =3D 49, ///< Linear delay (PI ticks)= , where the > positive increment moves all signals assigned to the CTL_GRP4 category la= ter > in time relative to all other signals on the bus. > + CtlGrp5 =3D 50, ///< Linear delay (PI ticks)= , where the > positive increment moves all signals assigned to the CTL_GRP5 category la= ter > in time relative to all other signals on the bus. > + CmdCtlAll =3D 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 =3D 52, ///< Linear delay (PI ticks)= , where the > positive increment moves all signals assigned to the CK_ALL category late= r in > time relative to all other signals on the bus. > + CmdVref =3D 53, ///< Linear increment (Vref = ticks), where > the positive increment moves the CMD Vref to a higher voltage. > + AlertVref =3D 54, ///< Linear increment (Vref = ticks), where > the positive increment moves the ALERT Vref to a higher voltage. > + CmdRon =3D 55, ///< Resistance setting with= in a set of > possible resistances, which may be a different set of values per product. > Indexed by integer values. > + > + EridDelay =3D 60, ///< Linear delay (PI ticks)= , where the > positive increment moves the ERID signals later in time relative to the i= nternal > sampling clock (i.e.closing the gap between ERID and internal sampling cl= ock in > the setup side of the eye). This group is applicable for DDRT DIMMs. > + EridVref =3D 61, ///< Linear increment (Vref = ticks), where > the positive increment moves the ERID Vref to a higher voltage. This grou= p is > applicable for DDRT DIMMs. > + ErrorVref =3D 62, ///< Linear increment (Vref = ticks), where > the positive increment moves the ERROR Vref to a higher voltage. This gro= up is > applicable for DDRT DIMMs. > + ReqVref =3D 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 =3D 64, ///< Linear delay (PI ticks)= , where the > positive increment moves the RCVEN sampling window later in time relative= to > the RX DQS strobes. > + RxDqsOffset =3D 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 =3D 66, ///< Linear increment (Vref = ticks), where > the positive increment moves the byte/nibble/bitlane RX Vref to a higher > voltage. > + TxDqsOffset =3D 67, ///< Linear delay (PI ticks)= , where the > positive increment moves the TX DQS strobe later in time relative to all = other > bus signals. > + TxDqOffset =3D 68, ///< Linear delay (PI ticks)= , where the > positive increment moves the TX DQ byte/nibble/bitlane later in time rela= tive > to all other bus signals. > + GsmGtMax, ///< SSA_GSM_GT enumeration > maximum value. > + GsmGtDelim =3D INT32_MAX ///< This value ensures the = enum > size is consistent on both sides of the PPI. > +} GSM_GT; > + > +typedef enum { > + SigRasN =3D 0, > + SigCasN =3D 1, > + SigWeN =3D 2, > + SigBa0 =3D 3, > + SigBa1 =3D 4, > + SigBa2 =3D 5, > + SigA0 =3D 6, > + SigA1 =3D 7, > + SigA2 =3D 8, > + SigA3 =3D 9, > + SigA4 =3D 10, > + SigA5 =3D 11, > + SigA6 =3D 12, > + SigA7 =3D 13, > + SigA8 =3D 14, > + SigA9 =3D 15, > + SigA10 =3D 16, > + SigA11 =3D 17, > + SigA12 =3D 18, > + SigA13 =3D 19, > + SigA14 =3D 20, > + SigA15 =3D 21, > + SigA16 =3D 22, > + SigA17 =3D 23, > + SigCs0N =3D 24, > + SigCs1N =3D 25, > + SigCs2N =3D 26, > + SigCs3N =3D 27, > + SigCs4N =3D 28, > + SigCs5N =3D 29, > + SigCs6N =3D 30, > + SigCs7N =3D 31, > + SigCs8N =3D 32, > + SigCs9N =3D 33, > + SigCke0 =3D 34, > + SigCke1 =3D 35, > + SigCke2 =3D 36, > + SigCke3 =3D 37, > + SigCke4 =3D 38, > + SigCke5 =3D 39, > + SigOdt0 =3D 40, //could also be used for CA-ODT for LP4 > + SigOdt1 =3D 41, //could also be used for CA-ODT for LP4 > + SigOdt2 =3D 42, > + SigOdt3 =3D 43, > + SigOdt4 =3D 44, > + SigOdt5 =3D 45, > + SigPar =3D 46, > + SigAlertN =3D 47, > + SigBg0 =3D 48, > + SigBg1 =3D 49, > + SigActN =3D 50, > + SigCid0 =3D 51, > + SigCid1 =3D 52, > + SigCid2 =3D 53, > + SigCk0 =3D 54, > + SigCk1 =3D 55, > + SigCk2 =3D 56, > + SigCk3 =3D 57, > + SigCk4 =3D 58, > + SigCk5 =3D 59, > + SigGnt0 =3D 60, > + SigGnt1 =3D 61, > + SigErid00 =3D 62, > + SigErid01 =3D 63, > + SigErid10 =3D 64, > + SigErid11 =3D 65, > + SigErr0 =3D 66, > + SigErr1 =3D 67, > + SigCa00 =3D 68, // First instantiation of the CA bus for a given = channel > + SigCa01 =3D 69, > + SigCa02 =3D 70, > + SigCa03 =3D 71, > + SigCa04 =3D 72, > + SigCa05 =3D 73, > + SigCa10 =3D 74, // Second instantiation of the CA bus for a given= channel > + SigCa11 =3D 75, > + SigCa12 =3D 76, > + SigCa13 =3D 77, > + SigCa14 =3D 78, > + SigCa15 =3D 79, > + GsmCsnMax, > + GsmCsnDelim =3D 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 "glo= bal > data". > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + 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 b= y the > rank. > +#define CHAR_BITS (8) ///< Number of bits in a char= . > +#define PSMI_SIZE_MB (64) ///< Define the max size of P= SMI > needed in MB > +#define BCLK_DEFAULT (100 * 1000 * 1000) ///< BCLK default v= alue, > 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 =3D=3D SUPPORT) && > ((SUPPORT_DDR3 =3D=3D SUPPORT) && (SUPPORT_LPDDR3 =3D=3D SUPPORT))) > +#define MRC_DDR3_LPDDR_SUPPORTED ((SUPPORT_DDR3 =3D=3D SUPPORT) || > (SUPPORT_LPDDR3 =3D=3D SUPPORT)) > +#define SPD3_MANUF_START 117 ///< The starting point for t= he > SPD manufacturing data. > +#define SPD3_MANUF_END 127 ///< The ending point for the > SPD manufacturing data. > +#if (SUPPORT_DDR4 =3D=3D SUPPORT) > +#define SPD4_MANUF_START 320 ///< The starting point for t= he > SPD manufacturing data. > +#define SPD4_MANUF_END 328 ///< The ending point for the > SPD manufacturing data. > +#endif > +#if (JEDEC_SUPPORT_LPDDR =3D=3D SUPPORT) > +#define SPDLP_MANUF_START 320 ///< The starting point for t= he > 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/Equalizati= on > 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 fl= ow > + 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 w= ith > 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 1= 10 - Power > Limit 2 Time Window X value: 0=3DMinimal, 3=3DMaximum, 1=3DDefault > + UINT8 RaplLim2WindY; ///< Offset 1= 11 - Power > Limit 2 Time Window Y value: 0=3DMinimal, 3=3DMaximum, 1=3DDefault > + UINT8 RaplLim1WindX; ///< Offset 1= 12 - Power > Limit 1 Time Window X value: 0=3DMinimal, 3=3DMaximum > + UINT8 RaplLim1WindY; ///< Offset 1= 13 - Power > Limit 1 Time Window Y value: 0=3DMinimal, 31=3DMaximum > + UINT16 RaplLim2Pwr; ///< Offset 1= 14 - Power > Limit 2: 0=3DMinimal, 16383=3DMaximum, 222=3DDefault > + UINT16 RaplLim1Pwr; ///< Offset 1= 16 - Power > Limit 1: 0=3DMinimal, 16383=3DMaximum > + UINT8 WarmThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///< > Offset 118 - Warm Threshold (Channel 0, Dimm 0): 0=3DMinimal, > 255=3DMaximum > + UINT8 HotThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///< > Offset 122 - Hot Threshold (Channel 0, Dimm 0): 0=3DMinimal, > 255=3DMaximum > + UINT8 WarmBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///< > Offset 126 - Warm Budget (Channel 0, Dimm 0): 0=3DMinimal, > 255=3DMaximum > + UINT8 HotBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///< > Offset 130 - Hot Budget (Channel 0, Dimm 0): 0=3DMinimal, > 255=3DMaximum > + 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 / Equalizatio= n > 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 Equaliza= tion > + 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 =3D 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 =3D 4133 (using Odd ratio mode) > +// RefClk100: 15*200 + 100 =3D 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] =3D 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 =3D 1000, > + VDD_1_05 =3D 1050, > + VDD_1_10 =3D 1100, > + VDD_1_15 =3D 1150, > + VDD_1_20 =3D 1200, > + VDD_1_25 =3D 1250, > + VDD_1_30 =3D 1300, > + VDD_1_35 =3D 1350, > + VDD_1_40 =3D 1400, > + VDD_1_45 =3D 1450, > + VDD_1_50 =3D 1500, > + VDD_1_55 =3D 1550, > + VDD_1_60 =3D 1600, > + VDD_1_65 =3D 1650, > + VDD_1_70 =3D 1700, > + VDD_1_75 =3D 1750, > + VDD_1_80 =3D 1800, > + VDD_1_85 =3D 1850, > + VDD_1_90 =3D 1900, > + VDD_1_95 =3D 1950, > + VDD_2_00 =3D 2000, > + VDD_2_05 =3D 2050, > + VDD_2_10 =3D 2100, > + VDD_2_15 =3D 2150, > + VDD_2_20 =3D 2200, > + VDD_2_25 =3D 2250, > + VDD_2_30 =3D 2300, > + VDD_2_35 =3D 2350, > + VDD_2_40 =3D 2400, > + VDD_2_45 =3D 2450, > + VDD_2_50 =3D 2500, > + VDD_2_55 =3D 2550, > + VDD_2_60 =3D 2600, > + VDD_2_65 =3D 2650, > + VDD_2_70 =3D 2700, > + VDD_2_75 =3D 2750, > + VDD_2_80 =3D 2800, > + VDD_2_85 =3D 2850, > + VDD_2_90 =3D 2900, > + VDD_2_95 =3D 2950, > + VDD_MAXIMUM =3D 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 =3D CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX, > ///< Coffeelake ULT/ULX > + cmCFL_DT_HALO =3D CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO > ///< Coffeelake DT/Halo > +} MrcCpuModel; > + > +/// > +/// Define the CPU Tick/Tock. > +/// > +typedef enum { > + cfCfl =3D 0, ///< Coffeelake > + cfMax > +} MrcCpuFamily; > + > +/// > +/// Define the CPU stepping number. > +/// > +typedef enum { > + /// > + /// Coffeelake ULX/ULT > + /// > + csKblH0 =3D EnumKblH0, > + csCflD0 =3D EnumCflD0, > + csCflW0 =3D EnumCflW0, > + csCflV0 =3D EnumCflV0, > + csCflUlxUltLast =3D csCflV0, > + > + /// > + /// Coffeelake DT/Halo > + /// > + csCflU0 =3D EnumCflU0, > + csCflB0 =3D EnumCflB0, > + csCflP0 =3D EnumCflP0, > + csCflR0 =3D EnumCflR0, > + csCflDtHaloLast =3D 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 disa= bled. > + CHANNEL_PRESENT, ///< There is a channel present and it is enab= led. > + 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 profi= le #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 determ= ines > the MrcFrequency. > + > +typedef enum { > + MRC_FREQ_INVALID =3D 0, > + MRC_FREQ_133 =3D (MRC_BIT0 << MRC_REF_CLOCK_133), // Bit 0 > + MRC_FREQ_100 =3D (MRC_BIT0 << MRC_REF_CLOCK_100), // Bit 1 > + MRC_FREQ_133_ODD_RATIO =3D (MRC_BIT2 << MRC_REF_CLOCK_133), // Bit > 2 > + MRC_FREQ_100_ODD_RATIO =3D (MRC_BIT2 << MRC_REF_CLOCK_100), // Bit > 3 > + MRC_FREQ_MAX // Delimiter > +} MrcFreqFlag; > + > +typedef UINT32 MrcBClkRef; ///< Base clock, in Hertz, Default is 100MH= z 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 =3D 0, > + MRC_DDR_TYPE_DDR3 =3D 1, > + MRC_DDR_TYPE_LPDDR3 =3D 2, > + MRC_DDR_TYPE_UNKNOWN =3D 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 =3D 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 thro= ugh > 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 consum= e by > the ddr on read. > + UINT16 BaseSavingWr; ///< Indicates the base line of power consum= e > by the ddr on write. > + UINT16 BaseSavingCmd; ///< Indicates the base line of power consum= e > 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 minim= um > four activate window delay time. > + UINT16 tRAS; ///< Number of tCK cycles for the channel DIMM's minim= um > 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 minim= um > Average Periodic Refresh Interval. > + UINT16 tRFC; ///< Number of tCK cycles for the channel DIMM's minim= um > 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 minim= um > refresh recovery delay time. > + UINT16 tRFC4; ///< Number of tCK cycles for the channel DIMM's minim= um > refresh recovery delay time. > + UINT16 tRPab; ///< Number of tCK cycles for the channel DIMM's minim= um > row precharge delay time for all banks. > + UINT16 tRRD; ///< Number of tCK cycles for the channel DIMM's minim= um > 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 minim= um > internal read to precharge command delay time. > + UINT16 tWR; ///< Number of tCK cycles for the channel DIMM's minim= um > 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 b= e > located at the start of the SPD data structure. It includes this string p= lus 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 =3D memory down, 1 =3D socketed. > + } Bit; > + UINT8 Data; > + } Flag; > + MrcSpd Data; ///< The SPD data for each DIMM. SPDGeneral fi= eld =3D > 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, U= INT8 > 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, UINT= 8 > *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, UINT= 32 > 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 struct= ure. > +/// > +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 s= et 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 se= t 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 =3D=3D 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 se= t 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) setti= ng > 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 add= ress > mirrored. > + BOOLEAN SelfRefreshTemp; ///< TRUE if the DIMM suppor= ts > self refresh extended operating temperature range (SRT). > + BOOLEAN AutoSelfRefresh; ///< TRUE if the DIMM suppor= ts > automatic self refresh (ASR). > + BOOLEAN PartialSelfRefresh; ///< TRUE if the DIMM suppor= ts > Partial Array Self Refresh (PASR). > + BOOLEAN OnDieThermalSensor; ///< TRUE if the DIMM suppor= ts > 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 =3D 2x. > + MrcDdrType DdrType; ///< DDR type: DDR3 or LPDDR= 3 > + 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 s= ize. > + UINT16 ColumnSize; ///< The DIMMs column addres= s 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 DIM= M > contains. > + UINT8 BankGroups; ///< Number of bank groups t= he > DIMM contains. > + UINT8 PrimaryBusWidth; ///< DIMM primary bus width. > + UINT8 SdramWidth; ///< DIMM SDRAM width. > + UINT8 SdramWidthIndex; ///< DIMM SDRAM width index = (0 =3D > x4, 1 =3D x8, 2 =3D x16, 3 =3D x32). > + UINT8 DensityIndex; ///< Total SDRAM capacity in= dex (0 =3D > 256Mb, 1 =3D 512Mb, 2 =3D 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 profil= es are > supported. 0 =3D None, 1 =3D XMP1 only, 2 =3D XMP2 only, 3 =3D All. > + UINT8 XmpRevision; ///< Indicates the XMP revis= ion of this > DIMM. 0 =3D None, 12h =3D 1.2, 13h =3D 1.3. > + MrcFrequency Speed; ///< Max DIMM speed in the c= urrent > 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 Rea= d > command. > + MrcTurnaroundTimes tRd2Wr; > ///< The system's minimal delay timings for Read command followed by Wri= te > command. > + MrcTurnaroundTimes tWr2Rd; > ///< The system's minimal delay timings for Write command followed by Rea= d > command. > + MrcTurnaroundTimes tWr2Wr; > ///< The system's minimal delay timings for Write command followed by Wri= te > 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 con= troller > should be used. > + UINT16 DeviceId; ///< The PCI device id of this = memory > controller. > + UINT8 RevisionId; ///< The PCI revision id of thi= s memory > controller. > + UINT8 ChannelCount; ///< Number of valid channels t= hat > 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 fas= t > 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 fas= t > and warm boot modes. > +/// The following are channel level definitions. > +/// > +typedef struct { > + MrcChannelSts Status; ///< Indicates whe= ther this > channel should be used. > + UINT32 DimmCount; ///< Number of val= id DIMMs > that exist in the channel. > + UINT8 ValidRankBitMask; ///< Bit map of th= e > populated ranks per channel > + MrcTiming Timing[MAX_PROFILE]; ///< The channel t= iming > 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 fas= t > and warm boot modes. > +/// The following are controller level definitions. > +/// > +typedef struct { > + MrcControllerSts Status; ///< Indicates whether this co= ntroller > 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 fas= t > and warm boot modes. > +/// The following are system level definitions. > +/// > +typedef struct { > + UINT32 Crc; ///< The CRC-32 of the data in this struc= ture. > +} 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 me= mory > 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 ma= nagebility > engine memory size, in Mbyte units. > + MrcCpuStepping CpuStepping; ///< The la= st cold > boot happended with this CPU stepping. > + MrcCpuModel CpuModel; ///< The la= st cold > boot happended with this CPU model. > + MrcCpuFamily CpuFamily; ///< CPU is= Coffeelake > + MrcVersion Version; ///< The la= st cold boot > happended with this MRC version. > + UINT32 SaMemCfgCrc; ///< The CR= C32 of the > system agent memory configuration structure. > + MrcContSave Controller[MAX_CONTROLLERS]; ///< The > following are controller level definitions. > + MrcFrequency FreqMax; ///< The sy= stem's > requested maximum frequency. > + MrcFrequency Frequency; ///< The sy= stem's > common memory controller frequency. > + UINT32 MemoryClock; ///< The sy= stem'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 f= or > SAGV Low point. > + BOOLEAN OddRatioModeHigh; ///< If Odd= Ratio > Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is f= or > SAGV High point, or SAGV disabled / fixed high / fixed low > + MrcRefClkSelect RefClk; ///< The me= mory > controller is going to use this reference clock. > + MrcClockRatio Ratio; ///< Reques= t for this > memory controller to use this clock ratio. > + MrcVddSelect VddVoltage[MAX_PROFILE]; ///< The vo= ltage > (VDD) setting for all DIMMs in the system, per profile. > + BOOLEAN EccSupport; ///< TRUE i= f ECC is > enabled and supported on this controller. > + MrcDdrType DdrType; ///< DDR ty= pe: 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 amon= g > all DIMMs. > + BOOLEAN BinnedLpddrDevices; ///< Binned= LPDDR3 > devices (6Gb/12Gb/etc) > + BOOLEAN TCRSensitiveHynixDDR4; ///< TCR se= nsitive > Hynix DDR4 in the system > + BOOLEAN TCRSensitiveMicronDDR4; ///< TCR se= nsitive > Micron DDR4 in the system > + BOOLEAN LpddrEctDone; ///< Set to TRUE o= nce Early > Command Training on LPDDR is done, and we can run JEDEC Init > + UINT8 BerEnable; ///< BER Enable (a= nd # 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 relate= d > variables used for serial output and debugging purposes. > + MrcVersion Version; ///< The memory refer= ence code > version. > + MrcFrequency FreqMax; ///< The requested ma= ximum > valid frequency. > + MrcFrequency Frequency; ///< The system's com= mon > memory controller frequency. > + UINT32 MemoryClockMax; ///< The system's com= mon > memory controller maximum clock, in femtoseconds. > + UINT32 MemoryClock; ///< The system's com= mon > memory controller clock, in femtoseconds. > + MrcRefClkSelect RefClk; ///< The memory contr= oller 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 St= olen > Memory size in MB > + MrcGfxGttSize GraphicsGttSize; ///< GTT graphics sto= len > 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 e= nabled and > supported on this controller. > + BOOLEAN EnDumRd; ///< Enable/Disable L= ogic > Analyzer > + BOOLEAN RestoreMRs; ///< Enable/Disable r= estoring > + 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 D= IMMs are > detected, this will indicate which XMP Profiles are common among all DIMM= s. > + BOOLEAN Capable100; ///< The MC is capabl= e of 100 > reference clock (0 =3D no, 1 =3D yes). > + BOOLEAN AutoSelfRefresh; ///< Indicates ASR is > supported for all the DIMMS for 2xRefresh > + MrcDdrType DdrType; ///< Current memory t= ype: > DDR3, DDR4, or LPDDR3 > + MrcSpdStatus SpdSecurityStatus; ///< Status variable = to > inform BIOS that memory contains an alias. > + UINT32 MrcTotalChannelLimit; ///< The maximum allo= wed > memory size per channel, in MBytes. > + UINT8 SdramCount; ///< The number of SD= RAM > components on a DIMM. > + UINT16 Qclkps; ///< Qclk period in p= S > + 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 - i= ncludes > both channels > + UINT8 ValidChBitMask; ///< Channel bit map = of the > populated channels > + BOOLEAN UpmPwrRetrainFlag; ///< A flag that indi= cates 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 saving= s > data. > + BOOLEAN TxDIMMVref[MAX_CHANNEL]; ///< Whether Write > DIMM Vref is enabled based on Channel > + UINT32 MchBarWriteCount; ///< The number of MM= IO > writes performed during MRC execution. > + UINT32 MchBarReadCount; ///< The number of MM= IO > reads performed during MRC execution. > + UINT8 BerEnable; ///< BER Enable (and = # of > Addresses) > + UINT64 BerAddress[4]; ///< BER Addresses > + UINT8 CmdVLoop; ///< Keeps track of t= he # of > CmdV training step runned > + UINT8 CmdVLoopStatus; ///< Keeps the last s= tatus of > the CmdV training step > + UINT8 tMAC; ///< Maximum Activate= Count for > pTRR. > + UINT8 LpddrMemWriteLatencySet; ///< 0 =3D Set A (WL)= , 1 =3D Set > B (WL) if supported > + BOOLEAN Ddr4PdaEnable; ///< Current status o= f PDA - if > true all the Mr6 operations need to use PDA mode. > + BOOLEAN BinnedLpddrDevices; ///< Binned LPDDR3 de= vices > (6Gb/12Gb/etc) > + MrcControllerOut Controller[MAX_CONTROLLERS]; ///< The following > are controller level definitions. > + BOOLEAN TCRSensitiveHynixDDR4; ///< TCR sensitive Hy= nix > DDR4 in the system > + BOOLEAN TCRSensitiveMicronDDR4; ///< TCR sensitive Mi= cron > DDR4 in the system > + BOOLEAN OddRatioMode; ///< If Odd Ratio Mod= e is > enabled, QCLK frequency has an addition of 133/100 MHz > + BOOLEAN LpddrDramOdt; ///< Indicates if LPD= DR > 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 B= DAT > 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 s= et 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 se= t 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 se= t to > these values. > +/// > +typedef struct { > + MrcDimmSts Status; ///< Indicates whether this DIMM s= hould > be used. > + MrcSpdData Spd; ///< The SPD data for each DIMM. > SPDGeneral field =3D 0 when absent. > + MrcTiming Timing; ///< The DIMMs requested timing > overrides. > + UINT8 SpdAddress; ///< The SMBus address for the DIM= M'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 th= is channel > should be used. > + UINT32 DimmCount; ///< The maximum number o= f > 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] - ClkDQ= ByteMap: > + ///< If clock is per ra= nk, 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] d= efines which DQ > bytes Group i services > + ///< DQByteMap[1] - CmdND= QByteMap: > Entry[0] is CmdN/CAA and Entry[1] is CmdN/CAB > + ///< DQByteMap[2] - CmdSD= QByteMap: > Entry[0] is CmdS/CAA and Entry[1] is CmdS/CAB > + ///< DQByteMap[3] - CkeDQ= ByteMap : > Entry[0] is CKE /CAA and Entry[1] is CKE /CAB > + ///< For D= DR, DQByteMap[3:1] > =3D [0xFF, 0] > + ///< DQByteMap[4] - CtlDQ= ByteMap : > Always program to [0xFF, 0] since we have 1 CTL / rank > + ///< = Variable only > exists to make the code easier to use > + ///< DQByteMap[5] - CmdVD= QByteMap: > 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 co= ntroller > 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 i= n 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 m= atch. > + UINT8 Header[28]; ///< Offset 0-27 Config Block Header > + UINT16 Size; ///< Offset 28 The size of this struct= ure, 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 selecti= on - for > XMP supported DIMM: 0=3DDefault DIMM profile, 1=3DCustomized profi= le, > 2=3DXMP profile 1, 3=3DXMP profile 2. > + // The following parameters are used only when MemoryProfile is > UserDefined (CUSTOM PROFILE) > + UINT16 tCL; ///< Offset 32 User defined Memory Tim= ing tCL > value, valid when MemoryProfile is CUSTOM_PROFILE: 0=3DAUTO, > 31=3DMaximum. > + UINT16 tRCDtRP; ///< Offset 34 User defined Memory Tim= ing > tRCD value (same as tRP), valid when MemoryProfile is CUSTOM_PROFILE: > 0=3DAUTO, 63=3DMaximum. > + UINT16 tRAS; ///< Offset 36 User defined Memory Tim= ing > tRAS value, valid when MemoryProfile is CUSTOM_PROFILE: 0=3DAUTO, > 64=3DMaximum. > + UINT16 tWR; ///< Offset 38 User defined Memory Tim= ing > tWR value, valid when MemoryProfile is CUSTOM_PROFILE: 0=3DAUTO, > legal values: 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 24. > + UINT16 tRFC; ///< Offset 40 User defined Memory Tim= ing > tRFC value, valid when MemoryProfile is CUSTOM_PROFILE: 0=3DAUTO, > 1023=3DMaximum. > + UINT16 tRRD; ///< Offset 42 User defined Memory Tim= ing > tRRD value, valid when MemoryProfile is CUSTOM_PROFILE: 0=3DAUTO, > 15=3DMaximum. > + UINT16 tWTR; ///< Offset 44 User defined Memory Tim= ing > tWTR value, valid when MemoryProfile is CUSTOM_PROFILE: 0=3DAUTO, > 28=3DMaximum. > + UINT16 tRTP; ///< Offset 46 User defined Memory Tim= ing > tRTP value, valid when MemoryProfile is CUSTOM_PROFILE: 0=3DAUTO, > 15=3DMaximum. DDR4 legal values: 5, 6, 7, 8, 9, 10, 12 > + UINT16 tFAW; ///< Offset 48 User defined Memory Tim= ing > tFAW value, valid when MemoryProfile is CUSTOM_PROFILE: 0=3DAUTO, > 63=3DMaximum. > + UINT16 tCWL; ///< Offset 50 User defined Memory Tim= ing > tCWL value, valid when MemoryProfile is CUSTOM_PROFILE: 0=3DAUTO, > 20=3DMaximum. > + UINT16 tREFI; ///< Offset 52 User defined Memory Tim= ing > tREFI value, valid when MemoryProfile is CUSTOM_PROFILE: 0=3DAUTO, > 65535=3DMaximum. > + UINT16 PciIndex; ///< Offset 54 Pci index register addr= ess: > 0xCF8=3DDefault > + UINT16 PciData; ///< Offset 56 Pci data register addre= ss: > 0xCFC=3DDefault > + UINT16 VddVoltage; ///< Offset 58 DRAM voltage (Vdd) in > millivolts: 0=3DPlatform Default (no override), 1200=3D1.2V, 1350= =3D1.35V > etc. > + UINT16 Idd3n; ///< Offset 60 EPG Active standby curr= ent > (Idd3N) in milliamps from DIMM datasheet. > + UINT16 Idd3p; ///< Offset 62 EPG Active power-down c= urrent > (Idd3P) in milliamps from DIMM datasheet. > + > + UINT32 EccSupport:1; ///< Offset 64 DIMM Ecc Suppor= t > option - for Desktop only: 0=3DDisable, 1=3DEnable > + UINT32 MrcSafeConfig:1; ///< - MRC Safe Mode: > 0=3DDisable, 1=3DEnable > + UINT32 RemapEnable:1; ///< - This option is used to= control > whether to enable/disable memory remap above 4GB: 0=3DDisable, > 1=3DEnable. > + UINT32 ScramblerEnable:1; ///< - Memory scrambler suppo= rt: > 0=3DDisable, 1=3DEnable > + UINT32 Vc1ReadMeter:1; ///< - VC1 Read Metering Enab= le: > 0=3DDisable, 1=3DEnable > + UINT32 DdrThermalSensor:1; ///< - Ddr Thermal Sensor: > 0=3DDisable, 1=3DEnable > + UINT32 LpddrMemWriteLatencySet:1; ///< - LPDDR3 Write Latency S= et > option: 0=3DSet A, 1=3DSet B > + UINT32 Off64Bits7to8Rsvd:2; ///< - Bits 7-8 Reserved > + UINT32 SimicsFlag:1; ///< - Option to Enable SIMIC= S: > 0=3DDisable, 1=3DEnable > + UINT32 Ddr4DdpSharedClock:1; ///< - New Select if CLK0 is = shared > between Rank0 and Rank1 in DDR4 DDP package. 0=3DNot shared, > 1=3DShared > + UINT32 Ddr4DdpSharedZq:1; ///< - Select if ZQ pin is sh= ared > between Rank0 and Rank1 in DDR4 DDP package. 0=3DNot shared, > 1=3DShared > + // Thermal Management > + UINT32 ThermalManagement:1; ///< - Memory Thermal > Management Support: 0=3DDisable, 1=3DEnable. > + UINT32 PeciInjectedTemp:1; ///< - Enable/Disable memory > temperatures to be injected to the processor via PECI: 0=3DDisable= , > 1=3DEnable. > + UINT32 ExttsViaTsOnBoard:1; ///< - Enable/Disable routing > TS-on-Board's ALERT# and THERM# to EXTTS# pins on the PCH: > 0=3DDisable, 1=3DEnable. > + UINT32 ExttsViaTsOnDimm:1; ///< - Enable/Disable routing > TS-on-DIMM's ALERT# to EXTTS# pin on the PCH: 0=3DDisable, 1=3DEna= ble. > + UINT32 VirtualTempSensor:1; ///< - Enable/Disable Virtual > Temperature Sensor (VTS): 0=3DDisable, 1=3DEnable. > + UINT32 Lp4DqsOscEn:1; ///< - DqDqsReTraining suppor= t: > 0=3DDisable, 1=3DEnable > + UINT32 DualDimmPerChannelBoardType:1; ///< - > DualDimmPerChannelBoardType: Option to indicate if the Memory Design for > the board includes two DIMMs per channel: 0=3DSingle DIMM Design, > 1=3DDual 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 =3D channel 0, 1 =3D cha= nnel 1)\n > + 0x0 =3D DIMM 0 and DIMM 1 enabled\n > + 0x1 =3D DIMM 0 disabled, DIMM 1 enabled\n > + 0x2 =3D DIMM 0 enabled, DIMM 1 disabled\n > + 0x3 =3D 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 freq= uency\n > + When RefClk is 133MHz\n > + 0x00 =3D Auto, 0x03 through 0x0C are valid values, all others = are > invalid\n > + When RefClk is 100MHz\n > + 0x00 =3D Auto, 0x06 through 0x10 are valid values, all others = are > invalid\n > + **/ > + UINT8 Ratio; ///< Offset 70 > + UINT8 ProbelessTrace; ///< Offset 71 Probeless Trace: > 0=3DDisabled, 1=3DEnabled > + UINT32 BClkFrequency; ///< Offset 72 Base reference clock va= lue, in > Hertz: 100000000 =3D 100Hz, 125000000=3D125Hz, 167000000=3D167Hz, > 250000000=3D250Hz > + /** > + - Channel Hash Enable.\n > + NOTE: BIT7 will interleave the channels at a 2 cacheline granularity= , BIT8 at > 4 and BIT9 at 8\n > + 0=3DBIT6, 1=3DBIT7, 2=3DBIT8, 3=3DBIT9 > + **/ > + UINT8 ChHashInterleaveBit; ///< Offset 76 > + UINT8 EnergyScaleFact; ///< Offset 77 - Energy Scale Factor. > 0=3DMinimal, 7=3DMaximum, 4=3DDefault > + UINT8 Reserved0; ///< Offset 78 - Reserved for future u= se. > + UINT8 McLock; ///< Offset 79 - Enable/Disable memory > configuration register locking: 0=3DDisable, 1=3DEnable. > + // 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: 0=3DDisable, > 1=3DEnable > + UINT32 MrcTimeMeasure:1; ///< - Enables serial debug level = to > display the MRC execution times only: 0=3DDisable, 1=3DEnable > + UINT32 MrcFastBoot:1; ///< - Enables the MRC fast boot p= ath for > faster cold boot execution: 0=3DDisable, 1=3DEnable > + UINT32 DqPinsInterleaved:1; ///< - Interleaving mode of DQ/DQS= pins > for HSW_ULT which depends on board routing: 0=3DDisable, 1=3DEnabl= e > + UINT32 RankInterleave:1; ///< - Rank Interleave Mode: 0=3DD= isable, > 1=3DEnable > + UINT32 EnhancedInterleave:1; ///< - Enhanced Interleave Mode: > 0=3DDisable, 1=3DEnable > + UINT32 WeaklockEn:1; ///< - Weak Lock Enable: 0=3DDisab= le, > 1=3DEnable > + UINT32 CmdTriStateDis:1; ///< - CMD Tri-State Support: > 0=3DEnable, 1=3DDisable. Note: This should be set to 1 (Disable) i= f > Command RTT is not present on the platform. > + UINT32 MemoryTrace:1; ///< - Memory Trace to second DDR > channel using Stacked Mode: 0=3DDisable, 1=3DEnable > + UINT32 ChHashEnable:1; ///< - Channel Hash Enable: 0=3DDi= sable, > 1=3DEnable > + UINT32 EnableExtts:1; ///< - Enable Extts: 0=3DDisabl= e, > 1=3DEnable > + UINT32 EnableCltm:1; ///< - Enable Closed Loop Thermal > Management: 0=3DDisable, 1=3DEnable > + UINT32 EnableOltm:1; ///< - Enable Open Loop Thermal > Management: 0=3DDisable, 1=3DEnable > + UINT32 EnablePwrDn:1; ///< - Enable Power Down control f= or > DDR: 0=3DPCODE control, 1=3DBIOS control > + UINT32 EnablePwrDnLpddr:1; ///< - Enable Power Down for LPDDR= : > 0=3DPCODE control, 1=3DBIOS control > + UINT32 LockPTMregs:1; ///< - Lock PCU Thermal Management > registers: 0=3DDisable, 1=3DEnable > + UINT32 UserPowerWeightsEn:1; ///< - Allows user to explicitly s= et > power weight, scale factor, and channel power floor values: 0=3DDisabl= e, > 1=3DEnable > + UINT32 RaplLim2Lock:1; ///< - Lock DDR_RAPL_LIMIT registe= r: > 0=3DDisable, 1=3DEnable > + UINT32 RaplLim2Ena:1; ///< - Enable Power Limit 2: > 0=3DDisable, 1=3DEnable > + UINT32 RaplLim1Ena:1; ///< - Enable Power Limit 1: > 0=3DDisable, 1=3DEnable > + UINT32 SrefCfgEna:1; ///< - Enable Self Refresh: 0=3DDi= sable, > 1=3DEnable > + UINT32 ThrtCkeMinDefeatLpddr:1; ///< - Throttler CKE min defeature= for > LPDDR: 0=3DDisable, 1=3DEnable > + UINT32 ThrtCkeMinDefeat:1; ///< - Throttler CKE min defeature= : > 0=3DDisable, 1=3DEnable > + UINT32 AutoSelfRefreshSupport:1; ///< - FALSE =3D No auto self refr= esh > support, TRUE =3D auto self refresh support > + UINT32 ExtTemperatureSupport:1; ///< - FALSE =3D No extended > temperature support, TRUE =3D extended temperature support > + UINT32 MobilePlatform:1; ///< - Memory controller device id > indicates: TRUE if mobile, FALSE if not. Note: This will be > auto-detected and updated. > + UINT32 Force1Dpc:1; ///< - TRUE means force one DIMM p= er > channel, FALSE means no limit > + UINT32 ForceSingleRank:1; ///< - TRUE means use Rank0 only (= in > each DIMM): 0=3DDisable, 1=3DEnable > + UINT32 RhPrevention:1; ///< - RH Prevention Enable/Disabl= e: > 0=3DDisable, 1=3DEnable > + UINT32 VttTermination:1; ///< - Vtt Termination for Data OD= T: > 0=3DDisable, 1=3DEnable > + UINT32 VttCompForVsshi:1; ///< - Enable/Disable Vtt Comparat= or > For Vsshi: 0=3DDisable, 1=3DEnable > + UINT32 ExitOnFailure:1; ///< - MRC option for exit on fail= ure or > continue on failure: 0=3DDisable, 1=3DEnable > + > + UINT32 VddSettleWaitTime; ///< Offset 92 - Amount of time in > microseconds to wait for Vdd to settle on top of 200us required by JEDEC = spec: > Default=3D0 > + UINT16 FreqSaGvLow; ///< Offset 96 - SA GV: 0 is Auto/defa= ult, > otherwise holds the frequency value: 0=3DDefault, 1067, 1200, 1333= , > 1400, 1600, 1800, 1867. > + UINT16 SrefCfgIdleTmr; ///< Offset 98 - Self Refresh idle tim= er: > 512=3DMinimal, 65535=3DMaximum > + UINT8 RhActProbability; ///< Offset 100 - Activation probabili= ty for > Hardware RHP > + UINT8 SmramMask; ///< Offset 101 - Reserved memory rang= es > for SMRAM > + UINT16 Vc1ReadMeterThreshold; ///< Offset 102 - VC1 Read Meter > Threshold (within Time Window): 0=3DMinimal, 0xFFFF=3DMaximum, > 0x118=3DDefault > + UINT32 Vc1ReadMeterTimeWindow; ///< Offset 104 - VC1 Read Meter > Time Window: 0=3DMinimal, 0x1FFFF=3DMaximum, 0x320=3DDefault > + UINT64 BerAddress[4]; ///< Offset 108 - 139 BER Address(es): > 0=3DMinimal, 0xFFFFFFFFFFFFFFFF=3DMaximum (step is 0x40) > + > + UINT16 ChHashMask; ///< Offset 140 - Channel Hash Mask: > 0x0001=3DBIT6 set(Minimal), 0x3FFF=3DBIT[19:6] set(Maximum), 0x30CE=3D > BIT[19:18, 13:12 ,9:7] set > + UINT16 DdrFreqLimit; ///< Offset 142 - Memory Frequency Lim= it: > 0=3DAuto (limited by SPD/CPU capability), 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: 0=3DODT Off, 1 =3D 120 ohms > + UINT8 ThrtCkeMinTmr; ///< Offset 189 - Throttler CKE min ti= mer: > 0=3DMinimal, 0xFF=3DMaximum, 0x30=3DDefault > + UINT8 ThrtCkeMinTmrLpddr; ///< Offset 190 - Throttler CKE min ti= mer > for LPDDR: 0=3DMinimal, 0xFF=3DMaximum, 0x40=3DDefault > + UINT8 BerEnable; ///< Offset 191 - BER Enable and # of > Addresses passed in: 0=3DMinimal, 8=3DMaximum > + UINT8 CkeRankMapping; ///< Offset 192 - Bits [7:4] - Channel= 1, bits > [3:0] - Channel 0. 0xAA=3DDefault Bit [i] specifies which rank CKE= [i] goes > to. > + UINT8 StrongWkLeaker; ///< Offset 193 - Strong Weak Leaker: > 1=3DMinimal, 7=3DMaximum > + UINT8 CaVrefConfig; ///< Offset 194 - 0=3DVREF_CA goes to = both > CH_A and CH_B, 1=3DVREF_CA to CH_A, VREF_DQ_A to CH_B, 2=3DVREF_CA to > CH_A, VREF_DQ_B to CH_B > + UINT8 SaGv; ///< Offset 195 - SA GV: 0=3DDisabl= ed, > 1=3DFixedLow, 2=3DFixedHigh, 3=3DEnabled > + UINT8 RaplPwrFlCh1; ///< Offset 196 - Power Channel 1 Floo= r value: > 0=3DMinimal, 255=3DMaximum > + UINT8 RaplPwrFlCh0; ///< Offset 197 - Power Channel 0 Floo= r value: > 0=3DMinimal, 255=3DMaximum > + UINT8 NModeSupport; ///< Offset 198 - Memory N Mode Suppor= t > - Enable user to select Auto, 1N or 2N: 0=3DAUTO, 1=3D1N, 2=3D2N. > + UINT8 RefClk; ///< Offset 199 - Selects the DDR base= reference > clock. 0x01 =3D 100MHz, 0x00 =3D 133MHz > + UINT8 EnCmdRate; ///< Offset 200 - CMD Rate Enable: 0= =3DDisable, > 1=3D1 CMD, 2=3D2 CMDs, 3=3D3 CMDs, 4=3D4 CMDs, 5=3D5 CMDs, 6=3D6 C= MDs, 7=3D7 > CMDs > + UINT8 Refresh2X; ///< Offset 201 - Refresh 2x: 0=3DD= isable, > 1=3DEnable for WARM or HOT, 2=3DEnable for HOT only > + UINT8 EpgEnable; ///< Offset 202 - Enable Energy Perfor= mance > Gain. > + UINT8 RhSolution; ///< Offset 203 - Type of solution to = be used > for RHP - 0/1 =3D HardwareRhp/Refresh2x > + UINT8 UserThresholdEnable; ///< Offset 204 - Flag to manually sel= ect > the DIMM CLTM Thermal Threshold, 0=3DDisable, 1=3DEnable, 0=3DDefault= > + UINT8 UserBudgetEnable; ///< Offset 205 - Flag to manually sel= ect the > Budget Registers for CLTM Memory Dimms , 0=3DDisable, 1=3DEnable, > 0=3DDefault > + UINT8 TsodTcritMax; ///< Offset 206 - TSOD Tcrit Maximum V= alue > to be Configure , 0=3DMinimal, 128=3DMaximum, , 105=3DDefault > + > + UINT8 TsodEventMode; ///< Offset 207 - Flag to Enable Event= Mode > Interruption in TSOD Configuration Register, 0=3DDisable, 1=3DEnable, > 1=3DDefault > + UINT8 TsodEventPolarity; ///< Offset 208 - Event Signal Polarit= y in > TSOD Configuration Register, 0=3DLow, 1=3DHigh, 0=3DDefault > + UINT8 TsodCriticalEventOnly; ///< Offset 209 - Critical Trigger Onl= y in > TSOD Configuration Register,0=3DDisable, 1=3DEnable, 1=3DDefault > + UINT8 TsodEventOutputControl; ///< Offset 210 - Event Output Control= in > TSOD Configuration Register,0=3DDisable, 1=3DEnable, 1=3DDefault > + UINT8 TsodAlarmwindowLockBit; ///< Offset 211 - Alarm Windows Lock B= it > in TSOD Configuration Register,0=3DUnlock, 1=3DLock, 0=3DDefault > + UINT8 TsodCriticaltripLockBit;///< Offset 212 - Critical Trip Lock B= it in TSOD > Configuration Register,0=3DUnlock, 1=3DLock, 0=3DDefault > + UINT8 TsodShutdownMode; ///< Offset 213 - Shutdown Mode TSOD > Configuration Register,0=3DEnable, 1=3DDisable, 0=3DDefault > + UINT8 TsodThigMax; ///< Offset 214 - Thigh Max Value In t= he for > CLTM Memory Dimms , 0=3DDisable, 1=3DEnable, 0=3DDefault > + UINT8 TsodManualEnable; ///< Offset 215 - Flag to manually sel= ect > the TSOD Register Values , 0=3DDisable, 1=3DEnable, 0=3DDefault > + UINT8 DllBwEn0; ///< Offset 216 - DllBwEn value for 10= 67 > + UINT8 DllBwEn1; ///< Offset 217 - DllBwEn value for 13= 33 > + UINT8 DllBwEn2; ///< Offset 218 - DllBwEn value for 16= 00 > + UINT8 DllBwEn3; ///< Offset 219 - DllBwEn value for 18= 67 and > up > + UINT8 RetrainOnFastFail; ///< Offset 220 - Restart MRC in Cold = mode if > SW MemTest fails during Fast flow. 0 =3D Disabled, 1 =3D Enabled > + UINT8 ForceOltmOrRefresh2x; ///< Offset 221 - Force OLTM or 2X Ref= resh > when needed. 0 =3D Force OLTM, 1 =3D Force 2x Refresh > + UINT8 PowerDownMode; ///< Offset 222 - CKE Power Down Mode: > 0xFF=3DAUTO, 0=3DNo Power Down, 1=3D APD mode, 6=3DPPD-DLL Off mod= e > + UINT8 PwdwnIdleCounter; ///< Offset 223 - CKE Power Down Mode > Idle Counter: 0=3DMinimal, 255=3DMaximum, 0x80=3D0x80 DCLK > + UINT8 IsvtIoPort; ///< Offset 224 ISVT IO Port Address: = 0=3DMinimal, > 0xFF=3DMaximum, 0x99=3DDefault > + UINT8 Reserved3; ///< Offset 225 - ConfigBlock size mu= st be a > multiple of DWORDs > + MrcGdxc Gdxc; ///< Offset 226 - 228 - GDXC enable an= d size. > + UINT8 RMTLoopCount; ///< Offset 229 - Indicates the Loop C= ount > to be used for Rank Margin Tool Testing: 1=3DMinimal, 32=3DMaximum, 0=3DA= UTO, > 0=3DDefault > + UINT8 Reserved4[2]; ///< Offset 230 - 231 Reserved for DWO= RD > alignment. > + UINT32 RmtPerTask:1; ///< Offset 232 Bit 0: Rank Marg= in Tool > Per Task. 0 =3D Disabled, 1 =3D Enabled > + UINT32 Off232Bit1Rsvd:2; ///< Offset 232 Bit 1-2: Reserve= d > + 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 =3D Disabled, 1 =3D Enabled > + UINT32 FastBootRmt:1; ///< Offset 232 Bit 5: Enable/Di= sable > RMT on FastBoot. 0 =3D Disabled, 1 =3D Enabled > + UINT32 MrcTrainOnWarm:1; ///< Offset 232 Bit 6: Enalbes M= RC > trainin on warm boot : 0=3DDisable, 1 =3D Enabled > + UINT32 LongFlyByModeEnabled:1; ///< Offset 232 Bit 7: Long FlyB= y > Mode Enabled : 0 =3D Disabled, 1 =3D Enabled > + UINT32 Off232RsvdBits:24; ///< Offset 232 Bit 8-31: Reserv= ed > + > + // > + // TurnAround Timing > + // > + MrcTurnaroundTimes tRd2Rd; ///< Offset 236 - User-defined overrid= es > for Read-to-Read Turn Around Timings. 0 =3D AUTO > + MrcTurnaroundTimes tRd2Wr; ///< Offset 240 - User-defined overrid= es > for Read-to-Write Turn Around Timings. 0 =3D AUTO > + MrcTurnaroundTimes tWr2Rd; ///< Offset 244 - User-defined overrid= es > for Write-to-Read Turn Around Timings. 0 =3D AUTO > + MrcTurnaroundTimes tWr2Wr; ///< Offset 248 - User-defined overrid= es > for Write-to-Write Turn Around Timings. 0 =3D AUTO > + UINT16 tRRD_L; ///< Offset 252 - User defined DDR4 Me= mory > Timing tRRD_L value, valid when MemoryProfile is CUSTOM_PROFILE: > 0=3DAUTO, 15=3DMaximum. > + UINT16 tRRD_S; ///< Offset 254 - User defined DDR4 Me= mory > Timing tRRD_S value, valid when MemoryProfile is CUSTOM_PROFILE: > 0=3DAUTO, 15=3DMaximum. > + UINT16 tWTR_L; ///< Offset 266 - User defined DDR4 Me= mory > Timing tWTR_L value, valid when MemoryProfile is CUSTOM_PROFILE: > 0=3DAUTO, 28=3DMaximum. > + UINT16 tWTR_S; ///< Offset 268 - User defined DDR4 Me= mory > Timing tWTR_S value, valid when MemoryProfile is CUSTOM_PROFILE: > 0=3DAUTO, 28=3DMaximum. > + > + // > + // End of synchronization to the SA MEMORY_CONFIGURATION structure. > + // > + MrcFrequency FreqMax; ///< The requested maxim= um > valid frequency. > + MrcBoardType BoardType; ///< Define the board ty= pe > (CRBMB,CRBDT,User1,User2). the OEM can add more boards. > + MrcCpuStepping CpuStepping; ///< Define the CPU step= ping. > + MrcCpuModel CpuModel; ///< Define the CPU mode= l. > + MrcCpuFamily CpuFamily; ///< CPU is Coffeelake > + MrcGfxDataSize GraphicsStolenSize; ///< Graphics Data Stole= n > Memory size in MB > + MrcGfxGttSize GraphicsGttSize; ///< GTT graphics stolen > memory size in MB > + MrcBaseTime BaseTime; ///< RTC base time. > + MrcIteration Iteration; ///< Number of iteration= s thru the > MRC core call table. > + MrcMode MrcMode; ///< The control for ful= l or > MiniBIOS MRC. > + MrcBootMode BootMode; ///< The requested memor= y > controller boot mode. > + BOOLEAN TxtFlag; ///< Trusted eXecution T= echnology > flag. > + BOOLEAN SetRxDqs32; ///< Set DQS Delay to 32= control. > + BOOLEAN GfxIsVersatileAcceleration; ///< iGFX engines are in > Versatile Acceleration > + BOOLEAN DDR4MAP; ///< DDR4 PDA Mapping tr= aining > control. > + POINTER_STRUCT SaMemCfgAddress; ///< Starting address of > the input parameters to CRC. > + UINT32 SaMemCfgSize; ///< The size of the inp= ut > parameters to CRC. > + UINT32 PciEBaseAddress; ///< define the PciE bas= e > 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 tha= t the ME > need in MB. > + UINT32 MmioSize; ///< define the MMIO siz= e in MB. > + UINT32 TsegSize; ///< TSEG size that requ= ire by the > system in MB. > + UINT32 IedSize; ///< IED size that requi= re by the > system in MB. > + UINT32 DprSize; ///< DPR size required b= y system in > MB. > + UINT32 PrmrrSize; ///< Prmrr size required= by the > system in MB. > + POINTER_STRUCT SerialBuffer; ///< Pointer to the star= t of the > serial buffer. > + UINT32 SerialBufferSize; ///< The size of the ser= ial buffer, in > bytes. > + UINT32 DebugStream; ///< The debug port poin= ter. > + 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 sp= ace, in > bytes. > + UINT32 MrcStackTop; ///< Top of the stack at= the > beginning of MRC, for stack usage calculations. > + BOOLEAN BdatEnable; ///< Option to enable ou= tput 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: 0=3DRMT, 1=3DRMT Per Bit, 2=3DMargin 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 Equaliza= tion > + BOOLEAN EnVttOdt; ///< Enable VTT Terminat= ion for > Data ODT > + UINT32 CpuidModel; ///< Unique CPU identifi= er. > + 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 fun= ction > 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 m= emory > clean > + UINT32 OcSupport:1; ///< TRUE if Overclockin= g is > enabled in BIOS > + UINT32 RsvdBits5:30; > + /** > + Sets the serial debug message level\n > + 0x00 =3D Disabled\n > + 0x01 =3D Errors only\n > + 0x02 =3D Errors and Warnings\n > + 0x03 =3D Errors, Warnings, and Info\n > + 0x04 =3D Errors, Warnings, Info, and Events\n > + 0x05 =3D 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, s= tarts > with "MRC". Must be the first entry in this structure. > + UINT32 MrcDataSize; ///< The size of the MRC global data ar= ea, 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 follo= w. > + 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 th= e > + Compatible BIOS data (BDAT) table. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _MrcRmtData_h_ > +#define _MrcRmtData_h_ > + > +#include "MrcTypes.h" > + > +#define VDD_1_350 1350 ///< VDD in mill= ivolts > +#define VDD_1_500 1500 ///< VDD in mill= ivolts > +#define PI_STEP_BASE 2048 ///< Magic numbe= r from > spec > +#define PI_STEP_INTERVAL 128 ///< tCK is spli= t into this > amount of intervals > +#define PI_STEP ((PI_STEP_BASE) / (PI_STEP_INTERVAL)) > +#define VREF_STEP_BASE 100 ///< Magic numbe= r from > spec > +#define TX_VREF_STEP 7800 ///< TX Vref ste= p in > microvolts > +#define TX_VREF(VDD) (((TX_VREF_STEP) * (VREF_STEP_BASE)) / (VD= D)) > ///< VDD passed in is in millivolts > +#define RX_VREF_STEP 8000 ///< TX Vref ste= p in > microvolts > +#define RX_VREF(VDD) (((RX_VREF_STEP) * (VREF_STEP_BASE)) / (VD= D)) > ///< VDD passed in is in millivolts > +#define CA_VREF_STEP 8000 ///< TX Vref ste= p in > microvolts > +#define CA_VREF(VDD) (((CA_VREF_STEP) * (VREF_STEP_BASE)) / (VD= D)) > ///< 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 m= ode > registers > +#define MAX_DRAM_DEVICE 9 ///< Maximum num= ber > of memory devices > +#define MAX_2D_EYE_TYPE 2 ///< Maximum num= ber > of supported Margin 2D Eye Types > +#define MAX_2D_EYE_OFFSETS 7 ///< Number of 2= D 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 file= s. > +typedef enum { > + DisableScrambler =3D 0, > + EnableScrambler =3D 1, > + DontTouchScrambler =3D 2, > + SCRAMBLER_OVERRIDE_MODE_DELIM =3D 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 fil= es. > + > +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 da= ta. > + UINT16 Crc16; ///< Crc= 16 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.
> + > + 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 =3D > 2000) > + UINT8 Week; ///< Year represented in = BCD (47h =3D > 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; ///< Mod= ule > Manufacturer ID Code > + SPD_MANUFACTURING_LOCATION Location; ///< > Module Manufacturing Location > + SPD_MANUFACTURING_DATE Date; ///< Mod= ule > 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 B= yte > + SPD_TRC_MIN_MTB_STRUCT tRCmin; ///< 196= , 231 > XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significa= nt > 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 B= yte > + SPD_TRC_MIN_MTB_STRUCT tRCmin; ///< 406= , 453 > XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significa= nt > 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 B= yte > + 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-1= 0 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 B= yte > + 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-1= 27 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _MRC_TYPES_H > +#define _MRC_TYPES_H > + > +#ifdef MRC_MINIBIOS_BUILD > +#include "MrcMiniBiosEfiDefs.h" > +#else > +#include > +#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) =3D (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 wa= rning > +// > +#pragma warning(disable : 4127) > +// > +// The given function was selected for inline expansion, but the compile= r 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 =3D 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 "glo= bal > data". > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _GRAPHICS_INIT_H_ > +#define _GRAPHICS_INIT_H_ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include "SaInitDxe.h" > +#include "SaInit.h" > +#include > +#include > +#include > + > + > +/** > + 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/IgdOpRegionIn= i > t.h > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIn= i > t.h > new file mode 100644 > index 0000000000..0e95db3d02 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIn= i > t.h > @@ -0,0 +1,193 @@ > +/** @file > + This is part of the implementation of an Intel Graphics drivers OpRegi= on / > + Software SCI interface between system BIOS, ASL code, and Graphics dri= vers. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _IGD_OPREGION_INIT_H_ > +#define _IGD_OPREGION_INIT_H_ > + > +/// > +/// Statements that include other header files. > +/// > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/// > +/// Driver Consumed Protocol Prototypes > +/// > +#include > +#include > +#include > +#include > + > + > +#include > + > +/// > +/// Driver Produced Protocol Prototypes > +/// > +#include > + > +/// > +/// > +/// 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 no= t > 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 bui= lt > + 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 =3D 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/PciExpressIni= t. > h > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressIni= t. > h > new file mode 100644 > index 0000000000..34a2809f80 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressIni= t. > h > @@ -0,0 +1,91 @@ > +/** @file > + Header file for PciExpress Initialization Driver. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _PCIEXPRESS_INITIALIZATION_DRIVER_H_ > +#define _PCIEXPRESS_INITIALIZATION_DRIVER_H_ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#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 read= y 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +EFI_STATUS > +PegInitBeforeEndOfDxe ( > + VOID > + ); > + > +/** > + This function performs SA registers Saving/Restoring in EndOfDxe callb= ack > + > + @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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _SA_INITIALIZATION_DRIVER_H_ > +#define _SA_INITIALIZATION_DRIVER_H_ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _SA_INITIALIZATION_DXE_DRIVER_H_ > +#define _SA_INITIALIZATION_DXE_DRIVER_H_ > + > +#include > +#include > +#include "VTd.h" > +#include "PcieComplex.h" > +#include "IgdOpRegionInit.h" > +#include > +#include "GraphicsInit.h" > +#include "PciExpressInit.h" > +#include "SwitchableGraphicsInit.h" > +#include > + > +/// > +/// Driver Consumed Protocol Prototypes > +/// > +#include > + > +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 initializati= on before > ExitPmAuth > + > + @param[in] Event - A pointer to the Event that triggered the callb= ack. > + @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 > + ); > + > +/** > + System Agent Initialization DXE Driver Entry Point > + - Introduction \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 Syste= m > Agent and PCH together appear as a Root Complex with root ports the numbe= r > 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 Agen= t 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 - B= IOS > Specification. > + The ASL files that go along with the driver define the IGD OpRegion > mailboxes in ACPI space and implement the software SCI interrupt mechanis= m. > + The IGD OpRegion/Software SCI code serves as a communication interfa= ce > between system BIOS, ASL, and Intel graphics driver including making a bl= ock of > customizable data (VBT) from the Intel video BIOS available. > + Reference Code for the SCI service functions "Get BIOS Data" and "Sy= stem > BIOS Callback" can be found in the ASL files, those functions can be plat= form > specific, the sample provided in the reference code are implemented for I= ntel > CRB. > + This module implements the VT-d functionality described in the Broad= well > 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 pointe= rs > 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 re= gisters > lockdown at end of post as required from Broadwell Bios Spec. > + In addition, this module publishes the SaInfo Protocol with informat= ion > 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 th= e 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 initiali= zed > (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 I= nternal > 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 > + > + - References \n > + IGD OpRegion/Software SCI for Broadwell > + Advanced Configuration and Power Interface Specification Revision 4.= 0a. > + > + - Porting Recommendations \n > + No modification of the DXE driver should be typically necessary. > + This driver should be executed after all related devices (audio, vid= eo, ME, > etc.) are initialized to ensure correct data in DMAR table and DMA-remapp= ing > 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 requir= ements. > + > + @param[in] Event - A pointer to the Event that triggered the callb= ack. > + @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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _SWITCHABLE_GRAPHICS_DXE_H_ > +#define _SWITCHABLE_GRAPHICS_DXE_H_ > + > + > +#include > + > + > +#endif > diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VT= d.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 Tech= nology > for Directed I/O). > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _VT_D_H_ > +#define _VT_D_H_ > + > +/// > +/// Include files > +/// > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > + > +#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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _SMM_ACCESS_DRIVER_H_ > +#define _SMM_ACCESS_DRIVER_H_ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +#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 > +// > +/** > + SMM Access Driver Entry Point > + This driver installs an SMM Access Protocol > + - Introduction \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 SMR= AM > 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 > + > + - Porting Recommendations \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 memor= y. > + The use of "open" means that the memory is visible from all boot-servi= ce > + 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 agen= ts, > + 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 Interfa= ce. > + @param[in] SmramMapSize - Pointer to the variable containing = size > of the > + buffer to contain the description informatio= n. > + @param[in] SmramMap - Buffer containing the data describi= ng > 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 initializa= tion. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "GraphicsInit.h" > +#include "SaInit.h" > +#include > +#include > +#include > + > +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 =3D > 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 =3D NULL; > + LegacyBios =3D NULL; > + Status =3D gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **= ) > &mSaPolicy); > + ASSERT_EFI_ERROR (Status); > + > + Status =3D GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid= , > (VOID *)&GraphicsDxeConfig); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Get Silicon Config data HOB > + // > + HobPtr.Guid =3D GetFirstGuidHob (&gSiConfigHobGuid); > + SiConfigHobData =3D (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA > (HobPtr.Guid); > + > + if (SiConfigHobData->CsmFlag =3D=3D 1) { > + Status =3D gBS->LocateProtocol ( > + &gEfiLegacyBiosProtocolGuid, > + NULL, > + (VOID **) &LegacyBios > + ); > + } > + > + if (LegacyBios =3D=3D NULL) { > + Status =3D gBS->LocateProtocol (&gGopComponentName2ProtocolGuid, > NULL, (VOID **)&GopComponentName2Protocol); > + if (!EFI_ERROR (Status)) { > + Status =3D GopComponentName2Protocol->GetDriverVersion ( > + GopComponentName2Protocol, > + "en-US", > + &DriverVersion > + ); > + if (!EFI_ERROR (Status)) { > + for (Index =3D 0; (DriverVersion[Index] !=3D '\0'); Index++) { > + } > + Index =3D (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 =3D 0; > + Status =3D EFI_SUCCESS; > + mMchBarBase.Data32.High =3D PciSegmentRead32 > (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, > R_SA_MCHBAR + 4)); > + mMchBarBase.Data32.Low =3D PciSegmentRead32 > (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, > R_SA_MCHBAR)); > + mMchBarBase.Data &=3D (UINT64) ~BIT0; > + > + Status =3D 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 =3D > GraphicsDxeConfig->AlsEnable; > + /// > + /// Initialize IGD state by checking if IGD Device 2 Function 0 is ena= bled 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 =3D 1; > + } else { > + mSaNvsAreaProtocol.Area->IgdState =3D 0; > + } > + > + mSaNvsAreaProtocol.Area->BrightnessPercentage =3D 100; > + mSaNvsAreaProtocol.Area->IgdBootType =3D > GraphicsDxeConfig->IgdBootType; > + mSaNvsAreaProtocol.Area->IgdPanelType =3D > GraphicsDxeConfig->IgdPanelType; > + mSaNvsAreaProtocol.Area->IgdPanelScaling =3D > 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 =3D > GraphicsDxeConfig->IgdDvmtMemSize; > + mSaNvsAreaProtocol.Area->IgdFunc1Enable =3D 0; > + mSaNvsAreaProtocol.Area->IgdHpllVco =3D MmioRead8 > (mMchBarBase.Data + 0xC0F) & 0x07; > + mSaNvsAreaProtocol.Area->IgdSciSmiMode =3D 0; > + mSaNvsAreaProtocol.Area->GfxTurboIMON =3D > GraphicsDxeConfig->GfxTurboIMON; > + > + mSaNvsAreaProtocol.Area->EdpValid =3D 0; > + > + return EFI_SUCCESS; > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIn= i > t.c > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIn= i > t.c > new file mode 100644 > index 0000000000..6ec0691074 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIn= i > t.c > @@ -0,0 +1,570 @@ > +/** @file > + This is part of the implementation of an Intel Graphics drivers OpRegi= on / > + Software SCI interface between system BIOS, ASL code, and Graphics dri= vers. > + The code in this file will load the driver and initialize the interfac= e > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + 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 =3D gBS->LocateProtocol ( > + &gSaPolicyProtocolGuid, > + NULL, > + (VOID **) &mSaPolicy > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status =3D GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid= , > (VOID *)&GraphicsDxeConfig); > + ASSERT_EFI_ERROR (Status); > + > + VbtAddress =3D GraphicsDxeConfig->VbtAddress; > + Size =3D GraphicsDxeConfig->Size; > + > + if (VbtAddress =3D=3D 0x00000000) { > + return EFI_NOT_FOUND; > + } else { > + /// > + /// Check VBT signature > + /// > + *VbtFileBuffer =3D NULL; > + *VbtFileBuffer =3D (VBIOS_VBT_STRUCTURE *) (UINTN) VbtAddress; > + if ((*((UINT32 *) ((*VbtFileBuffer)->HeaderSignature))) !=3D VBT_SIG= NATURE) > { > + FreePool (*VbtFileBuffer); > + *VbtFileBuffer =3D NULL; > + return EFI_UNSUPPORTED; > + } > + } > + if (Size =3D=3D 0) { > + return EFI_NOT_FOUND; > + } else { > + /// > + /// Check VBT size > + /// > + if ((*VbtFileBuffer)->HeaderVbtSize > Size) { > + (*VbtFileBuffer)->HeaderVbtSize =3D (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 vid= eo BIOS > + if the Intel graphic contoller is considered a secondary adapte= r. > + > + @param[out] VBiosImage - Pointer to an uncompressed Intel video BI= OS. > This pointer must > + be set to NULL if an uncompressed image o= f 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 obtainabl= e. > + /// > + VBiosRomImage =3D NULL; > + > + /// > + /// Get all PCI IO protocols > + /// > + Status =3D gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiPciIoProtocolGuid, > + NULL, > + &HandleCount, > + &HandleBuffer > + ); > + ASSERT_EFI_ERROR (Status); > + > + /// > + /// Find the video BIOS by checking each PCI IO handle for an Intel vi= deo > + /// BIOS OPROM. > + /// > + for (Index =3D 0; Index < HandleCount; Index++) { > + Status =3D gBS->HandleProtocol ( > + HandleBuffer[Index], > + &gEfiPciIoProtocolGuid, > + (VOID **) &PciIo > + ); > + ASSERT_EFI_ERROR (Status); > + > + VBiosRomImage =3D PciIo->RomImage; > + > + /// > + /// If this PCI device doesn't have a ROM image, skip to the next de= vice. > + /// > + if (!VBiosRomImage) { > + continue; > + } > + /// > + /// Get pointer to PCIR structure > + /// > + PcirBlockPtr =3D (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *) > VBiosRomImage + VBiosRomImage->PcirOffset); > + > + /// > + /// Check if we have an Intel video BIOS OPROM. > + /// > + if ((VBiosRomImage->Signature =3D=3D OPTION_ROM_SIGNATURE) && > + (PcirBlockPtr->VendorId =3D=3D V_SA_MC_VID) && > + (PcirBlockPtr->ClassCode[0] =3D=3D 0x00) && > + (PcirBlockPtr->ClassCode[1] =3D=3D 0x00) && > + (PcirBlockPtr->ClassCode[2] =3D=3D 0x03) > + ) { > + /// > + /// Found Intel video BIOS. > + /// > + *VBiosImage =3D 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 bui= lt > + 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 =3D 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 =3D NULL; > + LegacyVbtFound =3D 1; > + > + /// > + /// Get the SA policy. > + /// > + Status =3D gBS->LocateProtocol ( > + &gSaPolicyProtocolGuid, > + NULL, > + (VOID **) &mSaPolicy > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status =3D GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid= , > (VOID *)&GraphicsDxeConfig); > + ASSERT_EFI_ERROR (Status); > + > + LegacyBios =3D NULL; > + VBiosPtr =3D NULL; > + // > + // Get Silicon Config data HOB > + // > + HobPtr.Guid =3D GetFirstGuidHob (&gSiConfigHobGuid); > + SiConfigHobData =3D (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA > (HobPtr.Guid); > + if (SiConfigHobData->CsmFlag =3D=3D 1) { > + Status =3D gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (= VOID > **) &LegacyBios); > + > + if (LegacyBios) { > + VBiosPtr =3D (INTEL_VBIOS_OPTION_ROM_HEADER *) (UINTN) > (VBIOS_LOCATION_PRIMARY); > + PcirBlockAddress =3D VBIOS_LOCATION_PRIMARY + VBiosPtr->PcirOffset= ; > + PcirBlockPtr =3D (INTEL_VBIOS_PCIR_STRUCTURE *) (UINTN) > (PcirBlockAddress); > + PciVenderId =3D PcirBlockPtr->VendorId; > + /// > + /// If the video BIOS is not at 0xC0000 or it is not an Intel vide= o BIOS get > + /// the integrated Intel video BIOS (must be uncompressed). > + /// > + if ((VBiosPtr->Signature !=3D OPTION_ROM_SIGNATURE) || (PciVenderI= d !=3D > V_SA_MC_VID)) { > + GetIntegratedIntelVBiosPtr (&VBiosPtr); > + if (VBiosPtr !=3D NULL) { > + /// > + /// Video BIOS found. > + /// > + PcirBlockPtr =3D (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *) VB= iosPtr > + VBiosPtr->PcirOffset); > + PciVenderId =3D PcirBlockPtr->VendorId; > + > + if ((VBiosPtr->Signature !=3D OPTION_ROM_SIGNATURE) || > (PciVenderId !=3D V_SA_MC_VID)) { > + /// > + /// Intel video BIOS not found. > + /// > + VBiosVbtPtr =3D NULL; > + LegacyVbtFound =3D 0; > + } > + } > + } > + } > + } > + if ((LegacyBios =3D=3D NULL) || (LegacyVbtFound =3D=3D 0)) { > + /// > + /// No Video BIOS found, try to get VBT from FV. > + /// > + GetIntegratedIntelVbtPtr (&VbtFileBuffer); > + if (VbtFileBuffer !=3D NULL) { > + /// > + /// Video BIOS not found, use VBT from SaPolicy > + /// > + DEBUG ((DEBUG_INFO, "VBT data found\n")); > + for (Index =3D 0; (GraphicsDxeConfig->GopVersion[Index] !=3D '\0')= ; Index++) { > + } > + Index =3D (Index+1)*2; > + CopyMem (mIgdOpRegion.OpRegion->Header.DVER, > GraphicsDxeConfig->GopVersion, Index); > + CopyMem (mIgdOpRegion.OpRegion->MBox4.RVBT, VbtFileBuffer, > VbtFileBuffer->HeaderVbtSize); > + return EFI_SUCCESS; > + } > + } > + > + if (VBiosPtr =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + DEBUG ((DEBUG_INFO, "VBIOS found at 0x%X\n", VBiosPtr)); > + VBiosVbtPtr =3D (VBIOS_VBT_STRUCTURE *) ((UINT8 *) VBiosPtr + > VBiosPtr->VbtOffset); > + > + if ((*((UINT32 *) (VBiosVbtPtr->HeaderSignature))) !=3D VBT_SIGNATURE)= { > + return EFI_UNSUPPORTED; > + } > + > + /// > + /// Initialize Video BIOS version with its build number. > + /// > + mIgdOpRegion.OpRegion->Header.VVER[0] =3D > VBiosVbtPtr->CoreBlockBiosBuild[0]; > + mIgdOpRegion.OpRegion->Header.VVER[1] =3D > VBiosVbtPtr->CoreBlockBiosBuild[1]; > + mIgdOpRegion.OpRegion->Header.VVER[2] =3D > VBiosVbtPtr->CoreBlockBiosBuild[2]; > + mIgdOpRegion.OpRegion->Header.VVER[3] =3D > 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 no= t > 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 =3D gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID > **)&SaPolicy); > + > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status =3D GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, > (VOID *)&GraphicsDxeConfig); > + ASSERT_EFI_ERROR (Status); > + /// > + /// Locate the SA Global NVS Protocol. > + /// > + Status =3D gBS->LocateProtocol ( > + &gSaNvsAreaProtocolGuid, > + NULL, > + (VOID **) &SaNvsAreaProtocol > + ); > + ASSERT_EFI_ERROR (Status); > + > + /// > + /// Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initi= alize > + /// the first 1K, and set the IGD OpRegion pointer in the Global NVS > + /// area structure. > + /// > + Status =3D (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 =3D (UINT32) (UINTN) > (mIgdOpRegion.OpRegion); > + > + /// > + /// If IGD is disabled return > + /// > + IgdBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, > SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0); > + if (PciSegmentRead32 (IgdBaseAddress + 0) =3D=3D 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 =3D HEADER_SIZE / 1024; > + mIgdOpRegion.OpRegion->Header.OVER =3D (UINT32) (LShiftU64 > (HEADER_OPREGION_VER, 16) + LShiftU64 (HEADER_OPREGION_REV, 8)); > + > + /// > + /// All Mailboxes are supported. > + /// > + mIgdOpRegion.OpRegion->Header.MBOX =3D HEADER_MBOX_SUPPORT; > + > + /// > + /// Initialize OpRegion Mailbox 1 (Public ACPI Methods). > + /// > + /// Note - The initial setting of mailbox 1 fields is implementation s= pecific. > + /// Adjust them as needed many even coming from user setting in setup. > + /// > + /// > + /// Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservati= on). > + /// > + /// Note - The initial setting of mailbox 3 fields is implementation s= pecific. > + /// Adjust them as needed many even coming from user setting in setup. > + /// > + /// > + /// Do not initialize TCHE. This field is written by the graphics driv= er only. > + /// > + /// > + /// The ALSI field is generally initialized by ASL code by reading the > embedded controller. > + /// > + mIgdOpRegion.OpRegion->Header.PCON =3D > GraphicsDxeConfig->PlatformConfig; > + mIgdOpRegion.OpRegion->Header.PCON =3D > mIgdOpRegion.OpRegion->Header.PCON | 0x2; > + > + mIgdOpRegion.OpRegion->MBox3.BCLP =3D BACKLIGHT_BRIGHTNESS; > + > + mIgdOpRegion.OpRegion->MBox3.PFIT =3D (FIELD_VALID_BIT | > PFIT_STRETCH); > + > + /// > + /// Reporting to driver for VR IMON Calibration. Bits [5-1] values sup= ported > 14A to 31A. > + /// > + mIgdOpRegion.OpRegion->MBox3.PCFT =3D > (SaNvsAreaProtocol->Area->GfxTurboIMON << 1) & 0x003E; > + > + /// > + /// Set Initial current Brightness > + /// > + mIgdOpRegion.OpRegion->MBox3.CBLV =3D (INIT_BRIGHT_LEVEL | > FIELD_VALID_BIT); > + > + /// > + /// Static Backlight Brightness Level Duty cycle Mapping Table > + /// > + for (Index =3D 0; Index < MAX_BCLM_ENTRIES; Index++) { > + mIgdOpRegion.OpRegion->MBox3.BCLM[Index] =3D > GraphicsDxeConfig->BCLM[Index]; > + } > + > + mIgdOpRegion.OpRegion->MBox3.IUER =3D 0x00; > + > + if (!EFI_ERROR (Status)) { > + mIgdOpRegion.OpRegion->MBox3.IUER =3D > 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 =3D PciSegmentRead32 (IgdBaseAddress + > R_SA_IGD_ASLS_OFFSET); > + S3BootScriptSaveMemWrite ( > + S3BootScriptWidthUint32, > + (UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (IgdBaseAddress + > R_SA_IGD_ASLS_OFFSET), > + 1, > + &DwordData > + ); > + DwordData =3D 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 =3D NULL; > + Status =3D 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 =3D 0; > + Device =3D 0; > + Function =3D 0; > + > + DEBUG ((DEBUG_INFO, "UpdateIgdOpRegionEndOfDxe\n")); > + > + mIgdOpRegion.OpRegion->Header.PCON |=3D BIT8; //Set External Gfx > Adapter field is valid > + mIgdOpRegion.OpRegion->Header.PCON &=3D (UINT32) (~BIT7); //Assume No > External Gfx Adapter > + > + /// > + /// Get all PCI IO protocols handles > + /// > + Status =3D gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiPciIoProtocolGuid, > + NULL, > + &HandleCount, > + &HandleBuffer > + ); > + > + if (!EFI_ERROR (Status)) { > + for (Index =3D 0; Index < HandleCount; Index++) { > + /// > + /// Get the PCI IO Protocol Interface corresponding to each handle > + /// > + Status =3D gBS->HandleProtocol ( > + HandleBuffer[Index], > + &gEfiPciIoProtocolGuid, > + (VOID **) &PciIo > + ); > + > + if (!EFI_ERROR (Status)) { > + /// > + /// Read the PCI configuration space > + /// > + Status =3D 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 =3D 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 an= d > Available\n")); > + mIgdOpRegion.OpRegion->Header.PCON |=3D BIT7; > + break; > + } > + } > + } > + } > + } > + > + /// > + /// Free any allocated buffers > + /// > + if (HandleBuffer !=3D NULL) { > + FreePool (HandleBuffer); > + } > + > + /// > + /// Return final status > + /// > + return Status; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressIni= t.c > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressIni= t.c > new file mode 100644 > index 0000000000..bbdf0d0fab > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressIni= t.c > @@ -0,0 +1,171 @@ > +/** @file > + This driver does SA PCI Express ACPI table initialization. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + 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 t= o 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 =3D GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VO= ID > *)&PcieDxeConfig); > + ASSERT_EFI_ERROR (Status); > + > + > + Msr.Uint64 =3D AsmReadMsr64 > (MSR_BROADWELL_PKG_CST_CONFIG_CONTROL); > + mSaNvsAreaProtocol.Area->PackageCstateLimit =3D (UINT8) Msr.Bits.Limi= t; > + > + mSaNvsAreaProtocol.Area->PwrDnBundlesGlobalEnable =3D 0; > + > + if (mSaConfigHob !=3D NULL) { > + mSaNvsAreaProtocol.Area->Peg0PowerDownUnusedBundles =3D > mSaConfigHob->PowerDownUnusedBundles[0]; > + mSaNvsAreaProtocol.Area->Peg1PowerDownUnusedBundles =3D > mSaConfigHob->PowerDownUnusedBundles[1]; > + mSaNvsAreaProtocol.Area->Peg2PowerDownUnusedBundles =3D > mSaConfigHob->PowerDownUnusedBundles[2]; > + if (SA_PEG_MAX_FUN > 3) { > + mSaNvsAreaProtocol.Area->Peg3PowerDownUnusedBundles =3D > mSaConfigHob->PowerDownUnusedBundles[3]; > + } > + } > + /// > + /// LTR/OBFF > + /// > + mSaNvsAreaProtocol.Area->Peg0LtrEnable =3D > PcieDxeConfig->PegPwrOpt[0].LtrEnable; > + mSaNvsAreaProtocol.Area->Peg0ObffEnable =3D > PcieDxeConfig->PegPwrOpt[0].ObffEnable; > + mSaNvsAreaProtocol.Area->Peg1LtrEnable =3D > PcieDxeConfig->PegPwrOpt[1].LtrEnable; > + mSaNvsAreaProtocol.Area->Peg1ObffEnable =3D > PcieDxeConfig->PegPwrOpt[1].ObffEnable; > + mSaNvsAreaProtocol.Area->Peg2LtrEnable =3D > PcieDxeConfig->PegPwrOpt[2].LtrEnable; > + mSaNvsAreaProtocol.Area->Peg2ObffEnable =3D > PcieDxeConfig->PegPwrOpt[2].ObffEnable; > + mSaNvsAreaProtocol.Area->PegLtrMaxSnoopLatency =3D > LTR_MAX_SNOOP_LATENCY_VALUE; > + mSaNvsAreaProtocol.Area->PegLtrMaxNoSnoopLatency =3D > LTR_MAX_NON_SNOOP_LATENCY_VALUE; > + > + return EFI_SUCCESS; > +} > + > +/** > + Find the Offset to a given Capabilities ID > + CAPID list: > + 0x01 =3D PCI Power Management Interface > + 0x04 =3D Slot Identification > + 0x05 =3D MSI Capability > + 0x10 =3D 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 =3D PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, > Function, 0); > + CapHeader =3D PciSegmentRead8 (DeviceBaseAddress + > PCI_CAPBILITY_POINTER_OFFSET); > + if (CapHeader =3D=3D 0xFF) { > + return 0; > + } > + > + while (CapHeader !=3D 0) { > + /// > + /// Bottom 2 bits of the pointers are reserved per PCI Local Bus Spe= c 2.2 > + /// > + CapHeader &=3D ~(BIT1 + BIT0); > + /// > + /// Search for desired CapID > + /// > + if (PciSegmentRead8 (DeviceBaseAddress + CapHeader) =3D=3D CapId) { > + return CapHeader; > + } > + > + CapHeader =3D PciSegmentRead8 (DeviceBaseAddress + CapHeader + 1); > + } > + > + return 0; > +} > + > +/** > + Search and return the offset of desired Pci Express Capability ID > + CAPID list: > + 0x0001 =3D Advanced Error Rreporting Capability > + 0x0002 =3D Virtual Channel Capability > + 0x0003 =3D Device Serial Number Capability > + 0x0004 =3D 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 =3D PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, > Function, 0); > + CapHeaderId =3D 0; > + CapHeaderOffset =3D 0x100; > + > + while (CapHeaderOffset !=3D 0 && CapHeaderId !=3D 0xFFFF) { > + /// > + /// Search for desired CapID > + /// > + CapHeaderId =3D PciSegmentRead16 (DeviceBaseAddress + > CapHeaderOffset); > + if (CapHeaderId =3D=3D CapId) { > + return CapHeaderOffset; > + } > + > + CapHeaderOffset =3D (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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "PciExpressInit.h" > +#include > +#include "PcieComplex.h" > +#include > +#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 cal= lback. > + @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 =3D=3D 0) { > + // > + // Use global variable instead of protocol data since it maybe tampe= red in > unsecure environment > + // Get IOTrap address when first time this routine calling > (gEfiPciEnumerationCompleteProtocolGuid callback) > + // > + SaIotrapSmiProtocol =3D NULL; > + Status =3D gBS->LocateProtocol (&gSaIotrapSmiProtocolGuid, NULL, (VO= ID **) > &SaIotrapSmiProtocol); > + ASSERT_EFI_ERROR (Status); > + if (SaIotrapSmiProtocol !=3D NULL) { > + mSaIotrapSmiAddress =3D SaIotrapSmiProtocol->SaIotrapSmiAddress; > + } > + } > + > + ASSERT (mSaIotrapSmiAddress !=3D 0); > + if (mSaIotrapSmiAddress !=3D 0) { > + // > + // Generate IOTRAP SMI immediately > + // > + DEBUG ((DEBUG_INFO, "[SA] Issue IOTRAP SMI %X\n", > mSaIotrapSmiAddress)); > + IoWrite8 (mSaIotrapSmiAddress, 0); > + } > + if (Event !=3D 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 =3D FALSE; > + /// > + /// SMM mode ASPM handling > + /// Check if supported and enabled > + /// > + if ((mSaConfigHob !=3D NULL) && (mSaConfigHob->InitPcieAspmAfterOprom > =3D=3D TRUE)) { > + /// > + /// Do the Phase 1 SMI callback > + /// This will enumerate PCIe downstream devices > + /// > + SaLateInitSmiCallback (NULL, NULL); > + > + if (mSaIotrapSmiAddress !=3D 0) { > + /// > + /// Create an ReadyToBoot call back event to do the Phase 3 SMI ca= llback > + /// This will handle PEG ASPM programming after OROM execution > + /// Note: Phase 2 SMI callback will be triggered in EndOfDxe callb= ack > + /// to initialize rest of PCIe settings prior to OPROM > + /// > + Status =3D EfiCreateEventReadyToBootEx ( > + TPL_NOTIFY, > + (EFI_EVENT_NOTIFY) SaLateInitSmiCallback, > + NULL, > + &ReadyToBoot > + ); > + ASSERT_EFI_ERROR (Status); > + AspmHasBeenHandled =3D 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 initializat= ion > + /// > + if (AspmHasBeenHandled =3D=3D FALSE) { > + > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This function performs SA registers Saving/Restoring in EndOfDxe callb= ack > + > + @retval EFI_SUCCESS - Save/restore has done > + @retval EFI_UNSUPPORTED - Save/restore not done successfully > +**/ > +EFI_STATUS > +SaSaveRestore ( > + VOID > + ) > +{ > + BOOLEAN SaveRestoreHasBeenHandled; > + UINT8 SmiData; > + > + SaveRestoreHasBeenHandled =3D FALSE; > + > + if ((mSaConfigHob !=3D NULL) && (mSaConfigHob->InitPcieAspmAfterOprom > =3D=3D TRUE)) { > + /// > + /// Generate the Phase 2 of SA SMI to do SA chipset save/restore and > security lock > + /// > + SaLateInitSmiCallback (NULL, NULL); > + > + if (mSaIotrapSmiAddress !=3D 0) { > + /// > + /// Store IOTRAP SMI address into Boot Script save table > + /// This is required to trigger this IOTRAP during S3 resume to re= store all > settings > + /// > + SmiData =3D 0; > + S3BootScriptSaveIoWrite ( > + S3BootScriptWidthUint8, > + (UINTN) mSaIotrapSmiAddress, > + 1, > + &SmiData > + ); > + SaveRestoreHasBeenHandled =3D TRUE; > + } > + } > + > + /// > + /// Check if SMM mode already taken care this task > + /// > + if (SaveRestoreHasBeenHandled =3D=3D 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "SaInitDxe.h" > +#include "SaInit.h" > +#include > +#include > +#include > + > +/// > +/// Global Variables > +/// > +GLOBAL_REMOVE_IF_UNREFERENCED > SYSTEM_AGENT_NVS_AREA_PROTOCOL mSaNvsAreaProtocol; > +GLOBAL_REMOVE_IF_UNREFERENCED SA_POLICY_PROTOCOL > *mSaPolicy; > +extern SA_CONFIG_HOB *mSaConfig= Hob; > + > +/** > + 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 =3D NULL; > + SaAcpiTable =3D NULL; > + > + /// > + /// Locate ACPI Table protocol > + /// > + DEBUG ((DEBUG_INFO, "Init SA SSDT table\n")); > + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOI= D **) > &AcpiTable); > + if (Status !=3D 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 =3D gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiFirmwareVolume2ProtocolGuid, > + NULL, > + &NumberOfHandles, > + &HandleBuffer > + ); > + ASSERT_EFI_ERROR (Status); > + /// > + /// Looking for FV with ACPI storage file > + /// > + for (i =3D 0; i < NumberOfHandles; i++) { > + /// > + /// Get the protocol on this handle > + /// This should not fail because of LocateHandleBuffer > + /// > + Status =3D gBS->HandleProtocol ( > + HandleBuffer[i], > + &gEfiFirmwareVolume2ProtocolGuid, > + (VOID **) &FwVol > + ); > + ASSERT_EFI_ERROR (Status); > + > + /// > + /// See if it has the ACPI storage file > + /// > + Size =3D 0; > + FvStatus =3D 0; > + Status =3D FwVol->ReadFile ( > + FwVol, > + &gSaSsdtAcpiTableStorageGuid, > + NULL, > + &Size, > + &FileType, > + &Attributes, > + &FvStatus > + ); > + > + /// > + /// If we found it, then we are done > + /// > + if (Status =3D=3D EFI_SUCCESS) { > + break; > + } > + } > + /// > + /// Free any allocated buffers > + /// > + FreePool (HandleBuffer); > + > + /// > + /// Sanity check that we found our data file > + /// > + ASSERT (FwVol !=3D NULL); > + if (FwVol =3D=3D 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 opera= tions > + /// If the protocol was found, Instance already points to it. > + /// Read tables from the storage file. > + /// > + Instance =3D 0; > + CurrentTable =3D NULL; > + while (Status =3D=3D EFI_SUCCESS) { > + Status =3D 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 =3D= =3D > SIGNATURE_64 ('S', 'a', 'S', 's', 'd', 't', ' ', 0)) { > + SaAcpiTable =3D (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable; > + /// > + /// Locate the SSDT package > + /// > + CurrPtr =3D (UINT8 *) SaAcpiTable; > + EndPtr =3D CurrPtr + SaAcpiTable->Length; > + > + for (; CurrPtr <=3D EndPtr; CurrPtr++) { > + Signature =3D (UINT32 *) (CurrPtr + 3); > + if (*Signature =3D=3D SIGNATURE_32 ('S', 'A', 'N', 'V')) { > + ASSERT (*(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) = =3D=3D > 0xFFFF0000); > + ASSERT (*(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 += sizeof > (UINT32) + 1) =3D=3D 0xAA55); > + /// > + /// SA Global NVS Area address > + /// > + *(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) =3D (UIN= T32) (UINTN) > mSaNvsAreaProtocol.Area; > + /// > + /// SA Global NVS Area size > + /// > + *(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof = (UINT32) + > 1) =3D > + sizeof (SYSTEM_AGENT_NVS_AREA); > + > + AcpiTableKey =3D 0; > + Status =3D AcpiTable->InstallAcpiTable ( > + AcpiTable, > + SaAcpiTable, > + SaAcpiTable->Length, > + &AcpiTableKey > + ); > + ASSERT_EFI_ERROR (Status); > + return EFI_SUCCESS; > + } > + } > + } > + /// > + /// Increment the instance > + /// > + Instance++; > + CurrentTable =3D 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 =3D NULL; > + Table =3D NULL; > + > + DEBUG ((DEBUG_INFO, "Loading SSDT Table GUID: %g\n", SsdtTableGuid)); > + > + /// > + /// Locate FV protocol. > + /// > + Status =3D gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiFirmwareVolume2ProtocolGuid, > + NULL, > + &NumberOfHandles, > + &HandleBuffer > + ); > + ASSERT_EFI_ERROR (Status); > + > + /// > + /// Look for FV with ACPI storage file > + /// > + for (Index =3D 0; Index < NumberOfHandles; Index++) { > + /// > + /// Get the protocol on this handle > + /// This should not fail because of LocateHandleBuffer > + /// > + Status =3D gBS->HandleProtocol ( > + HandleBuffer[Index], > + &gEfiFirmwareVolume2ProtocolGuid, > + (VOID **) &FwVol > + ); > + ASSERT_EFI_ERROR (Status); > + if (FwVol =3D=3D NULL) { > + return EFI_NOT_FOUND; > + } > + /// > + /// See if it has the ACPI storage file > + /// > + Size =3D 0; > + FvStatus =3D 0; > + Status =3D 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 opera= tions > + /// 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 =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOI= D **) > &AcpiTable); > + > + /// > + /// Read tables from the storage file. > + /// > + if (FwVol =3D=3D NULL) { > + ASSERT_EFI_ERROR (EFI_NOT_FOUND); > + return EFI_NOT_FOUND; > + } > + Instance =3D 0; > + > + while (Status =3D=3D EFI_SUCCESS) { > + /// > + /// Read the ACPI tables > + /// > + Status =3D FwVol->ReadSection ( > + FwVol, > + &SsdtTableGuid, > + EFI_SECTION_RAW, > + Instance, > + (VOID **) &Table, > + &Size, > + &FvStatus > + ); > + if (!EFI_ERROR (Status)) { > + /// > + /// check and load SwitchableGraphics SSDT table > + /// > + LoadTable =3D FALSE; > + TableHeader =3D (EFI_ACPI_DESCRIPTION_HEADER *) Table; > + > + if (((EFI_ACPI_DESCRIPTION_HEADER *) TableHeader)->OemTableId =3D= =3D > Signature) { > + /// > + /// This is the SSDT table that match the Signature > + /// > + DEBUG ((DEBUG_INFO, "Found out SSDT Table GUID: %g\n", > SsdtTableGuid)); > + LoadTable =3D TRUE; > + } > + > + /// > + /// Add the table > + /// > + if (LoadTable) { > + TableHandle =3D 0; > + Status =3D AcpiTable->InstallAcpiTable ( > + AcpiTable, > + TableHeader, > + TableHeader->Length, > + &TableHandle > + ); > + } > + /// > + /// Increment the instance > + /// > + Instance++; > + Table =3D 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 callb= ack. > + @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)) !=3D 0xFFFF) { > + Status =3D PostPmInitEndOfDxe (); > + if (EFI_SUCCESS !=3D Status) { > + DEBUG ((DEBUG_WARN, "[SA] EndOfDxe GraphicsInit Error, Status =3D = %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)) !=3D 0xFFFF) { > + Status =3D GetVBiosVbtEndOfDxe (); > + if (EFI_SUCCESS !=3D Status) { > + DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Op Region Error, Status =3D %r = \n", > Status)); > + } > + > + Status =3D UpdateIgdOpRegionEndOfDxe (); > + if (EFI_SUCCESS !=3D Status) { > + DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Update Op Region Error, Status > =3D %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 =3D GetCpuFamily(); > + AsmCpuid (1, &CpuidRegs.RegEax, 0, 0, 0); > + /// > + /// Get the platform setup policy. > + /// > + Status =3D 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 =3D (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 =3D (UINT32) (PcdGet64 > (PcdPciExpressBaseAddress)); > + mSaNvsAreaProtocol.Area->CpuIdInfo =3D CpuidRegs.RegEax; > + if (mSaConfigHob !=3D NULL) { > + mSaNvsAreaProtocol.Area->IpuAcpiMode =3D > mSaConfigHob->IpuAcpiMode; > + } > + Status =3D 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 invoki= ng any > UEFI drivers, > + /// applications, or connecting consoles,... > + /// > + Status =3D gBS->CreateEventEx ( > + EVT_NOTIFY_SIGNAL, > + TPL_CALLBACK, > + SaAcpiEndOfDxeCallback, > + NULL, > + &gEfiEndOfDxeEventGroupGuid, > + &EndOfDxeEvent > + ); > + > + /// > + /// Install System Agent Global NVS ACPI table > + /// > + Status =3D 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)) !=3D V_SA_DEVICE_ID_INVALID) { > + Status =3D 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/Sa= Init.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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "SaInit.h" > +#include > +#include > +#include > + > +// > +// 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 addr= ess. > + Bit fields of PCI Library and CF8 formatted address is as follows: > + PCI Library formatted address CF8 Formatted Address > + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D > + 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 mSk= ipPamLock =3D > 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 followi= ng bits: > + 1. For all modern Intel processors, Intel strongly recommends that BI= OS > should set > + the D_LCK bit. Set B0:D0:F0.R088h [4] =3D 1b to lock down SMRAM s= pace. > + BaseAddr values for mSaSecurityRegisters that uses PciExpressBaseAddre= ss > will be initialized at > + Runtime inside function SaPcieInitPolicy(). > +*/ > +GLOBAL_REMOVE_IF_UNREFERENCED BOOT_SCRIPT_REGISTER_SETTING > mSaSecurityRegisters[] =3D { > + {0, R_SA_SMRAMC, 0xFFFFFFFF, BIT4} > +}; > + > +/** > + SystemAgent Initialization Common Function. > + > + @retval EFI_SUCCESS - Always. > +**/ > + > +VOID > +SaInitEntryPoint ( > + VOID > + ) > +{ > + /// > + /// Get SaConfigHob HOB > + /// > + mSaConfigHob =3D NULL; > + mSaConfigHob =3D (SA_CONFIG_HOB *) GetFirstGuidHob > (&gSaConfigHobGuid); > + if (mSaConfigHob !=3D NULL) { > + mSkipPamLock =3D 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 =3D=3D FALSE) { > + // > + // Lock PAM by PAM Lock Bit > + // > + BaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, 0, 0, 0); > + Data32Or =3D 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 =3D 0; Index < (sizeof (mSaSecurityRegisters) / sizeof > (BOOT_SCRIPT_REGISTER_SETTING)); Index++) { > + RegOffset =3D mSaSecurityRegisters[Index].Offset; > + Data32Or =3D mSaSecurityRegisters[Index].OrMask; > + > + if (RegOffset =3D=3D 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 =3D PciCf8Read8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, > SA_MC_FUN, R_SA_SMRAMC)); > + Data32 =3D 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 =3D 0; Index < (sizeof (mSaSecurityRegisters) / sizeof > (BOOT_SCRIPT_REGISTER_SETTING)); Index++) { > + if (mSaSecurityRegisters[Index].BaseAddr !=3D PcdGet64 > (PcdMchBaseAddress)) { > + mSaSecurityRegisters[Index].BaseAddr =3D 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "SaInitDxe.h" > +#include "SaInit.h" > +#include > +#include > +#include > + > +/// > +/// 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 =3D 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 initializati= on before > EndOfDxe > + > + @param[in] Event - A pointer to the Event that triggered the callb= ack. > + @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 =3D gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGui= d, > NULL, (VOID **) &ProtocolPointer); > + if (EFI_SUCCESS !=3D Status) { > + return; > + } > + > + gBS->CloseEvent (Event); > + > + Status =3D PegInitBeforeEndOfDxe (); > + if (EFI_SUCCESS !=3D Status) { > + DEBUG ((DEBUG_WARN, "[SA] Pcie initialization before EndOfDxe Error, > Status =3D %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 requir= ements. > + > + @param[in] Event - A pointer to the Event that triggered the callb= ack. > + @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/VT= d.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 Tech= nology > for Directed I/O). > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "SaInitDxe.h" > +#include "SaInit.h" > +#include "VTd.h" > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > + > +extern SA_CONFIG_HOB *mSaConfig= Hob; > + > +/** > + 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 DM= AR > table > +**/ > +UINT16 mDevEnMap[][2] =3D {{0x0200, 0x80}, {0x1400, 0x80}, {0x1401, 0x8= 0}, > {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 =3D 0; Index < sizeof (mDevEnMap) / 4; Index++) { > + if (mDevEnMap[Index][0] =3D=3D ((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 =3D (EFI_ACPI_DRHD_ENGINE1_STRUCT *) DrhdEnginePtr; > + Length =3D DrhdEngine->DrhdHeader.Header.Length; > + DisableBit =3D GetFunDisableBit ( > + DrhdEngine->DeviceScope[0].PciPath.Device, > + DrhdEngine->DeviceScope[0].PciPath.Function > + ); > + NeedRemove =3D FALSE; > + > + if ((DisableBit =3D=3D 0xFF) || > + (DrhdEngine->DrhdHeader.RegisterBaseAddress =3D=3D 0) || > + ((DisableBit =3D=3D 0x80) && > + (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, > DrhdEngine->DeviceScope[0].PciPath.Device, > DrhdEngine->DeviceScope[0].PciPath.Function, 0x00)) =3D=3D 0xFFFFFFFF)) > + ) { > + NeedRemove =3D TRUE; > + } > + if (NeedRemove) { > + Length -=3D 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 =3D=3D 0x01)) { > + DrhdEngine->DrhdHeader.Header.Length =3D Length; > + } else { > + DrhdEngine->DrhdHeader.Header.Length =3D 0; > + } > +} > + > +/** > + Get IOAPIC ID from LPC > + > + @retval APIC ID > +**/ > +UINT8 > +GetIoApicId ( > + VOID > + ) > +{ > + UINT32 IoApicAddress; > + UINT32 IoApicId; > + > + IoApicAddress =3D PcdGet32 (PcdIoApicBaseAddress); > + /// > + /// Get current IO APIC ID > + /// > + MmioWrite8 ((UINTN) (IoApicAddress + R_IO_APIC_INDEX_OFFSET), 0); > + IoApicId =3D 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 =3D (EFI_ACPI_DRHD_ENGINE3_STRUCT *) DrhdEnginePtr; > + > + Length =3D DrhdEngine->DrhdHeader.Header.Length; > + DeviceScopeNum =3D (DrhdEngine->DrhdHeader.Header.Length - > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) / sizeof > (EFI_ACPI_DEV_SCOPE_STRUCTURE); > + Bus =3D 0; > + ValidDeviceScopeNum =3D 0; > + Path[0] =3D 0; > + Path[1] =3D 0; > + > + HobPtr =3D GetFirstGuidHob (&gPchInfoHobGuid); > + ASSERT (HobPtr !=3D NULL); > + if (HobPtr =3D=3D NULL) { > + return; > + } > + PchInfoHob =3D (PCH_INFO_HOB *) GET_GUID_HOB_DATA (HobPtr); > + ASSERT (PchInfoHob !=3D NULL); > + if (PchInfoHob =3D=3D NULL) { > + return; > + } > + > + for (Index =3D 0; Index < DeviceScopeNum; Index++) { > + NeedRemove =3D FALSE; > + /** > + For HPET and APIC, update device scope if Interrupt remapping is > supported. remove device scope > + if interrupt remapping is not supported. > + - Index =3D 0 - IOAPIC > + - Index =3D 1 - HPET > + **/ > + if (mInterruptRemappingSupport) { > + if (Index =3D=3D 0) { > + /// > + /// Update source id for IoApic's device scope entry > + /// > + Bus =3D (UINT8) PchInfoHob->IoApicBusNum; > + Path[0] =3D (UINT8) PchInfoHob->IoApicDevNum; > + Path[1] =3D (UINT8) PchInfoHob->IoApicFuncNum; > + > DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNum > ber =3D Bus; > + DrhdEngine->DeviceScope[Index].PciPath.Device =3D Path[0]; > + DrhdEngine->DeviceScope[Index].PciPath.Function =3D Path[1]; > + // > + // Update APIC ID > + // > + > DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.EnumerationI > d =3D GetIoApicId (); > + } > + if (Index =3D=3D 1) { > + /// > + /// Update source id for HPET's device scope entry > + /// > + Bus =3D (UINT8) PchInfoHob->HpetBusNum; > + Path[0] =3D (UINT8) PchInfoHob->HpetDevNum; > + Path[1] =3D (UINT8) PchInfoHob->HpetFuncNum; > + > DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNum > ber =3D Bus; > + DrhdEngine->DeviceScope[Index].PciPath.Device =3D Path[0]; > + DrhdEngine->DeviceScope[Index].PciPath.Function =3D Path[1]; > + } > + } else { > + if ((Index =3D=3D 0) || (Index =3D=3D 1)) { > + NeedRemove =3D TRUE; > + } > + } > + > + CopyMem ( > + &DrhdEngine->DeviceScope[ValidDeviceScopeNum], > + &DrhdEngine->DeviceScope[Index], > + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE) > + ); > + if (NeedRemove) { > + Length -=3D 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 =3D=3D 0x01)) { > + DrhdEngine->DrhdHeader.Header.Length =3D Length; > + } else { > + DrhdEngine->DrhdHeader.Header.Length =3D 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 =3D (EFI_ACPI_RMRR_USB_STRUC *) RmrrPtr; > + > + Length =3D Rmrr->RmrrHeader.Header.Length; > + ValidDeviceScopeNum =3D 0; > + DeviceScopeNum =3D (Rmrr->RmrrHeader.Header.Length - > EFI_ACPI_RMRR_HEADER_LENGTH) / sizeof > (EFI_ACPI_DEV_SCOPE_STRUCTURE); > + for (Index =3D 0; Index < DeviceScopeNum; Index++) { > + DisableBit =3D GetFunDisableBit ( > + Rmrr->DeviceScope[Index].PciPath.Device, > + Rmrr->DeviceScope[Index].PciPath.Function > + ); > + NeedRemove =3D FALSE; > + if ((DisableBit =3D=3D 0xFF) || > + ((DisableBit =3D=3D 0x80) && > + (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, > Rmrr->DeviceScope[Index].PciPath.Device, > Rmrr->DeviceScope[Index].PciPath.Function, 0x00)) =3D=3D 0xFFFFFFFF)) > + ) { > + NeedRemove =3D TRUE; > + } else if (DisableBit =3D=3D 0x8F) { > + NeedRemove =3D FALSE; > + } > + CopyMem ( > + &Rmrr->DeviceScope[ValidDeviceScopeNum], > + &Rmrr->DeviceScope[Index], > + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE) > + ); > + > + if (Rmrr->RmrrHeader.ReservedMemoryRegionLimitAddress =3D=3D 0x0) { > + NeedRemove =3D TRUE; > + } > + > + if (NeedRemove) { > + Length -=3D 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 =3D Length; > + } else { > + Rmrr->RmrrHeader.Header.Length =3D 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 =3D 0; > + GttMemSize =3D 0; > + DmarTable =3D (EFI_ACPI_DMAR_TABLE *) TableHeader; > + > + Status =3D GetConfigBlock ((VOID *) mSaPolicy, &gMiscDxeConfigGuid, (V= OID > *)&MiscDxeConfig); > + ASSERT_EFI_ERROR (Status); > + > + /// > + /// Set INTR_REMAP bit (BIT 0) if interrupt remapping is supported > + /// > + if (mInterruptRemappingSupport) { > + DmarTable->DmarHeader.Flags |=3D BIT0; > + } > + > + if (mSaConfigHob->VtdData.X2ApicOptOut =3D=3D 1) { > + DmarTable->DmarHeader.Flags |=3D BIT1; > + } else { > + DmarTable->DmarHeader.Flags &=3D 0xFD; > + } > + > + /// > + /// Get OemId > + /// > + CopyMem (DmarTable->DmarHeader.Header.OemId, PcdGetPtr > (PcdAcpiDefaultOemId), sizeof (DmarTable->DmarHeader.Header.OemId)); > + DmarTable->DmarHeader.Header.OemTableId =3D PcdGet64 > (PcdAcpiDefaultOemTableId); > + DmarTable->DmarHeader.Header.OemRevision =3D PcdGet32 > (PcdAcpiDefaultOemRevision); > + DmarTable->DmarHeader.Header.CreatorId =3D PcdGet32 > (PcdAcpiDefaultCreatorId); > + DmarTable->DmarHeader.Header.CreatorRevision =3D PcdGet32 > (PcdAcpiDefaultCreatorRevision); > + > + /// > + /// Calculate IGD memsize > + /// > + McD0BaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, > SA_MC_BUS, 0, 0, 0); > + MchBar =3D PciSegmentRead32 (McD0BaseAddress + R_SA_MCHBAR) > & ~BIT0; > + IgdMode =3D ((PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) & > B_SA_GGC_GMS_MASK) >> N_SA_GGC_GMS_OFFSET) & 0xFF; > + if (IgdMode < 0xF0) { > + IgdMemSize =3D IgdMode * 32 * (1024) * (1024); > + } else { > + IgdMemSize =3D 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024); > + } > + /// > + /// Calculate GTT mem size > + /// > + GttMemSize =3D 0; > + GttMode =3D (PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) & > B_SA_GGC_GGMS_MASK) >> N_SA_GGC_GGMS_OFFSET; > + if (GttMode <=3D V_SA_GGC_GGMS_8MB) { > + GttMemSize =3D (1 << GttMode) * (1024) * (1024); > + } > + > + DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress =3D > (PciSegmentRead32 (McD0BaseAddress + R_SA_TOLUD) & ~(0x01)) - > IgdMemSize - GttMemSize; > + DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress =3D > 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 > =3D MiscDxeConfig->RmrrUsbBaseAddress[0]; > + DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress > =3D MiscDxeConfig->RmrrUsbBaseAddress[1]; > + > + /// > + /// Convert to 4KB alignment. > + /// > + if > (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress !=3D > 0x0) { > + DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress > &=3D (EFI_PHYSICAL_ADDRESS) ~0xFFF; > + DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress > &=3D (EFI_PHYSICAL_ADDRESS) ~0xFFF; > + DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress > +=3D 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 > =3D=3D 0) { > + DEBUG ((DEBUG_WARN, "WARNING: > RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress is 0.\n")); > + } > + > + DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress > =3D MiscDxeConfig->RmrrCsmeBaseAddress[0]; > + DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress > =3D 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 =3D > (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1); > + DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress =3D > (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 =3D (UINTN) (&TempDmarTable.DrhdEngine1); > + if (TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length !=3D 0) { > + Offset +=3D TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length; > + } > + if (TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length !=3D 0) { > + StructureLen =3D TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length; > + CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.DrhdEngine3, > TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length); > + Offset +=3D StructureLen; > + } > + /// > + /// Remove unused device scope or entire RMRR structures > + /// > + if (TempDmarTable.RmrrUsb.RmrrHeader.Header.Length !=3D 0) { > + StructureLen =3D TempDmarTable.RmrrUsb.RmrrHeader.Header.Length; > + CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrUsb, > TempDmarTable.RmrrUsb.RmrrHeader.Header.Length); > + Offset +=3D StructureLen; > + } > + if (TempDmarTable.RmrrIgd.RmrrHeader.Header.Length !=3D 0) { > + StructureLen =3D TempDmarTable.RmrrIgd.RmrrHeader.Header.Length; > + CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrIgd, > TempDmarTable.RmrrIgd.RmrrHeader.Header.Length); > + Offset +=3D StructureLen; > + } > + if (TempDmarTable.RmrrCsme.RmrrHeader.Header.Length !=3D 0) { > + StructureLen =3D TempDmarTable.RmrrCsme.RmrrHeader.Header.Length; > + CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrCsme, > TempDmarTable.RmrrCsme.RmrrHeader.Header.Length); > + Offset +=3D StructureLen; > + } > + > + Offset =3D Offset - (UINTN) &TempDmarTable; > + /// > + /// Re-calculate DMAR table check sum > + /// > + TempDmarTable.DmarHeader.Header.Checksum =3D (UINT8) > (TempDmarTable.DmarHeader.Header.Checksum + > TempDmarTable.DmarHeader.Header.Length - Offset); > + /// > + /// Set DMAR table length > + /// > + TempDmarTable.DmarHeader.Header.Length =3D (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 =3D FALSE; > + > + > + if (Triggered) { > + return; > + } > + > + Triggered =3D TRUE; > + > + FwVol =3D NULL; > + AcpiTable =3D NULL; > + VtdAcpiTable =3D NULL; > + > + DEBUG ((DEBUG_INFO, "UpdateDmarPciEnumCompleteCallback \n")); > + > + > + /// > + /// Fix DMAR Table always created, skip install when disabled > + /// > + if ((mSaConfigHob->VtdData.VtdDisable =3D=3D TRUE) || (PciSegmentRead3= 2 > (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 =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOI= D **) > &AcpiTable); > + > + /// > + /// Locate protocol. > + /// There is little chance we can't find an FV protocol > + /// > + Status =3D gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiFirmwareVolume2ProtocolGuid, > + NULL, > + &NumberOfHandles, > + &HandleBuffer > + ); > + ASSERT_EFI_ERROR (Status); > + > + /// > + /// Looking for FV with ACPI storage file > + /// > + for (i =3D 0; i < NumberOfHandles; i++) { > + /// > + /// Get the protocol on this handle > + /// This should not fail because of LocateHandleBuffer > + /// > + Status =3D gBS->HandleProtocol ( > + HandleBuffer[i], > + &gEfiFirmwareVolume2ProtocolGuid, > + (VOID **) &FwVol > + ); > + ASSERT_EFI_ERROR (Status); > + > + /// > + /// See if it has the ACPI storage file > + /// > + Size =3D 0; > + FvStatus =3D 0; > + Status =3D FwVol->ReadFile ( > + FwVol, > + &gSaAcpiTableStorageGuid, > + NULL, > + &Size, > + &FileType, > + &Attributes, > + &FvStatus > + ); > + > + /// > + /// If we found it, then we are done > + /// > + if (Status =3D=3D EFI_SUCCESS) { > + break; > + } > + } > + /// > + /// Our exit status is determined by the success of the previous opera= tions > + /// 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 =3D=3D NULL) { > + return; > + } > + /// > + /// By default, a table belongs in all ACPI table versions published. > + /// > + Version =3D 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 =3D 0; > + CurrentTable =3D NULL; > + > + while (Status =3D=3D EFI_SUCCESS) { > + Status =3D 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 =3D (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable; > + DmarTableUpdate (VtdAcpiTable, &Version); > + break; > + > + default: > + break; > + } > + /// > + /// Increment the instance > + /// > + Instance++; > + CurrentTable =3D NULL; > + } > + } > + /// > + /// Update the VTD table in the ACPI tables. > + /// > + AcpiTableHandle =3D 0; > + if (VtdAcpiTable !=3D NULL) { > + Status =3D 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 =3D FALSE; > + mSaConfigHob =3D NULL; > + mSaConfigHob =3D GetFirstGuidHob (&gSaConfigHobGuid); > + if (mSaConfigHob !=3D NULL) { > + mInterruptRemappingSupport =3D > mSaConfigHob->VtdData.InterruptRemappingSupport; > + } > + > + /// > + /// Locate the SA Global NVS Protocol. > + /// > + Status =3D gBS->LocateProtocol ( > + &gSaNvsAreaProtocolGuid, > + NULL, > + (VOID **) &SaNvsAreaProtocol > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + McD0BaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, > SA_MC_BUS, 0, 0, 0); > + McD2BaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, > SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0); > + mSaPolicy =3D SaPolicy; > + MchBar =3D PciSegmentRead32(McD0BaseAddress + R_SA_MCHBAR) > & ~BIT0; > + > + if (mSaConfigHob !=3D NULL) { > + SaNvsAreaProtocol->Area->VtdDisable =3D > mSaConfigHob->VtdData.VtdDisable; > + } > + SaNvsAreaProtocol->Area->VtdBaseAddress1 =3D (MmioRead32(MchBar + > R_SA_MCHBAR_VTD1_OFFSET) &~1); > + SaNvsAreaProtocol->Area->VtdBaseAddress3 =3D (MmioRead32(MchBar + > R_SA_MCHBAR_VTD3_OFFSET) &~1); > + SaNvsAreaProtocol->Area->VtdEngine1Vid =3D > PciSegmentRead16(McD2BaseAddress + PCI_VENDOR_ID_OFFSET); > + > + if (mSaConfigHob !=3D 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.
> + > + 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 =3D SMM_ACCESS_PRIVATE_DATA_SIGNATURE; > + mSmmAccess.Handle =3D NULL; > + > + /// > + /// Get Hob list > + /// > + Hob =3D GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid); > + if (Hob =3D=3D NULL) { > + DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n")); > + return EFI_NOT_FOUND; > + } > + > + DescriptorBlock =3D (VOID *) ((UINT8 *) Hob + sizeof (EFI_HOB_GUID_TYP= E)); > + > + /// > + /// Alloc space for mSmmAccess.SmramDesc > + /// > + mSmmAccess.SmramDesc =3D AllocateZeroPool > ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof > (EFI_SMRAM_DESCRIPTOR)); > + if (mSmmAccess.SmramDesc =3D=3D 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 =3D 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; > Index++) { > + mSmmAccess.SmramDesc[Index].PhysicalStart =3D > DescriptorBlock->Descriptor[Index].PhysicalStart; > + mSmmAccess.SmramDesc[Index].CpuStart =3D > DescriptorBlock->Descriptor[Index].CpuStart; > + mSmmAccess.SmramDesc[Index].PhysicalSize =3D > DescriptorBlock->Descriptor[Index].PhysicalSize; > + mSmmAccess.SmramDesc[Index].RegionState =3D > DescriptorBlock->Descriptor[Index].RegionState; > + } > + > + mSmmAccess.NumberRegions =3D Index; > + mSmmAccess.SmmAccess.Open =3D Open; > + mSmmAccess.SmmAccess.Close =3D Close; > + mSmmAccess.SmmAccess.Lock =3D Lock; > + mSmmAccess.SmmAccess.GetCapabilities =3D GetCapabilities; > + mSmmAccess.SmmAccess.LockState =3D FALSE; > + mSmmAccess.SmmAccess.OpenState =3D FALSE; > + > + /// > + /// Install our protocol interfaces on the device's handle > + /// > + Status =3D 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 memor= y. > + The use of "open" means that the memory is visible from all boot-servi= ce > + 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 =3D SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This); > + for (DescriptorIndex =3D 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 =3D PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, > R_SA_SMRAMC); > + > + SmramControl =3D PciRead8 (Address); > + /// > + /// Is SMRAM locked? > + /// > + for (DescriptorIndex =3D 0; DescriptorIndex < SmmAccess->NumberRegions= ; > DescriptorIndex++) { > + if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) !=3D 0) { > + /// > + /// Cannot Open a locked region > + /// > + SmmAccess->SmramDesc[DescriptorIndex].RegionState |=3D > EFI_SMRAM_LOCKED; > + DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n")); > + return EFI_DEVICE_ERROR; > + } > + } > + /// > + /// Open SMRAM region > + /// > + SmramControl |=3D B_SA_SMRAMC_D_OPEN_MASK; > + SmramControl &=3D ~(B_SA_SMRAMC_D_CLS_MASK); > + > + PciWrite8 (Address, SmramControl); > + /// > + /// END CHIPSET SPECIFIC CODE > + /// > + for (DescriptorIndex =3D 0; DescriptorIndex < SmmAccess->NumberRegions= ; > DescriptorIndex++) { > + SmmAccess->SmramDesc[DescriptorIndex].RegionState &=3D (UINT64) > ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED); > + SmmAccess->SmramDesc[DescriptorIndex].RegionState |=3D (UINT64) > EFI_SMRAM_OPEN; > + } > + SmmAccess->SmmAccess.OpenState =3D 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 agen= ts, > + 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 =3D SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This); > + > + for (DescriptorIndex =3D 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 =3D PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, > R_SA_SMRAMC); > + > + SmramControl =3D PciRead8 (Address); > + /// > + /// Is SMRAM locked? > + /// > + if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) !=3D 0) { > + /// > + /// Cannot Close a locked region > + /// > + SmmAccess->SmramDesc[DescriptorIndex].RegionState |=3D > EFI_SMRAM_LOCKED; > + DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n")); > + return EFI_DEVICE_ERROR; > + } > + /// > + /// Close SMRAM region > + /// > + SmramControl &=3D ~(B_SA_SMRAMC_D_OPEN_MASK); > + > + PciWrite8 (Address, SmramControl); > + /// > + /// END CHIPSET SPECIFIC CODE > + /// > + SmmAccess->SmramDesc[DescriptorIndex].RegionState &=3D (UINT64) > ~EFI_SMRAM_OPEN; > + SmmAccess->SmramDesc[DescriptorIndex].RegionState |=3D (UINT64) > (EFI_SMRAM_CLOSED | EFI_ALLOCATED); > + } > + > + /// > + /// Find out if any regions are still open > + /// > + OpenState =3D FALSE; > + for (Index =3D 0; Index < mSmmAccess.NumberRegions; Index++) { > + if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) =3D= =3D > EFI_SMRAM_OPEN) { > + OpenState =3D TRUE; > + } > + } > + > + SmmAccess->SmmAccess.OpenState =3D 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 =3D 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 =3D 0; DescriptorIndex < SmmAccess->NumberRegions= ; > DescriptorIndex++) { > + SmmAccess->SmramDesc[DescriptorIndex].RegionState |=3D > EFI_SMRAM_LOCKED; > + } > + SmmAccess->SmmAccess.LockState =3D TRUE; > + > + /// > + /// BEGIN CHIPSET SPECIFIC CODE > + /// > + /// > + /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit) > + /// > + Address =3D PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, > R_SA_SMRAMC); > + > + SmramControl =3D PciRead8 (Address); > + /// > + /// Lock the SMRAM > + /// > + SmramControl |=3D 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 Interfa= ce. > + @param[in] SmramMapSize - Pointer to the variable containing = size > of the > + buffer to contain the description i= nformation. > + @param[in] SmramMap - Buffer containing the data describi= ng > 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 =3D SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This); > + > + NecessaryBufferSize =3D SmmAccess->NumberRegions * sizeof > (EFI_SMRAM_DESCRIPTOR); > + > + if (*SmramMapSize < NecessaryBufferSize) { > + DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n")); > + Status =3D EFI_BUFFER_TOO_SMALL; > + } else { > + CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize); > + Status =3D EFI_SUCCESS; > + } > + > + *SmramMapSize =3D 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "Dmar.h" > +#include > + > +EFI_ACPI_DMAR_TABLE DmarTable =3D { > + // > + // 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 =3D 0 (DRHD) > + sizeof (EFI_ACPI_DRHD_ENGINE1_STRUCT)}, // Length of structure > + 0, // Flag - Do not inclu= de 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 =3D 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=3DIO 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=3DHPET > + 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 struct= ure > + 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 structu= re > + sizeof (EFI_ACPI_RMRR_IGD_STRUC)}, // Length > + {0x0000}, // Reserved > + 0x0000, // Segment Num > + 0x0000000000000000, // RMRR Base address - U= pdated > 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 structu= re > + sizeof (EFI_ACPI_RMRR_CSME_STRUC)}, // Length > + {0x0000}, // Reserved > + 0x0000, // Segment Num > + 0x0000000000000000, // RMRR Base address - U= pdated > 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 Bu= s. > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + 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 informati= on > +// 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 resource= s, > 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 u= se 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 !=3D 0. Set length =3D 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 =3D 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 t= he > 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.a= sl > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.a= sl > new file mode 100644 > index 0000000000..e7a797c973 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.a= sl > @@ -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.
> + > + 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, 0xF= FFFFFFF}) > +Name(TMPD,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, > 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, > + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF= FFFFFFF, > 0xFFFFFFFF}) > +Name(TMPE,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, > 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, > + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF= FFFFFFF, > 0xFFFFFFFF, 0xFFFFFFFF}) > +Name(TMPF,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, > 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, > + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF= FFFFFFF, > 0xFFFFFFFF, 0xFFFFFFFF, > + 0xFFFFFFFF}) > +Name(TMPG,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, > 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, > + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF= FFFFFFF, > 0xFFFFFFFF, 0xFFFFFFFF, > + 0xFFFFFFFF, 0xFFFFFFFF}) > + > +// Enable/Disable Output Switching. In WIN2K/WINXP, _DOS =3D 0 will > +// get called during initialization to prepare for an ACPI Display > +// Switch Event. During an ACPI Display Switch, the OS will call > +// _DOS =3D 2 immediately after a Notify=3D0x80 to temporarily disable > +// all Display Switching. After ACPI Display Switching is complete, > +// the OS will call _DOS =3D 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]=3D0 > + { > + 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, 3= 5, 36, 37, 38, > 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 5= 7, 58, 59, 60, > 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 7= 9, 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.
> + > + 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 > + // !=3D0, 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 p= arent > +;* method. > +;* Ex: If (PSTS()) {Return (FAIL)} > +;* > +;* Input: None > +;* > +;* Output: None > +;* > +;* References: CSTS (Notification status), ASLP (Driver recommended sle= ep > +;* 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 drive= r > +;* status. If all methods return success, do a notificatio= n of > +;* the graphics device. > +;* > +;* Usage: This method is to be called when a graphics device > +;* notification is required (display switch hotkey, etc). > +;* > +;* Input: Arg0 =3D Current event type: > +;* 1 =3D display switch > +;* 2 =3D lid > +;* 3 =3D dock > +;* Arg1 =3D Notification type: > +;* 0 =3D Re-enumeration > +;* 0x80 =3D Display switch > +;* > +;* Output: Returns 0 =3D success, 1 =3D 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 failur= e. > + // > + If(PDRD()) > + { > + Return(0x1) // Return failure if driver not loaded. > + } > + > + Store(Arg0, CEVT) // Set up the current event value > + Store(3, CSTS) // CSTS=3DBIOS 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 an= d > the > +;* purpose of that hotkey is to do a display switch. > +;* > +;* Input: Arg0 =3D Toggle table number. > +;* > +;* Output: Returns 0 =3D success, 1 =3D failure. > +;* CEVT and TIDX are indirect outputs. > +;* > +;* References: TIDX, GNOT > +;* > +;************************************************************** > **********/ > + > +Method(GHDS, 1) > +{ > + Store(Arg0, TIDX) // Store the table number > + // > + // Call GNOT for CEVT =3D 1 =3D hotkey, notify value =3D 0 > + // > + Return(GNOT(1, 0)) // Return stats from GNOT > +} > + > +/************************************************************** > **********; > +;* > +;* Name: GLID > +;* > +;* Description: Handle a lid event (performs the Notify(GFX0, 0), but no= t 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 =3D Lid state: > +;* 0 =3D All closed > +;* 1 =3D internal LFP lid open > +;* 2 =3D external lid open > +;* 3 =3D both external and internal open > +;* > +;* Output: Returns 0=3Dsuccess, 1=3Dfailure. > +;* 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=3D2=3DLid, notify value =3D 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 s= tatus > +;* and doing a notification. > +;* > +;* Usage: This method must be called when a docking event occurs. > +;* > +;* Input: Arg0 =3D Docking state: > +;* 0 =3D Undocked > +;* 1 =3D Docked > +;* > +;* Output: Returns 0=3Dsuccess, 1=3Dfailure. > +;* CDCK and CEVT are indirect outputs. > +;* > +;* References: CDCK, GNOT > +;* > +;************************************************************** > **********/ > + > +Method(GDCK, 1) > +{ > + Store(Arg0, CDCK) // Store the current dock state > + // > + // Call GNOT for CEVT=3D4=3DDock, notify value =3D 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 =3D success, 1 =3D 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 > + // !=3D0, do not generate the ASLE interrupt. > + // > + Return(LNot(ARDY)) > +} > + > +// > +// Intel Ultrabook Event Handler. Arg0 represents the Ultrabook Event B= it # > 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 interru= pt. > +;* This process includes ensuring the graphics driver is re= ady > +;* to process the interrupt, ensuring the driver supports t= he > +;* 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 =3D ASLE command function code: > +;* 0 =3D Set ALS illuminance > +;* 1 =3D Set backlight brightness > +;* 2 =3D Do Panel Fitting > +;* 4 =3D Reserved > +;* 5 =3D Button Indicator Event > +;* 6 =3D Convertible Indicator Event > +;* 7 =3D Docking Indicator Event > +;* Arg1 =3D If Arg0 =3D 0, current ALS reading: > +;* 0 =3D Reading below sensor range > +;* 1-0xFFFE =3D Current sensor reading > +;* 0xFFFF =3D Reading above sensor range > +;* Arg1 =3D If Arg0 =3D 1, requested backlight percentage > +;* > +;* Output: Returns 0 =3D success, 1 =3D 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 ze= ro. > + > + 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, o= r ALS). > + // > + If(LEqual(Arg0, 2)) // Arg0 =3D 2, so request a panel fitting = mode change. > + { > + If(CPFM) // If current mode field is non-zero use i= t. > + { > + 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 togg= le the > + { > + Xor(PFIT,7,PFIT) // mode setting between stretched and cent= ered > 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=3D1, so set the backlight brightness. > + { > + Store(Divide(Multiply(Arg1, 255), 100), BCLP) // Convert from perc= ent 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=3D0, 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.
> + > + 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 =3D Return Supported Functions) > +// Arg3: Additional Inputs/Package Parameters Bits [31:0] input as {Byte= 0, > 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, Byt= e3} > + // > + // Return: > + // Success for simple notification, Opregion update for some routine= s 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= =3D D0; 01h > =3D D1; 02h =3D D2; 04h =3D D3 (Cold/Hot); 08h =3D D4 (Hibernate Notifica= tion) > + // 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 =3D D1 (Arg3[0]=3D0= x01) > + // > + 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] =3D=3D 0) for C= S Exit > + // > + If (LEqual (Local0, 0)) { > + // GUAM - Global User Absent Mode Notification Method > + \GUAM(0) > + } > + } > + > + // Upon notification from driver that the Adapter Power State = =3D D0, > + // check if previous lid event failed. If it did, retry the l= id > + // 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 =3D On > + // 01h =3D Standby > + // 02h =3D Suspend > + // 04h =3D Off > + // 08h =3D 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 > + // An OEM may elect to implement this method. In that c= ase, > + // the input values must be saved into non-volatile storage fo= r > + // 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 dis= play 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 fo= r > + // 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 (C= hange if > + // panel type input is non-zero). Zero=3DNo change requested. > + If(And(DerefOf (Index (Arg3,1)), 0xFF)) { > + And(DerefOf (Index (Arg3,1)), 0xFF, IPAT) > + Decrement(IPAT) // 0 =3D 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 = =3D 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] =3D Boot device ty= pe > + 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 =3D On: Auto > + // 01h =3D On: Force Scaling > + // 02h =3D Off > + // 03h =3D Maintain Aspect Ratio > + > + Store(IPSC, Local0) > + Or(Local0, ShiftLeft(IPAT, 8), Local0) > + > + // Adjust panel type, 0 =3D VBT default > + // Bits [15:8] - Panel Type > + // Bits contain the panel type user setting from CMOS > + // 00h =3D Not Valid, use default Panel Type & Timings from VB= T > + // 01h - 0Fh =3D 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 =3D Lid Open > + // 1 =3D 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 set= ting > from CMOS > + // 000 =3D VBT Default > + // 001 =3D BIA Disabled (BLC may still be enabled) > + // 010 - 110 =3D 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=3DVGA) > + Xor(Local0, 1, Local0) // Invert the VGA mode = polarity > + > + Or(Local0, ShiftLeft(GMFN, 1), Local0) // Local0[1] - # I= GD PCI > functions-1 > + // Local0[3:2] - Res= erved > + // Local0[4] - IGD= D3 support(0=3Dcold) > + // Local0[10:5] - Res= erved > + Or(Local0, ShiftLeft(3, 11), Local0) // Local0[12:11] - DVM= T version > (11b =3D 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 modif= ied > + // settings flag must be programmed per the specification. Th= is > means > + // that the flag must be set to indicate that system BIOS requ= ests > + // these settings. Once "Set Internal Graphics" is called, th= e > + // modified settings flag must be cleared on all subsequent c= alls 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +Method (GBDA, 0, Serialized) > +{ > + // > + // Supported calls: Sub-function 0 > + // > + If (LEqual(GESF, 0)) > + { > + // > + // 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)) > + { > + // > + // 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)) > + { > + // > + // Get Boot Display Preferences function. > + // > + And(PARM, 0xEFFF0000, PARM) // PARM[30:16] =3D Boot device ports > + And(PARM, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), PARM) > + Or(IBTT, PARM, PARM) // PARM[7:0] =3D Boot device type > + Store(Zero, GESF) // Clear the exit parameter > + Return(SUCC) // Success > + } > + // > + // Panel details: Sub-function 5 > + // > + If (LEqual(GESF, 5)) > + { > + // > + // 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 =3D VBT default > + Or(PARM, ShiftLeft(LIDS, 16), PARM) // Report the lid state > + Add(PARM, 0x10000, PARM) // Adjust the lid state, 0 =3D 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=3DVGA) > + Xor(PARM, 1, PARM) // Invert the VGA mode polarity > + Or(PARM, ShiftLeft(GMFN, 1), PARM) // PARM[1] - # IGD PCI function= s-1 > + // PARM[3:2] - Reserved > + // PARM[4] - IGD D3 support(= 0=3Dcold) > + // PARM[10:5] - Reserved > + Or(PARM, ShiftLeft(3, 11), PARM) // PARM[12:11] - DVMT mode(11b =3D = 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 mea= ns > + // 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 t= o > + // 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),P= ARM, > 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/IgfxOp= R > 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.
> + > + 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 a= s > +// 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=3Devent pending) > + GSSB, 14, // Graphics SCI scratchpad bits > + GSES, 1, // Graphics event select (1=3DSCI) > + 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=3Dcall 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/IgfxOp= S > bcb.asl > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp= S > bcb.asl > new file mode 100644 > index 0000000000..0167d922ff > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp= S > 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +Method (SBCB, 0, Serialized) > +{ > + // > + // Supported Callbacks: Sub-function 0 > + // > + If (LEqual(GESF, 0x0)) > + { > + // > + // 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 =3D D1 (PARM[7:0]=3D0x01) > + // > + 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 =3D 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)) > + { > + // > + // 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)) > + { > + // > + // 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 dr= iver. > + // > + And(PARM, 0xFF, IPSC) > + // > + // Change panel type if a change is requested by the driver (Change = if > + // panel type input is non-zero). Zero=3DNo change requested. > + // > + If(And(ShiftRight(PARM, 8), 0xFF)) > + { > + And(ShiftRight(PARM, 8), 0xFF, IPAT) > + Decrement(IPAT) // 0 =3D 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)) > + { > + // > + // 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 opt= ion > + If(And(PARM, ShiftLeft(0xF, 13))) // Use fixed memory if fixed = size !=3D 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 =3D Unkno= wn > + 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)) > + { > + // > + // 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.as= l > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.as= l > new file mode 100644 > index 0000000000..e4e47ddf1e > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.as= l > @@ -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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +// > +// Device IPUA is the IPU AVStream virtual device and it appears under G= FX0 > +// > +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 devic= e 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. D= SM > 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 othe= r 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.
> + > + 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.
> + > + 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 addre= ss > + Offset(4), IMON, 8, // Offset(4), IMON Current Value > + Offset(5), IGDS, 8, // Offset(5), IGD State (Primary Display= =3D 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=3DSCI= ) > + Offset(15), PAVP, 8, // Offset(15), IGD PAVP data > + Offset(16), CADL, 8, // Offset(16), Current Attached Device Li= st > + 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 =3D 1) > + Offset(123), KSV0, 32, // Offset(123), First four bytes of AKSV > (manufacturing mode) > + Offset(127), KSV1, 8, // Offset(127), Fifth byte of AKSV (manufa= cturing > mode) > + Offset(128), BRTL, 8, // Offset(128), Brightness Level Percentag= e > + Offset(129), ALSE, 8, // Offset(129), Ambient Light Sensor Enabl= e > + Offset(130), ALAF, 8, // Offset(130), Ambient Light Adjusment Fa= ctor > + 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=3D= Disabled, > 1=3DAVStream virtual device as child of GFX) > + Offset(135), EDPV, 8, // Offset(135), Check for eDP display devi= ce > + Offset(136), SGMD, 8, // Offset(136), SG Mode (0=3DDisabled, 1= =3DSG > Muxed, 2=3DSG Muxless, 3=3DDGPU Only) > + Offset(137), SGFL, 8, // Offset(137), SG Feature List > + Offset(138), SGGP, 8, // Offset(138), PCIe0 GPIO Support (0=3DDi= sabled, > 1=3DPCH Based, 2=3DI2C 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 Expand= er > Number > + Offset(146), PWG0, 32, // Offset(146), PCIe0 PWR Enable GPIO Numb= er > + Offset(150), PWA0, 8, // Offset(150), PCIe0 PWR Enable GPIO Acti= ve > Information > + Offset(151), P1GP, 8, // Offset(151), PCIe1 GPIO Support (0=3DDi= sabled, > 1=3DPCH Based, 2=3DI2C 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 Expand= er > Number > + Offset(159), PWG1, 32, // Offset(159), PCIe1 PWR Enable GPIO Numb= er > + Offset(163), PWA1, 8, // Offset(163), PCIe1 PWR Enable GPIO Acti= ve > Information > + Offset(164), P2GP, 8, // Offset(164), PCIe2 GPIO Support (0=3DDi= sabled, > 1=3DPCH Based, 2=3DI2C 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 Expand= er > Number > + Offset(172), PWG2, 32, // Offset(172), PCIe2 PWR Enable GPIO Numb= er > + Offset(176), PWA2, 8, // Offset(176), PCIe2 PWR Enable GPIO Acti= ve > Information > + Offset(177), DLPW, 16, // Offset(177), Delay after power enable f= or 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 S= pace > 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 Reportin= g Enable > + Offset(201), OBFX, 8, // Offset(201), Optimized Buffer Flush and= Fill > + Offset(202), LTRY, 8, // Offset(202), Latency Tolerance Reportin= g Enable > + Offset(203), OBFY, 8, // Offset(203), Optimized Buffer Flush and= Fill > + Offset(204), LTRZ, 8, // Offset(204), Latency Tolerance Reportin= g Enable > + Offset(205), OBFZ, 8, // Offset(205), Optimized Buffer Flush and= Fill > + Offset(206), LTRW, 8, // Offset(206), Latency Tolerance Reportin= g > 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 R= eporting > 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=3DDisabled, 1=3DEnabled) > + Offset(218), M64B, 64, // Offset(218), Base of above 4GB MMIO res= ource > + 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 res= ource > + Offset(247), M32L, 32, // Offset(247), Length of below 4GB MMIO > resource > + Offset(251), P0WK, 32, // Offset(251), PCIe0 RTD3 Device Wake GPI= O > Number > + Offset(255), P1WK, 32, // Offset(255), PCIe1 RTD3 Device Wake GPI= O > Number > + Offset(259), P2WK, 32, // Offset(259), PCIe2 RTD3 Device Wake GPI= O > 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=3DDi= sabled, > 1=3DPCH Based, 2=3DI2C 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 Expand= er > Number > + Offset(289), PWG3, 32, // Offset(289), PCIe3 PWR Enable GPIO Numb= er > + Offset(293), PWA3, 8, // Offset(293), PCIe3 PWR Enable GPIO Acti= ve > Information > + Offset(294), P3WK, 32, // Offset(294), PCIe3 RTD3 Device Wake GPI= O > 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.
> + > + 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