/** @file
  PCI resources support functions implementation for PCI Bus module.

Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "PciBus.h"

//
// The default policy for the PCI bus driver is NOT to reserve I/O ranges for both ISA aliases and VGA aliases.
//
BOOLEAN  mReserveIsaAliases = FALSE;
BOOLEAN  mReserveVgaAliases = FALSE;
BOOLEAN  mPolicyDetermined  = FALSE;

/**
  The function is used to skip VGA range.

  @param Start    Returned start address including VGA range.
  @param Length   The length of VGA range.

**/
VOID
SkipVGAAperture (
  OUT UINT64  *Start,
  IN  UINT64  Length
  )
{
  UINT64  Original;
  UINT64  Mask;
  UINT64  StartOffset;
  UINT64  LimitOffset;

  ASSERT (Start != NULL);
  //
  // For legacy VGA, bit 10 to bit 15 is not decoded
  //
  Mask = 0x3FF;

  Original    = *Start;
  StartOffset = Original & Mask;
  LimitOffset = ((*Start) + Length - 1) & Mask;
  if (LimitOffset >= VGABASE1) {
    *Start = *Start - StartOffset + VGALIMIT2 + 1;
  }
}

/**
  This function is used to skip ISA aliasing aperture.

  @param Start    Returned start address including ISA aliasing aperture.
  @param Length   The length of ISA aliasing aperture.

**/
VOID
SkipIsaAliasAperture (
  OUT UINT64  *Start,
  IN  UINT64  Length
  )
{
  UINT64  Original;
  UINT64  Mask;
  UINT64  StartOffset;
  UINT64  LimitOffset;

  ASSERT (Start != NULL);

  //
  // For legacy ISA, bit 10 to bit 15 is not decoded
  //
  Mask = 0x3FF;

  Original    = *Start;
  StartOffset = Original & Mask;
  LimitOffset = ((*Start) + Length - 1) & Mask;

  if (LimitOffset >= ISABASE) {
    *Start = *Start - StartOffset + ISALIMIT + 1;
  }
}

/**
  This function inserts a resource node into the resource list.
  The resource list is sorted in descend order.

  @param Bridge  PCI resource node for bridge.
  @param ResNode Resource node want to be inserted.

**/
VOID
InsertResourceNode (
  IN OUT PCI_RESOURCE_NODE  *Bridge,
  IN     PCI_RESOURCE_NODE  *ResNode
  )
{
  LIST_ENTRY         *CurrentLink;
  PCI_RESOURCE_NODE  *Temp;
  UINT64             ResNodeAlignRest;
  UINT64             TempAlignRest;

  ASSERT (Bridge  != NULL);
  ASSERT (ResNode != NULL);

  InsertHeadList (&Bridge->ChildList, &ResNode->Link);

  CurrentLink = Bridge->ChildList.ForwardLink->ForwardLink;
  while (CurrentLink != &Bridge->ChildList) {
    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);

    if (ResNode->Alignment > Temp->Alignment) {
      break;
    } else if (ResNode->Alignment == Temp->Alignment) {
      ResNodeAlignRest = ResNode->Length & ResNode->Alignment;
      TempAlignRest    = Temp->Length & Temp->Alignment;
      if ((ResNodeAlignRest == 0) || (ResNodeAlignRest >= TempAlignRest)) {
        break;
      }
    }

    SwapListEntries (&ResNode->Link, CurrentLink);

    CurrentLink = ResNode->Link.ForwardLink;
  }
}

/**
  This routine is used to merge two different resource trees in need of
  resource degradation.

  For example, if an upstream PPB doesn't support,
  prefetchable memory decoding, the PCI bus driver will choose to call this function
  to merge prefetchable memory resource list into normal memory list.

  If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource
  type.
  If Dst is NULL or Res is NULL, ASSERT ().

  @param Dst        Point to destination resource tree.
  @param Res        Point to source resource tree.
  @param TypeMerge  If the TypeMerge is TRUE, Res resource type is changed to the type of
                    destination resource type.

**/
VOID
MergeResourceTree (
  IN PCI_RESOURCE_NODE  *Dst,
  IN PCI_RESOURCE_NODE  *Res,
  IN BOOLEAN            TypeMerge
  )
{
  LIST_ENTRY         *CurrentLink;
  PCI_RESOURCE_NODE  *Temp;

  ASSERT (Dst != NULL);
  ASSERT (Res != NULL);

  while (!IsListEmpty (&Res->ChildList)) {
    CurrentLink = Res->ChildList.ForwardLink;

    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);

    if (TypeMerge) {
      Temp->ResType = Dst->ResType;
    }

    RemoveEntryList (CurrentLink);
    InsertResourceNode (Dst, Temp);
  }
}

/**
  This function is used to calculate the IO16 aperture
  for a bridge.

  @param Bridge    PCI resource node for bridge.

**/
VOID
CalculateApertureIo16 (
  IN PCI_RESOURCE_NODE  *Bridge
  )
{
  EFI_STATUS               Status;
  UINT64                   Aperture;
  LIST_ENTRY               *CurrentLink;
  PCI_RESOURCE_NODE        *Node;
  UINT64                   Offset;
  EFI_PCI_PLATFORM_POLICY  PciPolicy;
  UINT64                   PaddingAperture;

  if (!mPolicyDetermined) {
    //
    // Check PciPlatform policy
    //
    Status    = EFI_NOT_FOUND;
    PciPolicy = 0;
    if (gPciPlatformProtocol != NULL) {
      Status = gPciPlatformProtocol->GetPlatformPolicy (
                                       gPciPlatformProtocol,
                                       &PciPolicy
                                       );
    }

    if (EFI_ERROR (Status) && (gPciOverrideProtocol != NULL)) {
      Status = gPciOverrideProtocol->GetPlatformPolicy (
                                       gPciOverrideProtocol,
                                       &PciPolicy
                                       );
    }

    if (!EFI_ERROR (Status)) {
      if ((PciPolicy & EFI_RESERVE_ISA_IO_ALIAS) != 0) {
        mReserveIsaAliases = TRUE;
      }

      if ((PciPolicy & EFI_RESERVE_VGA_IO_ALIAS) != 0) {
        mReserveVgaAliases = TRUE;
      }
    }

    mPolicyDetermined = TRUE;
  }

  Aperture        = 0;
  PaddingAperture = 0;

  if (Bridge == NULL) {
    return;
  }

  //
  // Assume the bridge is aligned
  //
  for ( CurrentLink = GetFirstNode (&Bridge->ChildList)
        ; !IsNull (&Bridge->ChildList, CurrentLink)
        ; CurrentLink = GetNextNode (&Bridge->ChildList, CurrentLink)
        )
  {
    Node = RESOURCE_NODE_FROM_LINK (CurrentLink);
    if (Node->ResourceUsage == PciResUsagePadding) {
      ASSERT (PaddingAperture == 0);
      PaddingAperture = Node->Length;
      continue;
    }

    //
    // Consider the aperture alignment
    //
    Offset = Aperture & (Node->Alignment);

    if (Offset != 0) {
      Aperture = Aperture + (Node->Alignment + 1) - Offset;
    }

    //
    // IsaEnable and VGAEnable can not be implemented now.
    // If both of them are enabled, then the IO resource would
    // become too limited to meet the requirement of most of devices.
    //
    if (mReserveIsaAliases || mReserveVgaAliases) {
      if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci)) && !IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {
        //
        // Check if there is need to support ISA/VGA decoding
        // If so, we need to avoid isa/vga aliasing range
        //
        if (mReserveIsaAliases) {
          SkipIsaAliasAperture (
            &Aperture,
            Node->Length
            );
          Offset = Aperture & (Node->Alignment);
          if (Offset != 0) {
            Aperture = Aperture + (Node->Alignment + 1) - Offset;
          }
        } else if (mReserveVgaAliases) {
          SkipVGAAperture (
            &Aperture,
            Node->Length
            );
          Offset = Aperture & (Node->Alignment);
          if (Offset != 0) {
            Aperture = Aperture + (Node->Alignment + 1) - Offset;
          }
        }
      }
    }

    Node->Offset = Aperture;

    //
    // Increment aperture by the length of node
    //
    Aperture += Node->Length;
  }

  //
  // Adjust the aperture with the bridge's alignment
  //
  Offset = Aperture & (Bridge->Alignment);

  if (Offset != 0) {
    Aperture = Aperture + (Bridge->Alignment + 1) - Offset;
  }

  Bridge->Length = Aperture;
  //
  // At last, adjust the bridge's alignment to the first child's alignment
  // if the bridge has at least one child
  //
  CurrentLink = Bridge->ChildList.ForwardLink;
  if (CurrentLink != &Bridge->ChildList) {
    Node = RESOURCE_NODE_FROM_LINK (CurrentLink);
    if (Node->Alignment > Bridge->Alignment) {
      Bridge->Alignment = Node->Alignment;
    }
  }

  //
  // Hotplug controller needs padding resources.
  // Use the larger one between the padding resource and actual occupied resource.
  //
  Bridge->Length = MAX (Bridge->Length, PaddingAperture);
}

