From: Vu Nguyen <[email protected]> Registers the Platform NotifyPhase() to prevent unexpected issues caused by the enabled PCIe controllers with unstable link.
Cc: Thang Nguyen <[email protected]> Cc: Chuong Tran <[email protected]> Cc: Phong Vo <[email protected]> Cc: Leif Lindholm <[email protected]> Cc: Michael D Kinney <[email protected]> Cc: Ard Biesheuvel <[email protected]> Cc: Nate DeSimone <[email protected]> Signed-off-by: Nhi Pham <[email protected]> Reviewed-by: Leif Lindholm <[email protected]> --- Platform/Ampere/JadePkg/Jade.dsc | 5 + Platform/Ampere/JadePkg/Jade.fdf | 1 + Platform/Ampere/JadePkg/Drivers/PciPlatformDxe/PciPlatformDxe.inf | 41 ++++ Platform/Ampere/JadePkg/Drivers/PciPlatformDxe/PciPlatformDxe.c | 258 ++++++++++++++++++++ 4 files changed, 305 insertions(+) diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc index 9315c1c71cc7..ffba757a6130 100644 --- a/Platform/Ampere/JadePkg/Jade.dsc +++ b/Platform/Ampere/JadePkg/Jade.dsc @@ -129,3 +129,8 @@ [Components.common] Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf + + # + # PCIe + # + Platform/Ampere/JadePkg/Drivers/PciPlatformDxe/PciPlatformDxe.inf diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf index 00184f105e6f..19e7cf16697e 100644 --- a/Platform/Ampere/JadePkg/Jade.fdf +++ b/Platform/Ampere/JadePkg/Jade.fdf @@ -299,6 +299,7 @@ [FV.FvMain] # INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf + INF Platform/Ampere/JadePkg/Drivers/PciPlatformDxe/PciPlatformDxe.inf # # UEFI application (Shell Embedded Boot Loader) diff --git a/Platform/Ampere/JadePkg/Drivers/PciPlatformDxe/PciPlatformDxe.inf b/Platform/Ampere/JadePkg/Drivers/PciPlatformDxe/PciPlatformDxe.inf new file mode 100644 index 000000000000..ddf6eeb759eb --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/PciPlatformDxe/PciPlatformDxe.inf @@ -0,0 +1,41 @@ +## @file +# +# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[defines] + INF_VERSION = 0x0001001B + BASE_NAME = PciPlatformDxe + FILE_GUID = 73276F3D-DCBC-49B2-9890-7564F917501D + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = PciPlatformDriverEntry + +[Sources] + PciPlatformDxe.c + +[Packages] + MdePkg/MdePkg.dec + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec + +[LibraryClasses] + Ac01PcieLib + DebugLib + HobLib + TimerLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Protocols] + gEfiDevicePathProtocolGuid + gEfiPciHostBridgeResourceAllocationProtocolGuid + gEfiPciPlatformProtocolGuid + +[Guids] + gRootComplexInfoHobGuid + +[Depex] + TRUE diff --git a/Platform/Ampere/JadePkg/Drivers/PciPlatformDxe/PciPlatformDxe.c b/Platform/Ampere/JadePkg/Drivers/PciPlatformDxe/PciPlatformDxe.c new file mode 100644 index 000000000000..865dfb891a24 --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/PciPlatformDxe/PciPlatformDxe.c @@ -0,0 +1,258 @@ +/** @file + + Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Uefi.h> + +#include <Guid/RootComplexInfoHob.h> +#include <Library/DebugLib.h> +#include <Library/HobLib.h> +#include <Library/Ac01PcieLib.h> +#include <Library/TimerLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Protocol/DevicePath.h> +#include <Protocol/PciHostBridgeResourceAllocation.h> +#include <Protocol/PciPlatform.h> + +#pragma pack(1) +typedef struct { + ACPI_HID_DEVICE_PATH AcpiDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH; +#pragma pack () + +/** + Callback funciton for EndEnumeration notification from PCI stack. + + @param[in] RootBridgeIndex Index to identify of PCIE Root bridge. + @param[in] Phase The phase of enumeration as informed from PCI stack. +**/ +VOID +NotifyPhaseCallBack ( + IN UINTN RootBridgeIndex, + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase + ) +{ + AC01_ROOT_COMPLEX *RootComplexList; + VOID *Hob; + + Hob = GetFirstGuidHob (&gRootComplexInfoHobGuid); + if (Hob == NULL) { + return; + } + + RootComplexList = (AC01_ROOT_COMPLEX *)GET_GUID_HOB_DATA (Hob); + + switch (Phase) { + case EfiPciHostBridgeEndEnumeration: + Ac01PcieCoreEndEnumeration (&RootComplexList[RootBridgeIndex]); + break; + + case EfiPciHostBridgeBeginEnumeration: + // 100ms that help fixing completion timeout issue + MicroSecondDelay (100000); + break; + + case EfiPciHostBridgeBeginBusAllocation: + case EfiPciHostBridgeEndBusAllocation: + case EfiPciHostBridgeBeginResourceAllocation: + case EfiPciHostBridgeAllocateResources: + case EfiPciHostBridgeSetResources: + case EfiPciHostBridgeFreeResources: + case EfiPciHostBridgeEndResourceAllocation: + case EfiMaxPciHostBridgeEnumerationPhase: + break; + } +} + +/** + + Perform initialization by the phase indicated. + + @param This Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance. + @param HostBridge The associated PCI host bridge handle. + @param Phase The phase of the PCI controller enumeration. + @param ChipsetPhase Defines the execution phase of the PCI chipset driver. + + @retval EFI_SUCCESS Must return with success. + +**/ +EFI_STATUS +EFIAPI +PhaseNotify ( + IN EFI_PCI_PLATFORM_PROTOCOL *This, + IN EFI_HANDLE HostBridge, + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase, + IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase + ) +{ + EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *RootBridgeDevPath; + EFI_HANDLE RootBridgeHandle = NULL; + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *ResAlloc = NULL; + EFI_STATUS Status; + + if (ChipsetPhase != ChipsetExit) { + return EFI_SUCCESS; + } + + // + // Get HostBridgeInstance from HostBridge handle. + // + Status = gBS->HandleProtocol ( + HostBridge, + &gEfiPciHostBridgeResourceAllocationProtocolGuid, + (VOID **)&ResAlloc + ); + + while (TRUE) { + Status = ResAlloc->GetNextRootBridge (ResAlloc, &RootBridgeHandle); + if (EFI_ERROR (Status)) { + break; + } + + Status = gBS->HandleProtocol ( + RootBridgeHandle, + &gEfiDevicePathProtocolGuid, + (VOID **)&RootBridgeDevPath + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a %d: Failed to locate RootBridge DevicePath\n", __FUNCTION__, __LINE__)); + break; + } + + NotifyPhaseCallBack (RootBridgeDevPath->AcpiDevicePath.UID, Phase); + } + + return EFI_SUCCESS; +} + +/** + + The PlatformPrepController() function can be used to notify the platform driver so that + it can perform platform-specific actions. No specific actions are required. + Several notification points are defined at this time. More synchronization points may be + added as required in the future. The PCI bus driver calls the platform driver twice for + every PCI controller-once before the PCI Host Bridge Resource Allocation Protocol driver + is notified, and once after the PCI Host Bridge Resource Allocation Protocol driver has + been notified. + This member function may not perform any error checking on the input parameters. It also + does not return any error codes. If this member function detects any error condition, it + needs to handle those errors on its own because there is no way to surface any errors to + the caller. + + @param This Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance. + @param HostBridge The associated PCI host bridge handle. + @param RootBridge The associated PCI root bridge handle. + @param PciAddress The address of the PCI device on the PCI bus. + @param Phase The phase of the PCI controller enumeration. + @param ChipsetPhase Defines the execution phase of the PCI chipset driver. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_UNSUPPORTED Not supported. + +**/ +EFI_STATUS +EFIAPI +PlatformPrepController ( + IN EFI_PCI_PLATFORM_PROTOCOL *This, + IN EFI_HANDLE HostBridge, + IN EFI_HANDLE RootBridge, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress, + IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase, + IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Set the PciPolicy as EFI_RESERVE_ISA_IO_NO_ALIAS | EFI_RESERVE_VGA_IO_NO_ALIAS. + + @param This The pointer to the Protocol itself. + @param PciPolicy The returned Policy. + + @retval EFI_UNSUPPORTED Function not supported. + @retval EFI_INVALID_PARAMETER Invalid PciPolicy value. + +**/ +EFI_STATUS +EFIAPI +GetPlatformPolicy ( + IN CONST EFI_PCI_PLATFORM_PROTOCOL *This, + OUT EFI_PCI_PLATFORM_POLICY *PciPolicy + ) +{ + return EFI_UNSUPPORTED; +} + +/** + + Return a PCI ROM image for the onboard device represented by PciHandle. + + @param This Protocol instance pointer. + @param PciHandle PCI device to return the ROM image for. + @param RomImage PCI Rom Image for onboard device. + @param RomSize Size of RomImage in bytes. + + @retval EFI_SUCCESS RomImage is valid. + @retval EFI_NOT_FOUND No RomImage. + +**/ +EFI_STATUS +EFIAPI +GetPciRom ( + IN CONST EFI_PCI_PLATFORM_PROTOCOL *This, + IN EFI_HANDLE PciHandle, + OUT VOID **RomImage, + OUT UINTN *RomSize + ) +{ + return EFI_NOT_FOUND; +} + +// +// Interface defintion of PCI Platform protocol. +// +EFI_PCI_PLATFORM_PROTOCOL mPciPlatformProtocol = { + .PlatformNotify = PhaseNotify, + .PlatformPrepController = PlatformPrepController, + .GetPlatformPolicy = GetPlatformPolicy, + .GetPciRom = GetPciRom +}; + +/** + + The Entry point of the Pci Platform Driver. + + @param ImageHandle Handle to the image. + @param SystemTable Handle to System Table. + + @retval EFI_STATUS Status of the function calling. + +**/ +EFI_STATUS +PciPlatformDriverEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE PciPlatformHandle; + + // + // Install on a new handle + // + PciPlatformHandle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &PciPlatformHandle, + &gEfiPciPlatformProtocolGuid, + &mPciPlatformProtocol, + NULL + ); + + return Status; +} -- 2.17.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#82493): https://edk2.groups.io/g/devel/message/82493 Mute This Topic: https://groups.io/mt/86507932/21656 Group Owner: [email protected] Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
