/** @file
  PCI eunmeration implementation on entire PCI bus system for PCI Bus module.

Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "PciBus.h"

/**
  This routine is used to enumerate entire pci bus system
  in a given platform.

  @param Controller          Parent controller handle.
  @param HostBridgeHandle    Host bridge handle.

  @retval EFI_SUCCESS    PCI enumeration finished successfully.
  @retval other          Some error occurred when enumerating the pci bus system.

**/
EFI_STATUS
PciEnumerator (
  IN EFI_HANDLE  Controller,
  IN EFI_HANDLE  HostBridgeHandle
  )
{
  EFI_STATUS                                        Status;
  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc;

  //
  // Get the pci host bridge resource allocation protocol
  //
  Status = gBS->OpenProtocol (
                  HostBridgeHandle,
                  &gEfiPciHostBridgeResourceAllocationProtocolGuid,
                  (VOID **)&PciResAlloc,
                  gPciBusDriverBinding.DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Notify the pci bus enumeration is about to begin
  //
  Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Start the bus allocation phase
  //
  Status = PciHostBridgeEnumerator (PciResAlloc);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Submit the resource request
  //
  Status = PciHostBridgeResourceAllocator (PciResAlloc);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Notify the pci bus enumeration is about to complete
  //
  Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeEndEnumeration);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Process P2C
  //
  Status = PciHostBridgeP2CProcess (PciResAlloc);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Process attributes for devices on this host bridge
  //
  Status = PciHostBridgeDeviceAttribute (PciResAlloc);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Enumerate PCI root bridge.

  @param PciResAlloc   Pointer to protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL.
  @param RootBridgeDev Instance of root bridge device.

  @retval EFI_SUCCESS  Successfully enumerated root bridge.
  @retval other        Failed to enumerate root bridge.

**/
EFI_STATUS
PciRootBridgeEnumerator (
  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc,
  IN PCI_IO_DEVICE                                     *RootBridgeDev
  )
{
  EFI_STATUS                         Status;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Configuration;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Configuration1;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Configuration2;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Configuration3;
  UINT8                              SubBusNumber;
  UINT8                              StartBusNumber;
  UINT8                              PaddedBusRange;
  EFI_HANDLE                         RootBridgeHandle;
  UINT8                              Desc;
  UINT64                             AddrLen;
  UINT64                             AddrRangeMin;

  SubBusNumber   = 0;
  StartBusNumber = 0;
  PaddedBusRange = 0;

  //
  // Get the root bridge handle
  //
  RootBridgeHandle = RootBridgeDev->Handle;

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_IO_BUS_PCI | EFI_IOB_PCI_BUS_ENUM,
    RootBridgeDev->DevicePath
    );

  //
  // Get the Bus information
  //
  Status = PciResAlloc->StartBusEnumeration (
                          PciResAlloc,
                          RootBridgeHandle,
                          (VOID **)&Configuration
                          );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  if ((Configuration == NULL) || (Configuration->Desc == ACPI_END_TAG_DESCRIPTOR)) {
    return EFI_INVALID_PARAMETER;
  }

  RootBridgeDev->BusNumberRanges = Configuration;

  //
  // Sort the descriptors in ascending order
  //
  for (Configuration1 = Configuration; Configuration1->Desc != ACPI_END_TAG_DESCRIPTOR; Configuration1++) {
    Configuration2 = Configuration1;
    for (Configuration3 = Configuration1 + 1; Configuration3->Desc != ACPI_END_TAG_DESCRIPTOR; Configuration3++) {
      if (Configuration2->AddrRangeMin > Configuration3->AddrRangeMin) {
        Configuration2 = Configuration3;
      }
    }

    //
    // All other fields other than AddrRangeMin and AddrLen are ignored in a descriptor,
    // so only need to swap these two fields.
    //
    if (Configuration2 != Configuration1) {
      AddrRangeMin                 = Configuration1->AddrRangeMin;
      Configuration1->AddrRangeMin = Configuration2->AddrRangeMin;
      Configuration2->AddrRangeMin = AddrRangeMin;

      AddrLen                 = Configuration1->AddrLen;
      Configuration1->AddrLen = Configuration2->AddrLen;
      Configuration2->AddrLen = AddrLen;
    }
  }

  //
  // Get the bus number to start with
  //
  StartBusNumber = (UINT8)(Configuration->AddrRangeMin);

  //
  // Initialize the subordinate bus number
  //
  SubBusNumber = StartBusNumber;

  //
  // Reset all assigned PCI bus number
  //
  ResetAllPpbBusNumber (
    RootBridgeDev,
    StartBusNumber
    );

  //
  // Assign bus number
  //
  Status = PciScanBus (
             RootBridgeDev,
             StartBusNumber,
             &SubBusNumber,
             &PaddedBusRange
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Assign max bus number scanned
  //

  Status = PciAllocateBusNumber (RootBridgeDev, SubBusNumber, PaddedBusRange, &SubBusNumber);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Find the bus range which contains the higest bus number, then returns the number of buses
  // that should be decoded.
  //
  while (Configuration->AddrRangeMin + Configuration->AddrLen - 1 < SubBusNumber) {
    Configuration++;
  }

  AddrLen                = Configuration->AddrLen;
  Configuration->AddrLen = SubBusNumber - Configuration->AddrRangeMin + 1;

  //
  // Save the Desc field of the next descriptor. Mark the next descriptor as an END descriptor.
  //
  Configuration++;
  Desc                = Configuration->Desc;
  Configuration->Desc = ACPI_END_TAG_DESCRIPTOR;

  //
  // Set bus number
  //
  Status = PciResAlloc->SetBusNumbers (
                          PciResAlloc,
                          RootBridgeHandle,
                          RootBridgeDev->BusNumberRanges
                          );

  //
  // Restore changed fields
  //
  Configuration->Desc          = Desc;
  (Configuration - 1)->AddrLen = AddrLen;

  return Status;
}

/**
  This routine is used to process all PCI devices' Option Rom
  on a certain root bridge.

  @param Bridge     Given parent's root bridge.
  @param RomBase    Base address of ROM driver loaded from.
  @param MaxLength  Maximum rom size.

**/
VOID
ProcessOptionRom (
  IN PCI_IO_DEVICE  *Bridge,
  IN UINT64         RomBase,
  IN UINT64         MaxLength
  )
{
  LIST_ENTRY     *CurrentLink;
  PCI_IO_DEVICE  *Temp;

  //
  // Go through bridges to reach all devices
  //
  CurrentLink = Bridge->ChildList.ForwardLink;
  while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) {
    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
    if (!IsListEmpty (&Temp->ChildList)) {
      //
      // Go further to process the option rom under this bridge
      //
      ProcessOptionRom (Temp, RomBase, MaxLength);
    }

    if ((Temp->RomSize != 0) && (Temp->RomSize <= MaxLength)) {
      //
      // Load and process the option rom
      //
      LoadOpRomImage (Temp, RomBase);
    }

    CurrentLink = CurrentLink->ForwardLink;
  }
}