/**
  This function is used to calculate the resource aperture
  for a given bridge device.

  @param Bridge      PCI resource node for given bridge device.

**/
VOID
CalculateResourceAperture (
  IN PCI_RESOURCE_NODE  *Bridge
  )
{
  UINT64             Aperture[2];
  LIST_ENTRY         *CurrentLink;
  PCI_RESOURCE_NODE  *Node;

  if (Bridge == NULL) {
    return;
  }

  if (Bridge->ResType == PciBarTypeIo16) {
    CalculateApertureIo16 (Bridge);
    return;
  }

  Aperture[PciResUsageTypical] = 0;
  Aperture[PciResUsagePadding] = 0;
  //
  // Assume the bridge is aligned
  //
  for ( CurrentLink = GetFirstNode (&Bridge->ChildList)
        ; !IsNull (&Bridge->ChildList, CurrentLink)
        ; CurrentLink = GetNextNode (&Bridge->ChildList, CurrentLink)
        )
  {
    Node = RESOURCE_NODE_FROM_LINK (CurrentLink);

    //
    // It's possible for a bridge to contain multiple padding resource
    // nodes due to DegradeResource().
    //
    ASSERT (
      (Node->ResourceUsage == PciResUsageTypical) ||
      (Node->ResourceUsage == PciResUsagePadding)
      );
    ASSERT (Node->ResourceUsage < ARRAY_SIZE (Aperture));
    //
    // Recode current aperture as a offset
    // Apply padding resource to meet alignment requirement
    // Node offset will be used in future real allocation
    //
    Node->Offset = ALIGN_VALUE (Aperture[Node->ResourceUsage], Node->Alignment + 1);

    //
    // Record the total aperture.
    //
    Aperture[Node->ResourceUsage] = Node->Offset + Node->Length;
  }

  //
  // Adjust the aperture with the bridge's alignment
  //
  Aperture[PciResUsageTypical] = ALIGN_VALUE (Aperture[PciResUsageTypical], Bridge->Alignment + 1);
  Aperture[PciResUsagePadding] = ALIGN_VALUE (Aperture[PciResUsagePadding], Bridge->Alignment + 1);

  //
  // Hotplug controller needs padding resources.
  // Use the larger one between the padding resource and actual occupied resource.
  //
  Bridge->Length = MAX (Aperture[PciResUsageTypical], Aperture[PciResUsagePadding]);

  //
  // Adjust the bridge's alignment to the MAX (first) alignment of all children.
  //
  CurrentLink = Bridge->ChildList.ForwardLink;
  if (CurrentLink != &Bridge->ChildList) {
    Node = RESOURCE_NODE_FROM_LINK (CurrentLink);
    if (Node->Alignment > Bridge->Alignment) {
      Bridge->Alignment = Node->Alignment;
    }
  }
}

