From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga18.intel.com (mga18.intel.com []) by mx.groups.io with SMTP id smtpd.web08.5230.1612428710391778925 for ; Thu, 04 Feb 2021 00:51:51 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: heng.luo@intel.com) IronPort-SDR: lGk/zF85PYDq9RpH4TWJJ1OFASja6Dgnfh+29VPZqPMUjWs6VLYsn24pfbKGkQkZ5QGsjJEnfz Ni0lG8FVA4/g== X-IronPort-AV: E=McAfee;i="6000,8403,9884"; a="168881030" X-IronPort-AV: E=Sophos;i="5.79,400,1602572400"; d="scan'208";a="168881030" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Feb 2021 00:51:48 -0800 IronPort-SDR: GZh+LojJkNhI3x0LNHn67kVv2SxQROQB4ZEOitv+oZKsuoDBam0bEfUliR/p9Pzm4v7wovwEoY ntO2Df+OtrNA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,400,1602572400"; d="scan'208";a="393062441" Received: from hengluo-dev.ccr.corp.intel.com ([10.239.153.154]) by orsmga008.jf.intel.com with ESMTP; 04 Feb 2021 00:51:47 -0800 From: "Heng Luo" To: devel@edk2.groups.io Cc: Sai Chaganty , Nate DeSimone Subject: [Patch V2 37/40] TigerlakeSiliconPkg/SystemAgent: Add SystemAgent modules Date: Thu, 4 Feb 2021 16:49:16 +0800 Message-Id: <20210204084919.3603-37-heng.luo@intel.com> X-Mailer: git-send-email 2.24.0.windows.2 In-Reply-To: <20210204084919.3603-1-heng.luo@intel.com> References: <20210204084919.3603-1-heng.luo@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3171 Adds the following files: * SystemAgent/SaInit/Dxe * SystemAgent/SaInit/Smm Cc: Sai Chaganty Cc: Nate DeSimone Signed-off-by: Heng Luo --- Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c = | 431 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c = | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h = | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c = | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h = | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf = | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/CpuPcieSmm.c = | 454 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++ Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.c = | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.h = | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.inf= | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ 10 files changed, 1803 insertions(+) diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcp= i.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c new file mode 100644 index 0000000000..d84a0c1fa4 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c @@ -0,0 +1,431 @@ +/** @file=0D + This is the driver that initializes the Intel System Agent.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include "SaInitDxe.h"=0D +#include "SaInit.h"=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +///=0D +/// Global Variables=0D +///=0D +GLOBAL_REMOVE_IF_UNREFERENCED SYSTEM_AGENT_NVS_AREA_PROTOCOL mSaNvsAreaPr= otocol;=0D +GLOBAL_REMOVE_IF_UNREFERENCED SA_POLICY_PROTOCOL *mSaPolicy;= =0D +extern SA_CONFIG_HOB *mSaConfigHo= b;=0D +=0D +/**=0D + A protocol callback which updates 64bits MMIO Base and Length in SA GNVS= area=0D +**/=0D +VOID=0D +UpdateSaGnvsForMmioResourceBaseLength (=0D + VOID=0D + )=0D +{=0D + EFI_PHYSICAL_ADDRESS PciBaseAddress;=0D + UINT32 Tolud;=0D + UINT64 Length;=0D + UINT64 McD0BaseAddress;=0D + UINTN ResMemLimit1;=0D + UINT8 EnableAbove4GBMmioBiosAssignemnt;=0D + HOST_BRIDGE_DATA_HOB *HostBridgeDataHob;=0D +=0D + PciBaseAddress =3D 0;=0D + Tolud =3D 0;=0D + Length =3D 0;=0D + ResMemLimit1 =3D 0;=0D + EnableAbove4GBMmioBiosAssignemnt =3D 0;=0D + HostBridgeDataHob =3D NULL;=0D + //=0D + // Read memory map registers=0D + //=0D + McD0BaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BU= S, 0, 0, 0);=0D + Tolud =3D PciSegmentRead32 (McD0BaseAddress + R_SA_TOLU= D) & B_SA_TOLUD_TOLUD_MASK;=0D + PciBaseAddress =3D Tolud;=0D +=0D + ResMemLimit1 =3D (UINTN) PcdGet64 (PcdSiPciExpressBaseAddress);=0D +=0D + Length =3D ResMemLimit1 - PciBaseAddress;=0D +=0D + //=0D + // Get HostBridgeData HOB and see if above 4GB MMIO BIOS assignment enab= led=0D + //=0D + HostBridgeDataHob =3D (HOST_BRIDGE_DATA_HOB *) GetFirstGuidHob (&gHostBr= idgeDataHobGuid);=0D + if ((HostBridgeDataHob !=3D NULL) && (HostBridgeDataHob->EnableAbove4GBM= mio =3D=3D 1)) {=0D + EnableAbove4GBMmioBiosAssignemnt =3D 1;=0D + }=0D +=0D + //=0D + // Enable Above 4GB MMIO when Aperture Size is 2GB or higher=0D + //=0D + if ((mSaConfigHob !=3D NULL) && (mSaConfigHob->ApertureSize >=3D 15)) {= =0D + EnableAbove4GBMmioBiosAssignemnt =3D 1;=0D + }=0D +=0D + //=0D + // Check Enable Above 4GB MMIO or not=0D + //=0D +=0D + DEBUG ((DEBUG_INFO, "Update SA GNVS Area.\n"));=0D + mSaNvsAreaProtocol.Area->Mmio32Base =3D (UINT32) PciBaseAddress;=0D + mSaNvsAreaProtocol.Area->Mmio32Length =3D (UINT32) Length;=0D + if (EnableAbove4GBMmioBiosAssignemnt =3D=3D 1) {=0D + mSaNvsAreaProtocol.Area->Mmio64Base =3D BASE_256GB;=0D + mSaNvsAreaProtocol.Area->Mmio64Length =3D SIZE_256GB;=0D + }=0D + DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio64Base =3D %lx\n", mSaN= vsAreaProtocol.Area->Mmio64Base));=0D + DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio64Length =3D %lx\n", mS= aNvsAreaProtocol.Area->Mmio64Length));=0D + DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio32Base =3D %lx\n", mSaN= vsAreaProtocol.Area->Mmio32Base));=0D + DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio32Length =3D %lx\n", mS= aNvsAreaProtocol.Area->Mmio32Length));=0D +}=0D +=0D +/**=0D + Install SSDT Table=0D +=0D + @retval EFI_SUCCESS - SSDT Table load successful.=0D +**/=0D +EFI_STATUS=0D +InstallSsdtAcpiTable (=0D + IN GUID SsdtTableGuid,=0D + IN UINT64 Signature=0D + )=0D +{=0D + EFI_STATUS Status;=0D + EFI_HANDLE *HandleBuffer;=0D + BOOLEAN LoadTable;=0D + UINTN NumberOfHandles;=0D + UINTN Index;=0D + INTN Instance;=0D + UINTN Size;=0D + UINT32 FvStatus;=0D + UINTN TableHandle;=0D + EFI_FV_FILETYPE FileType;=0D + EFI_FV_FILE_ATTRIBUTES Attributes;=0D + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;=0D + EFI_ACPI_TABLE_PROTOCOL *AcpiTable;=0D + EFI_ACPI_DESCRIPTION_HEADER *TableHeader;=0D + EFI_ACPI_COMMON_HEADER *Table;=0D +=0D + FwVol =3D NULL;=0D + Table =3D NULL;=0D +=0D + DEBUG ((DEBUG_INFO, "Loading SSDT Table GUID: %g\n", SsdtTableGuid));=0D +=0D + ///=0D + /// Locate FV protocol.=0D + ///=0D + Status =3D gBS->LocateHandleBuffer (=0D + ByProtocol,=0D + &gEfiFirmwareVolume2ProtocolGuid,=0D + NULL,=0D + &NumberOfHandles,=0D + &HandleBuffer=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + ///=0D + /// Look for FV with ACPI storage file=0D + ///=0D + for (Index =3D 0; Index < NumberOfHandles; Index++) {=0D + ///=0D + /// Get the protocol on this handle=0D + /// This should not fail because of LocateHandleBuffer=0D + ///=0D + Status =3D gBS->HandleProtocol (=0D + HandleBuffer[Index],=0D + &gEfiFirmwareVolume2ProtocolGuid,=0D + (VOID **) &FwVol=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D + if (FwVol =3D=3D NULL) {=0D + return EFI_NOT_FOUND;=0D + }=0D + ///=0D + /// See if it has the ACPI storage file=0D + ///=0D + Size =3D 0;=0D + FvStatus =3D 0;=0D + Status =3D FwVol->ReadFile (=0D + FwVol,=0D + &SsdtTableGuid,=0D + NULL,=0D + &Size,=0D + &FileType,=0D + &Attributes,=0D + &FvStatus=0D + );=0D +=0D + ///=0D + /// If we found it, then we are done=0D + ///=0D + if (!EFI_ERROR (Status)) {=0D + break;=0D + }=0D + }=0D + ///=0D + /// Our exit status is determined by the success of the previous operati= ons=0D + /// If the protocol was found, Instance already points to it.=0D + ///=0D + ///=0D + /// Free any allocated buffers=0D + ///=0D + FreePool (HandleBuffer);=0D +=0D + ///=0D + /// Sanity check that we found our data file=0D + ///=0D + ASSERT (FwVol);=0D +=0D + ///=0D + /// Locate ACPI tables=0D + ///=0D + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID = **) &AcpiTable);=0D +=0D + ///=0D + /// Read tables from the storage file.=0D + ///=0D + if (FwVol =3D=3D NULL) {=0D + ASSERT_EFI_ERROR (EFI_NOT_FOUND);=0D + return EFI_NOT_FOUND;=0D + }=0D + Instance =3D 0;=0D +=0D + while (Status =3D=3D EFI_SUCCESS) {=0D + ///=0D + /// Read the ACPI tables=0D + ///=0D + Status =3D FwVol->ReadSection (=0D + FwVol,=0D + &SsdtTableGuid,=0D + EFI_SECTION_RAW,=0D + Instance,=0D + (VOID **) &Table,=0D + &Size,=0D + &FvStatus=0D + );=0D + if (!EFI_ERROR (Status)) {=0D + ///=0D + /// check and load HybridGraphics SSDT table=0D + ///=0D + LoadTable =3D FALSE;=0D + TableHeader =3D (EFI_ACPI_DESCRIPTION_HEADER *) Table;=0D +=0D + if (((EFI_ACPI_DESCRIPTION_HEADER *) TableHeader)->OemTableId =3D=3D= Signature) {=0D + ///=0D + /// This is the SSDT table that match the Signature=0D + ///=0D + DEBUG ((DEBUG_INFO, "Found out SSDT Table GUID: %g\n", SsdtTableGu= id));=0D + LoadTable =3D TRUE;=0D + }=0D +=0D + ///=0D + /// Add the table=0D + ///=0D + if (LoadTable) {=0D + TableHandle =3D 0;=0D + Status =3D AcpiTable->InstallAcpiTable (=0D + AcpiTable,=0D + TableHeader,=0D + TableHeader->Length,=0D + &TableHandle=0D + );=0D + }=0D + ///=0D + /// Increment the instance=0D + ///=0D + Instance++;=0D + Table =3D NULL;=0D + }=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This function gets registered as a callback to perform Dmar Igd=0D +=0D + @param[in] Event - A pointer to the Event that triggered the callbac= k.=0D + @param[in] Context - A pointer to private data registered with the cal= lback function.=0D +**/=0D +VOID=0D +EFIAPI=0D +SaAcpiEndOfDxeCallback (=0D + IN EFI_EVENT Event,=0D + IN VOID *Context=0D + )=0D +{=0D + EFI_STATUS Status;=0D +=0D + if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, = IGD_DEV_NUM, IGD_FUN_NUM, PCI_VENDOR_ID_OFFSET)) !=3D 0xFFFF) {=0D + Status =3D PostPmInitEndOfDxe ();=0D + if (EFI_SUCCESS !=3D Status) {=0D + DEBUG ((DEBUG_WARN, "[SA] EndOfDxe GraphicsInit Error, Status =3D %r= \n", Status));=0D + ASSERT_EFI_ERROR (Status);=0D + }=0D + }=0D +=0D + if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, = IGD_DEV_NUM, IGD_FUN_NUM, PCI_VENDOR_ID_OFFSET)) !=3D 0xFFFF) {=0D + Status =3D GetVBiosVbtEndOfDxe ();=0D + if (EFI_SUCCESS !=3D Status) {=0D + DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Op Region Error, Status =3D %r \n= ", Status));=0D + }=0D +=0D + Status =3D UpdateIgdOpRegionEndOfDxe ();=0D + if (EFI_SUCCESS !=3D Status) {=0D + DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Update Op Region Error, Status = =3D %r \n", Status));=0D + }=0D + }=0D +=0D + return;=0D +}=0D +=0D +/**=0D + SystemAgent Acpi Initialization.=0D +=0D + @param[in] ImageHandle Handle for the image of this driver=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SaAcpiInit (=0D + IN EFI_HANDLE ImageHandle=0D + )=0D +{=0D + EFI_STATUS Status;=0D + EFI_CPUID_REGISTER CpuidRegs;=0D + EFI_EVENT EndOfDxeEvent;=0D +=0D + CPU_PCIE_HOB *CpuPcieHob;=0D +=0D + AsmCpuid (1, &CpuidRegs.RegEax, 0, 0, 0);=0D + ///=0D + /// Get the platform setup policy.=0D + ///=0D + Status =3D gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) = &mSaPolicy);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + ///=0D + /// Install System Agent Global NVS protocol=0D + ///=0D + DEBUG ((DEBUG_INFO, "Install SA GNVS protocol\n"));=0D + Status =3D (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof (SYSTEM_AGENT_N= VS_AREA), (VOID **) &mSaNvsAreaProtocol.Area);=0D + ASSERT_EFI_ERROR (Status);=0D + ZeroMem ((VOID *) mSaNvsAreaProtocol.Area, sizeof (SYSTEM_AGENT_NVS_AREA= ));=0D + mSaNvsAreaProtocol.Area->XPcieCfgBaseAddress =3D (UINT32) (PcdGet64 (Pc= dSiPciExpressBaseAddress));=0D + mSaNvsAreaProtocol.Area->CpuIdInfo =3D CpuidRegs.RegEax;=0D +=0D + ///=0D + /// Get CpuPcieHob HOB=0D + ///=0D + CpuPcieHob =3D NULL;=0D + CpuPcieHob =3D (CPU_PCIE_HOB *) GetFirstGuidHob (&gCpuPcieHobGuid);=0D + if (CpuPcieHob =3D=3D NULL) {=0D + DEBUG((DEBUG_ERROR, "CpuPcieHob not found\n"));=0D + // @todo: Will add it back once it will get add into NVS library since= currently it is failing for JSL=0D + //ASSERT(CpuPcieHob !=3D NULL);=0D + //return EFI_NOT_FOUND;=0D + } else {=0D + mSaNvsAreaProtocol.Area->SlotSelection =3D CpuPcieHob->SlotSelection;= =0D + DEBUG((DEBUG_INFO, "RpEnabledMask =3D=3D %x\n", CpuPcieHob->RpEnabledM= ask));=0D + if (CpuPcieHob->RpEnabledMask =3D=3D 0) {=0D + DEBUG ((DEBUG_ERROR, "All CPU PCIe root ports are disabled!!\n"));=0D + } else {=0D + if (CpuPcieHob->RpEnabledMask & BIT0) {=0D + mSaNvsAreaProtocol.Area->CpuPcieRp0Enable =3D 1;=0D + }=0D + if (CpuPcieHob->RpEnabledMask & BIT1) {=0D + mSaNvsAreaProtocol.Area->CpuPcieRp1Enable =3D 1;=0D + }=0D + if (CpuPcieHob->RpEnabledMask & BIT2) {=0D + mSaNvsAreaProtocol.Area->CpuPcieRp2Enable =3D 1;=0D + }=0D + if (CpuPcieHob->RpEnabledMask & BIT3) {=0D + mSaNvsAreaProtocol.Area->CpuPcieRp3Enable =3D 1;=0D + }=0D + }=0D + mSaNvsAreaProtocol.Area->MaxPegPortNumber =3D GetMaxCpuPciePortNum ();= =0D + }=0D +=0D + mSaNvsAreaProtocol.Area->SimicsEnvironment =3D 0;=0D +=0D + Status =3D gBS->InstallMultipleProtocolInterfaces (=0D + &ImageHandle,=0D + &gSaNvsAreaProtocolGuid,=0D + &mSaNvsAreaProtocol,=0D + NULL=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + ///=0D + /// GtPostInit Initialization=0D + ///=0D + DEBUG ((DEBUG_INFO, "Initializing GT ACPI tables\n"));=0D + GraphicsInit (ImageHandle, mSaPolicy);=0D +=0D + ///=0D + /// Audio (dHDA) Initialization=0D + ///=0D + ///=0D + /// Vtd Initialization=0D + ///=0D + DEBUG ((DEBUG_INFO, "Initializing VT-d ACPI tables\n"));=0D + VtdInit (mSaPolicy);=0D +=0D + ///=0D + /// IgdOpRegion Install Initialization=0D + ///=0D + DEBUG ((DEBUG_INFO, "Initializing IGD OpRegion\n"));=0D + IgdOpRegionInit ();=0D +=0D + ///=0D + /// Register an end of DXE event for SA ACPI to do tasks before invoking= any UEFI drivers,=0D + /// applications, or connecting consoles,...=0D + ///=0D + Status =3D gBS->CreateEventEx (=0D + EVT_NOTIFY_SIGNAL,=0D + TPL_CALLBACK,=0D + SaAcpiEndOfDxeCallback,=0D + NULL,=0D + &gEfiEndOfDxeEventGroupGuid,=0D + &EndOfDxeEvent=0D + );=0D +=0D + ///=0D + /// Install System Agent Global NVS ACPI table=0D + ///=0D + Status =3D InstallSsdtAcpiTable (gSaSsdtAcpiTableStorageGuid, SIGNATURE_= 64 ('S', 'a', 'S', 's', 'd', 't', ' ', 0));=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + ///=0D + /// Update CPU PCIE RP NVS AREA=0D + ///=0D + UpdateCpuPcieNVS();=0D + ///=0D + /// Install Intel Graphics SSDT=0D + ///=0D + Status =3D InstallSsdtAcpiTable (gGraphicsAcpiTableStorageGuid, SIGNATUR= E_64 ('I','g','f','x','S','s','d','t'));=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + ///=0D + /// Install IPU SSDT if IPU is present.=0D + ///=0D + if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IPU_BUS_NUM, = IPU_DEV_NUM, IPU_FUN_NUM, 0)) !=3D V_SA_DEVICE_ID_INVALID) {=0D + Status =3D InstallSsdtAcpiTable (gIpuAcpiTableStorageGuid, SIGNATURE= _64 ('I','p','u','S','s','d','t',0));=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaIni= t.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c new file mode 100644 index 0000000000..5c0fea422b --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c @@ -0,0 +1,120 @@ +/** @file=0D + This is the Common driver that initializes the Intel System Agent.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include "SaInit.h"=0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +///=0D +/// Global Variables=0D +///=0D +GLOBAL_REMOVE_IF_UNREFERENCED SA_CONFIG_HOB *mSaC= onfigHob;=0D +BOOLEAN mSkip= PamLock =3D FALSE;=0D +=0D +/*=0D + Intel(R) Core Processor Skylake BWG version 0.4.0=0D +=0D + 18.6 System Agent Configuration Locking=0D + For reliable operation and security, System BIOS must set the following= bits:=0D + 1. For all modern Intel processors, Intel strongly recommends that BIOS= should set=0D + the D_LCK bit. Set B0:D0:F0.R088h [4] =3D 1b to lock down SMRAM spa= ce.=0D + BaseAddr values for mSaSecurityRegisters that uses PciExpressBaseAddress= will be initialized at=0D + Runtime inside function CpuPcieInitPolicy().=0D +*/=0D +GLOBAL_REMOVE_IF_UNREFERENCED BOOT_SCRIPT_REGISTER_SETTING mSaSecurityRegi= sters[] =3D {=0D + {0, R_SA_SMRAMC, 0xFFFFFFFF, BIT4}=0D +};=0D +=0D +/**=0D + SystemAgent Initialization Common Function.=0D +=0D + @retval EFI_SUCCESS - Always.=0D +**/=0D +=0D +VOID=0D +SaInitEntryPoint (=0D + VOID=0D + )=0D +{=0D + HOST_BRIDGE_DATA_HOB *HostBridgeDataHob;=0D +=0D + ///=0D + /// Get Host Bridge Data HOB=0D + ///=0D + HostBridgeDataHob =3D NULL;=0D + HostBridgeDataHob =3D (HOST_BRIDGE_DATA_HOB *) GetFirstGuidHob (&gHostBr= idgeDataHobGuid);=0D + if (HostBridgeDataHob !=3D NULL) {=0D + mSkipPamLock =3D HostBridgeDataHob->SkipPamLock;=0D + }=0D + return;=0D +}=0D +=0D +/**=0D + This function does SA security lock=0D +**/=0D +VOID=0D +SaSecurityLock (=0D + VOID=0D + )=0D +{=0D + UINT8 Index;=0D + UINT64 BaseAddress;=0D + UINT32 RegOffset;=0D + UINT32 Data32And;=0D + UINT32 Data32Or;=0D +=0D + ///=0D + /// 17.2 System Agent Security Lock configuration=0D + ///=0D + DEBUG ((DEBUG_INFO, "DXE SaSecurityLock\n"));=0D + for (Index =3D 0; Index < (sizeof (mSaSecurityRegisters) / sizeof (BOOT_= SCRIPT_REGISTER_SETTING)); Index++) {=0D + BaseAddress =3D mSaSecurityRegisters[Index].BaseAddr;=0D + RegOffset =3D mSaSecurityRegisters[Index].Offset;=0D + Data32And =3D mSaSecurityRegisters[Index].AndMask;=0D + Data32Or =3D mSaSecurityRegisters[Index].OrMask;=0D +=0D + if (RegOffset =3D=3D R_SA_SMRAMC) {=0D + ///=0D + /// SMRAMC LOCK must use CF8/CFC access=0D + ///=0D + PciCf8Or8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_S= A_SMRAMC), (UINT8) Data32Or);=0D + BaseAddress =3D S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (SA_MC_BUS, SA_MC_DEV= , SA_MC_FUN, R_SA_SMRAMC);=0D + S3BootScriptSavePciCfgReadWrite (=0D + S3BootScriptWidthUint8,=0D + (UINTN) BaseAddress,=0D + &Data32Or,=0D + &Data32And=0D + );=0D + }=0D + }=0D +=0D +}=0D +=0D +/**=0D + This function performs SA Security locking in EndOfDxe callback=0D +=0D + @retval EFI_SUCCESS - Security lock has done=0D + @retval EFI_UNSUPPORTED - Security lock not done successfully=0D +**/=0D +EFI_STATUS=0D +SaSecurityInit (=0D + VOID=0D + )=0D +{=0D +=0D + UINT8 Index;=0D +=0D + for (Index =3D 0; Index < (sizeof (mSaSecurityRegisters) / sizeof (BOOT_= SCRIPT_REGISTER_SETTING)); Index++) {=0D + if (mSaSecurityRegisters[Index].BaseAddr !=3D PcdGet64 (PcdMchBaseAddr= ess)) {=0D + mSaSecurityRegisters[Index].BaseAddr =3D PcdGet64 (PcdSiPciExpressBa= seAddress);=0D + }=0D + }=0D + SaSecurityLock ();=0D +=0D + return EFI_SUCCESS;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaIni= t.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h new file mode 100644 index 0000000000..5c8f7dfd5f --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h @@ -0,0 +1,58 @@ +/** @file=0D + Header file for SA Common Initialization Driver.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _SA_INITIALIZATION_DRIVER_H_=0D +#define _SA_INITIALIZATION_DRIVER_H_=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +extern SA_POLICY_PROTOCOL *mSaPolicy;=0D +extern SA_CONFIG_HOB *SaConfigHob;=0D +=0D +typedef struct {=0D + UINT64 BaseAddr;=0D + UINT32 Offset;=0D + UINT32 AndMask;=0D + UINT32 OrMask;=0D +} BOOT_SCRIPT_REGISTER_SETTING;=0D +=0D +/**=0D + SystemAgent Initialization Common Function.=0D +=0D + @retval EFI_SUCCESS - Always.=0D +**/=0D +VOID=0D +SaInitEntryPoint (=0D + VOID=0D + );=0D +=0D +/**=0D + This function performs SA Security locking in EndOfDxe callback=0D +=0D + @retval EFI_SUCCESS - Security lock has done=0D + @retval EFI_UNSUPPORTED - Security lock not done successfully=0D +**/=0D +EFI_STATUS=0D +SaSecurityInit (=0D + VOID=0D + );=0D +=0D +#endif=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaIni= tDxe.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe= .c new file mode 100644 index 0000000000..2a0e0accf5 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c @@ -0,0 +1,181 @@ +/** @file=0D + This is the driver that initializes the Intel System Agent.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include "SaInitDxe.h"=0D +#include "SaInit.h"=0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPcieIoTrapAddress;= =0D +=0D +///=0D +/// Global Variables=0D +///=0D +extern SA_CONFIG_HOB *mSaConfigHob;=0D +=0D +=0D +/**=0D + SystemAgent Dxe Initialization.=0D +=0D + @param[in] ImageHandle Handle for the image of this driver=0D + @param[in] SystemTable Pointer to the EFI System Table=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SaInitEntryPointDxe (=0D + IN EFI_HANDLE ImageHandle,=0D + IN EFI_SYSTEM_TABLE *SystemTable=0D + )=0D +{=0D + EFI_STATUS Status;=0D + VOID *Registration;=0D + EFI_EVENT ReadyToBoot;=0D +=0D +=0D + DEBUG ((DEBUG_INFO, "SaInitDxe Start\n"));=0D +=0D + SaInitEntryPoint ();=0D +=0D + Status =3D SaAcpiInit (ImageHandle);=0D + ///=0D + /// Create PCI Enumeration Completed callback for CPU PCIe=0D + ///=0D + EfiCreateProtocolNotifyEvent (=0D + &gEfiPciEnumerationCompleteProtocolGuid,=0D + TPL_CALLBACK,=0D + CpuPciEnumCompleteCallback,=0D + NULL,=0D + &Registration=0D + );=0D +=0D + //=0D + // Register a Ready to boot event to config PCIE power management settin= g after OPROM executed=0D + //=0D + Status =3D EfiCreateEventReadyToBootEx (=0D + TPL_CALLBACK,=0D + SaOnReadyToBoot,=0D + NULL,=0D + &ReadyToBoot=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + DEBUG ((DEBUG_INFO, "SaInitDxe End\n"));=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Do PCIE power management while resume from S3=0D +**/=0D +VOID=0D +ReconfigureCpuPciePowerManagementForS3 (=0D + VOID=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINT32 Data32;=0D + SA_IOTRAP_SMI_PROTOCOL *CpuPcieIoTrapProtocol;=0D +=0D + Status =3D gBS->LocateProtocol (&gCpuPcieIoTrapProtocolGuid, NULL, (VOID= **) &CpuPcieIoTrapProtocol);=0D + if (EFI_ERROR (Status)) {=0D + return;=0D + }=0D + mPcieIoTrapAddress =3D CpuPcieIoTrapProtocol->SaIotrapSmiAddress;=0D + DEBUG ((DEBUG_INFO, "PcieIoTrapAddress: %0x\n", mPcieIoTrapAddress));=0D +=0D + if (mPcieIoTrapAddress !=3D 0) {=0D + //=0D + // Save PCH PCIE IoTrap address to re-config PCIE power management set= ting after resume from S3=0D + //=0D + Data32 =3D CpuPciePmTrap;=0D + S3BootScriptSaveIoWrite (=0D + S3BootScriptWidthUint32,=0D + (UINTN) (mPcieIoTrapAddress),=0D + 1,=0D + &Data32=0D + );=0D + } else {=0D + ASSERT (FALSE);=0D + }=0D +}=0D +=0D +=0D +/**=0D + SA initialization before boot to OS=0D +=0D + @param[in] Event A pointer to the Event that triggered th= e callback.=0D + @param[in] Context A pointer to private data registered wit= h the callback function.=0D +**/=0D +VOID=0D +EFIAPI=0D +SaOnReadyToBoot (=0D + IN EFI_EVENT Event,=0D + IN VOID *Context=0D + )=0D +{=0D + DEBUG ((DEBUG_INFO, "Uefi SaOnReadyToBoot() Start\n"));=0D +=0D + if (Event !=3D NULL) {=0D + gBS->CloseEvent (Event);=0D + }=0D +=0D + //=0D + // Trigger an Iotrap SMI to config PCIE power management setting after P= CI enumrate is done=0D + //=0D +#if FixedPcdGetBool(PcdCpuPcieEnable) =3D=3D 1=0D + if (mPcieIoTrapAddress !=3D 0) {=0D + IoWrite32 ((UINTN) mPcieIoTrapAddress, CpuPciePmTrap);=0D + } else {=0D + ASSERT (FALSE);=0D + }=0D +#endif=0D + DEBUG ((DEBUG_INFO, "Uefi SaOnReadyToBoot() End\n"));=0D +}=0D +=0D +=0D +/**=0D + This function gets registered as a callback to perform CPU PCIe initiali= zation before EndOfDxe=0D +=0D + @param[in] Event - A pointer to the Event that triggered the callbac= k.=0D + @param[in] Context - A pointer to private data registered with the cal= lback function.=0D +**/=0D +VOID=0D +EFIAPI=0D +CpuPciEnumCompleteCallback (=0D + IN EFI_EVENT Event,=0D + IN VOID *Context=0D + )=0D +{=0D + EFI_STATUS Status;=0D + VOID *ProtocolPointer;=0D +=0D + DEBUG ((DEBUG_INFO, "CpuPciEnumCompleteCallback Start\n"));=0D + ///=0D + /// Check if this is first time called by EfiCreateProtocolNotifyEvent()= or not,=0D + /// if it is, we will skip it until real event is triggered=0D + ///=0D + Status =3D gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid,= NULL, (VOID **) &ProtocolPointer);=0D + if (EFI_SUCCESS !=3D Status) {=0D + return;=0D + }=0D +=0D + gBS->CloseEvent (Event);=0D +=0D + ReconfigureCpuPciePowerManagementForS3();=0D + //=0D + // Routine for update DMAR=0D + //=0D + UpdateDmarEndOfPcieEnum ();=0D +=0D + UpdateSaGnvsForMmioResourceBaseLength ();=0D + DEBUG ((DEBUG_INFO, "CpuPciEnumCompleteCallback End\n"));=0D + return;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaIni= tDxe.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe= .h new file mode 100644 index 0000000000..7110d049a8 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h @@ -0,0 +1,136 @@ +/** @file=0D + Header file for SA Initialization Driver.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _SA_INIT_DXE_DRIVER_H_=0D +#define _SA_INIT_DXE_DRIVER_H_=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +///=0D +/// Driver Consumed Protocol Prototypes=0D +///=0D +#include =0D +=0D +extern EFI_GUID gSaAcpiTableStorageGuid;=0D +extern EFI_GUID gSaSsdtAcpiTableStorageGuid;=0D +=0D +typedef struct {=0D + UINT64 Address;=0D + EFI_BOOT_SCRIPT_WIDTH Width;=0D + UINT32 Value;=0D +} BOOT_SCRIPT_PCI_REGISTER_SAVE;=0D +=0D +///=0D +/// Function Prototype=0D +///=0D +/**=0D + This function gets registered as a callback to perform CPU PCIe initiali= zation before ExitPmAuth=0D +=0D + @param[in] Event - A pointer to the Event that triggered the callbac= k.=0D + @param[in] Context - A pointer to private data registered with the cal= lback function.=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +CpuPciEnumCompleteCallback (=0D + IN EFI_EVENT Event,=0D + IN VOID *Context=0D + );=0D +=0D +/**=0D + System Agent Initialization DXE Driver Entry Point=0D + - Introduction \n=0D + Based on the information/data in SA_POLICY_PROTOCOL, this module perfo= rms further SA initialization in DXE phase,=0D + e.g. internal devices enable/disable, SSVID/SID programming, graphic p= ower-management, VT-d, IGD OpRegion initialization.=0D + From the perspective of a PCI Express hierarchy, the Broadwell System = Agent and PCH together appear as a Root Complex with root ports the number = of which depends on how the 8 PCH ports and 4 System Agent PCIe ports are c= onfigured [4x1, 2x8, 1x16].=0D + There is an internal link (DMI or OPI) that connects the System Agent = to the PCH component. This driver includes initialization of SA DMI, PCI Ex= press, SA & PCH Root Complex Topology.=0D + For iGFX, this module implements the initialization of the Graphics Te= chnology Power Management from the Broadwell System Agent BIOS Specificatio= n and the initialization of the IGD OpRegion/Software SCI - BIOS Specificat= ion.=0D + The ASL files that go along with the driver define the IGD OpRegion ma= ilboxes in ACPI space and implement the software SCI interrupt mechanism.=0D + The IGD OpRegion/Software SCI code serves as a communication interface= between system BIOS, ASL, and Intel graphics driver including making a blo= ck of customizable data (VBT) from the Intel video BIOS available.=0D + Reference Code for the SCI service functions "Get BIOS Data" and "Syst= em BIOS Callback" can be found in the ASL files, those functions can be pla= tform specific, the sample provided in the reference code are implemented f= or Intel CRB.=0D + This module implements the VT-d functionality described in the Broadwe= ll System Agent BIOS Specification.=0D + This module publishes the LegacyRegion protocol to control the read an= d write accesses to the Legacy BIOS ranges.=0D + E000 and F000 segments are the legacy BIOS ranges and contain pointers= to the ACPI regions, SMBIOS tables and so on. This is a private protocol u= sed by Intel Framework.=0D + This module registers CallBack function that performs SA security regi= sters lockdown at end of post as required from Broadwell Bios Spec.=0D + In addition, this module publishes the SaInfo Protocol with informatio= n such as current System Agent reference code version#.=0D +=0D + - @pre=0D + - EFI_FIRMWARE_VOLUME_PROTOCOL: Documented in Firmware Volume Specific= ation, available at the URL: http://www.intel.com/technology/framework/spec= .htm=0D + - SA_POLICY_PROTOCOL: A protocol published by a platform DXE module ex= ecuted earlier; this is documented in this document as well.=0D + - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL: Documented in the Unified Extensibl= e Firmware Interface Specification, version 2.0, available at the URL: http= ://www.uefi.org/specs/=0D + - EFI_BOOT_SCRIPT_SAVE_PROTOCOL: A protocol published by a platform DX= E module executed earlier; refer to the Sample Code section of the Framewor= k PCH Reference Code.=0D + - 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/=0D + - EFI_ACPI_TABLE_PROTOCOL : Documented in PI Specification 1.2=0D + - EFI_CPU_IO_PROTOCOL: Documented in CPU I/O Protocol Specification, a= vailable at the URL: http://www.intel.com/technology/framework/spec.htm=0D + - EFI_DATA_HUB_PROTOCOL: Documented in EFI Data Hub Infrastructure Spe= cification, available at the URL: http://www.intel.com/technology/framework= /spec.htm=0D + - EFI_HII_PROTOCOL (or EFI_HII_DATABASE_PROTOCOL for UEFI 2.1): Docume= nted in Human Interface Infrastructure Specification, available at the URL:= http://www.intel.com/technology/framework/spec.htm=0D + (For EFI_HII_DATABASE_PROTOCOL, refer to UEFI Specification Version 2.= 1 available at the URL: http://www.uefi.org/)=0D +=0D + - @result=0D + IGD power-management functionality is initialized; VT-d is initialize= d (meanwhile, the DMAR table is updated); IGD OpRegion is initialized - IGD= _OPREGION_PROTOCOL installed, IGD OpRegion allocated and mailboxes initiali= zed, chipset initialized and ready to generate Software SCI for Internal gr= aphics events. Publishes the SA_INFO_PROTOCOL with current SA reference cod= e version #. Publishes the EFI_LEGACY_REGION_PROTOCOL documented in the Com= patibility Support Module Specification, version 0.9, available at the URL:= http://www.intel.com/technology/framework/spec.htm=0D +=0D + - References \n=0D + IGD OpRegion/Software SCI for Broadwell=0D + Advanced Configuration and Power Interface Specification Revision 4.0a= .=0D +=0D + - Porting Recommendations \n=0D + No modification of the DXE driver should be typically necessary.=0D + This driver should be executed after all related devices (audio, video= , ME, etc.) are initialized to ensure correct data in DMAR table and DMA-re= mapping registers.=0D +=0D + @param[in] ImageHandle Handle for the image of this driver=0D + @param[in] SystemTable Pointer to the EFI System Table=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SaInitEntryPointDxe (=0D + IN EFI_HANDLE ImageHandle,=0D + IN EFI_SYSTEM_TABLE *SystemTable=0D + );=0D +=0D +/**=0D + SystemAgent Acpi Initialization.=0D +=0D + @param[in] ImageHandle Handle for the image of this driver=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SaAcpiInit (=0D + IN EFI_HANDLE ImageHandle=0D + );=0D +=0D +/**=0D + A protocol callback which updates 64bits MMIO Base and Length in SA GNVS= area=0D +**/=0D +VOID=0D +UpdateSaGnvsForMmioResourceBaseLength (=0D + VOID=0D + );=0D +=0D +/**=0D + SA initialization before boot to OS=0D +=0D + @param[in] Event A pointer to the Event that triggered th= e callback.=0D + @param[in] Context A pointer to private data registered wit= h the callback function.=0D +**/=0D +VOID=0D +EFIAPI=0D +SaOnReadyToBoot (=0D + IN EFI_EVENT Event,=0D + IN VOID *Context=0D + );=0D +=0D +#endif=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaIni= tDxe.inf b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitD= xe.inf new file mode 100644 index 0000000000..d23ba0fa3b --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf @@ -0,0 +1,117 @@ +## @file=0D +# Component description file for SystemAgent Initialization driver=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D SaInitDxe=0D +FILE_GUID =3D DE23ACEE-CF55-4fb6-AA77-984AB53DE811=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D DXE_DRIVER=0D +ENTRY_POINT =3D SaInitEntryPointDxe=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 EBC=0D +#=0D +=0D +=0D +=0D +[LibraryClasses]=0D +UefiDriverEntryPoint=0D +UefiLib=0D +UefiBootServicesTableLib=0D +DxeServicesTableLib=0D +DebugLib=0D +PciCf8Lib=0D +PciSegmentLib=0D +BaseMemoryLib=0D +MemoryAllocationLib=0D +IoLib=0D +S3BootScriptLib=0D +PmcLib=0D +PchInfoLib=0D +GpioLib=0D +ConfigBlockLib=0D +SaPlatformLib=0D +PchPcieRpLib=0D +DxeGraphicsInitLib=0D +DxeIgdOpRegionInitLib=0D +DxeVtdInitLib=0D +PciExpressHelpersLib=0D +DxeCpuPcieRpLib=0D +SataLib=0D +=0D +[Packages]=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +MdePkg/MdePkg.dec=0D +UefiCpuPkg/UefiCpuPkg.dec=0D +IntelSiliconPkg/IntelSiliconPkg.dec=0D +=0D +[Pcd]=0D +gSiPkgTokenSpaceGuid.PcdSiPciExpressBaseAddress=0D +gSiPkgTokenSpaceGuid.PcdMchBaseAddress=0D +gSiPkgTokenSpaceGuid.PcdSiIoApicBaseAddress=0D +gSiPkgTokenSpaceGuid.PcdCpuPcieEnable ## CONSUMES=0D +=0D +[FixedPcd]=0D +=0D +[Sources]=0D +SaInitDxe.h=0D +SaInitDxe.c=0D +SaInit.h=0D +SaInit.c=0D +SaAcpi.c=0D +=0D +=0D +[Protocols]=0D +gEfiAcpiTableProtocolGuid ## CONSUMES=0D +gSaNvsAreaProtocolGuid ## PRODUCES=0D +gSaPolicyProtocolGuid ## CONSUMES=0D +gEfiCpuArchProtocolGuid ## CONSUMES=0D +gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES=0D +gEfiPciRootBridgeIoProtocolGuid ## CONSUMES=0D +gIgdOpRegionProtocolGuid ## PRODUCES=0D +gEfiFirmwareVolume2ProtocolGuid ## CONSUMES=0D +gGopComponentName2ProtocolGuid ## CONSUMES=0D +gSaIotrapSmiProtocolGuid ## CONSUMES=0D +gCpuPcieIoTrapProtocolGuid ## CONSUMES=0D +=0D +[Guids]=0D +gSaConfigHobGuid=0D +gHgAcpiTablePchStorageGuid=0D +gSaAcpiTableStorageGuid=0D +gHgAcpiTableStorageGuid=0D +gSaSsdtAcpiTableStorageGuid=0D +gSegSsdtAcpiTableStorageGuid=0D +gTcssSsdtAcpiTableStorageGuid=0D +gGraphicsAcpiTableStorageGuid=0D +gIpuAcpiTableStorageGuid=0D +gEfiEndOfDxeEventGroupGuid=0D +gSiConfigHobGuid ## CONSUMES=0D +gGraphicsDxeConfigGuid=0D +gMemoryDxeConfigGuid=0D +gPcieDxeConfigGuid=0D +gPchInfoHobGuid=0D +gTcssHobGuid=0D +gSaConfigHobGuid=0D +gSaDataHobGuid=0D +gCpuPcieHobGuid=0D +gHostBridgeDataHobGuid=0D +gVmdInfoHobGuid ## CONSUMES=0D +=0D +[FixedPcd]=0D +=0D +[Depex]=0D +gEfiAcpiTableProtocolGuid AND=0D +gEfiFirmwareVolume2ProtocolGuid AND=0D +gSaPolicyProtocolGuid AND=0D +gEfiPciRootBridgeIoProtocolGuid AND=0D +gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure th= at PCI MMIO resource has been prepared and available for this driver to all= ocate.=0D +gEfiHiiDatabaseProtocolGuid=0D +=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/CpuPc= ieSmm.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/CpuPcieS= mm.c new file mode 100644 index 0000000000..70d47e787f --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/CpuPcieSmm.c @@ -0,0 +1,454 @@ +/** @file=0D + CPU PCIe SMM Driver Entry=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include "SaLateInitSmm.h"=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSaBusNumber;=0D +//=0D +// @note:=0D +// These temp bus numbers cannot be used in runtime (hot-plug).=0D +// These can be used only during boot.=0D +//=0D +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mTempRootPortBus= NumMin;=0D +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mTempRootPortBus= NumMax;=0D +GLOBAL_REMOVE_IF_UNREFERENCED CPU_PCIE_ROOT_PORT_CONFIG mCpuPcieRootPort= Config[CPU_PCIE_MAX_ROOT_PORTS];=0D +GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mCpuPciePmTrapEx= ecuted =3D FALSE;=0D +GLOBAL_REMOVE_IF_UNREFERENCED PCH_PCIE_DEVICE_OVERRIDE *mDevAspmOverrid= e;=0D +GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mNumOfDevAspmOve= rride;=0D +=0D +/**=0D + An IoTrap callback to config PCIE power management settings=0D +**/=0D +VOID=0D +CpuPciePmIoTrapSmiCallback (=0D + VOID=0D + )=0D +{=0D + UINT32 PortIndex;=0D + UINT64 RpBase;=0D + UINT8 MaxPciePortNum;=0D + UINTN RpDevice;=0D + UINTN RpFunction;=0D +=0D + MaxPciePortNum =3D GetMaxCpuPciePortNum ();=0D +=0D + for (PortIndex =3D 0; PortIndex < MaxPciePortNum; PortIndex++) {=0D + GetCpuPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);=0D + RpBase =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, (UINT32) Rp= Device, (UINT32) RpFunction, 0);=0D +=0D + if (PciSegmentRead16 (RpBase) !=3D 0xFFFF) {=0D + mDevAspmOverride =3D NULL;=0D + mNumOfDevAspmOverride =3D 0;=0D + RootportDownstreamPmConfiguration (=0D + SA_SEG_NUM,=0D + SA_MC_BUS,=0D + (UINT8)RpDevice,=0D + (UINT8)RpFunction,=0D + mTempRootPortBusNumMin,=0D + mTempRootPortBusNumMax,=0D + &mCpuPcieRootPortConfig[PortIndex].PcieRpCommonConfig,=0D + mNumOfDevAspmOverride,=0D + mDevAspmOverride=0D + );=0D +=0D + }=0D + }=0D +}=0D +=0D +/**=0D + Program Common Clock and ASPM of Downstream Devices=0D +=0D + @param[in] PortIndex Pcie Root Port Number=0D + @param[in] RpDevice Pcie Root Pci Device Number=0D + @param[in] RpFunction Pcie Root Pci Function Number=0D +=0D + @retval EFI_SUCCESS Root port complete successfully=0D + @retval EFI_UNSUPPORTED PMC has invalid vendor ID=0D +**/=0D +EFI_STATUS=0D +CpuPcieSmi (=0D + IN UINT8 PortIndex,=0D + IN UINT8 RpDevice,=0D + IN UINT8 RpFunction=0D + )=0D +{=0D + UINT8 SecBus;=0D + UINT8 SubBus;=0D + UINT64 RpBase;=0D + UINT64 EpBase;=0D + UINT8 EpPcieCapPtr;=0D + UINT8 EpMaxSpeed;=0D + BOOLEAN DownstreamDevicePresent;=0D + UINT32 Timeout;=0D + UINT32 MaxLinkSpeed;=0D +=0D + RpBase =3D PCI_SEGMENT_LIB_ADDRESS (=0D + SA_SEG_NUM,=0D + SA_MC_BUS,=0D + (UINT32) RpDevice,=0D + (UINT32) RpFunction,=0D + 0=0D + );=0D +=0D + if (PciSegmentRead16 (RpBase + PCI_VENDOR_ID_OFFSET) =3D=3D 0xFFFF) {=0D + DEBUG((DEBUG_INFO, "PCIe controller is disabled, return!!\n"));=0D + return EFI_SUCCESS;=0D + }=0D + //=0D + // Check presence detect state. Here the endpoint must be detected using= PDS rather than=0D + // the usual LinkActive check, because PDS changes immediately and LA ta= kes a few milliseconds to stabilize=0D + //=0D + DownstreamDevicePresent =3D !!(PciSegmentRead16 (RpBase + R_PCIE_SLSTS) = & B_PCIE_SLSTS_PDS);=0D +=0D + if (DownstreamDevicePresent) {=0D + ///=0D + /// Make sure the link is active before trying to talk to device behin= d it=0D + /// Wait up to 100ms, according to PCIE spec chapter 6.7.3.3=0D + ///=0D + Timeout =3D 100 * 1000;=0D + while (CpuPcieIsLinkActive(RpBase) =3D=3D 0) {=0D + MicroSecondDelay (10);=0D + Timeout-=3D10;=0D + if (Timeout =3D=3D 0) {=0D + DEBUG((DEBUG_INFO, "PDS set but timeout while waiting for LA bit t= o get set!!!\n"));=0D + return EFI_NOT_FOUND;=0D + }=0D + }=0D + SecBus =3D PciSegmentRead8 (RpBase + PCI_BRIDGE_SECONDARY_BUS_REGISTE= R_OFFSET);=0D + SubBus =3D PciSegmentRead8 (RpBase + PCI_BRIDGE_SUBORDINATE_BUS_REGIS= TER_OFFSET);=0D + ASSERT (SecBus !=3D 0 && SubBus !=3D 0);=0D + if (SecBus =3D=3D 0) {=0D + DEBUG((DEBUG_INFO, "Secondary Bus is 0, return!!!\n"));=0D + return EFI_NOT_FOUND;=0D + }=0D + RootportDownstreamConfiguration (=0D + SA_SEG_NUM,=0D + SA_MC_BUS,=0D + RpDevice,=0D + RpFunction,=0D + mTempRootPortBusNumMin,=0D + mTempRootPortBusNumMax,=0D + EnumCpuPcie=0D + );=0D + RootportDownstreamPmConfiguration (=0D + SA_SEG_NUM,=0D + SA_MC_BUS,=0D + RpDevice,=0D + RpFunction,=0D + mTempRootPortBusNumMin,=0D + mTempRootPortBusNumMax,=0D + &mCpuPcieRootPortConfig[PortIndex].PcieRpCommonConfig,=0D + mNumOfDevAspmOverride,=0D + mDevAspmOverride=0D + );=0D + //=0D + // Perform Equalization=0D + //=0D + EpBase =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SecBus, 0, 0, 0);=0D + EpPcieCapPtr =3D PcieFindCapId (SA_SEG_NUM, SecBus, 0, 0, EFI_PCI_CAPA= BILITY_ID_PCIEXP);=0D + EpMaxSpeed =3D PciSegmentRead8 (EpBase + EpPcieCapPtr + R_PCIE_LCAP_OF= FSET) & B_PCIE_LCAP_MLS;=0D + MaxLinkSpeed =3D CpuPcieGetMaxLinkSpeed (RpBase);=0D + if (EpMaxSpeed < MaxLinkSpeed) {=0D + MaxLinkSpeed =3D EpMaxSpeed;=0D + }=0D + if (EpMaxSpeed >=3D V_PCIE_LCAP_MLS_GEN3 && EpMaxSpeed <=3D V_PCIE_LCA= P_MLS_GEN4) {=0D + PciSegmentAndThenOr16 (RpBase + R_PCIE_LCTL2, (UINT16)~B_PCIE_LCTL2_= TLS, (UINT16)MaxLinkSpeed);=0D + PciSegmentOr32 (RpBase + R_PCIE_LCTL3, B_PCIE_LCTL3_PE);=0D + PciSegmentOr32 (RpBase + R_PCIE_LCTL, B_PCIE_LCTL_RL);=0D + }=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + PCIE Hotplug SMI call back function for each Root port=0D +=0D + @param[in] DispatchHandle Handle of this dispatch function=0D + @param[in] RpContext Rootport context, which contains R= ootPort Index,=0D + and RootPort PCI BDF.=0D +**/=0D +VOID=0D +EFIAPI=0D +CpuPcieSmiRpHandlerFunction (=0D + IN EFI_HANDLE DispatchHandle,=0D + IN PCH_PCIE_SMI_RP_CONTEXT *RpContext=0D + )=0D +{=0D + CpuPcieSmi (RpContext->RpIndex, RpContext->DevNum, RpContext->FuncNum);= =0D +}=0D +=0D +/**=0D + PCIE Link Active State Change Hotplug SMI call back function for all Roo= t ports=0D +=0D + @param[in] DispatchHandle Handle of this dispatch function=0D + @param[in] RpContext Rootport context, which contains R= ootPort Index,=0D + and RootPort PCI BDF.=0D +**/=0D +VOID=0D +EFIAPI=0D +CpuPcieLinkActiveStateChange (=0D + IN EFI_HANDLE DispatchHandle,=0D + IN PCH_PCIE_SMI_RP_CONTEXT *RpContext=0D + )=0D +{=0D + return;=0D +}=0D +=0D +/**=0D + PCIE Link Equalization Request SMI call back function for all Root ports= =0D +=0D + @param[in] DispatchHandle Handle of this dispatch function=0D + @param[in] RpContext Rootport context, which contains R= ootPort Index,=0D + and RootPort PCI BDF.=0D +**/=0D +VOID=0D +EFIAPI=0D +CpuPcieLinkEqHandlerFunction (=0D + IN EFI_HANDLE DispatchHandle,=0D + IN PCH_PCIE_SMI_RP_CONTEXT *RpContext=0D + )=0D +{=0D + ///=0D + /// From PCI Express specification, the PCIe device can request for Link= Equalization. When the=0D + /// Link Equalization is requested by the device, an SMI will be generat= ed by PCIe RP when=0D + /// enabled and the SMI subroutine would invoke the Software Preset/Coef= ficient Search=0D + /// software to re-equalize the link.=0D + ///=0D +=0D + return;=0D +=0D +}=0D +/**=0D + An IoTrap callback to config PCIE power management settings=0D +=0D + @param[in] DispatchHandle - The handle of this callback, obtained when = registering=0D + @param[in] DispatchContext - Pointer to the EFI_SMM_IO_TRAP_DISPATCH_CAL= LBACK_CONTEXT=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +CpuPcieIoTrapSmiCallback (=0D + IN EFI_HANDLE DispatchHandle,=0D + IN EFI_SMM_IO_TRAP_CONTEXT *CallbackContext,=0D + IN OUT VOID *CommBuffer,=0D + IN OUT UINTN *CommBufferSize=0D + )=0D +{=0D + if (CallbackContext->WriteData =3D=3D CpuPciePmTrap) {=0D + if (mCpuPciePmTrapExecuted =3D=3D FALSE) {=0D + CpuPciePmIoTrapSmiCallback ();=0D + mCpuPciePmTrapExecuted =3D TRUE;=0D + }=0D + } else {=0D + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);=0D + }=0D +}=0D +=0D +/**=0D + This function clear the Io trap executed flag before enter S3=0D +=0D + @param[in] Handle Handle of the callback=0D + @param[in] Context The dispatch context=0D +=0D + @retval EFI_SUCCESS SA register saved=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +CpuPcieS3EntryCallBack (=0D + IN EFI_HANDLE Handle,=0D + IN CONST VOID *Context OPTIONAL,=0D + IN OUT VOID *CommBuffer OPTIONAL,=0D + IN OUT UINTN *CommBufferSize OPTIONAL=0D + )=0D +{=0D + mCpuPciePmTrapExecuted =3D FALSE;=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling=0D +=0D + @param[in] ImageHandle The image handle of this module=0D + @param[in] SystemTable The EFI System Table=0D +=0D + @retval EFI_SUCCESS The function completes successfully=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +InitializeCpuPcieSmm (=0D + IN EFI_HANDLE ImageHandle,=0D + IN EFI_SYSTEM_TABLE *SystemTable=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINT8 PortIndex;=0D + UINT8 Data8;=0D + UINT32 Data32Or;=0D + UINT32 Data32And;=0D + UINT64 RpBase;=0D + UINTN RpDevice;=0D + UINTN RpFunction;=0D + EFI_HANDLE PcieHandle;=0D + EFI_HANDLE PchIoTrapHandle;=0D + PCH_PCIE_SMI_DISPATCH_PROTOCOL *PchPcieSmiDispatchProtocol;=0D + EFI_SMM_IO_TRAP_REGISTER_CONTEXT PchIoTrapContext;=0D + EFI_SMM_SX_REGISTER_CONTEXT SxDispatchContext;=0D + SA_IOTRAP_SMI_PROTOCOL *CpuPcieIoTrapProtocol;=0D + EFI_HANDLE SxDispatchHandle;=0D + UINT8 MaxPciePortNum;=0D + CPU_PCIE_HOB *CpuPcieHob;=0D +=0D + DEBUG ((DEBUG_INFO, "InitializeCpuPcieSmm () Start\n"));=0D +=0D + MaxPciePortNum =3D GetMaxCpuPciePortNum ();=0D +=0D + //=0D + // Locate Pch Pcie Smi Dispatch Protocol=0D + //=0D + Status =3D gSmst->SmmLocateProtocol (&gPchPcieSmiDispatchProtocolGuid, N= ULL, (VOID**) &PchPcieSmiDispatchProtocol);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + mTempRootPortBusNumMin =3D PcdGet8 (PcdSiliconInitTempPciBusMin);=0D + mTempRootPortBusNumMax =3D PcdGet8 (PcdSiliconInitTempPciBusMax);=0D +=0D + ///=0D + /// Locate HOB for CPU PCIe=0D + ///=0D + CpuPcieHob =3D GetFirstGuidHob(&gCpuPcieHobGuid);=0D + if (CpuPcieHob !=3D NULL) {=0D + ASSERT (sizeof mCpuPcieRootPortConfig =3D=3D sizeof CpuPcieHob->RootPo= rt);=0D + CopyMem (=0D + mCpuPcieRootPortConfig,=0D + &(CpuPcieHob->RootPort),=0D + sizeof (mCpuPcieRootPortConfig)=0D + );=0D + }=0D +=0D + //=0D + // Throught all PCIE root port function and register the SMI Handler for= enabled ports.=0D + //=0D + for (PortIndex =3D 0; PortIndex < MaxPciePortNum; PortIndex++) {=0D + GetCpuPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);=0D + RpBase =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, (UINT32) Rp= Device, (UINT32) RpFunction, 0);=0D + //=0D + // Skip the root port function which is not enabled=0D + //=0D + if (PciSegmentRead32 (RpBase) =3D=3D 0xFFFFFFFF) {=0D + continue;=0D + }=0D +=0D + //=0D + // Register SMI Handlers for Hot Plug and Link Active State Change=0D + //=0D + Data8 =3D PciSegmentRead8 (RpBase + R_PCIE_SLCAP);=0D + if (Data8 & B_PCIE_SLCAP_HPC) {=0D + PcieHandle =3D NULL;=0D + Status =3D PchPcieSmiDispatchProtocol->HotPlugRegister (=0D + PchPcieSmiDispatchProtocol,=0D + CpuPcieSmiRpHandlerFunction,= =0D + (PortIndex + CpuRpIndex0),=0D + &PcieHandle=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + Status =3D PchPcieSmiDispatchProtocol->LinkActiveRegister (=0D + PchPcieSmiDispatchProtocol,=0D + CpuPcieLinkActiveStateChange,= =0D + (PortIndex + CpuRpIndex0),=0D + &PcieHandle=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + Data32Or =3D B_PCIE_MPC_HPME;=0D + Data32And =3D (UINT32) ~B_PCIE_MPC_HPME;=0D + S3BootScriptSaveMemReadWrite (=0D + S3BootScriptWidthUint32,=0D + PcdGet64 (PcdSiPciExpressBaseAddress) + RpBase + R_PCIE_MPC,=0D + &Data32Or, /// Data to be ORed=0D + &Data32And /// Data to be ANDed=0D + );=0D + }=0D +=0D + //=0D + // Register SMI Handler for Link Equalization Request from Gen 3 Devic= es.=0D + //=0D + Data8 =3D PciSegmentRead8 (RpBase + R_PCIE_LCAP);=0D + if ((Data8 & B_PCIE_LCAP_MLS) =3D=3D V_PCIE_LCAP_MLS_GEN3) {=0D + Status =3D PchPcieSmiDispatchProtocol->LinkEqRegister (=0D + PchPcieSmiDispatchProtocol,=0D + CpuPcieLinkEqHandlerFunction,= =0D + (PortIndex + CpuRpIndex0),=0D + &PcieHandle=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D + }=0D + }=0D +=0D + ASSERT_EFI_ERROR (Status);=0D + PchIoTrapContext.Type =3D WriteTrap;=0D + PchIoTrapContext.Length =3D 4;=0D + PchIoTrapContext.Address =3D 0;=0D + Status =3D mPchIoTrap->Register (=0D + mPchIoTrap,=0D + (EFI_SMM_HANDLER_ENTRY_POINT2) CpuPcieIoTrapSmiCa= llback,=0D + &PchIoTrapContext,=0D + &PchIoTrapHandle=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + //=0D + // Install the SA Pcie IoTrap protocol=0D + //=0D + (gBS->AllocatePool) (EfiBootServicesData, sizeof (SA_IOTRAP_SMI_PROTOCOL= ), (VOID **)&CpuPcieIoTrapProtocol);=0D + CpuPcieIoTrapProtocol->SaIotrapSmiAddress =3D PchIoTrapContext.Address;= =0D +=0D + Status =3D gBS->InstallMultipleProtocolInterfaces (=0D + &ImageHandle,=0D + &gCpuPcieIoTrapProtocolGuid,=0D + CpuPcieIoTrapProtocol,=0D + NULL=0D + );=0D +=0D + //=0D + // Register the callback for S3 entry=0D + //=0D + SxDispatchContext.Type =3D SxS3;=0D + SxDispatchContext.Phase =3D SxEntry;=0D + Status =3D mSxDispatch->Register (=0D + mSxDispatch,=0D + CpuPcieS3EntryCallBack,=0D + &SxDispatchContext,=0D + &SxDispatchHandle=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + DEBUG ((DEBUG_INFO, "InitializeCpuPcieSmm, IoTrap @ %x () End\n", PchIoT= rapContext.Address));=0D +=0D + return EFI_SUCCESS;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLat= eInitSmm.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLat= eInitSmm.c new file mode 100644 index 0000000000..0e9ba41f1b --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSm= m.c @@ -0,0 +1,112 @@ +/** @file=0D + This SMM driver will handle SA relevant late initialization=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include "SaLateInitSmm.h"=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include "CpuPcieInfo.h"=0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +typedef enum {=0D + EnumSaSmiCallbackForMaxPayLoad,=0D + EnumSaSmiCallbackForSaSaveRestore,=0D + EnumSaSmiCallbackForLateInit,=0D + EnumSaSmiCallbackForS3resume,=0D + EnumSaSmiCallbackMax=0D +} SMI_OPERATION;=0D +=0D +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSaSmiCallba= ckPhase =3D EnumSaSmiCallbackForMaxPayLoad;=0D +GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL *m= PchIoTrap;=0D +GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_SX_DISPATCH2_PROTOCOL *m= SxDispatch;=0D +=0D +=0D +typedef struct {=0D + UINT64 BaseAddr;=0D + UINT32 Offset;=0D + UINT32 AndMask;=0D + UINT32 OrMask;=0D +} BOOT_SCRIPT_REGISTER_SETTING;=0D +=0D +/**=0D + Initializes the SA SMM handler=0D +=0D + @param[in] ImageHandle - The image handle of Wake On Lan driver=0D + @param[in] SystemTable - The standard EFI system table=0D +=0D + @retval EFI_SUCCESS - SA SMM handler was installed or not necessary=0D + @retval EFI_NOT_FOUND - Fail to register SMI callback or required proto= col/hob missing.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SaLateInitSmmEntryPoint (=0D + IN EFI_HANDLE ImageHandle,=0D + IN EFI_SYSTEM_TABLE *SystemTable=0D + )=0D +{=0D +#if FixedPcdGetBool(PcdCpuPcieEnable) =3D=3D 1=0D + CPU_PCIE_HOB *CpuPcieHob =3D NULL;=0D + EFI_STATUS Status;=0D +#endif=0D +=0D + DEBUG ((DEBUG_INFO, "SaLateInitSmmEntryPoint()\n"));=0D +=0D +#if FixedPcdGetBool(PcdCpuPcieEnable) =3D=3D 1=0D + CpuPcieHob =3D (CPU_PCIE_HOB *) GetFirstGuidHob (&gCpuPcieHobGuid);=0D + Status =3D EFI_NOT_FOUND;=0D + if (CpuPcieHob =3D=3D NULL) {=0D + DEBUG ((DEBUG_INFO, "CPU PCIE HOB Not found\n"));=0D + ASSERT (CpuPcieHob !=3D NULL);=0D + return Status;=0D + }=0D +=0D + ///=0D + /// Locate the PCH Trap dispatch protocol=0D + ///=0D + Status =3D gSmst->SmmLocateProtocol (&gEfiSmmIoTrapDispatch2ProtocolGuid= , NULL, (VOID **) &mPchIoTrap);=0D + ASSERT_EFI_ERROR (Status);=0D + Status =3D gSmst->SmmLocateProtocol (&gEfiSmmSxDispatch2ProtocolGuid, NU= LL, (VOID**) &mSxDispatch);=0D + ASSERT_EFI_ERROR (Status);=0D + if (Status =3D=3D EFI_SUCCESS) {=0D + ///=0D + /// If ASPM policy is set to "Before OPROM", this SMI callback is not = necessary=0D + /// Ensure the SMI callback handler will directly return and continue = the POST.=0D + ///=0D + mSaSmiCallbackPhase =3D EnumSaSmiCallbackMax;=0D + Status =3D EFI_SUCCESS;=0D + }=0D +=0D + Status =3D InitializeCpuPcieSmm (ImageHandle, SystemTable);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + if (Status !=3D EFI_SUCCESS) {=0D + DEBUG ((DEBUG_ERROR, "Failed to register SaIotrapSmiCallback!\n"));=0D + ///=0D + /// System will halt when failing to register required SMI handler=0D + ///=0D + CpuDeadLoop ();=0D + }=0D +#endif=0D + return EFI_SUCCESS;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLat= eInitSmm.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLat= eInitSmm.h new file mode 100644 index 0000000000..c93f92305c --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSm= m.h @@ -0,0 +1,122 @@ +/** @file=0D + Header file for SA SMM Handler=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _SaLateInitSmm_H_=0D +#define _SaLateInitSmm_H_=0D +=0D +///=0D +/// Driver Consumed Protocol Prototypes=0D +///=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +extern EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL *mPchIoTrap;=0D +extern EFI_SMM_SX_DISPATCH2_PROTOCOL *mSxDispatch;=0D +=0D +///=0D +/// The value before AutoConfig match the setting of PCI Express Base Spec= ification 1.1, please be careful for adding new feature=0D +///=0D +typedef enum {=0D + PcieAspmDisabled,=0D + PcieAspmL0s,=0D + PcieAspmL1,=0D + PcieAspmL0sL1,=0D + PcieAspmAutoConfig,=0D + PcieAspmMax=0D +} CPU_PCIE_ASPM_CONFIG;=0D +=0D +typedef struct {=0D + UINT64 Address;=0D + S3_BOOT_SCRIPT_LIB_WIDTH Width;=0D + UINT32 Value;=0D +} BOOT_SCRIPT_PCI_REGISTER_SAVE;=0D +=0D +=0D +/**=0D + System Agent Initialization SMM Driver Entry Point=0D + - Introduction \n=0D + This is an optional driver to support PCIe ASPM initialization later t= han Option ROM initialization.\n=0D + In this scenario S3 Save Boot Script table has been closed per securit= y consideration so the ASPM settings will be stored in SMM memory and resto= red during S3 resume.=0D + If platform does not support this scenario this driver can be excluded= and SI_SA_POLICY_PPI -> PCIE_CONFIG -> InitPcieAspmAfterOprom must be set = to FALSE. \n=0D + Note: When InitPcieAspmAfterOprom enabled, the SMI callback handler mu= st be registered successfully, otherwise it will halt the system.=0D +=0D + - @pre=0D + - _EFI_SMM_BASE_PROTOCOL (or _EFI_SMM_BASE2_PROTOCOL for EDK2): Provid= es SMM infrastructure services.=0D + - _EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL (or _EFI_SMM_IO_TRAP_DISPATCH2_PR= OTOCOL for EDK2): Interface structure for the SMM IO trap specific SMI Disp= atch Protocol=0D + - SA_POLICY_PROTOCOL: A protocol published by a platform DXE module ex= ecuted earlier; this is documented in this document as well.=0D +=0D + - @result=0D + PCIe ASPM has been initialized on all end point devices discovered and= same settings will be restored during S3 resume.=0D +=0D + @param[in] ImageHandle - The image handle of Wake On Lan driver=0D + @param[in] SystemTable - The standard EFI system table=0D +=0D + @retval EFI_SUCCESS - SA SMM handler was installed or not necessary=0D + @retval EFI_NOT_FOUND - Fail to register SMI callback or required proto= col/hob missing.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SaLateInitSmmEntryPoint (=0D + IN EFI_HANDLE ImageHandle,=0D + IN EFI_SYSTEM_TABLE *SystemTable=0D + );=0D +=0D +/**=0D +An IoTrap callback to config PCIE power management settings=0D +=0D +@param[in] DispatchHandle - The handle of this callback, obtained when re= gistering=0D +@param[in] DispatchContext - Pointer to the EFI_SMM_IO_TRAP_DISPATCH_CALLB= ACK_CONTEXT=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +CpuPcieIoTrapSmiCallback(=0D +IN EFI_HANDLE DispatchHandle,=0D +IN EFI_SMM_IO_TRAP_CONTEXT *CallbackContext,=0D +IN OUT VOID *CommBuffer,=0D +IN OUT UINTN *CommBufferSize=0D +);=0D +=0D +/**=0D + This function is used to set or clear flags at S3 entry=0D + Clear the Io trap executed flag before enter S3=0D +=0D + @param[in] Handle Handle of the callback=0D + @param[in] Context The dispatch context=0D + @param[in,out] CommBuffer A pointer to a collection of data in memo= ry that will be conveyed from a non-SMM environment into an SMM environment= .=0D + @param[in,out] CommBufferSize The size of the CommBuffer.=0D + @retval EFI_SUCCESS SA register saved=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +CpuPcieS3EntryCallBack (=0D + IN EFI_HANDLE Handle,=0D + IN CONST VOID *Context OPTIONAL,=0D + IN OUT VOID *CommBuffer OPTIONAL,=0D + IN OUT UINTN *CommBufferSize OPTIONAL=0D + );=0D +=0D +/**=0D + Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling=0D +=0D + @param[in] ImageHandle The image handle of this module=0D + @param[in] SystemTable The EFI System Table=0D +=0D + @retval EFI_SUCCESS The function completes successfully=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +InitializeCpuPcieSmm (=0D + IN EFI_HANDLE ImageHandle,=0D + IN EFI_SYSTEM_TABLE *SystemTable=0D + );=0D +#endif=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLat= eInitSmm.inf b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaL= ateInitSmm.inf new file mode 100644 index 0000000000..ef3486d2a6 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSm= m.inf @@ -0,0 +1,72 @@ +## @file=0D +# Component description file for the SA late initialization SMM module.=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D SaLateInitSmm=0D +FILE_GUID =3D 2D1E361C-7B3F-4d15-8B1F-66E551FABDC7=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D DXE_SMM_DRIVER=0D +PI_SPECIFICATION_VERSION =3D 1.10=0D +ENTRY_POINT =3D SaLateInitSmmEntryPoint=0D +=0D +[LibraryClasses]=0D +UefiDriverEntryPoint=0D +UefiBootServicesTableLib=0D +DxeServicesTableLib=0D +DebugLib=0D +HobLib=0D +BaseLib=0D +S3BootScriptLib=0D +PciSegmentLib=0D +SaPlatformLib=0D +TimerLib=0D +PciExpressHelpersLib=0D +PcdLib=0D +S3BootScriptLib=0D +CpuPcieInfoFruLib=0D +ConfigBlockLib=0D +CpuPcieRpLib=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +[Pcd]=0D +gSiPkgTokenSpaceGuid.PcdSiPciExpressBaseAddress=0D +gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMax=0D +gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMin=0D +gSiPkgTokenSpaceGuid.PcdCpuPcieEnable ## CONSUMES=0D +=0D +=0D +[Sources]=0D +SaLateInitSmm.c=0D +CpuPcieSmm.c=0D +SaLateInitSmm.h=0D +=0D +[Protocols]=0D +gSaPolicyProtocolGuid ## CONSUMES=0D +gEfiSmmIoTrapDispatch2ProtocolGuid ## CONSUMES=0D +gSaIotrapSmiProtocolGuid ## PRODUCES=0D +gCpuPcieIoTrapProtocolGuid ## PRODUCES=0D +gEfiSmmSxDispatch2ProtocolGuid ## CONSUMES=0D +gPchSmiDispatchProtocolGuid ## CONSUMES=0D +gPchPcieSmiDispatchProtocolGuid ## CONSUMES=0D +=0D +[Guids]=0D +gSaConfigHobGuid=0D +gCpuPcieHobGuid=0D +gPcieDxeConfigGuid=0D +gSaPegHobGuid=0D +=0D +[Depex]=0D +gEfiSmmBase2ProtocolGuid AND=0D +gEfiSmmSxDispatch2ProtocolGuid AND=0D +gEfiSmmIoTrapDispatch2ProtocolGuid AND=0D +gSaPolicyProtocolGuid=0D +=0D --=20 2.24.0.windows.2