/**
  This routine is used to assign bus number to the given PCI bus system

  @param Bridge             Parent root bridge instance.
  @param StartBusNumber     Number of beginning.
  @param SubBusNumber       The number of sub bus.

  @retval EFI_SUCCESS       Successfully assigned bus number.
  @retval EFI_DEVICE_ERROR  Failed to assign bus number.

**/
EFI_STATUS
PciAssignBusNumber (
  IN PCI_IO_DEVICE  *Bridge,
  IN UINT8          StartBusNumber,
  OUT UINT8         *SubBusNumber
  )
{
  EFI_STATUS                       Status;
  PCI_TYPE00                       Pci;
  UINT8                            Device;
  UINT8                            Func;
  UINT64                           Address;
  UINTN                            SecondBus;
  UINT16                           Register;
  UINT8                            Register8;
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo;

  PciRootBridgeIo = Bridge->PciRootBridgeIo;

  SecondBus = 0;
  Register  = 0;

  *SubBusNumber = StartBusNumber;

  //
  // First check to see whether the parent is ppb
  //
  for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
    for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
      //
      // Check to see whether a pci device is present
      //
      Status = PciDevicePresent (
                 PciRootBridgeIo,
                 &Pci,
                 StartBusNumber,
                 Device,
                 Func
                 );

      if (EFI_ERROR (Status) && (Func == 0)) {
        //
        // go to next device if there is no Function 0
        //
        break;
      }

      if (!EFI_ERROR (Status)   &&
          (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci)))
      {
        //
        // Reserved one bus for cardbus bridge
        //
        Status = PciAllocateBusNumber (Bridge, *SubBusNumber, 1, SubBusNumber);
        if (EFI_ERROR (Status)) {
          return Status;
        }

        SecondBus = *SubBusNumber;

        Register = (UINT16)((SecondBus << 8) | (UINT16)StartBusNumber);

        Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);

        Status = PciRootBridgeIo->Pci.Write (
                                        PciRootBridgeIo,
                                        EfiPciWidthUint16,
                                        Address,
                                        1,
                                        &Register
                                        );

        //
        // Initialize SubBusNumber to SecondBus
        //
        Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
        Status  = PciRootBridgeIo->Pci.Write (
                                         PciRootBridgeIo,
                                         EfiPciWidthUint8,
                                         Address,
                                         1,
                                         SubBusNumber
                                         );
        //
        // If it is PPB, resursively search down this bridge
        //
        if (IS_PCI_BRIDGE (&Pci)) {
          Register8 = 0xFF;
          Status    = PciRootBridgeIo->Pci.Write (
                                             PciRootBridgeIo,
                                             EfiPciWidthUint8,
                                             Address,
                                             1,
                                             &Register8
                                             );

          Status = PciAssignBusNumber (
                     Bridge,
                     (UINT8)(SecondBus),
                     SubBusNumber
                     );

          if (EFI_ERROR (Status)) {
            return EFI_DEVICE_ERROR;
          }
        }

        //
        // Set the current maximum bus number under the PPB
        //
        Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);

        Status = PciRootBridgeIo->Pci.Write (
                                        PciRootBridgeIo,
                                        EfiPciWidthUint8,
                                        Address,
                                        1,
                                        SubBusNumber
                                        );
      }

      if ((Func == 0) && !IS_PCI_MULTI_FUNC (&Pci)) {
        //
        // Skip sub functions, this is not a multi function device
        //
        Func = PCI_MAX_FUNC;
      }
    }
  }

  return EFI_SUCCESS;
}

/**
  This routine is used to determine the root bridge attribute by interfacing
  the host bridge resource allocation protocol.

  @param PciResAlloc    Protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
  @param RootBridgeDev  Root bridge instance

  @retval EFI_SUCCESS  Successfully got root bridge's attribute.
  @retval other        Failed to get attribute.

**/
EFI_STATUS
DetermineRootBridgeAttributes (
  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc,
  IN PCI_IO_DEVICE                                     *RootBridgeDev
  )
{
  UINT64      Attributes;
  EFI_STATUS  Status;
  EFI_HANDLE  RootBridgeHandle;

  Attributes       = 0;
  RootBridgeHandle = RootBridgeDev->Handle;

  //
  // Get root bridge attribute by calling into pci host bridge resource allocation protocol
  //
  Status = PciResAlloc->GetAllocAttributes (
                          PciResAlloc,
                          RootBridgeHandle,
                          &Attributes
                          );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Here is the point where PCI bus driver calls HOST bridge allocation protocol
  // Currently we hardcoded for ea815
  //
  if ((Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) {
    RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED;
  }

  if ((Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) != 0) {
    RootBridgeDev->Decodes |= EFI_BRIDGE_MEM64_DECODE_SUPPORTED;
    RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;
  }

  RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;
  RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;
  RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;

  return EFI_SUCCESS;
}

/**
  Get Max Option Rom size on specified bridge.

  @param Bridge    Given bridge device instance.

  @return Max size of option rom needed.

**/
UINT32
GetMaxOptionRomSize (
  IN PCI_IO_DEVICE  *Bridge
  )
{
  LIST_ENTRY     *CurrentLink;
  PCI_IO_DEVICE  *Temp;
  UINT32         MaxOptionRomSize;
  UINT32         TempOptionRomSize;

  MaxOptionRomSize = 0;

  //
  // Go through bridges to reach all devices
  //
  CurrentLink = Bridge->ChildList.ForwardLink;
  while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) {
    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
    if (!IsListEmpty (&Temp->ChildList)) {
      //
      // Get max option rom size under this bridge
      //
      TempOptionRomSize = GetMaxOptionRomSize (Temp);

      //
      // Compare with the option rom size of the bridge
      // Get the larger one
      //
      if (Temp->RomSize > TempOptionRomSize) {
        TempOptionRomSize = Temp->RomSize;
      }
    } else {
      //
      // For devices get the rom size directly
      //
      TempOptionRomSize = Temp->RomSize;
    }

    //
    // Get the largest rom size on this bridge
    //
    if (TempOptionRomSize > MaxOptionRomSize) {
      MaxOptionRomSize = TempOptionRomSize;
    }

    CurrentLink = CurrentLink->ForwardLink;
  }

  return MaxOptionRomSize;
}