/**
  Get IO/Memory resource info for given PCI device.

  @param PciDev     Pci device instance.
  @param IoNode     Resource info node for IO .
  @param Mem32Node  Resource info node for 32-bit memory.
  @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
  @param Mem64Node  Resource info node for 64-bit memory.
  @param PMem64Node Resource info node for 64-bit Prefetchable Memory.

**/
VOID
GetResourceFromDevice (
  IN     PCI_IO_DEVICE      *PciDev,
  IN OUT PCI_RESOURCE_NODE  *IoNode,
  IN OUT PCI_RESOURCE_NODE  *Mem32Node,
  IN OUT PCI_RESOURCE_NODE  *PMem32Node,
  IN OUT PCI_RESOURCE_NODE  *Mem64Node,
  IN OUT PCI_RESOURCE_NODE  *PMem64Node
  )
{
  UINT8              Index;
  PCI_RESOURCE_NODE  *Node;
  BOOLEAN            ResourceRequested;

  Node              = NULL;
  ResourceRequested = FALSE;

  for (Index = 0; Index < PCI_MAX_BAR; Index++) {
    switch ((PciDev->PciBar)[Index].BarType) {
      case PciBarTypeMem32:
      case PciBarTypeOpRom:

        Node = CreateResourceNode (
                 PciDev,
                 (PciDev->PciBar)[Index].Length,
                 (PciDev->PciBar)[Index].Alignment,
                 Index,
                 (PciDev->PciBar)[Index].BarType,
                 PciResUsageTypical
                 );

        InsertResourceNode (
          Mem32Node,
          Node
          );

        ResourceRequested = TRUE;
        break;

      case PciBarTypeMem64:

        Node = CreateResourceNode (
                 PciDev,
                 (PciDev->PciBar)[Index].Length,
                 (PciDev->PciBar)[Index].Alignment,
                 Index,
                 PciBarTypeMem64,
                 PciResUsageTypical
                 );

        InsertResourceNode (
          Mem64Node,
          Node
          );

        ResourceRequested = TRUE;
        break;

      case PciBarTypePMem64:

        Node = CreateResourceNode (
                 PciDev,
                 (PciDev->PciBar)[Index].Length,
                 (PciDev->PciBar)[Index].Alignment,
                 Index,
                 PciBarTypePMem64,
                 PciResUsageTypical
                 );

        InsertResourceNode (
          PMem64Node,
          Node
          );

        ResourceRequested = TRUE;
        break;

      case PciBarTypePMem32:

        Node = CreateResourceNode (
                 PciDev,
                 (PciDev->PciBar)[Index].Length,
                 (PciDev->PciBar)[Index].Alignment,
                 Index,
                 PciBarTypePMem32,
                 PciResUsageTypical
                 );

        InsertResourceNode (
          PMem32Node,
          Node
          );
        ResourceRequested = TRUE;
        break;

      case PciBarTypeIo16:
      case PciBarTypeIo32:

        Node = CreateResourceNode (
                 PciDev,
                 (PciDev->PciBar)[Index].Length,
                 (PciDev->PciBar)[Index].Alignment,
                 Index,
                 PciBarTypeIo16,
                 PciResUsageTypical
                 );

        InsertResourceNode (
          IoNode,
          Node
          );
        ResourceRequested = TRUE;
        break;

      case PciBarTypeUnknown:
        break;

      default:
        break;
    }
  }

  //
  // Add VF resource
  //
  for (Index = 0; Index < PCI_MAX_BAR; Index++) {
    switch ((PciDev->VfPciBar)[Index].BarType) {
      case PciBarTypeMem32:

        Node = CreateVfResourceNode (
                 PciDev,
                 (PciDev->VfPciBar)[Index].Length,
                 (PciDev->VfPciBar)[Index].Alignment,
                 Index,
                 PciBarTypeMem32,
                 PciResUsageTypical
                 );

        InsertResourceNode (
          Mem32Node,
          Node
          );

        break;

      case PciBarTypeMem64:

        Node = CreateVfResourceNode (
                 PciDev,
                 (PciDev->VfPciBar)[Index].Length,
                 (PciDev->VfPciBar)[Index].Alignment,
                 Index,
                 PciBarTypeMem64,
                 PciResUsageTypical
                 );

        InsertResourceNode (
          Mem64Node,
          Node
          );

        break;

      case PciBarTypePMem64:

        Node = CreateVfResourceNode (
                 PciDev,
                 (PciDev->VfPciBar)[Index].Length,
                 (PciDev->VfPciBar)[Index].Alignment,
                 Index,
                 PciBarTypePMem64,
                 PciResUsageTypical
                 );

        InsertResourceNode (
          PMem64Node,
          Node
          );

        break;

      case PciBarTypePMem32:

        Node = CreateVfResourceNode (
                 PciDev,
                 (PciDev->VfPciBar)[Index].Length,
                 (PciDev->VfPciBar)[Index].Alignment,
                 Index,
                 PciBarTypePMem32,
                 PciResUsageTypical
                 );

        InsertResourceNode (
          PMem32Node,
          Node
          );
        break;

      case PciBarTypeIo16:
      case PciBarTypeIo32:
        break;

      case PciBarTypeUnknown:
        break;

      default:
        break;
    }
  }

  // If there is no resource requested from this device,
  // then we indicate this device has been allocated naturally.
  //
  if (!ResourceRequested) {
    PciDev->Allocated = TRUE;
  }
}

/**
  This function is used to create a resource node.

  @param PciDev       Pci device instance.
  @param Length       Length of Io/Memory resource.
  @param Alignment    Alignment of resource.
  @param Bar          Bar index.
  @param ResType      Type of resource: IO/Memory.
  @param ResUsage     Resource usage.

  @return PCI resource node created for given PCI device.
          NULL means PCI resource node is not created.

**/
PCI_RESOURCE_NODE *
CreateResourceNode (
  IN PCI_IO_DEVICE       *PciDev,
  IN UINT64              Length,
  IN UINT64              Alignment,
  IN UINT8               Bar,
  IN PCI_BAR_TYPE        ResType,
  IN PCI_RESOURCE_USAGE  ResUsage
  )
{
  PCI_RESOURCE_NODE  *Node;

  Node = NULL;

  Node = AllocateZeroPool (sizeof (PCI_RESOURCE_NODE));
  ASSERT (Node != NULL);
  if (Node == NULL) {
    return NULL;
  }

  Node->Signature     = PCI_RESOURCE_SIGNATURE;
  Node->PciDev        = PciDev;
  Node->Length        = Length;
  Node->Alignment     = Alignment;
  Node->Bar           = Bar;
  Node->ResType       = ResType;
  Node->Reserved      = FALSE;
  Node->ResourceUsage = ResUsage;
  InitializeListHead (&Node->ChildList);

  return Node;
}

/**
  This function is used to create a IOV VF resource node.

  @param PciDev       Pci device instance.
  @param Length       Length of Io/Memory resource.
  @param Alignment    Alignment of resource.
  @param Bar          Bar index.
  @param ResType      Type of resource: IO/Memory.
  @param ResUsage     Resource usage.

  @return PCI resource node created for given VF PCI device.
          NULL means PCI resource node is not created.

**/
PCI_RESOURCE_NODE *
CreateVfResourceNode (
  IN PCI_IO_DEVICE       *PciDev,
  IN UINT64              Length,
  IN UINT64              Alignment,
  IN UINT8               Bar,
  IN PCI_BAR_TYPE        ResType,
  IN PCI_RESOURCE_USAGE  ResUsage
  )
{
  PCI_RESOURCE_NODE  *Node;

  Node = CreateResourceNode (PciDev, Length, Alignment, Bar, ResType, ResUsage);
  if (Node == NULL) {
    return Node;
  }

  Node->Virtual = TRUE;

  return Node;
}

