123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- /** @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;
- }
|