/**
  Process attributes of devices on this host bridge

  @param PciResAlloc Protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL.

  @retval EFI_SUCCESS   Successfully process attribute.
  @retval EFI_NOT_FOUND Can not find the specific root bridge device.
  @retval other         Failed to determine the root bridge device's attribute.

**/
EFI_STATUS
PciHostBridgeDeviceAttribute (
  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc
  )
{
  EFI_HANDLE     RootBridgeHandle;
  PCI_IO_DEVICE  *RootBridgeDev;
  EFI_STATUS     Status;

  RootBridgeHandle = NULL;

  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
    //
    // Get RootBridg Device by handle
    //
    RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);

    if (RootBridgeDev == NULL) {
      return EFI_NOT_FOUND;
    }

    //
    // Set the attributes for devcies behind the Root Bridge
    //
    Status = DetermineDeviceAttribute (RootBridgeDev);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/**
  Get resource allocation status from the ACPI resource descriptor.

  @param AcpiConfig       Point to Acpi configuration table.
  @param IoResStatus      Return the status of I/O resource.
  @param Mem32ResStatus   Return the status of 32-bit Memory resource.
  @param PMem32ResStatus  Return the status of 32-bit Prefetchable Memory resource.
  @param Mem64ResStatus   Return the status of 64-bit Memory resource.
  @param PMem64ResStatus  Return the status of 64-bit Prefetchable Memory resource.

**/
VOID
GetResourceAllocationStatus (
  VOID        *AcpiConfig,
  OUT UINT64  *IoResStatus,
  OUT UINT64  *Mem32ResStatus,
  OUT UINT64  *PMem32ResStatus,
  OUT UINT64  *Mem64ResStatus,
  OUT UINT64  *PMem64ResStatus
  )
{
  UINT8                              *Temp;
  UINT64                             ResStatus;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *ACPIAddressDesc;

  Temp = (UINT8 *)AcpiConfig;

  while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
    ACPIAddressDesc = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp;
    ResStatus       = ACPIAddressDesc->AddrTranslationOffset;

    switch (ACPIAddressDesc->ResType) {
      case 0:
        if (ACPIAddressDesc->AddrSpaceGranularity == 32) {
          if (ACPIAddressDesc->SpecificFlag == 0x06) {
            //
            // Pmem32
            //
            *PMem32ResStatus = ResStatus;
          } else {
            //
            // Mem32
            //
            *Mem32ResStatus = ResStatus;
          }
        }

        if (ACPIAddressDesc->AddrSpaceGranularity == 64) {
          if (ACPIAddressDesc->SpecificFlag == 0x06) {
            //
            // PMem64
            //
            *PMem64ResStatus = ResStatus;
          } else {
            //
            // Mem64
            //
            *Mem64ResStatus = ResStatus;
          }
        }

        break;

      case 1:
        //
        // Io
        //
        *IoResStatus = ResStatus;
        break;

      default:
        break;
    }

    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
  }
}

/**
  Remove a PCI device from device pool and mark its bar.

  @param PciDevice Instance of Pci device.

  @retval EFI_SUCCESS Successfully remove the PCI device.
  @retval EFI_ABORTED Pci device is a root bridge or a PCI-PCI bridge.

**/
EFI_STATUS
RejectPciDevice (
  IN PCI_IO_DEVICE  *PciDevice
  )
{
  PCI_IO_DEVICE  *Bridge;
  PCI_IO_DEVICE  *Temp;
  LIST_ENTRY     *CurrentLink;

  //
  // Remove the padding resource from a bridge
  //
  if ( IS_PCI_BRIDGE (&PciDevice->Pci) &&
       (PciDevice->ResourcePaddingDescriptors != NULL))
  {
    FreePool (PciDevice->ResourcePaddingDescriptors);
    PciDevice->ResourcePaddingDescriptors = NULL;
    return EFI_SUCCESS;
  }

  //
  // Skip RB and PPB
  //
  if (IS_PCI_BRIDGE (&PciDevice->Pci) || (PciDevice->Parent == NULL)) {
    return EFI_ABORTED;
  }

  if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) {
    //
    // Get the root bridge device
    //
    Bridge = PciDevice;
    while (Bridge->Parent != NULL) {
      Bridge = Bridge->Parent;
    }

    RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice);

    //
    // Mark its bar
    //
    InitializeP2C (PciDevice);
  }

  //
  // Remove the device
  //
  Bridge      = PciDevice->Parent;
  CurrentLink = Bridge->ChildList.ForwardLink;
  while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) {
    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
    if (Temp == PciDevice) {
      InitializePciDevice (Temp);
      RemoveEntryList (CurrentLink);
      return EFI_SUCCESS;
    }

    CurrentLink = CurrentLink->ForwardLink;
  }

  return EFI_ABORTED;
}

/**
  Determine whethter a PCI device can be rejected.

  @param  PciResNode Pointer to Pci resource node instance.

  @retval TRUE  The PCI device can be rejected.
  @retval TRUE  The PCI device cannot be rejected.

**/
BOOLEAN
IsRejectiveDevice (
  IN  PCI_RESOURCE_NODE  *PciResNode
  )
{
  PCI_IO_DEVICE  *Temp;

  Temp = PciResNode->PciDev;

  //
  // Ensure the device is present
  //
  if (Temp == NULL) {
    return FALSE;
  }

  //
  // PPB and RB should go ahead
  //
  if (IS_PCI_BRIDGE (&Temp->Pci) || (Temp->Parent == NULL)) {
    return TRUE;
  }

  //
  // Skip device on Bus0
  //
  if ((Temp->Parent != NULL) && (Temp->BusNumber == 0)) {
    return FALSE;
  }

  //
  // Skip VGA
  //
  if (IS_PCI_VGA (&Temp->Pci)) {
    return FALSE;
  }

  return TRUE;
}

/**
  Compare two resource nodes and get the larger resource consumer.

  @param PciResNode1  resource node 1 want to be compared
  @param PciResNode2  resource node 2 want to be compared

  @return Larger resource node.

**/
PCI_RESOURCE_NODE *
GetLargerConsumerDevice (
  IN  PCI_RESOURCE_NODE  *PciResNode1,
  IN  PCI_RESOURCE_NODE  *PciResNode2
  )
{
  if (PciResNode2 == NULL) {
    return PciResNode1;
  }

  if (  (IS_PCI_BRIDGE (&(PciResNode2->PciDev->Pci)) || (PciResNode2->PciDev->Parent == NULL)) \
     && (PciResNode2->ResourceUsage != PciResUsagePadding))
  {
    return PciResNode1;
  }

  if (PciResNode1 == NULL) {
    return PciResNode2;
  }

  if ((PciResNode1->Length) > (PciResNode2->Length)) {
    return PciResNode1;
  }

  return PciResNode2;
}

/**
  Get the max resource consumer in the host resource pool.

  @param ResPool  Pointer to resource pool node.

  @return The max resource consumer in the host resource pool.

**/
PCI_RESOURCE_NODE *
GetMaxResourceConsumerDevice (
  IN  PCI_RESOURCE_NODE  *ResPool
  )
{
  PCI_RESOURCE_NODE  *Temp;
  LIST_ENTRY         *CurrentLink;
  PCI_RESOURCE_NODE  *PciResNode;
  PCI_RESOURCE_NODE  *PPBResNode;

  PciResNode = NULL;

  CurrentLink = ResPool->ChildList.ForwardLink;
  while (CurrentLink != NULL && CurrentLink != &ResPool->ChildList) {
    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);

    if (!IsRejectiveDevice (Temp)) {
      CurrentLink = CurrentLink->ForwardLink;
      continue;
    }

    if (  (IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (Temp->PciDev->Parent == NULL)) \
       && (Temp->ResourceUsage != PciResUsagePadding))
    {
      PPBResNode = GetMaxResourceConsumerDevice (Temp);
      PciResNode = GetLargerConsumerDevice (PciResNode, PPBResNode);
    } else {
      PciResNode = GetLargerConsumerDevice (PciResNode, Temp);
    }

    CurrentLink = CurrentLink->ForwardLink;
  }

  return PciResNode;
}