/**
  This function is used to extract resource request from
  device node list.

  @param Bridge     Pci device instance.
  @param IoNode     Resource info node for IO.
  @param Mem32Node  Resource info node for 32-bit memory.
  @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
  @param Mem64Node  Resource info node for 64-bit memory.
  @param PMem64Node Resource info node for 64-bit Prefetchable Memory.

**/
VOID
CreateResourceMap (
  IN     PCI_IO_DEVICE      *Bridge,
  IN OUT PCI_RESOURCE_NODE  *IoNode,
  IN OUT PCI_RESOURCE_NODE  *Mem32Node,
  IN OUT PCI_RESOURCE_NODE  *PMem32Node,
  IN OUT PCI_RESOURCE_NODE  *Mem64Node,
  IN OUT PCI_RESOURCE_NODE  *PMem64Node
  )
{
  PCI_IO_DEVICE      *Temp;
  PCI_RESOURCE_NODE  *IoBridge;
  PCI_RESOURCE_NODE  *Mem32Bridge;
  PCI_RESOURCE_NODE  *PMem32Bridge;
  PCI_RESOURCE_NODE  *Mem64Bridge;
  PCI_RESOURCE_NODE  *PMem64Bridge;
  LIST_ENTRY         *CurrentLink;

  CurrentLink = Bridge->ChildList.ForwardLink;

  while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) {
    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

    //
    // Create resource nodes for this device by scanning the
    // Bar array in the device private data
    // If the upstream bridge doesn't support this device,
    // no any resource node will be created for this device
    //
    GetResourceFromDevice (
      Temp,
      IoNode,
      Mem32Node,
      PMem32Node,
      Mem64Node,
      PMem64Node
      );

    if (IS_PCI_BRIDGE (&Temp->Pci)) {
      //
      // If the device has children, create a bridge resource node for this PPB
      // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
      // is aligned with 4KB (smaller alignments may be supported).
      //
      IoBridge = CreateResourceNode (
                   Temp,
                   0,
                   Temp->BridgeIoAlignment,
                   PPB_IO_RANGE,
                   PciBarTypeIo16,
                   PciResUsageTypical
                   );

      Mem32Bridge = CreateResourceNode (
                      Temp,
                      0,
                      0xFFFFF,
                      PPB_MEM32_RANGE,
                      PciBarTypeMem32,
                      PciResUsageTypical
                      );

      PMem32Bridge = CreateResourceNode (
                       Temp,
                       0,
                       0xFFFFF,
                       PPB_PMEM32_RANGE,
                       PciBarTypePMem32,
                       PciResUsageTypical
                       );

      Mem64Bridge = CreateResourceNode (
                      Temp,
                      0,
                      0xFFFFF,
                      PPB_MEM64_RANGE,
                      PciBarTypeMem64,
                      PciResUsageTypical
                      );

      PMem64Bridge = CreateResourceNode (
                       Temp,
                       0,
                       0xFFFFF,
                       PPB_PMEM64_RANGE,
                       PciBarTypePMem64,
                       PciResUsageTypical
                       );

      //
      // Recursively create resource map on this bridge
      //
      CreateResourceMap (
        Temp,
        IoBridge,
        Mem32Bridge,
        PMem32Bridge,
        Mem64Bridge,
        PMem64Bridge
        );

      if (ResourceRequestExisted (IoBridge)) {
        InsertResourceNode (
          IoNode,
          IoBridge
          );
      } else {
        FreePool (IoBridge);
        IoBridge = NULL;
      }

      //
      // If there is node under this resource bridge,
      // then calculate bridge's aperture of this type
      // and insert it into the respective resource tree.
      // If no, delete this resource bridge
      //
      if (ResourceRequestExisted (Mem32Bridge)) {
        InsertResourceNode (
          Mem32Node,
          Mem32Bridge
          );
      } else {
        FreePool (Mem32Bridge);
        Mem32Bridge = NULL;
      }

      //
      // If there is node under this resource bridge,
      // then calculate bridge's aperture of this type
      // and insert it into the respective resource tree.
      // If no, delete this resource bridge
      //
      if (ResourceRequestExisted (PMem32Bridge)) {
        InsertResourceNode (
          PMem32Node,
          PMem32Bridge
          );
      } else {
        FreePool (PMem32Bridge);
        PMem32Bridge = NULL;
      }

      //
      // If there is node under this resource bridge,
      // then calculate bridge's aperture of this type
      // and insert it into the respective resource tree.
      // If no, delete this resource bridge
      //
      if (ResourceRequestExisted (Mem64Bridge)) {
        InsertResourceNode (
          Mem64Node,
          Mem64Bridge
          );
      } else {
        FreePool (Mem64Bridge);
        Mem64Bridge = NULL;
      }

      //
      // If there is node under this resource bridge,
      // then calculate bridge's aperture of this type
      // and insert it into the respective resource tree.
      // If no, delete this resource bridge
      //
      if (ResourceRequestExisted (PMem64Bridge)) {
        InsertResourceNode (
          PMem64Node,
          PMem64Bridge
          );
      } else {
        FreePool (PMem64Bridge);
        PMem64Bridge = NULL;
      }
    }

    //
    // If it is P2C, apply hard coded resource padding
    //
    if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {
      ResourcePaddingForCardBusBridge (
        Temp,
        IoNode,
        Mem32Node,
        PMem32Node,
        Mem64Node,
        PMem64Node
        );
    }

    CurrentLink = CurrentLink->ForwardLink;
  }

  //
  // To do some platform specific resource padding ...
  //
  ResourcePaddingPolicy (
    Bridge,
    IoNode,
    Mem32Node,
    PMem32Node,
    Mem64Node,
    PMem64Node
    );

  //
  // Degrade resource if necessary
  //
  DegradeResource (
    Bridge,
    Mem32Node,
    PMem32Node,
    Mem64Node,
    PMem64Node
    );

  //
  // Calculate resource aperture for this bridge device
  //
  CalculateResourceAperture (Mem32Node);
  CalculateResourceAperture (PMem32Node);
  CalculateResourceAperture (Mem64Node);
  CalculateResourceAperture (PMem64Node);
  CalculateResourceAperture (IoNode);
}

/**
  This function is used to do the resource padding for a specific platform.

  @param PciDev     Pci device instance.
  @param IoNode     Resource info node for IO.
  @param Mem32Node  Resource info node for 32-bit memory.
  @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
  @param Mem64Node  Resource info node for 64-bit memory.
  @param PMem64Node Resource info node for 64-bit Prefetchable Memory.

**/
VOID
ResourcePaddingPolicy (
  IN PCI_IO_DEVICE      *PciDev,
  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
  )
{
  //
  // Create padding resource node
  //
  if (PciDev->ResourcePaddingDescriptors != NULL) {
    ApplyResourcePadding (
      PciDev,
      IoNode,
      Mem32Node,
      PMem32Node,
      Mem64Node,
      PMem64Node
      );
  }
}

/**
  This function is used to degrade resource if the upstream bridge
  doesn't support certain resource. Degradation path is
  PMEM64 -> MEM64  -> MEM32
  PMEM64 -> PMEM32 -> MEM32
  IO32   -> IO16.

  @param Bridge     Pci device instance.
  @param Mem32Node  Resource info node for 32-bit memory.
  @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
  @param Mem64Node  Resource info node for 64-bit memory.
  @param PMem64Node Resource info node for 64-bit Prefetchable Memory.

**/
VOID
DegradeResource (
  IN PCI_IO_DEVICE      *Bridge,
  IN PCI_RESOURCE_NODE  *Mem32Node,
  IN PCI_RESOURCE_NODE  *PMem32Node,
  IN PCI_RESOURCE_NODE  *Mem64Node,
  IN PCI_RESOURCE_NODE  *PMem64Node
  )
{
  PCI_IO_DEVICE      *PciIoDevice;
  LIST_ENTRY         *ChildDeviceLink;
  LIST_ENTRY         *ChildNodeLink;
  LIST_ENTRY         *NextChildNodeLink;
  PCI_RESOURCE_NODE  *ResourceNode;

  if (FeaturePcdGet (PcdPciDegradeResourceForOptionRom)) {
    //
    // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64
    // requests in case that if a legacy option ROM image can not access 64-bit resources.
    //
    ChildDeviceLink = Bridge->ChildList.ForwardLink;
    while (ChildDeviceLink != NULL && ChildDeviceLink != &Bridge->ChildList) {
      PciIoDevice = PCI_IO_DEVICE_FROM_LINK (ChildDeviceLink);
      if (PciIoDevice->RomSize != 0) {
        if (!IsListEmpty (&Mem64Node->ChildList)) {
          ChildNodeLink = Mem64Node->ChildList.ForwardLink;
          while (ChildNodeLink != &Mem64Node->ChildList) {
            ResourceNode      = RESOURCE_NODE_FROM_LINK (ChildNodeLink);
            NextChildNodeLink = ChildNodeLink->ForwardLink;

            if ((ResourceNode->PciDev == PciIoDevice) &&
                (ResourceNode->Virtual || !PciIoDevice->PciBar[ResourceNode->Bar].BarTypeFixed)
                )
            {
              RemoveEntryList (ChildNodeLink);
              InsertResourceNode (Mem32Node, ResourceNode);
            }

            ChildNodeLink = NextChildNodeLink;
          }
        }

        if (!IsListEmpty (&PMem64Node->ChildList)) {
          ChildNodeLink = PMem64Node->ChildList.ForwardLink;
          while (ChildNodeLink != &PMem64Node->ChildList) {
            ResourceNode      = RESOURCE_NODE_FROM_LINK (ChildNodeLink);
            NextChildNodeLink = ChildNodeLink->ForwardLink;

            if ((ResourceNode->PciDev == PciIoDevice) &&
                (ResourceNode->Virtual || !PciIoDevice->PciBar[ResourceNode->Bar].BarTypeFixed)
                )
            {
              RemoveEntryList (ChildNodeLink);
              InsertResourceNode (PMem32Node, ResourceNode);
            }

            ChildNodeLink = NextChildNodeLink;
          }
        }
      }

      ChildDeviceLink = ChildDeviceLink->ForwardLink;
    }
  }

  //
  // If firmware is in 32-bit mode,
  // then degrade PMEM64/MEM64 requests
  //
  if (sizeof (UINTN) <= 4) {
    MergeResourceTree (
      Mem32Node,
      Mem64Node,
      TRUE
      );

    MergeResourceTree (
      PMem32Node,
      PMem64Node,
      TRUE
      );
  } else {
    //
    // if the bridge does not support MEM64, degrade MEM64 to MEM32
    //
    if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {
      MergeResourceTree (
        Mem32Node,
        Mem64Node,
        TRUE
        );
    }

    //
    // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32
    //
    if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {
      MergeResourceTree (
        PMem32Node,
        PMem64Node,
        TRUE
        );
    }

    //
    // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied
    // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32.
    //
    if (!IsListEmpty (&PMem64Node->ChildList) && (Bridge->Parent != NULL)) {
      MergeResourceTree (
        Mem32Node,
        PMem32Node,
        TRUE
        );
    }
  }

  //
  // If bridge doesn't support Pmem32
  // degrade it to mem32
  //
  if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED)) {
    MergeResourceTree (
      Mem32Node,
      PMem32Node,
      TRUE
      );
  }

  //
  // if root bridge supports combined Pmem Mem decoding
  // merge these two type of resource
  //
  if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) {
    MergeResourceTree (
      Mem32Node,
      PMem32Node,
      FALSE
      );

    //
    // No need to check if to degrade MEM64 after merge, because
    // if there are PMEM64 still here, 64-bit decode should be supported
    // by the root bride.
    //
    MergeResourceTree (
      Mem64Node,
      PMem64Node,
      FALSE
      );
  }
}

/**
  Test whether bridge device support decode resource.

  @param Bridge    Bridge device instance.
  @param Decode    Decode type according to resource type.

  @return TRUE     The bridge device support decode resource.
  @return FALSE    The bridge device don't support decode resource.

**/
BOOLEAN
BridgeSupportResourceDecode (
  IN PCI_IO_DEVICE  *Bridge,
  IN UINT32         Decode
  )
{
  if (((Bridge->Decodes) & Decode) != 0) {
    return TRUE;
  }

  return FALSE;
}

/**
  This function is used to program the resource allocated
  for each resource node under specified bridge.

  @param Base     Base address of resource to be programmed.
  @param Bridge   PCI resource node for the bridge device.

  @retval EFI_SUCCESS            Successfully to program all resources
                                 on given PCI bridge device.
  @retval EFI_OUT_OF_RESOURCES   Base is all one.

**/
EFI_STATUS
ProgramResource (
  IN UINT64             Base,
  IN PCI_RESOURCE_NODE  *Bridge
  )
{
  LIST_ENTRY         *CurrentLink;
  PCI_RESOURCE_NODE  *Node;
  EFI_STATUS         Status;

  if (Base == gAllOne) {
    return EFI_OUT_OF_RESOURCES;
  }

  CurrentLink = Bridge->ChildList.ForwardLink;

  while (CurrentLink != &Bridge->ChildList) {
    Node = RESOURCE_NODE_FROM_LINK (CurrentLink);

    if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci))) {
      if (IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {
        //
        // Program the PCI Card Bus device
        //
        ProgramP2C (Base, Node);
      } else {
        //
        // Program the PCI device BAR
        //
        ProgramBar (Base, Node);
      }
    } else {
      //
      // Program the PCI devices under this bridge
      //
      Status = ProgramResource (Base + Node->Offset, Node);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      ProgramPpbApperture (Base, Node);
    }

    CurrentLink = CurrentLink->ForwardLink;
  }

  return EFI_SUCCESS;
}

/**
  Program Bar register for PCI device.

  @param Base  Base address for PCI device resource to be programmed.
  @param Node  Point to resource node structure.

**/
VOID
ProgramBar (
  IN UINT64             Base,
  IN PCI_RESOURCE_NODE  *Node
  )
{
  EFI_PCI_IO_PROTOCOL  *PciIo;
  UINT64               Address;
  UINT32               Address32;

  ASSERT (Node->Bar < PCI_MAX_BAR);

  //
  // Check VF BAR
  //
  if (Node->Virtual) {
    ProgramVfBar (Base, Node);
    return;
  }

  Address = 0;
  PciIo   = &(Node->PciDev->PciIo);

  Address = Base + Node->Offset;

  //
  // Indicate pci bus driver has allocated
  // resource for this device
  // It might be a temporary solution here since
  // pci device could have multiple bar
  //
  Node->PciDev->Allocated = TRUE;

  switch ((Node->PciDev->PciBar[Node->Bar]).BarType) {
    case PciBarTypeIo16:
    case PciBarTypeIo32:
    case PciBarTypeMem32:
    case PciBarTypePMem32:

      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   (Node->PciDev->PciBar[Node->Bar]).Offset,
                   1,
                   &Address
                   );
    //
    // Continue to the case PciBarTypeOpRom to set the BaseAddress.
    // PciBarTypeOpRom is a virtual BAR only in root bridge, to capture
    // the MEM32 resource requirement for Option ROM shadow.
    //

    case PciBarTypeOpRom:
      Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

      break;

    case PciBarTypeMem64:
    case PciBarTypePMem64:

      Address32 = (UINT32)(Address & 0x00000000FFFFFFFF);

      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   (Node->PciDev->PciBar[Node->Bar]).Offset,
                   1,
                   &Address32
                   );

      Address32 = (UINT32)RShiftU64 (Address, 32);

      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   (UINT8)((Node->PciDev->PciBar[Node->Bar]).Offset + 4),
                   1,
                   &Address32
                   );

      Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

      break;

    default:
      break;
  }
}