/**
  Adjust host bridge allocation so as to reduce resource requirement

  @param IoPool           Pointer to instance of I/O resource Node.
  @param Mem32Pool        Pointer to instance of 32-bit memory resource Node.
  @param PMem32Pool       Pointer to instance of 32-bit Prefetchable memory resource node.
  @param Mem64Pool        Pointer to instance of 64-bit memory resource node.
  @param PMem64Pool       Pointer to instance of 64-bit Prefetchable memory resource node.
  @param IoResStatus      Status of I/O resource Node.
  @param Mem32ResStatus   Status of 32-bit memory resource Node.
  @param PMem32ResStatus  Status of 32-bit Prefetchable memory resource node.
  @param Mem64ResStatus   Status of 64-bit memory resource node.
  @param PMem64ResStatus  Status of 64-bit Prefetchable memory resource node.

  @retval EFI_SUCCESS     Successfully adjusted resource on host bridge.
  @retval EFI_ABORTED     Host bridge hasn't this resource type or no resource be adjusted.

**/
EFI_STATUS
PciHostBridgeAdjustAllocation (
  IN  PCI_RESOURCE_NODE  *IoPool,
  IN  PCI_RESOURCE_NODE  *Mem32Pool,
  IN  PCI_RESOURCE_NODE  *PMem32Pool,
  IN  PCI_RESOURCE_NODE  *Mem64Pool,
  IN  PCI_RESOURCE_NODE  *PMem64Pool,
  IN  UINT64             IoResStatus,
  IN  UINT64             Mem32ResStatus,
  IN  UINT64             PMem32ResStatus,
  IN  UINT64             Mem64ResStatus,
  IN  UINT64             PMem64ResStatus
  )
{
  BOOLEAN                                        AllocationAjusted;
  PCI_RESOURCE_NODE                              *PciResNode;
  PCI_RESOURCE_NODE                              *ResPool[5];
  PCI_IO_DEVICE                                  *RemovedPciDev[5];
  UINT64                                         ResStatus[5];
  UINTN                                          RemovedPciDevNum;
  UINTN                                          DevIndex;
  UINTN                                          ResType;
  EFI_STATUS                                     Status;
  EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD  AllocFailExtendedData;

  PciResNode = NULL;
  ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *));
  RemovedPciDevNum = 0;

  ResPool[0] = IoPool;
  ResPool[1] = Mem32Pool;
  ResPool[2] = PMem32Pool;
  ResPool[3] = Mem64Pool;
  ResPool[4] = PMem64Pool;

  ResStatus[0] = IoResStatus;
  ResStatus[1] = Mem32ResStatus;
  ResStatus[2] = PMem32ResStatus;
  ResStatus[3] = Mem64ResStatus;
  ResStatus[4] = PMem64ResStatus;

  AllocationAjusted = FALSE;

  for (ResType = 0; ResType < 5; ResType++) {
    if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) {
      continue;
    }

    if (ResStatus[ResType] == EFI_RESOURCE_NOT_SATISFIED) {
      //
      // Host bridge hasn't this resource type
      //
      return EFI_ABORTED;
    }

    //
    // Hostbridge hasn't enough resource
    //
    PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]);
    if (PciResNode == NULL) {
      continue;
    }

    //
    // Check if the device has been removed before
    //
    for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) {
      if (PciResNode->PciDev == RemovedPciDev[DevIndex]) {
        break;
      }
    }

    if (DevIndex != RemovedPciDevNum) {
      continue;
    }

    //
    // Remove the device if it isn't in the array
    //
    Status = RejectPciDevice (PciResNode->PciDev);
    if (Status == EFI_SUCCESS) {
      DEBUG ((
        DEBUG_ERROR,
        "PciBus: [%02x|%02x|%02x] was rejected due to resource confliction.\n",
        PciResNode->PciDev->BusNumber,
        PciResNode->PciDev->DeviceNumber,
        PciResNode->PciDev->FunctionNumber
        ));

      //
      // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code
      //
      //
      // Have no way to get ReqRes, AllocRes & Bar here
      //
      ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));
      AllocFailExtendedData.DevicePathSize = (UINT16)sizeof (EFI_DEVICE_PATH_PROTOCOL);
      AllocFailExtendedData.DevicePath     = (UINT8 *)PciResNode->PciDev->DevicePath;
      AllocFailExtendedData.Bar            = PciResNode->Bar;

      REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
        EFI_PROGRESS_CODE,
        EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,
        (VOID *)&AllocFailExtendedData,
        sizeof (AllocFailExtendedData)
        );

      //
      // Add it to the array and indicate at least a device has been rejected
      //
      RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev;
      AllocationAjusted                 = TRUE;
    }
  }

  //
  // End for
  //

  if (AllocationAjusted) {
    return EFI_SUCCESS;
  } else {
    return EFI_ABORTED;
  }
}