/**
  Program IOV VF Bar register for PCI device.

  @param Base  Base address for PCI device resource to be programmed.
  @param Node  Point to resource node structure.

**/
EFI_STATUS
ProgramVfBar (
  IN UINT64             Base,
  IN PCI_RESOURCE_NODE  *Node
  )
{
  EFI_PCI_IO_PROTOCOL  *PciIo;
  UINT64               Address;
  UINT32               Address32;

  ASSERT (Node->Bar < PCI_MAX_BAR);
  ASSERT (Node->Virtual);

  Address = 0;
  PciIo   = &(Node->PciDev->PciIo);

  Address = Base + Node->Offset;

  //
  // Indicate pci bus driver has allocated
  // resource for this device
  // It might be a temporary solution here since
  // pci device could have multiple bar
  //
  Node->PciDev->Allocated = TRUE;

  switch ((Node->PciDev->VfPciBar[Node->Bar]).BarType) {
    case PciBarTypeMem32:
    case PciBarTypePMem32:

      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   (Node->PciDev->VfPciBar[Node->Bar]).Offset,
                   1,
                   &Address
                   );

      Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address;
      break;

    case PciBarTypeMem64:
    case PciBarTypePMem64:

      Address32 = (UINT32)(Address & 0x00000000FFFFFFFF);

      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   (Node->PciDev->VfPciBar[Node->Bar]).Offset,
                   1,
                   &Address32
                   );

      Address32 = (UINT32)RShiftU64 (Address, 32);

      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   ((Node->PciDev->VfPciBar[Node->Bar]).Offset + 4),
                   1,
                   &Address32
                   );

      Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address;
      break;

    case PciBarTypeIo16:
    case PciBarTypeIo32:
      break;

    default:
      break;
  }

  return EFI_SUCCESS;
}

/**
  Program PCI-PCI bridge aperture.

  @param Base  Base address for resource.
  @param Node  Point to resource node structure.

**/
VOID
ProgramPpbApperture (
  IN UINT64             Base,
  IN PCI_RESOURCE_NODE  *Node
  )
{
  EFI_PCI_IO_PROTOCOL  *PciIo;
  UINT64               Address;
  UINT32               Address32;

  Address = 0;
  //
  // If no device resource of this PPB, return anyway
  // Aperture is set default in the initialization code
  //
  if ((Node->Length == 0) || (Node->ResourceUsage == PciResUsagePadding)) {
    //
    // For padding resource node, just ignore when programming
    //
    return;
  }

  PciIo   = &(Node->PciDev->PciIo);
  Address = Base + Node->Offset;

  //
  // Indicate the PPB resource has been allocated
  //
  Node->PciDev->Allocated = TRUE;

  switch (Node->Bar) {
    case PPB_BAR_0:
    case PPB_BAR_1:
      switch ((Node->PciDev->PciBar[Node->Bar]).BarType) {
        case PciBarTypeIo16:
        case PciBarTypeIo32:
        case PciBarTypeMem32:
        case PciBarTypePMem32:

          PciIo->Pci.Write (
                       PciIo,
                       EfiPciIoWidthUint32,
                       (Node->PciDev->PciBar[Node->Bar]).Offset,
                       1,
                       &Address
                       );

          Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
          Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;
          break;

        case PciBarTypeMem64:
        case PciBarTypePMem64:

          Address32 = (UINT32)(Address & 0x00000000FFFFFFFF);

          PciIo->Pci.Write (
                       PciIo,
                       EfiPciIoWidthUint32,
                       (Node->PciDev->PciBar[Node->Bar]).Offset,
                       1,
                       &Address32
                       );

          Address32 = (UINT32)RShiftU64 (Address, 32);

          PciIo->Pci.Write (
                       PciIo,
                       EfiPciIoWidthUint32,
                       (UINT8)((Node->PciDev->PciBar[Node->Bar]).Offset + 4),
                       1,
                       &Address32
                       );

          Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
          Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;
          break;

        default:
          break;
      }

      break;

    case PPB_IO_RANGE:

      Address32 = ((UINT32)(Address)) >> 8;
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint8,
                   0x1C,
                   1,
                   &Address32
                   );

      Address32 >>= 8;
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint16,
                   0x30,
                   1,
                   &Address32
                   );

      Address32 = (UINT32)(Address + Node->Length - 1);
      Address32 = ((UINT32)(Address32)) >> 8;
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint8,
                   0x1D,
                   1,
                   &Address32
                   );

      Address32 >>= 8;
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint16,
                   0x32,
                   1,
                   &Address32
                   );

      Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
      Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;
      break;

    case PPB_MEM32_RANGE:

      Address32 = ((UINT32)(Address)) >> 16;
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint16,
                   0x20,
                   1,
                   &Address32
                   );

      Address32 = (UINT32)(Address + Node->Length - 1);
      Address32 = ((UINT32)(Address32)) >> 16;
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint16,
                   0x22,
                   1,
                   &Address32
                   );

      Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
      Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;
      break;

    case PPB_PMEM32_RANGE:
    case PPB_PMEM64_RANGE:

      Address32 = ((UINT32)(Address)) >> 16;
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint16,
                   0x24,
                   1,
                   &Address32
                   );

      Address32 = (UINT32)(Address + Node->Length - 1);
      Address32 = ((UINT32)(Address32)) >> 16;
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint16,
                   0x26,
                   1,
                   &Address32
                   );

      Address32 = (UINT32)RShiftU64 (Address, 32);
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   0x28,
                   1,
                   &Address32
                   );

      Address32 = (UINT32)RShiftU64 ((Address + Node->Length - 1), 32);
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   0x2C,
                   1,
                   &Address32
                   );

      Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
      Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;
      break;

    default:
      break;
  }
}