/**
  Summary requests for all resource type, and construct ACPI resource
  requestor instance.

  @param Bridge           detecting bridge
  @param IoNode           Pointer to instance of I/O resource Node
  @param Mem32Node        Pointer to instance of 32-bit memory resource Node
  @param PMem32Node       Pointer to instance of 32-bit Pmemory resource node
  @param Mem64Node        Pointer to instance of 64-bit memory resource node
  @param PMem64Node       Pointer to instance of 64-bit Pmemory resource node
  @param Config           Output buffer holding new constructed APCI resource requestor

  @retval EFI_SUCCESS           Successfully constructed ACPI resource.
  @retval EFI_OUT_OF_RESOURCES  No memory available.

**/
EFI_STATUS
ConstructAcpiResourceRequestor (
  IN PCI_IO_DEVICE      *Bridge,
  IN PCI_RESOURCE_NODE  *IoNode,
  IN PCI_RESOURCE_NODE  *Mem32Node,
  IN PCI_RESOURCE_NODE  *PMem32Node,
  IN PCI_RESOURCE_NODE  *Mem64Node,
  IN PCI_RESOURCE_NODE  *PMem64Node,
  OUT VOID              **Config
  )
{
  UINT8                              NumConfig;
  UINT8                              Aperture;
  UINT8                              *Configuration;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Ptr;
  EFI_ACPI_END_TAG_DESCRIPTOR        *PtrEnd;

  NumConfig = 0;
  Aperture  = 0;

  *Config = NULL;

  //
  // if there is io request, add to the io aperture
  //
  if (ResourceRequestExisted (IoNode)) {
    NumConfig++;
    Aperture |= 0x01;
  }

  //
  // if there is mem32 request, add to the mem32 aperture
  //
  if (ResourceRequestExisted (Mem32Node)) {
    NumConfig++;
    Aperture |= 0x02;
  }

  //
  // if there is pmem32 request, add to the pmem32 aperture
  //
  if (ResourceRequestExisted (PMem32Node)) {
    NumConfig++;
    Aperture |= 0x04;
  }

  //
  // if there is mem64 request, add to the mem64 aperture
  //
  if (ResourceRequestExisted (Mem64Node)) {
    NumConfig++;
    Aperture |= 0x08;
  }

  //
  // if there is pmem64 request, add to the pmem64 aperture
  //
  if (ResourceRequestExisted (PMem64Node)) {
    NumConfig++;
    Aperture |= 0x10;
  }

  if (NumConfig != 0) {
    //
    // If there is at least one type of resource request,
    // allocate a acpi resource node
    //
    Configuration = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
    if (Configuration == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Configuration;

    //
    // Deal with io aperture
    //
    if ((Aperture & 0x01) != 0) {
      Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
      Ptr->Len  = (UINT16)(sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3);
      //
      // Io
      //
      Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
      //
      // non ISA range
      //
      Ptr->SpecificFlag = 1;
      Ptr->AddrLen      = IoNode->Length;
      Ptr->AddrRangeMax = IoNode->Alignment;

      Ptr++;
    }

    //
    // Deal with mem32 aperture
    //
    if ((Aperture & 0x02) != 0) {
      Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
      Ptr->Len  = (UINT16)(sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3);
      //
      // Mem
      //
      Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
      //
      // Nonprefechable
      //
      Ptr->SpecificFlag = 0;
      //
      // 32 bit
      //
      Ptr->AddrSpaceGranularity = 32;
      Ptr->AddrLen              = Mem32Node->Length;
      Ptr->AddrRangeMax         = Mem32Node->Alignment;

      Ptr++;
    }

    //
    // Deal with Pmem32 aperture
    //
    if ((Aperture & 0x04) != 0) {
      Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
      Ptr->Len  = (UINT16)(sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3);
      //
      // Mem
      //
      Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
      //
      // prefechable
      //
      Ptr->SpecificFlag = 0x6;
      //
      // 32 bit
      //
      Ptr->AddrSpaceGranularity = 32;
      Ptr->AddrLen              = PMem32Node->Length;
      Ptr->AddrRangeMax         = PMem32Node->Alignment;

      Ptr++;
    }

    //
    // Deal with mem64 aperture
    //
    if ((Aperture & 0x08) != 0) {
      Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
      Ptr->Len  = (UINT16)(sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3);
      //
      // Mem
      //
      Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
      //
      // nonprefechable
      //
      Ptr->SpecificFlag = 0;
      //
      // 64 bit
      //
      Ptr->AddrSpaceGranularity = 64;
      Ptr->AddrLen              = Mem64Node->Length;
      Ptr->AddrRangeMax         = Mem64Node->Alignment;

      Ptr++;
    }

    //
    // Deal with Pmem64 aperture
    //
    if ((Aperture & 0x10) != 0) {
      Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
      Ptr->Len  = (UINT16)(sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3);
      //
      // Mem
      //
      Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
      //
      // prefechable
      //
      Ptr->SpecificFlag = 0x06;
      //
      // 64 bit
      //
      Ptr->AddrSpaceGranularity = 64;
      Ptr->AddrLen              = PMem64Node->Length;
      Ptr->AddrRangeMax         = PMem64Node->Alignment;

      Ptr++;
    }

    //
    // put the checksum
    //
    PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr;

    PtrEnd->Desc     = ACPI_END_TAG_DESCRIPTOR;
    PtrEnd->Checksum = 0;
  } else {
    //
    // If there is no resource request
    //
    Configuration = AllocateZeroPool (sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
    if (Configuration == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    PtrEnd           = (EFI_ACPI_END_TAG_DESCRIPTOR *)(Configuration);
    PtrEnd->Desc     = ACPI_END_TAG_DESCRIPTOR;
    PtrEnd->Checksum = 0;
  }

  *Config = Configuration;

  return EFI_SUCCESS;
}

/**
  Get resource base from an acpi configuration descriptor.

  @param Config       An acpi configuration descriptor.
  @param IoBase       Output of I/O resource base address.
  @param Mem32Base    Output of 32-bit memory base address.
  @param PMem32Base   Output of 32-bit prefetchable memory base address.
  @param Mem64Base    Output of 64-bit memory base address.
  @param PMem64Base   Output of 64-bit prefetchable memory base address.

**/
VOID
GetResourceBase (
  IN VOID     *Config,
  OUT UINT64  *IoBase,
  OUT UINT64  *Mem32Base,
  OUT UINT64  *PMem32Base,
  OUT UINT64  *Mem64Base,
  OUT UINT64  *PMem64Base
  )
{
  UINT8                              *Temp;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Ptr;
  UINT64                             ResStatus;

  ASSERT (Config != NULL);

  *IoBase     = 0xFFFFFFFFFFFFFFFFULL;
  *Mem32Base  = 0xFFFFFFFFFFFFFFFFULL;
  *PMem32Base = 0xFFFFFFFFFFFFFFFFULL;
  *Mem64Base  = 0xFFFFFFFFFFFFFFFFULL;
  *PMem64Base = 0xFFFFFFFFFFFFFFFFULL;

  Temp = (UINT8 *)Config;

  while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
    Ptr       = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp;
    ResStatus = Ptr->AddrTranslationOffset;

    if (ResStatus == EFI_RESOURCE_SATISFIED) {
      switch (Ptr->ResType) {
        //
        // Memory type aperture
        //
        case 0:

          //
          // Check to see the granularity
          //
          if (Ptr->AddrSpaceGranularity == 32) {
            if ((Ptr->SpecificFlag & 0x06) != 0) {
              *PMem32Base = Ptr->AddrRangeMin;
            } else {
              *Mem32Base = Ptr->AddrRangeMin;
            }
          }

          if (Ptr->AddrSpaceGranularity == 64) {
            if ((Ptr->SpecificFlag & 0x06) != 0) {
              *PMem64Base = Ptr->AddrRangeMin;
            } else {
              *Mem64Base = Ptr->AddrRangeMin;
            }
          }

          break;

        case 1:

          //
          // Io type aperture
          //
          *IoBase = Ptr->AddrRangeMin;
          break;

        default:
          break;
      }

      //
      // End switch
      //
    }

    //
    // End for
    //
    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
  }
}

/**
  Enumerate pci bridge, allocate resource and determine attribute
  for devices on this bridge.

  @param BridgeDev    Pointer to instance of bridge device.

  @retval EFI_SUCCESS Successfully enumerated PCI bridge.
  @retval other       Failed to enumerate.

**/
EFI_STATUS
PciBridgeEnumerator (
  IN PCI_IO_DEVICE  *BridgeDev
  )
{
  UINT8                SubBusNumber;
  UINT8                StartBusNumber;
  EFI_PCI_IO_PROTOCOL  *PciIo;
  EFI_STATUS           Status;

  SubBusNumber   = 0;
  StartBusNumber = 0;
  PciIo          = &(BridgeDev->PciIo);
  Status         = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = PciAssignBusNumber (
             BridgeDev,
             StartBusNumber,
             &SubBusNumber
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = PciBridgeResourceAllocator (BridgeDev);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = DetermineDeviceAttribute (BridgeDev);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Allocate all kinds of resource for PCI bridge.

  @param  Bridge      Pointer to bridge instance.

  @retval EFI_SUCCESS Successfully allocated resource for PCI bridge.
  @retval other       Failed to allocate resource for bridge.

**/
EFI_STATUS
PciBridgeResourceAllocator (
  IN PCI_IO_DEVICE  *Bridge
  )
{
  PCI_RESOURCE_NODE  *IoBridge;
  PCI_RESOURCE_NODE  *Mem32Bridge;
  PCI_RESOURCE_NODE  *PMem32Bridge;
  PCI_RESOURCE_NODE  *Mem64Bridge;
  PCI_RESOURCE_NODE  *PMem64Bridge;
  UINT64             IoBase;
  UINT64             Mem32Base;
  UINT64             PMem32Base;
  UINT64             Mem64Base;
  UINT64             PMem64Base;
  EFI_STATUS         Status;

  IoBridge = CreateResourceNode (
               Bridge,
               0,
               Bridge->BridgeIoAlignment,
               0,
               PciBarTypeIo16,
               PciResUsageTypical
               );

  Mem32Bridge = CreateResourceNode (
                  Bridge,
                  0,
                  0xFFFFF,
                  0,
                  PciBarTypeMem32,
                  PciResUsageTypical
                  );

  PMem32Bridge = CreateResourceNode (
                   Bridge,
                   0,
                   0xFFFFF,
                   0,
                   PciBarTypePMem32,
                   PciResUsageTypical
                   );

  Mem64Bridge = CreateResourceNode (
                  Bridge,
                  0,
                  0xFFFFF,
                  0,
                  PciBarTypeMem64,
                  PciResUsageTypical
                  );

  PMem64Bridge = CreateResourceNode (
                   Bridge,
                   0,
                   0xFFFFF,
                   0,
                   PciBarTypePMem64,
                   PciResUsageTypical
                   );

  //
  // Create resourcemap by going through all the devices subject to this root bridge
  //
  CreateResourceMap (
    Bridge,
    IoBridge,
    Mem32Bridge,
    PMem32Bridge,
    Mem64Bridge,
    PMem64Bridge
    );

  Status = GetResourceBaseFromBridge (
             Bridge,
             &IoBase,
             &Mem32Base,
             &PMem32Base,
             &Mem64Base,
             &PMem64Base
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Program IO resources
  //
  ProgramResource (
    IoBase,
    IoBridge
    );

  //
  // Program Mem32 resources
  //
  ProgramResource (
    Mem32Base,
    Mem32Bridge
    );

  //
  // Program PMem32 resources
  //
  ProgramResource (
    PMem32Base,
    PMem32Bridge
    );

  //
  // Program Mem64 resources
  //
  ProgramResource (
    Mem64Base,
    Mem64Bridge
    );

  //
  // Program PMem64 resources
  //
  ProgramResource (
    PMem64Base,
    PMem64Bridge
    );

  DestroyResourceTree (IoBridge);
  DestroyResourceTree (Mem32Bridge);
  DestroyResourceTree (PMem32Bridge);
  DestroyResourceTree (PMem64Bridge);
  DestroyResourceTree (Mem64Bridge);

  gBS->FreePool (IoBridge);
  gBS->FreePool (Mem32Bridge);
  gBS->FreePool (PMem32Bridge);
  gBS->FreePool (PMem64Bridge);
  gBS->FreePool (Mem64Bridge);

  return EFI_SUCCESS;
}

/**
  Get resource base address for a pci bridge device.

  @param Bridge     Given Pci driver instance.
  @param IoBase     Output for base address of I/O type resource.
  @param Mem32Base  Output for base address of 32-bit memory type resource.
  @param PMem32Base Ooutput for base address of 32-bit Pmemory type resource.
  @param Mem64Base  Output for base address of 64-bit memory type resource.
  @param PMem64Base Output for base address of 64-bit Pmemory type resource.

  @retval EFI_SUCCESS           Successfully got resource base address.
  @retval EFI_OUT_OF_RESOURCES  PCI bridge is not available.

**/
EFI_STATUS
GetResourceBaseFromBridge (
  IN  PCI_IO_DEVICE  *Bridge,
  OUT UINT64         *IoBase,
  OUT UINT64         *Mem32Base,
  OUT UINT64         *PMem32Base,
  OUT UINT64         *Mem64Base,
  OUT UINT64         *PMem64Base
  )
{
  if (!Bridge->Allocated) {
    return EFI_OUT_OF_RESOURCES;
  }

  *IoBase     = gAllOne;
  *Mem32Base  = gAllOne;
  *PMem32Base = gAllOne;
  *Mem64Base  = gAllOne;
  *PMem64Base = gAllOne;

  if (IS_PCI_BRIDGE (&Bridge->Pci)) {
    if (Bridge->PciBar[PPB_IO_RANGE].Length > 0) {
      *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress;
    }

    if (Bridge->PciBar[PPB_MEM32_RANGE].Length > 0) {
      *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress;
    }

    if (Bridge->PciBar[PPB_PMEM32_RANGE].Length > 0) {
      *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress;
    }

    if (Bridge->PciBar[PPB_PMEM64_RANGE].Length > 0) {
      *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress;
    } else {
      *PMem64Base = gAllOne;
    }
  }

  if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) {
    if (Bridge->PciBar[P2C_IO_1].Length > 0) {
      *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress;
    } else {
      if (Bridge->PciBar[P2C_IO_2].Length > 0) {
        *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress;
      }
    }

    if (Bridge->PciBar[P2C_MEM_1].Length > 0) {
      if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) {
        *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;
      }

      if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) {
        *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;
      }
    }

    if (Bridge->PciBar[P2C_MEM_2].Length > 0) {
      if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) {
        *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;
      }

      if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) {
        *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;
      }
    }
  }

  return EFI_SUCCESS;
}

/**
   These are the notifications from the PCI bus driver that it is about to enter a certain
   phase of the PCI enumeration process.

   This member function can be used to notify the host bridge driver to perform specific actions,
   including any chipset-specific initialization, so that the chipset is ready to enter the next phase.
   Eight notification points are defined at this time. See belows:
   EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures and internal data
                                          structures. The PCI enumerator should issue this notification
                                          before starting a fresh enumeration process. Enumeration cannot
                                          be restarted after sending any other notification such as
                                          EfiPciHostBridgeBeginBusAllocation.
   EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to begin. No specific action is
                                          required here. This notification can be used to perform any
                                          chipset-specific programming.
   EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming phase is complete. No
                                          specific action is required here. This notification can be used to
                                          perform any chipset-specific programming.
   EfiPciHostBridgeBeginResourceAllocation
                                          The resource allocation phase is about to begin. No specific
                                          action is required here. This notification can be used to perform
                                          any chipset-specific programming.
   EfiPciHostBridgeAllocateResources      Allocates resources per previously submitted requests for all the PCI
                                          root bridges. These resource settings are returned on the next call to
                                          GetProposedResources(). Before calling NotifyPhase() with a Phase of
                                          EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible
                                          for gathering I/O and memory requests for
                                          all the PCI root bridges and submitting these requests using
                                          SubmitResources(). This function pads the resource amount
                                          to suit the root bridge hardware, takes care of dependencies between
                                          the PCI root bridges, and calls the Global Coherency Domain (GCD)
                                          with the allocation request. In the case of padding, the allocated range
                                          could be bigger than what was requested.
   EfiPciHostBridgeSetResources           Programs the host bridge hardware to decode previously allocated
                                          resources (proposed resources) for all the PCI root bridges. After the
                                          hardware is programmed, reassigning resources will not be supported.
                                          The bus settings are not affected.
   EfiPciHostBridgeFreeResources          Deallocates resources that were previously allocated for all the PCI
                                          root bridges and resets the I/O and memory apertures to their initial
                                          state. The bus settings are not affected. If the request to allocate
                                          resources fails, the PCI enumerator can use this notification to
                                          deallocate previous resources, adjust the requests, and retry
                                          allocation.
   EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is completed. No specific action is
                                          required here. This notification can be used to perform any chipsetspecific
                                          programming.

   @param[in] PciResAlloc         The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
   @param[in] Phase               The phase during enumeration

   @retval EFI_NOT_READY          This phase cannot be entered at this time. For example, this error
                                  is valid for a Phase of EfiPciHostBridgeAllocateResources if
                                  SubmitResources() has not been called for one or more
                                  PCI root bridges before this call
   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error. This error is valid
                                  for a Phase of EfiPciHostBridgeSetResources.
   @retval EFI_INVALID_PARAMETER  Invalid phase parameter
   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
                                  This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the
                                  previously submitted resource requests cannot be fulfilled or
                                  were only partially fulfilled.
   @retval EFI_SUCCESS            The notification was accepted without any errors.

**/
EFI_STATUS
NotifyPhase (
  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc,
  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE        Phase
  )
{
  EFI_HANDLE                       HostBridgeHandle;
  EFI_HANDLE                       RootBridgeHandle;
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo;
  EFI_STATUS                       Status;

  HostBridgeHandle = NULL;
  RootBridgeHandle = NULL;
  if (gPciPlatformProtocol != NULL) {
    //
    // Get Host Bridge Handle.
    //
    PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);

    //
    // Get the rootbridge Io protocol to find the host bridge handle
    //
    Status = gBS->HandleProtocol (
                    RootBridgeHandle,
                    &gEfiPciRootBridgeIoProtocolGuid,
                    (VOID **)&PciRootBridgeIo
                    );

    if (EFI_ERROR (Status)) {
      return EFI_NOT_FOUND;
    }

    HostBridgeHandle = PciRootBridgeIo->ParentHandle;

    //
    // Call PlatformPci::PlatformNotify() if the protocol is present.
    //
    gPciPlatformProtocol->PlatformNotify (
                            gPciPlatformProtocol,
                            HostBridgeHandle,
                            Phase,
                            ChipsetEntry
                            );
  } else if (gPciOverrideProtocol != NULL) {
    //
    // Get Host Bridge Handle.
    //
    PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);

    //
    // Get the rootbridge Io protocol to find the host bridge handle
    //
    Status = gBS->HandleProtocol (
                    RootBridgeHandle,
                    &gEfiPciRootBridgeIoProtocolGuid,
                    (VOID **)&PciRootBridgeIo
                    );

    if (EFI_ERROR (Status)) {
      return EFI_NOT_FOUND;
    }

    HostBridgeHandle = PciRootBridgeIo->ParentHandle;

    //
    // Call PlatformPci::PhaseNotify() if the protocol is present.
    //
    gPciOverrideProtocol->PlatformNotify (
                            gPciOverrideProtocol,
                            HostBridgeHandle,
                            Phase,
                            ChipsetEntry
                            );
  }

  Status = PciResAlloc->NotifyPhase (
                          PciResAlloc,
                          Phase
                          );

  if (gPciPlatformProtocol != NULL) {
    //
    // Call PlatformPci::PlatformNotify() if the protocol is present.
    //
    gPciPlatformProtocol->PlatformNotify (
                            gPciPlatformProtocol,
                            HostBridgeHandle,
                            Phase,
                            ChipsetExit
                            );
  } else if (gPciOverrideProtocol != NULL) {
    //
    // Call PlatformPci::PhaseNotify() if the protocol is present.
    //
    gPciOverrideProtocol->PlatformNotify (
                            gPciOverrideProtocol,
                            HostBridgeHandle,
                            Phase,
                            ChipsetExit
                            );
  }

  return Status;
}