/**
  Program parent bridge for Option Rom.

  @param PciDevice      Pci device instance.
  @param OptionRomBase  Base address for Option Rom.
  @param Enable         Enable or disable PCI memory.

**/
VOID
ProgramUpstreamBridgeForRom (
  IN PCI_IO_DEVICE  *PciDevice,
  IN UINT32         OptionRomBase,
  IN BOOLEAN        Enable
  )
{
  PCI_IO_DEVICE        *Parent;
  EFI_PCI_IO_PROTOCOL  *PciIo;
  UINT16               Base;
  UINT16               Limit;

  //
  // For root bridge, just return.
  //
  Parent = PciDevice->Parent;
  while (Parent != NULL) {
    if (!IS_PCI_BRIDGE (&Parent->Pci)) {
      break;
    }

    PciIo = &Parent->PciIo;

    //
    // Program PPB to only open a single <= 16MB aperture
    //
    if (Enable) {
      //
      // Only cover MMIO for Option ROM.
      //
      Base  = (UINT16)(OptionRomBase >> 16);
      Limit = (UINT16)((OptionRomBase + PciDevice->RomSize - 1) >> 16);
      PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), 1, &Base);
      PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), 1, &Limit);

      PCI_ENABLE_COMMAND_REGISTER (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);
    } else {
      //
      // Cover 32bit MMIO for devices below the bridge.
      //
      if (Parent->PciBar[PPB_MEM32_RANGE].Length == 0) {
        //
        // When devices under the bridge contains Option ROM and doesn't require 32bit MMIO.
        //
        Base  = (UINT16)gAllOne;
        Limit = (UINT16)gAllZero;
      } else {
        Base  = (UINT16)((UINT32)Parent->PciBar[PPB_MEM32_RANGE].BaseAddress >> 16);
        Limit = (UINT16)((UINT32)(Parent->PciBar[PPB_MEM32_RANGE].BaseAddress
                                  + Parent->PciBar[PPB_MEM32_RANGE].Length - 1) >> 16);
      }

      PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), 1, &Base);
      PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), 1, &Limit);

      PCI_DISABLE_COMMAND_REGISTER (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);
    }

    Parent = Parent->Parent;
  }
}

/**
  Test whether resource exists for a bridge.

  @param Bridge  Point to resource node for a bridge.

  @retval TRUE   There is resource on the given bridge.
  @retval FALSE  There isn't resource on the given bridge.

**/
BOOLEAN
ResourceRequestExisted (
  IN PCI_RESOURCE_NODE  *Bridge
  )
{
  if (Bridge != NULL) {
    if (!IsListEmpty (&Bridge->ChildList) || (Bridge->Length != 0)) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Initialize resource pool structure.

  @param ResourcePool Point to resource pool structure. This pool
                      is reset to all zero when returned.
  @param ResourceType Type of resource.

**/
VOID
InitializeResourcePool (
  IN OUT PCI_RESOURCE_NODE  *ResourcePool,
  IN     PCI_BAR_TYPE       ResourceType
  )
{
  ZeroMem (ResourcePool, sizeof (PCI_RESOURCE_NODE));
  ResourcePool->ResType   = ResourceType;
  ResourcePool->Signature = PCI_RESOURCE_SIGNATURE;
  InitializeListHead (&ResourcePool->ChildList);
}

/**
  Destroy given resource tree.

  @param Bridge  PCI resource root node of resource tree.

**/
VOID
DestroyResourceTree (
  IN PCI_RESOURCE_NODE  *Bridge
  )
{
  PCI_RESOURCE_NODE  *Temp;
  LIST_ENTRY         *CurrentLink;

  while (!IsListEmpty (&Bridge->ChildList)) {
    CurrentLink = Bridge->ChildList.ForwardLink;

    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);
    ASSERT (Temp);

    RemoveEntryList (CurrentLink);

    if (IS_PCI_BRIDGE (&(Temp->PciDev->Pci))) {
      DestroyResourceTree (Temp);
    }

    FreePool (Temp);
  }
}

/**
  Insert resource padding for P2C.

  @param PciDev     Pci device instance.
  @param IoNode     Resource info node for IO.
  @param Mem32Node  Resource info node for 32-bit memory.
  @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
  @param Mem64Node  Resource info node for 64-bit memory.
  @param PMem64Node Resource info node for 64-bit Prefetchable Memory.

**/
VOID
ResourcePaddingForCardBusBridge (
  IN PCI_IO_DEVICE      *PciDev,
  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
  )
{
  PCI_RESOURCE_NODE  *Node;

  Node = NULL;

  //
  // Memory Base/Limit Register 0
  // Bar 1 decodes memory range 0
  //
  Node = CreateResourceNode (
           PciDev,
           0x2000000,
           0x1ffffff,
           1,
           PciBarTypeMem32,
           PciResUsagePadding
           );

  InsertResourceNode (
    Mem32Node,
    Node
    );

  //
  // Memory Base/Limit Register 1
  // Bar 2 decodes memory range1
  //
  Node = CreateResourceNode (
           PciDev,
           0x2000000,
           0x1ffffff,
           2,
           PciBarTypePMem32,
           PciResUsagePadding
           );

  InsertResourceNode (
    PMem32Node,
    Node
    );

  //
  // Io Base/Limit
  // Bar 3 decodes io range 0
  //
  Node = CreateResourceNode (
           PciDev,
           0x100,
           0xff,
           3,
           PciBarTypeIo16,
           PciResUsagePadding
           );

  InsertResourceNode (
    IoNode,
    Node
    );

  //
  // Io Base/Limit
  // Bar 4 decodes io range 0
  //
  Node = CreateResourceNode (
           PciDev,
           0x100,
           0xff,
           4,
           PciBarTypeIo16,
           PciResUsagePadding
           );

  InsertResourceNode (
    IoNode,
    Node
    );
}

/**
  Program PCI Card device register for given resource node.

  @param Base    Base address of PCI Card device to be programmed.
  @param Node    Given resource node.

**/
VOID
ProgramP2C (
  IN UINT64             Base,
  IN PCI_RESOURCE_NODE  *Node
  )
{
  EFI_PCI_IO_PROTOCOL  *PciIo;
  UINT64               Address;
  UINT64               TempAddress;
  UINT16               BridgeControl;

  Address = 0;
  PciIo   = &(Node->PciDev->PciIo);

  Address = Base + Node->Offset;

  //
  // Indicate pci bus driver has allocated
  // resource for this device
  // It might be a temporary solution here since
  // pci device could have multiple bar
  //
  Node->PciDev->Allocated = TRUE;

  switch (Node->Bar) {
    case P2C_BAR_0:
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   (Node->PciDev->PciBar[Node->Bar]).Offset,
                   1,
                   &Address
                   );

      Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
      Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;
      break;

    case P2C_MEM_1:
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   PCI_CARD_MEMORY_BASE_0,
                   1,
                   &Address
                   );

      TempAddress = Address + Node->Length - 1;
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   PCI_CARD_MEMORY_LIMIT_0,
                   1,
                   &TempAddress
                   );

      if (Node->ResType == PciBarTypeMem32) {
        //
        // Set non-prefetchable bit
        //
        PciIo->Pci.Read (
                     PciIo,
                     EfiPciIoWidthUint16,
                     PCI_CARD_BRIDGE_CONTROL,
                     1,
                     &BridgeControl
                     );

        BridgeControl &= (UINT16) ~PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE;
        PciIo->Pci.Write (
                     PciIo,
                     EfiPciIoWidthUint16,
                     PCI_CARD_BRIDGE_CONTROL,
                     1,
                     &BridgeControl
                     );
      } else {
        //
        // Set prefetchable bit
        //
        PciIo->Pci.Read (
                     PciIo,
                     EfiPciIoWidthUint16,
                     PCI_CARD_BRIDGE_CONTROL,
                     1,
                     &BridgeControl
                     );

        BridgeControl |= PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE;
        PciIo->Pci.Write (
                     PciIo,
                     EfiPciIoWidthUint16,
                     PCI_CARD_BRIDGE_CONTROL,
                     1,
                     &BridgeControl
                     );
      }

      Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
      Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;
      Node->PciDev->PciBar[Node->Bar].BarType     = Node->ResType;

      break;

    case P2C_MEM_2:
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   PCI_CARD_MEMORY_BASE_1,
                   1,
                   &Address
                   );

      TempAddress = Address + Node->Length - 1;

      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   PCI_CARD_MEMORY_LIMIT_1,
                   1,
                   &TempAddress
                   );

      if (Node->ResType == PciBarTypeMem32) {
        //
        // Set non-prefetchable bit
        //
        PciIo->Pci.Read (
                     PciIo,
                     EfiPciIoWidthUint16,
                     PCI_CARD_BRIDGE_CONTROL,
                     1,
                     &BridgeControl
                     );

        BridgeControl &= (UINT16) ~(PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE);
        PciIo->Pci.Write (
                     PciIo,
                     EfiPciIoWidthUint16,
                     PCI_CARD_BRIDGE_CONTROL,
                     1,
                     &BridgeControl
                     );
      } else {
        //
        // Set prefetchable bit
        //
        PciIo->Pci.Read (
                     PciIo,
                     EfiPciIoWidthUint16,
                     PCI_CARD_BRIDGE_CONTROL,
                     1,
                     &BridgeControl
                     );

        BridgeControl |= PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE;
        PciIo->Pci.Write (
                     PciIo,
                     EfiPciIoWidthUint16,
                     PCI_CARD_BRIDGE_CONTROL,
                     1,
                     &BridgeControl
                     );
      }

      Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
      Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;
      Node->PciDev->PciBar[Node->Bar].BarType     = Node->ResType;
      break;

    case P2C_IO_1:
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   PCI_CARD_IO_BASE_0_LOWER,
                   1,
                   &Address
                   );

      TempAddress = Address + Node->Length - 1;
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   PCI_CARD_IO_LIMIT_0_LOWER,
                   1,
                   &TempAddress
                   );

      Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
      Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;
      Node->PciDev->PciBar[Node->Bar].BarType     = Node->ResType;

      break;

    case P2C_IO_2:
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   PCI_CARD_IO_BASE_1_LOWER,
                   1,
                   &Address
                   );

      TempAddress = Address + Node->Length - 1;
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint32,
                   PCI_CARD_IO_LIMIT_1_LOWER,
                   1,
                   &TempAddress
                   );

      Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;
      Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;
      Node->PciDev->PciBar[Node->Bar].BarType     = Node->ResType;
      break;

    default:
      break;
  }
}