/**
  Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various
  stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual
  PCI controllers before enumeration.

  This function is called during the PCI enumeration process. No specific action is expected from this
  member function. It allows the host bridge driver to preinitialize individual PCI controllers before
  enumeration.

  @param Bridge            Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
  @param Bus               The bus number of the pci device.
  @param Device            The device number of the pci device.
  @param Func              The function number of the pci device.
  @param Phase             The phase of the PCI device enumeration.

  @retval EFI_SUCCESS              The requested parameters were returned.
  @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge handle.
  @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined in
                                   EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
  @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error. The PCI enumerator should
                                   not enumerate this device, including its child devices if it is a PCI-to-PCI
                                   bridge.

**/
EFI_STATUS
PreprocessController (
  IN PCI_IO_DEVICE                                 *Bridge,
  IN UINT8                                         Bus,
  IN UINT8                                         Device,
  IN UINT8                                         Func,
  IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE  Phase
  )
{
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS       RootBridgePciAddress;
  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc;
  EFI_HANDLE                                        RootBridgeHandle;
  EFI_HANDLE                                        HostBridgeHandle;
  EFI_STATUS                                        Status;

  //
  // Get the host bridge handle
  //
  HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle;

  //
  // Get the pci host bridge resource allocation protocol
  //
  Status = gBS->OpenProtocol (
                  HostBridgeHandle,
                  &gEfiPciHostBridgeResourceAllocationProtocolGuid,
                  (VOID **)&PciResAlloc,
                  NULL,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  //
  // Get Root Brige Handle
  //
  while (Bridge->Parent != NULL) {
    Bridge = Bridge->Parent;
  }

  RootBridgeHandle = Bridge->Handle;

  RootBridgePciAddress.Register         = 0;
  RootBridgePciAddress.Function         = Func;
  RootBridgePciAddress.Device           = Device;
  RootBridgePciAddress.Bus              = Bus;
  RootBridgePciAddress.ExtendedRegister = 0;

  if (gPciPlatformProtocol != NULL) {
    //
    // Call PlatformPci::PrepController() if the protocol is present.
    //
    gPciPlatformProtocol->PlatformPrepController (
                            gPciPlatformProtocol,
                            HostBridgeHandle,
                            RootBridgeHandle,
                            RootBridgePciAddress,
                            Phase,
                            ChipsetEntry
                            );
  } else if (gPciOverrideProtocol != NULL) {
    //
    // Call PlatformPci::PrepController() if the protocol is present.
    //
    gPciOverrideProtocol->PlatformPrepController (
                            gPciOverrideProtocol,
                            HostBridgeHandle,
                            RootBridgeHandle,
                            RootBridgePciAddress,
                            Phase,
                            ChipsetEntry
                            );
  }

  Status = PciResAlloc->PreprocessController (
                          PciResAlloc,
                          RootBridgeHandle,
                          RootBridgePciAddress,
                          Phase
                          );

  if (gPciPlatformProtocol != NULL) {
    //
    // Call PlatformPci::PrepController() if the protocol is present.
    //
    gPciPlatformProtocol->PlatformPrepController (
                            gPciPlatformProtocol,
                            HostBridgeHandle,
                            RootBridgeHandle,
                            RootBridgePciAddress,
                            Phase,
                            ChipsetExit
                            );
  } else if (gPciOverrideProtocol != NULL) {
    //
    // Call PlatformPci::PrepController() if the protocol is present.
    //
    gPciOverrideProtocol->PlatformPrepController (
                            gPciOverrideProtocol,
                            HostBridgeHandle,
                            RootBridgeHandle,
                            RootBridgePciAddress,
                            Phase,
                            ChipsetExit
                            );
  }

  return EFI_SUCCESS;
}

/**
  This function allows the PCI bus driver to be notified to act as requested when a hot-plug event has
  happened on the hot-plug controller. Currently, the operations include add operation and remove operation..

  @param This                 A pointer to the hot plug request protocol.
  @param Operation            The operation the PCI bus driver is requested to make.
  @param Controller           The handle of the hot-plug controller.
  @param RemainingDevicePath  The remaining device path for the PCI-like hot-plug device.
  @param NumberOfChildren     The number of child handles.
                              For a add operation, it is an output parameter.
                              For a remove operation, it's an input parameter.
  @param ChildHandleBuffer    The buffer which contains the child handles.

  @retval EFI_INVALID_PARAMETER  Operation is not a legal value.
                                 Controller is NULL or not a valid handle.
                                 NumberOfChildren is NULL.
                                 ChildHandleBuffer is NULL while Operation is add.
  @retval EFI_OUT_OF_RESOURCES   There are no enough resources to start the devices.
  @retval EFI_NOT_FOUND          Can not find bridge according to controller handle.
  @retval EFI_SUCCESS            The handles for the specified device have been created or destroyed
                                 as requested, and for an add operation, the new handles are
                                 returned in ChildHandleBuffer.
**/
EFI_STATUS
EFIAPI
PciHotPlugRequestNotify (
  IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL  *This,
  IN EFI_PCI_HOTPLUG_OPERATION         Operation,
  IN EFI_HANDLE                        Controller,
  IN EFI_DEVICE_PATH_PROTOCOL          *RemainingDevicePath OPTIONAL,
  IN OUT UINT8                         *NumberOfChildren,
  IN OUT EFI_HANDLE                    *ChildHandleBuffer
  )
{
  PCI_IO_DEVICE        *Bridge;
  PCI_IO_DEVICE        *Temp;
  EFI_PCI_IO_PROTOCOL  *PciIo;
  UINTN                Index;
  EFI_HANDLE           RootBridgeHandle;
  EFI_STATUS           Status;

  //
  // Check input parameter validity
  //
  if ((Controller == NULL) || (NumberOfChildren == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Operation != EfiPciHotPlugRequestAdd) && (Operation != EfiPciHotplugRequestRemove)) {
    return EFI_INVALID_PARAMETER;
  }

  if (Operation == EfiPciHotPlugRequestAdd) {
    if (ChildHandleBuffer == NULL) {
      return EFI_INVALID_PARAMETER;
    }
  } else if ((Operation == EfiPciHotplugRequestRemove) && (*NumberOfChildren != 0)) {
    if (ChildHandleBuffer == NULL) {
      return EFI_INVALID_PARAMETER;
    }
  }

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&PciIo,
                  gPciBusDriverBinding.DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);

  //
  // Get root bridge handle
  //
  Temp = Bridge;
  while (Temp->Parent != NULL) {
    Temp = Temp->Parent;
  }

  RootBridgeHandle = Temp->Handle;

  if (Operation == EfiPciHotPlugRequestAdd) {
    //
    // Report Status Code to indicate hot plug happens
    //
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_PROGRESS_CODE,
      (EFI_IO_BUS_PCI | EFI_IOB_PC_HOTPLUG),
      Temp->DevicePath
      );

    if (NumberOfChildren != NULL) {
      *NumberOfChildren = 0;
    }

    if (IsListEmpty (&Bridge->ChildList)) {
      Status = PciBridgeEnumerator (Bridge);

      if (EFI_ERROR (Status)) {
        return Status;
      }
    }

    Status = StartPciDevicesOnBridge (
               RootBridgeHandle,
               Bridge,
               RemainingDevicePath,
               NumberOfChildren,
               ChildHandleBuffer
               );

    return Status;
  }

  if (Operation == EfiPciHotplugRequestRemove) {
    if (*NumberOfChildren == 0) {
      //
      // Remove all devices on the bridge
      //
      RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge);
      return EFI_SUCCESS;
    }

    for (Index = 0; Index < *NumberOfChildren; Index++) {
      //
      // De register all the pci device
      //
      Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]);

      if (EFI_ERROR (Status)) {
        return Status;
      }
    }

    //
    // End for
    //
    return EFI_SUCCESS;
  }

  return EFI_SUCCESS;
}

/**
  Search hostbridge according to given handle

  @param RootBridgeHandle  Host bridge handle.

  @retval TRUE             Found host bridge handle.
  @retval FALSE            Not found hot bridge handle.

**/
BOOLEAN
SearchHostBridgeHandle (
  IN EFI_HANDLE  RootBridgeHandle
  )
{
  EFI_HANDLE                       HostBridgeHandle;
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo;
  UINTN                            Index;
  EFI_STATUS                       Status;

  //
  // Get the rootbridge Io protocol to find the host bridge handle
  //
  Status = gBS->OpenProtocol (
                  RootBridgeHandle,
                  &gEfiPciRootBridgeIoProtocolGuid,
                  (VOID **)&PciRootBridgeIo,
                  gPciBusDriverBinding.DriverBindingHandle,
                  RootBridgeHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  HostBridgeHandle = PciRootBridgeIo->ParentHandle;
  for (Index = 0; Index < gPciHostBridgeNumber; Index++) {
    if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Add host bridge handle to global variable for enumerating.

  @param HostBridgeHandle   Host bridge handle.

  @retval EFI_SUCCESS       Successfully added host bridge.
  @retval EFI_ABORTED       Host bridge is NULL, or given host bridge
                            has been in host bridge list.

**/
EFI_STATUS
AddHostBridgeEnumerator (
  IN EFI_HANDLE  HostBridgeHandle
  )
{
  UINTN  Index;

  if (HostBridgeHandle == NULL) {
    return EFI_ABORTED;
  }

  for (Index = 0; Index < gPciHostBridgeNumber; Index++) {
    if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {
      return EFI_ABORTED;
    }
  }

  if (Index < PCI_MAX_HOST_BRIDGE_NUM) {
    gPciHostBrigeHandles[Index] = HostBridgeHandle;
    gPciHostBridgeNumber++;
  }

  return EFI_SUCCESS;
}