/**
  Create padding resource node.

  @param PciDev     Pci device instance.
  @param IoNode     Resource info node for IO.
  @param Mem32Node  Resource info node for 32-bit memory.
  @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
  @param Mem64Node  Resource info node for 64-bit memory.
  @param PMem64Node Resource info node for 64-bit Prefetchable Memory.

**/
VOID
ApplyResourcePadding (
  IN PCI_IO_DEVICE      *PciDev,
  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
  )
{
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Ptr;
  PCI_RESOURCE_NODE                  *Node;
  UINT8                              DummyBarIndex;

  DummyBarIndex = 0;
  Ptr           = PciDev->ResourcePaddingDescriptors;

  while (((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Desc != ACPI_END_TAG_DESCRIPTOR) {
    if ((Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) && (Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO)) {
      if (Ptr->AddrLen != 0) {
        Node = CreateResourceNode (
                 PciDev,
                 Ptr->AddrLen,
                 Ptr->AddrRangeMax,
                 DummyBarIndex,
                 PciBarTypeIo16,
                 PciResUsagePadding
                 );
        InsertResourceNode (
          IoNode,
          Node
          );
      }

      Ptr++;
      continue;
    }

    if ((Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) && (Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM)) {
      if (Ptr->AddrSpaceGranularity == 32) {
        //
        // prefetchable
        //
        if (Ptr->SpecificFlag == 0x6) {
          if (Ptr->AddrLen != 0) {
            Node = CreateResourceNode (
                     PciDev,
                     Ptr->AddrLen,
                     Ptr->AddrRangeMax,
                     DummyBarIndex,
                     PciBarTypePMem32,
                     PciResUsagePadding
                     );
            InsertResourceNode (
              PMem32Node,
              Node
              );
          }

          Ptr++;
          continue;
        }

        //
        // Non-prefetchable
        //
        if (Ptr->SpecificFlag == 0) {
          if (Ptr->AddrLen != 0) {
            Node = CreateResourceNode (
                     PciDev,
                     Ptr->AddrLen,
                     Ptr->AddrRangeMax,
                     DummyBarIndex,
                     PciBarTypeMem32,
                     PciResUsagePadding
                     );
            InsertResourceNode (
              Mem32Node,
              Node
              );
          }

          Ptr++;
          continue;
        }
      }

      if (Ptr->AddrSpaceGranularity == 64) {
        //
        // prefetchable
        //
        if (Ptr->SpecificFlag == 0x6) {
          if (Ptr->AddrLen != 0) {
            Node = CreateResourceNode (
                     PciDev,
                     Ptr->AddrLen,
                     Ptr->AddrRangeMax,
                     DummyBarIndex,
                     PciBarTypePMem64,
                     PciResUsagePadding
                     );
            InsertResourceNode (
              PMem64Node,
              Node
              );
          }

          Ptr++;
          continue;
        }

        //
        // Non-prefetchable
        //
        if (Ptr->SpecificFlag == 0) {
          if (Ptr->AddrLen != 0) {
            Node = CreateResourceNode (
                     PciDev,
                     Ptr->AddrLen,
                     Ptr->AddrRangeMax,
                     DummyBarIndex,
                     PciBarTypeMem64,
                     PciResUsagePadding
                     );
            InsertResourceNode (
              Mem64Node,
              Node
              );
          }

          Ptr++;
          continue;
        }
      }
    }

    Ptr++;
  }
}

/**
  Get padding resource for PCI-PCI bridge.

  @param  PciIoDevice     PCI-PCI bridge device instance.

  @note   Feature flag PcdPciBusHotplugDeviceSupport determines
          whether need to pad resource for them.
**/
VOID
GetResourcePaddingPpb (
  IN  PCI_IO_DEVICE  *PciIoDevice
  )
{
  if ((gPciHotPlugInit != NULL) && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
    if (PciIoDevice->ResourcePaddingDescriptors == NULL) {
      GetResourcePaddingForHpb (PciIoDevice);
    }
  }
}
