diff --git a/ArmVirtPkg/PciHostBridgeDxe/PciHostBridge.c b/ArmVirtPkg/PciHostBridgeDxe/PciHostBridge.c
deleted file mode 100644
index 669c903..0000000
--- a/ArmVirtPkg/PciHostBridgeDxe/PciHostBridge.c
+++ /dev/null
@@ -1,1458 +0,0 @@
-/** @file
-  Provides the basic interfaces to abstract a PCI Host Bridge Resource Allocation
-
-Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials are
-licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "PciHostBridge.h"
-
-//
-// Hard code: Root Bridge Number within the host bridge
-//            Root Bridge's attribute
-//            Root Bridge's device path
-//            Root Bridge's resource aperture
-//
-UINTN RootBridgeNumber[1] = { 1 };
-
-UINT64 RootBridgeAttribute[1][1] = { { EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM } };
-
-EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[1][1] = {
-  {
-    {
-      {
-        {
-          ACPI_DEVICE_PATH,
-          ACPI_DP,
-          {
-            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
-            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
-          }
-        },
-        EISA_PNP_ID(0x0A03),
-        0
-      },
-
-      {
-        END_DEVICE_PATH_TYPE,
-        END_ENTIRE_DEVICE_PATH_SUBTYPE,
-        {
-          END_DEVICE_PATH_LENGTH,
-          0
-        }
-      }
-    }
-  }
-};
-
-STATIC PCI_ROOT_BRIDGE_RESOURCE_APERTURE  mResAperture[1][1];
-
-EFI_HANDLE mDriverImageHandle;
-
-PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = {
-  PCI_HOST_BRIDGE_SIGNATURE,  // Signature
-  NULL,                       // HostBridgeHandle
-  0,                          // RootBridgeNumber
-  {NULL, NULL},               // Head
-  FALSE,                      // ResourceSubiteed
-  TRUE,                       // CanRestarted
-  {
-    NotifyPhase,
-    GetNextRootBridge,
-    GetAttributes,
-    StartBusEnumeration,
-    SetBusNumbers,
-    SubmitResources,
-    GetProposedResources,
-    PreprocessController
-  }
-};
-
-//
-// Implementation
-//
-
-//
-// We expect the "ranges" property of "pci-host-ecam-generic" to consist of
-// records like this.
-//
-#pragma pack (1)
-typedef struct {
-  UINT32 Type;
-  UINT64 ChildBase;
-  UINT64 CpuBase;
-  UINT64 Size;
-} DTB_PCI_HOST_RANGE_RECORD;
-#pragma pack ()
-
-#define DTB_PCI_HOST_RANGE_RELOCATABLE  BIT31
-#define DTB_PCI_HOST_RANGE_PREFETCHABLE BIT30
-#define DTB_PCI_HOST_RANGE_ALIASED      BIT29
-#define DTB_PCI_HOST_RANGE_MMIO32       BIT25
-#define DTB_PCI_HOST_RANGE_MMIO64       (BIT25 | BIT24)
-#define DTB_PCI_HOST_RANGE_IO           BIT24
-#define DTB_PCI_HOST_RANGE_TYPEMASK     (BIT31 | BIT30 | BIT29 | BIT25 | BIT24)
-
-STATIC
-EFI_STATUS
-ProcessPciHost (
-  OUT  UINT64    *IoBase,
-  OUT  UINT64    *IoSize,
-  OUT  UINT64    *IoTranslation,
-  OUT  UINT64    *MmioBase,
-  OUT  UINT64    *MmioSize,
-  OUT  UINT64    *MmioTranslation,
-  OUT  UINT32    *BusMin,
-  OUT  UINT32    *BusMax
-  )
-{
-  FDT_CLIENT_PROTOCOL         *FdtClient;
-  INT32                       Node;
-  UINT64                      ConfigBase, ConfigSize;
-  CONST VOID                  *Prop;
-  UINT32                      Len;
-  UINT32                      RecordIdx;
-  EFI_STATUS                  Status;
-
-  //
-  // The following output arguments are initialized only in
-  // order to suppress '-Werror=maybe-uninitialized' warnings
-  // *incorrectly* emitted by some gcc versions.
-  //
-  *IoBase = 0;
-  *IoTranslation = 0;
-  *MmioBase = 0;
-  *MmioTranslation = 0;
-  *BusMin = 0;
-  *BusMax = 0;
-
-  //
-  // *IoSize and *MmioSize are initialized to zero because the logic below
-  // requires it. However, since they are also affected by the issue reported
-  // above, they are initialized early.
-  //
-  *IoSize = 0;
-  *MmioSize = 0;
-
-  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
-                  (VOID **)&FdtClient);
-  ASSERT_EFI_ERROR (Status);
-
-  Status = FdtClient->FindCompatibleNode (FdtClient, "pci-host-ecam-generic",
-                        &Node);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_INFO,
-      "%a: No 'pci-host-ecam-generic' compatible DT node found\n",
-      __FUNCTION__));
-    return EFI_NOT_FOUND;
-  }
-
-  DEBUG_CODE (
-    INT32 Tmp;
-
-    //
-    // A DT can legally describe multiple PCI host bridges, but we are not
-    // equipped to deal with that. So assert that there is only one.
-    //
-    Status = FdtClient->FindNextCompatibleNode (FdtClient,
-                          "pci-host-ecam-generic", Node, &Tmp);
-    ASSERT (Status == EFI_NOT_FOUND);
-  );
-
-  Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg", &Prop, &Len);
-  if (EFI_ERROR (Status) || Len != 2 * sizeof (UINT64)) {
-    DEBUG ((EFI_D_ERROR, "%a: 'reg' property not found or invalid\n",
-      __FUNCTION__));
-    return EFI_PROTOCOL_ERROR;
-  }
-
-  //
-  // Fetch the ECAM window.
-  //
-  ConfigBase = SwapBytes64 (((CONST UINT64 *)Prop)[0]);
-  ConfigSize = SwapBytes64 (((CONST UINT64 *)Prop)[1]);
-
-  //
-  // Fetch the bus range (note: inclusive).
-  //
-  Status = FdtClient->GetNodeProperty (FdtClient, Node, "bus-range", &Prop,
-                        &Len);
-  if (EFI_ERROR (Status) || Len != 2 * sizeof (UINT32)) {
-    DEBUG ((EFI_D_ERROR, "%a: 'bus-range' not found or invalid\n",
-      __FUNCTION__));
-    return EFI_PROTOCOL_ERROR;
-  }
-  *BusMin = SwapBytes32 (((CONST UINT32 *)Prop)[0]);
-  *BusMax = SwapBytes32 (((CONST UINT32 *)Prop)[1]);
-
-  //
-  // Sanity check: the config space must accommodate all 4K register bytes of
-  // all 8 functions of all 32 devices of all buses.
-  //
-  if (*BusMax < *BusMin || *BusMax - *BusMin == MAX_UINT32 ||
-      DivU64x32 (ConfigSize, SIZE_4KB * 8 * 32) < *BusMax - *BusMin + 1) {
-    DEBUG ((EFI_D_ERROR, "%a: invalid 'bus-range' and/or 'reg'\n",
-      __FUNCTION__));
-    return EFI_PROTOCOL_ERROR;
-  }
-
-  //
-  // Iterate over "ranges".
-  //
-  Status = FdtClient->GetNodeProperty (FdtClient, Node, "ranges", &Prop, &Len);
-  if (EFI_ERROR (Status) || Len == 0 ||
-      Len % sizeof (DTB_PCI_HOST_RANGE_RECORD) != 0) {
-    DEBUG ((EFI_D_ERROR, "%a: 'ranges' not found or invalid\n", __FUNCTION__));
-    return EFI_PROTOCOL_ERROR;
-  }
-
-  for (RecordIdx = 0; RecordIdx < Len / sizeof (DTB_PCI_HOST_RANGE_RECORD);
-       ++RecordIdx) {
-    CONST DTB_PCI_HOST_RANGE_RECORD *Record;
-
-    Record = (CONST DTB_PCI_HOST_RANGE_RECORD *)Prop + RecordIdx;
-    switch (SwapBytes32 (Record->Type) & DTB_PCI_HOST_RANGE_TYPEMASK) {
-    case DTB_PCI_HOST_RANGE_IO:
-      *IoBase = SwapBytes64 (Record->ChildBase);
-      *IoSize = SwapBytes64 (Record->Size);
-      *IoTranslation = SwapBytes64 (Record->CpuBase) - *IoBase;
-      break;
-
-    case DTB_PCI_HOST_RANGE_MMIO32:
-      *MmioBase = SwapBytes64 (Record->ChildBase);
-      *MmioSize = SwapBytes64 (Record->Size);
-      *MmioTranslation = SwapBytes64 (Record->CpuBase) - *MmioBase;
-
-      if (*MmioBase > MAX_UINT32 || *MmioSize > MAX_UINT32 ||
-          *MmioBase + *MmioSize > SIZE_4GB) {
-        DEBUG ((EFI_D_ERROR, "%a: MMIO32 space invalid\n", __FUNCTION__));
-        return EFI_PROTOCOL_ERROR;
-      }
-
-      if (*MmioTranslation != 0) {
-        DEBUG ((EFI_D_ERROR, "%a: unsupported nonzero MMIO32 translation "
-          "0x%Lx\n", __FUNCTION__, *MmioTranslation));
-        return EFI_UNSUPPORTED;
-      }
-
-      break;
-    }
-  }
-  if (*IoSize == 0 || *MmioSize == 0) {
-    DEBUG ((EFI_D_ERROR, "%a: %a space empty\n", __FUNCTION__,
-      (*IoSize == 0) ? "IO" : "MMIO32"));
-    return EFI_PROTOCOL_ERROR;
-  }
-
-  //
-  // The dynamic PCD PcdPciExpressBaseAddress should have already been set,
-  // and should match the value we found in the DT node.
-  //
-  ASSERT (PcdGet64 (PcdPciExpressBaseAddress) == ConfigBase);
-
-  DEBUG ((EFI_D_INFO, "%a: Config[0x%Lx+0x%Lx) Bus[0x%x..0x%x] "
-    "Io[0x%Lx+0x%Lx)@0x%Lx Mem[0x%Lx+0x%Lx)@0x%Lx\n", __FUNCTION__, ConfigBase,
-    ConfigSize, *BusMin, *BusMax, *IoBase, *IoSize, *IoTranslation, *MmioBase,
-    *MmioSize, *MmioTranslation));
-  return EFI_SUCCESS;
-}
-
-
-/**
-  Entry point of this driver
-
-  @param ImageHandle     Handle of driver image
-  @param SystemTable     Point to EFI_SYSTEM_TABLE
-
-  @retval EFI_ABORTED           PCI host bridge not present
-  @retval EFI_OUT_OF_RESOURCES  Can not allocate memory resource
-  @retval EFI_DEVICE_ERROR      Can not install the protocol instance
-  @retval EFI_SUCCESS           Success to initialize the Pci host bridge.
-**/
-EFI_STATUS
-EFIAPI
-InitializePciHostBridge (
-  IN EFI_HANDLE        ImageHandle,
-  IN EFI_SYSTEM_TABLE  *SystemTable
-  )
-{
-  UINT64                      MmioAttributes;
-  EFI_STATUS                  Status;
-  UINTN                       Loop1;
-  UINTN                       Loop2;
-  PCI_HOST_BRIDGE_INSTANCE    *HostBridge;
-  PCI_ROOT_BRIDGE_INSTANCE    *PrivateData;
-  UINT64                      IoBase, IoSize, IoTranslation;
-  UINT64                      MmioBase, MmioSize, MmioTranslation;
-  UINT32                      BusMin, BusMax;
-
-  if (PcdGet64 (PcdPciExpressBaseAddress) == 0) {
-    DEBUG ((EFI_D_INFO, "%a: PCI host bridge not present\n", __FUNCTION__));
-    return EFI_ABORTED;
-  }
-
-  Status = ProcessPciHost (&IoBase, &IoSize, &IoTranslation, &MmioBase,
-             &MmioSize, &MmioTranslation, &BusMin, &BusMax);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  mDriverImageHandle = ImageHandle;
-
-  mResAperture[0][0].BusBase  = BusMin;
-  mResAperture[0][0].BusLimit = BusMax;
-
-  mResAperture[0][0].MemBase  = MmioBase;
-  mResAperture[0][0].MemLimit = MmioBase + MmioSize - 1;
-
-  mResAperture[0][0].IoBase        = IoBase;
-  mResAperture[0][0].IoLimit       = IoBase + IoSize - 1;
-  mResAperture[0][0].IoTranslation = IoTranslation;
-
-  //
-  // Add IO and MMIO memory space, so that resources can be allocated in the
-  // EfiPciHostBridgeAllocateResources phase.
-  //
-  Status = gDS->AddIoSpace (
-                  EfiGcdIoTypeIo,
-                  IoBase,
-                  IoSize
-                  );
-  ASSERT_EFI_ERROR (Status);
-
-  MmioAttributes = EFI_MEMORY_UC;
-
-  Status = gDS->AddMemorySpace (
-                  EfiGcdMemoryTypeMemoryMappedIo,
-                  MmioBase,
-                  MmioSize,
-                  MmioAttributes
-                  );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_ERROR, "%a: AddMemorySpace: %r\n", __FUNCTION__, Status));
-    return Status;
-  }
-
-  Status = gDS->SetMemorySpaceAttributes (
-                  MmioBase,
-                  MmioSize,
-                  MmioAttributes
-                  );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_ERROR, "%a: SetMemorySpaceAttributes: %r\n", __FUNCTION__,
-      Status));
-    return Status;
-  }
-
-  //
-  // Create Host Bridge Device Handle
-  //
-  for (Loop1 = 0; Loop1 < HOST_BRIDGE_NUMBER; Loop1++) {
-    HostBridge = AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE), &mPciHostBridgeInstanceTemplate);
-    if (HostBridge == NULL) {
-      return EFI_OUT_OF_RESOURCES;
-    }
-
-    HostBridge->RootBridgeNumber = RootBridgeNumber[Loop1];
-    InitializeListHead (&HostBridge->Head);
-
-    Status = gBS->InstallMultipleProtocolInterfaces (
-                    &HostBridge->HostBridgeHandle,
-                    &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
-                    NULL
-                    );
-    if (EFI_ERROR (Status)) {
-      FreePool (HostBridge);
-      return EFI_DEVICE_ERROR;
-    }
-
-    //
-    // Create Root Bridge Device Handle in this Host Bridge
-    //
-
-    for (Loop2 = 0; Loop2 < HostBridge->RootBridgeNumber; Loop2++) {
-      PrivateData = AllocateZeroPool (sizeof(PCI_ROOT_BRIDGE_INSTANCE));
-      if (PrivateData == NULL) {
-        return EFI_OUT_OF_RESOURCES;
-      }
-
-      PrivateData->Signature = PCI_ROOT_BRIDGE_SIGNATURE;
-      PrivateData->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[Loop1][Loop2];
-
-      RootBridgeConstructor (
-        &PrivateData->Io,
-        HostBridge->HostBridgeHandle,
-        RootBridgeAttribute[Loop1][Loop2],
-        &mResAperture[Loop1][Loop2]
-        );
-
-      Status = gBS->InstallMultipleProtocolInterfaces(
-                      &PrivateData->Handle,
-                      &gEfiDevicePathProtocolGuid,      PrivateData->DevicePath,
-                      &gEfiPciRootBridgeIoProtocolGuid, &PrivateData->Io,
-                      NULL
-                      );
-      if (EFI_ERROR (Status)) {
-        FreePool(PrivateData);
-        return EFI_DEVICE_ERROR;
-      }
-
-      InsertTailList (&HostBridge->Head, &PrivateData->Link);
-    }
-  }
-
-  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] This                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
-EFIAPI
-NotifyPhase(
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase
-  )
-{
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  PCI_RESOURCE_TYPE                     Index;
-  LIST_ENTRY                            *List;
-  EFI_PHYSICAL_ADDRESS                  BaseAddress;
-  UINT64                                AddrLen;
-  UINTN                                 BitsOfAlignment;
-  EFI_STATUS                            Status;
-  EFI_STATUS                            ReturnStatus;
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-
-  switch (Phase) {
-
-  case EfiPciHostBridgeBeginEnumeration:
-    if (HostBridgeInstance->CanRestarted) {
-      //
-      // Reset the Each Root Bridge
-      //
-      List = HostBridgeInstance->Head.ForwardLink;
-
-      while (List != &HostBridgeInstance->Head) {
-        RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-        for (Index = TypeIo; Index < TypeMax; Index++) {
-          RootBridgeInstance->ResAllocNode[Index].Type      = Index;
-          RootBridgeInstance->ResAllocNode[Index].Base      = 0;
-          RootBridgeInstance->ResAllocNode[Index].Length    = 0;
-          RootBridgeInstance->ResAllocNode[Index].Status    = ResNone;
-        }
-
-        List = List->ForwardLink;
-      }
-
-      HostBridgeInstance->ResourceSubmited = FALSE;
-      HostBridgeInstance->CanRestarted     = TRUE;
-    } else {
-      //
-      // Can not restart
-      //
-      return EFI_NOT_READY;
-    }
-    break;
-
-  case EfiPciHostBridgeEndEnumeration:
-    break;
-
-  case EfiPciHostBridgeBeginBusAllocation:
-    //
-    // No specific action is required here, can perform any chipset specific programing
-    //
-    HostBridgeInstance->CanRestarted = FALSE;
-    break;
-
-  case EfiPciHostBridgeEndBusAllocation:
-    //
-    // No specific action is required here, can perform any chipset specific programing
-    //
-    //HostBridgeInstance->CanRestarted = FALSE;
-    break;
-
-  case EfiPciHostBridgeBeginResourceAllocation:
-    //
-    // No specific action is required here, can perform any chipset specific programing
-    //
-    //HostBridgeInstance->CanRestarted = FALSE;
-    break;
-
-  case EfiPciHostBridgeAllocateResources:
-    ReturnStatus = EFI_SUCCESS;
-    if (HostBridgeInstance->ResourceSubmited) {
-      //
-      // Take care of the resource dependencies between the root bridges
-      //
-      List = HostBridgeInstance->Head.ForwardLink;
-
-      while (List != &HostBridgeInstance->Head) {
-        RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-        for (Index = TypeIo; Index < TypeBus; Index++) {
-          if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
-
-            AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
-
-            //
-            // Get the number of '1' in Alignment.
-            //
-            BitsOfAlignment = (UINTN) (HighBitSet64 (RootBridgeInstance->ResAllocNode[Index].Alignment) + 1);
-
-            switch (Index) {
-
-              case TypeIo:
-                //
-                // It is impossible for this chipset to align 0xFFFF for IO16
-                // So clear it
-                //
-                if (BitsOfAlignment >= 16) {
-                  BitsOfAlignment = 0;
-                }
-
-                BaseAddress = mResAperture[0][0].IoLimit;
-                Status = gDS->AllocateIoSpace (
-                                EfiGcdAllocateMaxAddressSearchTopDown,
-                                EfiGcdIoTypeIo,
-                                BitsOfAlignment,
-                                AddrLen,
-                                &BaseAddress,
-                                mDriverImageHandle,
-                                NULL
-                                );
-
-                if (!EFI_ERROR (Status)) {
-                  RootBridgeInstance->ResAllocNode[Index].Base   = (UINTN)BaseAddress;
-                  RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated;
-                } else {
-                  ReturnStatus = Status;
-                  if (Status != EFI_OUT_OF_RESOURCES) {
-                    RootBridgeInstance->ResAllocNode[Index].Length = 0;
-                  }
-                }
-
-                break;
-
-
-              case TypeMem32:
-                //
-                // It is impossible for this chipset to align 0xFFFFFFFF for Mem32
-                // So clear it
-                //
-
-                if (BitsOfAlignment >= 32) {
-                  BitsOfAlignment = 0;
-                }
-
-                BaseAddress = mResAperture[0][0].MemLimit;
-                Status = gDS->AllocateMemorySpace (
-                                EfiGcdAllocateMaxAddressSearchTopDown,
-                                EfiGcdMemoryTypeMemoryMappedIo,
-                                BitsOfAlignment,
-                                AddrLen,
-                                &BaseAddress,
-                                mDriverImageHandle,
-                                NULL
-                                );
-
-                if (!EFI_ERROR (Status)) {
-                  // We were able to allocate the PCI memory
-                  RootBridgeInstance->ResAllocNode[Index].Base   = (UINTN)BaseAddress;
-                  RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated;
-
-                } else {
-                  // Not able to allocate enough PCI memory
-                  ReturnStatus = Status;
-
-                  if (Status != EFI_OUT_OF_RESOURCES) {
-                    RootBridgeInstance->ResAllocNode[Index].Length = 0;
-                  }
-                  ASSERT (FALSE);
-                }
-                break;
-
-              case TypePMem32:
-              case TypeMem64:
-              case TypePMem64:
-                  ReturnStatus = EFI_ABORTED;
-                  break;
-              default:
-                ASSERT (FALSE);
-                break;
-              }; //end switch
-          }
-        }
-
-        List = List->ForwardLink;
-      }
-
-      return ReturnStatus;
-    } else {
-      return EFI_NOT_READY;
-    }
-
-  case EfiPciHostBridgeSetResources:
-    break;
-
-  case EfiPciHostBridgeFreeResources:
-    ReturnStatus = EFI_SUCCESS;
-    List = HostBridgeInstance->Head.ForwardLink;
-    while (List != &HostBridgeInstance->Head) {
-      RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-      for (Index = TypeIo; Index < TypeBus; Index++) {
-        if (RootBridgeInstance->ResAllocNode[Index].Status == ResAllocated) {
-          AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
-          BaseAddress = RootBridgeInstance->ResAllocNode[Index].Base;
-          switch (Index) {
-
-          case TypeIo:
-            Status = gDS->FreeIoSpace (BaseAddress, AddrLen);
-            if (EFI_ERROR (Status)) {
-              ReturnStatus = Status;
-            }
-            break;
-
-          case TypeMem32:
-            Status = gDS->FreeMemorySpace (BaseAddress, AddrLen);
-            if (EFI_ERROR (Status)) {
-              ReturnStatus = Status;
-            }
-            break;
-
-          case TypePMem32:
-            break;
-
-          case TypeMem64:
-            break;
-
-          case TypePMem64:
-            break;
-
-          default:
-            ASSERT (FALSE);
-            break;
-
-          }; //end switch
-          RootBridgeInstance->ResAllocNode[Index].Type      = Index;
-          RootBridgeInstance->ResAllocNode[Index].Base      = 0;
-          RootBridgeInstance->ResAllocNode[Index].Length    = 0;
-          RootBridgeInstance->ResAllocNode[Index].Status    = ResNone;
-        }
-      }
-
-      List = List->ForwardLink;
-    }
-
-    HostBridgeInstance->ResourceSubmited = FALSE;
-    HostBridgeInstance->CanRestarted     = TRUE;
-    return ReturnStatus;
-
-  case EfiPciHostBridgeEndResourceAllocation:
-    HostBridgeInstance->CanRestarted = FALSE;
-    break;
-
-  default:
-    return EFI_INVALID_PARAMETER;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-   Return the device handle of the next PCI root bridge that is associated with this Host Bridge.
-
-   This function is called multiple times to retrieve the device handles of all the PCI root bridges that
-   are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI
-   root bridges. On each call, the handle that was returned by the previous call is passed into the
-   interface, and on output the interface returns the device handle of the next PCI root bridge. The
-   caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
-   for that root bridge. When there are no more PCI root bridges to report, the interface returns
-   EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they
-   are returned by this function.
-   For D945 implementation, there is only one root bridge in PCI host bridge.
-
-   @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
-   @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.
-
-   @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the
-                                  specific Host bridge and return EFI_SUCCESS.
-   @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was
-                                  returned on a previous call to GetNextRootBridge().
-**/
-EFI_STATUS
-EFIAPI
-GetNextRootBridge(
-  IN       EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN OUT   EFI_HANDLE                                       *RootBridgeHandle
-  )
-{
-  BOOLEAN                               NoRootBridge;
-  LIST_ENTRY                            *List;
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-
-  NoRootBridge = TRUE;
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-
-  while (List != &HostBridgeInstance->Head) {
-    NoRootBridge = FALSE;
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (*RootBridgeHandle == NULL) {
-      //
-      // Return the first Root Bridge Handle of the Host Bridge
-      //
-      *RootBridgeHandle = RootBridgeInstance->Handle;
-      return EFI_SUCCESS;
-    } else {
-      if (*RootBridgeHandle == RootBridgeInstance->Handle) {
-        //
-        // Get next if have
-        //
-        List = List->ForwardLink;
-        if (List!=&HostBridgeInstance->Head) {
-          RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-          *RootBridgeHandle = RootBridgeInstance->Handle;
-          return EFI_SUCCESS;
-        } else {
-          return EFI_NOT_FOUND;
-        }
-      }
-    }
-
-    List = List->ForwardLink;
-  } //end while
-
-  if (NoRootBridge) {
-    return EFI_NOT_FOUND;
-  } else {
-    return EFI_INVALID_PARAMETER;
-  }
-}
-
-/**
-   Returns the allocation attributes of a PCI root bridge.
-
-   The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary
-   from one PCI root bridge to another. These attributes are different from the decode-related
-   attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
-   RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device
-   handles of all the root bridges that are associated with this host bridge must be obtained by calling
-   GetNextRootBridge(). The attributes are static in the sense that they do not change during or
-   after the enumeration process. The hardware may provide mechanisms to change the attributes on
-   the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is
-   installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
-   "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.
-   For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to
-   include requests for the prefetchable memory in the nonprefetchable memory pool and not request any
-   prefetchable memory.
-      Attribute                                 Description
-   ------------------------------------         ----------------------------------------------------------------------
-   EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate
-                                                windows for nonprefetchable and prefetchable memory. A PCI bus
-                                                driver needs to include requests for prefetchable memory in the
-                                                nonprefetchable memory pool.
-
-   EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory
-                                                windows. If this bit is not set, the PCI bus driver needs to include
-                                                requests for a 64-bit memory address in the corresponding 32-bit
-                                                memory pool.
-
-   @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
-   @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type
-                                   EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter
-
-   @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL
-   @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.
-   @retval EFI_SUCCESS             Success to get attribute of interested root bridge.
-
-**/
-EFI_STATUS
-EFIAPI
-GetAttributes(
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN  EFI_HANDLE                                       RootBridgeHandle,
-  OUT UINT64                                           *Attributes
-  )
-{
-  LIST_ENTRY                            *List;
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-
-  if (Attributes == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (RootBridgeHandle == RootBridgeInstance->Handle) {
-      *Attributes = RootBridgeInstance->RootBridgeAttrib;
-      return EFI_SUCCESS;
-    }
-    List = List->ForwardLink;
-  }
-
-  //
-  // RootBridgeHandle is not an EFI_HANDLE
-  // that was returned on a previous call to GetNextRootBridge()
-  //
-  return EFI_INVALID_PARAMETER;
-}
-
-/**
-   Sets up the specified PCI root bridge for the bus enumeration process.
-
-   This member function sets up the root bridge for bus enumeration and returns the PCI bus range
-   over which the search should be performed in ACPI 2.0 resource descriptor format.
-
-   @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
-   @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.
-   @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.
-
-   @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
-   @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.
-   @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.
-
-**/
-EFI_STATUS
-EFIAPI
-StartBusEnumeration(
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN  EFI_HANDLE                                       RootBridgeHandle,
-  OUT VOID                                             **Configuration
-  )
-{
-  LIST_ENTRY                            *List;
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  VOID                                  *Buffer;
-  UINT8                                 *Temp;
-  UINT64                                BusStart;
-  UINT64                                BusEnd;
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (RootBridgeHandle == RootBridgeInstance->Handle) {
-      //
-      // Set up the Root Bridge for Bus Enumeration
-      //
-      BusStart = RootBridgeInstance->BusBase;
-      BusEnd   = RootBridgeInstance->BusLimit;
-      //
-      // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
-      //
-
-      Buffer = AllocatePool (sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR));
-      if (Buffer == NULL) {
-        return EFI_OUT_OF_RESOURCES;
-      }
-
-      Temp = (UINT8 *)Buffer;
-
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Desc = 0x8A;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Len  = 0x2B;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->ResType = 2;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->GenFlag = 0;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->SpecificFlag = 0;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrSpaceGranularity = 0;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMin = BusStart;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMax = 0;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrTranslationOffset = 0;
-      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrLen = BusEnd - BusStart + 1;
-
-      Temp = Temp + sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
-      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = 0x79;
-      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;
-
-      *Configuration = Buffer;
-      return EFI_SUCCESS;
-    }
-    List = List->ForwardLink;
-  }
-
-  return EFI_INVALID_PARAMETER;
-}
-
-/**
-   Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.
-
-   This member function programs the specified PCI root bridge to decode the bus range that is
-   specified by the input parameter Configuration.
-   The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.
-
-   @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
-   @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed
-   @param[in] Configuration     The pointer to the PCI bus resource descriptor
-
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
-   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
-   @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.
-   @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than
-                                  bus descriptors.
-   @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.
-   @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.
-   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.
-   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
-   @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.
-
-**/
-EFI_STATUS
-EFIAPI
-SetBusNumbers(
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN EFI_HANDLE                                       RootBridgeHandle,
-  IN VOID                                             *Configuration
-  )
-{
-  LIST_ENTRY                            *List;
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  UINT8                                 *Ptr;
-  UINTN                                 BusStart;
-  UINTN                                 BusEnd;
-  UINTN                                 BusLen;
-
-  if (Configuration == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Ptr = Configuration;
-
-  //
-  // Check the Configuration is valid
-  //
-  if(*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType != 2) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Ptr += sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
-  if (*Ptr != ACPI_END_TAG_DESCRIPTOR) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  Ptr = Configuration;
-
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (RootBridgeHandle == RootBridgeInstance->Handle) {
-      BusStart = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin;
-      BusLen = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen;
-      BusEnd = BusStart + BusLen - 1;
-
-      if (BusStart > BusEnd) {
-        return EFI_INVALID_PARAMETER;
-      }
-
-      if ((BusStart < RootBridgeInstance->BusBase) || (BusEnd > RootBridgeInstance->BusLimit)) {
-        return EFI_INVALID_PARAMETER;
-      }
-
-      //
-      // Update the Bus Range
-      //
-      RootBridgeInstance->ResAllocNode[TypeBus].Base   = BusStart;
-      RootBridgeInstance->ResAllocNode[TypeBus].Length = BusLen;
-      RootBridgeInstance->ResAllocNode[TypeBus].Status = ResAllocated;
-
-      //
-      // Program the Root Bridge Hardware
-      //
-
-      return EFI_SUCCESS;
-    }
-
-    List = List->ForwardLink;
-  }
-
-  return EFI_INVALID_PARAMETER;
-}
-
-
-/**
-   Submits the I/O and memory resource requirements for the specified PCI root bridge.
-
-   This function is used to submit all the I/O and memory resources that are required by the specified
-   PCI root bridge. The input parameter Configuration is used to specify the following:
-   - The various types of resources that are required
-   - The associated lengths in terms of ACPI 2.0 resource descriptor format
-
-   @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.
-   @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.
-
-   @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
-   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
-   @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are
-                                  not supported by this PCI root bridge. This error will happen if the caller
-                                  did not combine resources according to Attributes that were returned by
-                                  GetAllocAttributes().
-   @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.
-   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.
-
-**/
-EFI_STATUS
-EFIAPI
-SubmitResources(
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN EFI_HANDLE                                       RootBridgeHandle,
-  IN VOID                                             *Configuration
-  )
-{
-  LIST_ENTRY                            *List;
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  UINT8                                 *Temp;
-  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr;
-  UINT64                                AddrLen;
-  UINT64                                Alignment;
-
-  //
-  // Check the input parameter: Configuration
-  //
-  if (Configuration == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  Temp = (UINT8 *)Configuration;
-  while ( *Temp == 0x8A) {
-    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;
-  }
-  if (*Temp != 0x79) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Temp = (UINT8 *)Configuration;
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (RootBridgeHandle == RootBridgeInstance->Handle) {
-      for (;
-           *Temp == 0x8A;
-           Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)
-           ) {
-        Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp ;
-
-        //
-        // Check Address Length
-        //
-        if (Ptr->AddrLen == 0) {
-          HostBridgeInstance->ResourceSubmited = TRUE;
-          continue;
-        }
-        if (Ptr->AddrLen > 0xffffffff) {
-          return EFI_INVALID_PARAMETER;
-        }
-
-        //
-        // Check address range alignment
-        //
-        if (Ptr->AddrRangeMax >= 0xffffffff || Ptr->AddrRangeMax != (GetPowerOfTwo64 (Ptr->AddrRangeMax + 1) - 1)) {
-          return EFI_INVALID_PARAMETER;
-        }
-
-        switch (Ptr->ResType) {
-
-        case 0:
-
-          //
-          // Check invalid Address Sapce Granularity
-          //
-          if (Ptr->AddrSpaceGranularity != 32) {
-            return EFI_INVALID_PARAMETER;
-          }
-
-          //
-          // check the memory resource request is supported by PCI root bridge
-          //
-          if (RootBridgeInstance->RootBridgeAttrib == EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM &&
-               Ptr->SpecificFlag == 0x06) {
-            return EFI_INVALID_PARAMETER;
-          }
-
-          AddrLen = Ptr->AddrLen;
-          Alignment = Ptr->AddrRangeMax;
-          if (Ptr->AddrSpaceGranularity == 32) {
-            if (Ptr->SpecificFlag == 0x06) {
-              //
-              // Apply from GCD
-              //
-              RootBridgeInstance->ResAllocNode[TypePMem32].Status = ResSubmitted;
-            } else {
-              RootBridgeInstance->ResAllocNode[TypeMem32].Length = AddrLen;
-              RootBridgeInstance->ResAllocNode[TypeMem32].Alignment = Alignment;
-              RootBridgeInstance->ResAllocNode[TypeMem32].Status = ResRequested;
-              HostBridgeInstance->ResourceSubmited = TRUE;
-            }
-          }
-
-          if (Ptr->AddrSpaceGranularity == 64) {
-            if (Ptr->SpecificFlag == 0x06) {
-              RootBridgeInstance->ResAllocNode[TypePMem64].Status = ResSubmitted;
-            } else {
-              RootBridgeInstance->ResAllocNode[TypeMem64].Status = ResSubmitted;
-            }
-          }
-          break;
-
-        case 1:
-          AddrLen = (UINTN) Ptr->AddrLen;
-          Alignment = (UINTN) Ptr->AddrRangeMax;
-          RootBridgeInstance->ResAllocNode[TypeIo].Length  = AddrLen;
-          RootBridgeInstance->ResAllocNode[TypeIo].Alignment = Alignment;
-          RootBridgeInstance->ResAllocNode[TypeIo].Status  = ResRequested;
-          HostBridgeInstance->ResourceSubmited = TRUE;
-          break;
-
-        default:
-            break;
-        };
-      }
-
-      return EFI_SUCCESS;
-    }
-
-    List = List->ForwardLink;
-  }
-
-  return EFI_INVALID_PARAMETER;
-}
-
-/**
-   Returns the proposed resource settings for the specified PCI root bridge.
-
-   This member function returns the proposed resource settings for the specified PCI root bridge. The
-   proposed resource settings are prepared when NotifyPhase() is called with a Phase of
-   EfiPciHostBridgeAllocateResources. The output parameter Configuration
-   specifies the following:
-   - The various types of resources, excluding bus resources, that are allocated
-   - The associated lengths in terms of ACPI 2.0 resource descriptor format
-
-   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
-
-   @retval EFI_SUCCESS            The requested parameters were returned.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-GetProposedResources(
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN  EFI_HANDLE                                       RootBridgeHandle,
-  OUT VOID                                             **Configuration
-  )
-{
-  LIST_ENTRY                            *List;
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  UINTN                                 Index;
-  UINTN                                 Number;
-  VOID                                  *Buffer;
-  UINT8                                 *Temp;
-  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr;
-  UINT64                                ResStatus;
-
-  Buffer = NULL;
-  Number = 0;
-  //
-  // Get the Host Bridge Instance from the resource allocation protocol
-  //
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  //
-  // Enumerate the root bridges in this host bridge
-  //
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (RootBridgeHandle == RootBridgeInstance->Handle) {
-      for (Index = 0; Index < TypeBus; Index ++) {
-        if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
-          Number ++;
-        }
-      }
-
-      if (Number ==  0) {
-        EFI_ACPI_END_TAG_DESCRIPTOR *End;
-
-        End = AllocateZeroPool (sizeof *End);
-        if (End == NULL) {
-          return EFI_OUT_OF_RESOURCES;
-        }
-        End->Desc = ACPI_END_TAG_DESCRIPTOR;
-        *Configuration = End;
-        return EFI_SUCCESS;
-      }
-
-      Buffer = AllocateZeroPool (Number * sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR));
-      if (Buffer == NULL) {
-        return EFI_OUT_OF_RESOURCES;
-      }
-
-      Temp = Buffer;
-      for (Index = 0; Index < TypeBus; Index ++) {
-        if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
-          Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp ;
-          ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;
-
-          switch (Index) {
-
-          case TypeIo:
-            //
-            // Io
-            //
-            Ptr->Desc = 0x8A;
-            Ptr->Len  = 0x2B;
-            Ptr->ResType = 1;
-            Ptr->GenFlag = 0;
-            Ptr->SpecificFlag = 0;
-            Ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base;
-            Ptr->AddrRangeMax = 0;
-            Ptr->AddrTranslationOffset = \
-                 (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
-            Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
-            break;
-
-          case TypeMem32:
-            //
-            // Memory 32
-            //
-            Ptr->Desc = 0x8A;
-            Ptr->Len  = 0x2B;
-            Ptr->ResType = 0;
-            Ptr->GenFlag = 0;
-            Ptr->SpecificFlag = 0;
-            Ptr->AddrSpaceGranularity = 32;
-            Ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base;
-            Ptr->AddrRangeMax = 0;
-            Ptr->AddrTranslationOffset = \
-                 (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
-            Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
-            break;
-
-          case TypePMem32:
-            //
-            // Prefetch memory 32
-            //
-            Ptr->Desc = 0x8A;
-            Ptr->Len  = 0x2B;
-            Ptr->ResType = 0;
-            Ptr->GenFlag = 0;
-            Ptr->SpecificFlag = 6;
-            Ptr->AddrSpaceGranularity = 32;
-            Ptr->AddrRangeMin = 0;
-            Ptr->AddrRangeMax = 0;
-            Ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;
-            Ptr->AddrLen = 0;
-            break;
-
-          case TypeMem64:
-            //
-            // Memory 64
-            //
-            Ptr->Desc = 0x8A;
-            Ptr->Len  = 0x2B;
-            Ptr->ResType = 0;
-            Ptr->GenFlag = 0;
-            Ptr->SpecificFlag = 0;
-            Ptr->AddrSpaceGranularity = 64;
-            Ptr->AddrRangeMin = 0;
-            Ptr->AddrRangeMax = 0;
-            Ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;
-            Ptr->AddrLen = 0;
-            break;
-
-          case TypePMem64:
-            //
-            // Prefetch memory 64
-            //
-            Ptr->Desc = 0x8A;
-            Ptr->Len  = 0x2B;
-            Ptr->ResType = 0;
-            Ptr->GenFlag = 0;
-            Ptr->SpecificFlag = 6;
-            Ptr->AddrSpaceGranularity = 64;
-            Ptr->AddrRangeMin = 0;
-            Ptr->AddrRangeMax = 0;
-            Ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;
-            Ptr->AddrLen = 0;
-            break;
-          };
-
-          Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
-        }
-      }
-
-      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = 0x79;
-      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;
-
-      *Configuration = Buffer;
-
-      return EFI_SUCCESS;
-    }
-
-    List = List->ForwardLink;
-  }
-
-  return EFI_INVALID_PARAMETER;
-}
-
-/**
-   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 This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in
-                            InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the
-                            EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI
-                            configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for
-                            the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
-   @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
-EFIAPI
-PreprocessController (
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL          *This,
-  IN  EFI_HANDLE                                                RootBridgeHandle,
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS               PciAddress,
-  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE              Phase
-  )
-{
-  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
-  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
-  LIST_ENTRY                            *List;
-
-  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
-  List = HostBridgeInstance->Head.ForwardLink;
-
-  //
-  // Enumerate the root bridges in this host bridge
-  //
-  while (List != &HostBridgeInstance->Head) {
-    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
-    if (RootBridgeHandle == RootBridgeInstance->Handle) {
-      break;
-    }
-    List = List->ForwardLink;
-  }
-  if (List == &HostBridgeInstance->Head) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if ((UINT32)Phase > EfiPciBeforeResourceCollection) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  return EFI_SUCCESS;
-}
diff --git a/ArmVirtPkg/PciHostBridgeDxe/PciHostBridge.h b/ArmVirtPkg/PciHostBridgeDxe/PciHostBridge.h
deleted file mode 100644
index 647fe1a..0000000
--- a/ArmVirtPkg/PciHostBridgeDxe/PciHostBridge.h
+++ /dev/null
@@ -1,499 +0,0 @@
-/** @file
-  The Header file of the Pci Host Bridge Driver
-
-  Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials are
-  licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef _PCI_HOST_BRIDGE_H_
-#define _PCI_HOST_BRIDGE_H_
-
-#include <PiDxe.h>
-
-#include <IndustryStandard/Pci.h>
-#include <IndustryStandard/Acpi.h>
-
-#include <Protocol/PciHostBridgeResourceAllocation.h>
-#include <Protocol/PciRootBridgeIo.h>
-#include <Protocol/Metronome.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/FdtClient.h>
-
-
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/DxeServicesTableLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/IoLib.h>
-#include <Library/PciLib.h>
-#include <Library/PcdLib.h>
-
-//
-// Hard code the host bridge number in the platform.
-// In this chipset, there is only one host bridge.
-//
-#define HOST_BRIDGE_NUMBER  1
-
-#define MAX_PCI_DEVICE_NUMBER      31
-#define MAX_PCI_FUNCTION_NUMBER    7
-#define MAX_PCI_REG_ADDRESS        (SIZE_4KB - 1)
-
-typedef enum {
-  IoOperation,
-  MemOperation,
-  PciOperation
-} OPERATION_TYPE;
-
-#define PCI_HOST_BRIDGE_SIGNATURE  SIGNATURE_32('e', 'h', 's', 't')
-typedef struct {
-  UINTN                                             Signature;
-  EFI_HANDLE                                        HostBridgeHandle;
-  UINTN                                             RootBridgeNumber;
-  LIST_ENTRY                                        Head;
-  BOOLEAN                                           ResourceSubmited;
-  BOOLEAN                                           CanRestarted;
-  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  ResAlloc;
-} PCI_HOST_BRIDGE_INSTANCE;
-
-#define INSTANCE_FROM_RESOURCE_ALLOCATION_THIS(a) \
-  CR(a, PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE)
-
-//
-//  HostBridge Resource Allocation interface
-//
-
-/**
-   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] This                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
-EFIAPI
-NotifyPhase(
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase
-  );
-
-/**
-   Return the device handle of the next PCI root bridge that is associated with this Host Bridge.
-
-   This function is called multiple times to retrieve the device handles of all the PCI root bridges that
-   are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI
-   root bridges. On each call, the handle that was returned by the previous call is passed into the
-   interface, and on output the interface returns the device handle of the next PCI root bridge. The
-   caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
-   for that root bridge. When there are no more PCI root bridges to report, the interface returns
-   EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they
-   are returned by this function.
-   For D945 implementation, there is only one root bridge in PCI host bridge.
-
-   @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
-   @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.
-
-   @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the
-                                  specific Host bridge and return EFI_SUCCESS.
-   @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was
-                                  returned on a previous call to GetNextRootBridge().
-**/
-EFI_STATUS
-EFIAPI
-GetNextRootBridge(
-  IN       EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN OUT   EFI_HANDLE                                       *RootBridgeHandle
-  );
-
-/**
-   Returns the allocation attributes of a PCI root bridge.
-
-   The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary
-   from one PCI root bridge to another. These attributes are different from the decode-related
-   attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
-   RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device
-   handles of all the root bridges that are associated with this host bridge must be obtained by calling
-   GetNextRootBridge(). The attributes are static in the sense that they do not change during or
-   after the enumeration process. The hardware may provide mechanisms to change the attributes on
-   the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is
-   installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
-   "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.
-   For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to
-   include requests for the prefetchable memory in the nonprefetchable memory pool and not request any
-   prefetchable memory.
-      Attribute                                 Description
-   ------------------------------------         ----------------------------------------------------------------------
-   EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate
-                                                windows for nonprefetchable and prefetchable memory. A PCI bus
-                                                driver needs to include requests for prefetchable memory in the
-                                                nonprefetchable memory pool.
-
-   EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory
-                                                windows. If this bit is not set, the PCI bus driver needs to include
-                                                requests for a 64-bit memory address in the corresponding 32-bit
-                                                memory pool.
-
-   @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
-   @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type
-                                   EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter
-
-   @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL
-   @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.
-   @retval EFI_SUCCESS             Success to get attribute of interested root bridge.
-
-**/
-EFI_STATUS
-EFIAPI
-GetAttributes(
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN  EFI_HANDLE                                       RootBridgeHandle,
-  OUT UINT64                                           *Attributes
-  );
-
-/**
-   Sets up the specified PCI root bridge for the bus enumeration process.
-
-   This member function sets up the root bridge for bus enumeration and returns the PCI bus range
-   over which the search should be performed in ACPI 2.0 resource descriptor format.
-
-   @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
-   @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.
-   @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.
-
-   @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
-   @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.
-   @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.
-
-**/
-EFI_STATUS
-EFIAPI
-StartBusEnumeration(
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN  EFI_HANDLE                                       RootBridgeHandle,
-  OUT VOID                                             **Configuration
-  );
-
-/**
-   Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.
-
-   This member function programs the specified PCI root bridge to decode the bus range that is
-   specified by the input parameter Configuration.
-   The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.
-
-   @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
-   @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed
-   @param[in] Configuration     The pointer to the PCI bus resource descriptor
-
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
-   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
-   @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.
-   @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than
-                                  bus descriptors.
-   @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.
-   @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.
-   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.
-   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
-   @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.
-
-**/
-EFI_STATUS
-EFIAPI
-SetBusNumbers(
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN EFI_HANDLE                                       RootBridgeHandle,
-  IN VOID                                             *Configuration
-  );
-
-/**
-   Submits the I/O and memory resource requirements for the specified PCI root bridge.
-
-   This function is used to submit all the I/O and memory resources that are required by the specified
-   PCI root bridge. The input parameter Configuration is used to specify the following:
-   - The various types of resources that are required
-   - The associated lengths in terms of ACPI 2.0 resource descriptor format
-
-   @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.
-   @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.
-
-   @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
-   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
-   @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are
-                                  not supported by this PCI root bridge. This error will happen if the caller
-                                  did not combine resources according to Attributes that were returned by
-                                  GetAllocAttributes().
-   @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.
-   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.
-
-**/
-EFI_STATUS
-EFIAPI
-SubmitResources(
-  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN EFI_HANDLE                                       RootBridgeHandle,
-  IN VOID                                             *Configuration
-  );
-
-/**
-   Returns the proposed resource settings for the specified PCI root bridge.
-
-   This member function returns the proposed resource settings for the specified PCI root bridge. The
-   proposed resource settings are prepared when NotifyPhase() is called with a Phase of
-   EfiPciHostBridgeAllocateResources. The output parameter Configuration
-   specifies the following:
-   - The various types of resources, excluding bus resources, that are allocated
-   - The associated lengths in terms of ACPI 2.0 resource descriptor format
-
-   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
-
-   @retval EFI_SUCCESS            The requested parameters were returned.
-   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
-   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-GetProposedResources(
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
-  IN  EFI_HANDLE                                       RootBridgeHandle,
-  OUT VOID                                             **Configuration
-  );
-
-/**
-   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 This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
-   @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in
-                            InstallProtocolInterface() in the UEFI 2.0 Specification.
-   @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the
-                            EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI
-                            configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for
-                            the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
-   @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
-EFIAPI
-PreprocessController (
-  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,
-  IN  EFI_HANDLE                                        RootBridgeHandle,
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS       PciAddress,
-  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE      Phase
-  );
-
-
-//
-// Define resource status constant
-//
-#define EFI_RESOURCE_NONEXISTENT   0xFFFFFFFFFFFFFFFFULL
-#define EFI_RESOURCE_LESS          0xFFFFFFFFFFFFFFFEULL
-
-
-//
-// Driver Instance Data Prototypes
-//
-
-typedef struct {
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation;
-  UINTN                                      NumberOfBytes;
-  UINTN                                      NumberOfPages;
-  EFI_PHYSICAL_ADDRESS                       HostAddress;
-  EFI_PHYSICAL_ADDRESS                       MappedHostAddress;
-} MAP_INFO;
-
-typedef struct {
-  ACPI_HID_DEVICE_PATH              AcpiDevicePath;
-  EFI_DEVICE_PATH_PROTOCOL          EndDevicePath;
-} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
-
-typedef struct {
-  UINT64          BusBase;
-  UINT64          BusLimit;
-
-  UINT64          MemBase;
-  UINT64          MemLimit;
-
-  UINT64          IoBase;
-  UINT64          IoLimit;
-  UINT64          IoTranslation;
-} PCI_ROOT_BRIDGE_RESOURCE_APERTURE;
-
-typedef enum {
-  TypeIo = 0,
-  TypeMem32,
-  TypePMem32,
-  TypeMem64,
-  TypePMem64,
-  TypeBus,
-  TypeMax
-} PCI_RESOURCE_TYPE;
-
-typedef enum {
-  ResNone = 0,
-  ResSubmitted,
-  ResRequested,
-  ResAllocated,
-  ResStatusMax
-} RES_STATUS;
-
-typedef struct {
-  PCI_RESOURCE_TYPE Type;
-  UINT64            Base;
-  UINT64            Length;
-  UINT64            Alignment;
-  RES_STATUS        Status;
-} PCI_RES_NODE;
-
-#define PCI_ROOT_BRIDGE_SIGNATURE  SIGNATURE_32('e', '2', 'p', 'b')
-
-typedef struct {
-  UINT32                 Signature;
-  LIST_ENTRY             Link;
-  EFI_HANDLE             Handle;
-  UINT64                 RootBridgeAttrib;
-  UINT64                 Attributes;
-  UINT64                 Supports;
-
-  //
-  // Specific for this memory controller: Bus, I/O, Mem
-  //
-  PCI_RES_NODE           ResAllocNode[6];
-
-  //
-  // Addressing for Memory and I/O and Bus arrange
-  //
-  UINT64                 BusBase;
-  UINT64                 MemBase;
-  UINT64                 IoBase;
-  UINT64                 BusLimit;
-  UINT64                 MemLimit;
-  UINT64                 IoLimit;
-  UINT64                 IoTranslation;
-
-  EFI_DEVICE_PATH_PROTOCOL                *DevicePath;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         Io;
-
-} PCI_ROOT_BRIDGE_INSTANCE;
-
-
-//
-// Driver Instance Data Macros
-//
-#define DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) \
-  CR(a, PCI_ROOT_BRIDGE_INSTANCE, Io, PCI_ROOT_BRIDGE_SIGNATURE)
-
-
-#define DRIVER_INSTANCE_FROM_LIST_ENTRY(a) \
-  CR(a, PCI_ROOT_BRIDGE_INSTANCE, Link, PCI_ROOT_BRIDGE_SIGNATURE)
-
-/**
-
-  Construct the Pci Root Bridge Io protocol
-
-  @param Protocol         Point to protocol instance
-  @param HostBridgeHandle Handle of host bridge
-  @param Attri            Attribute of host bridge
-  @param ResAperture      ResourceAperture for host bridge
-
-  @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.
-
-**/
-EFI_STATUS
-RootBridgeConstructor (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *Protocol,
-  IN EFI_HANDLE                         HostBridgeHandle,
-  IN UINT64                             Attri,
-  IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE  *ResAperture
-  );
-
-#endif
diff --git a/ArmVirtPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf b/ArmVirtPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf
deleted file mode 100644
index 8c75eda..0000000
--- a/ArmVirtPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf
+++ /dev/null
@@ -1,64 +0,0 @@
-## @file
-#  The basic interfaces implementation to a single segment PCI Host Bridge driver.
-#
-#  Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
-#  This program and the accompanying materials
-#  are licensed and made available under the terms and conditions of the BSD License
-#  which accompanies this distribution.  The full text of the license may be found at
-#  http://opensource.org/licenses/bsd-license.php
-#
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-##
-
-[Defines]
-  INF_VERSION                    = 0x00010005
-  BASE_NAME                      = PciHostBridge
-  FILE_GUID                      = 9f609346-37cb-4eb7-801f-f55099373998
-  MODULE_TYPE                    = DXE_DRIVER
-  VERSION_STRING                 = 1.0
-
-  ENTRY_POINT                    = InitializePciHostBridge
-
-[Packages]
-  MdeModulePkg/MdeModulePkg.dec
-  MdePkg/MdePkg.dec
-  ArmVirtPkg/ArmVirtPkg.dec
-
-[LibraryClasses]
-  UefiDriverEntryPoint
-  UefiBootServicesTableLib
-  DxeServicesTableLib
-  UefiLib
-  MemoryAllocationLib
-  BaseMemoryLib
-  BaseLib
-  DebugLib
-  DevicePathLib
-  IoLib
-  PciLib
-  PcdLib
-
-[Sources]
-  PciHostBridge.c
-  PciRootBridgeIo.c
-  PciHostBridge.h
-
-[Protocols]
-  gEfiPciHostBridgeResourceAllocationProtocolGuid       ## PRODUCES
-  gEfiPciRootBridgeIoProtocolGuid                       ## PRODUCES
-  gEfiMetronomeArchProtocolGuid                         ## CONSUMES
-  gEfiDevicePathProtocolGuid                            ## PRODUCES
-  gFdtClientProtocolGuid                                ## CONSUMES
-
-[Pcd]
-  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
-
-[FeaturePcd]
-  gArmVirtTokenSpaceGuid.PcdPureAcpiBoot
-
-[depex]
-  gEfiMetronomeArchProtocolGuid AND
-  gEfiCpuArchProtocolGuid AND
-  gFdtClientProtocolGuid
diff --git a/ArmVirtPkg/PciHostBridgeDxe/PciRootBridgeIo.c b/ArmVirtPkg/PciHostBridgeDxe/PciRootBridgeIo.c
deleted file mode 100644
index c867887..0000000
--- a/ArmVirtPkg/PciHostBridgeDxe/PciRootBridgeIo.c
+++ /dev/null
@@ -1,2144 +0,0 @@
-/** @file
-  PCI Root Bridge Io Protocol implementation
-
-Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials are
-licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "PciHostBridge.h"
-
-typedef struct {
-  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     SpaceDesp[TypeMax];
-  EFI_ACPI_END_TAG_DESCRIPTOR           EndDesp;
-} RESOURCE_CONFIGURATION;
-
-RESOURCE_CONFIGURATION Configuration = {
-  {{0x8A, 0x2B, 1, 0, 0, 0, 0, 0, 0, 0},
-  {0x8A, 0x2B, 0, 0, 0, 32, 0, 0, 0, 0},
-  {0x8A, 0x2B, 0, 0, 6, 32, 0, 0, 0, 0},
-  {0x8A, 0x2B, 0, 0, 0, 64, 0, 0, 0, 0},
-  {0x8A, 0x2B, 0, 0, 6, 64, 0, 0, 0, 0},
-  {0x8A, 0x2B, 2, 0, 0, 0, 0, 0, 0, 0}},
-  {0x79, 0}
-};
-
-//
-// Protocol Member Function Prototypes
-//
-
-/**
-   Polls an address in memory mapped I/O space until an exit condition is met, or
-   a timeout occurs.
-
-   This function provides a standard way to poll a PCI memory location. A PCI memory read
-   operation is performed at the PCI memory address specified by Address for the width specified
-   by Width. The result of this PCI memory read operation is stored in Result. This PCI memory
-   read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &
-   Mask) is equal to Value.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operations.
-   @param[in]   Address   The base address of the memory operations. The caller is
-                          responsible for aligning Address if required.
-   @param[in]   Mask      Mask used for the polling criteria. Bytes above Width in Mask
-                          are ignored. The bits in the bytes below Width which are zero in
-                          Mask are ignored when polling the memory address.
-   @param[in]   Value     The comparison value used for the polling exit criteria.
-   @param[in]   Delay     The number of 100 ns units to poll. Note that timer available may
-                          be of poorer granularity.
-   @param[out]  Result    Pointer to the last value read from the memory location.
-
-   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
-   @retval EFI_INVALID_PARAMETER  Width is invalid.
-   @retval EFI_INVALID_PARAMETER  Result is NULL.
-   @retval EFI_TIMEOUT            Delay expired before a match occurred.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPollMem (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN  UINT64                                 Address,
-  IN  UINT64                                 Mask,
-  IN  UINT64                                 Value,
-  IN  UINT64                                 Delay,
-  OUT UINT64                                 *Result
-  );
-
-/**
-   Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is
-   satisfied or after a defined duration.
-
-   This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is
-   performed at the PCI I/O address specified by Address for the width specified by Width.
-   The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is
-   repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal
-   to Value.
-
-   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in] Width     Signifies the width of the I/O operations.
-   @param[in] Address   The base address of the I/O operations. The caller is responsible
-                        for aligning Address if required.
-   @param[in] Mask      Mask used for the polling criteria. Bytes above Width in Mask
-                        are ignored. The bits in the bytes below Width which are zero in
-                        Mask are ignored when polling the I/O address.
-   @param[in] Value     The comparison value used for the polling exit criteria.
-   @param[in] Delay     The number of 100 ns units to poll. Note that timer available may
-                        be of poorer granularity.
-   @param[out] Result   Pointer to the last value read from the memory location.
-
-   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
-   @retval EFI_INVALID_PARAMETER  Width is invalid.
-   @retval EFI_INVALID_PARAMETER  Result is NULL.
-   @retval EFI_TIMEOUT            Delay expired before a match occurred.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPollIo (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN  UINT64                                 Address,
-  IN  UINT64                                 Mask,
-  IN  UINT64                                 Value,
-  IN  UINT64                                 Delay,
-  OUT UINT64                                 *Result
-  );
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
-
-   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
-   registers in the PCI root bridge memory space.
-   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
-   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operation.
-   @param[in]   Address   The base address of the memory operation. The caller is
-                          responsible for aligning the Address if required.
-   @param[in]   Count     The number of memory operations to perform. Bytes moved is
-                          Width size * Count, starting at Address.
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoMemRead (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  OUT    VOID                                   *Buffer
-  );
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
-
-   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
-   registers in the PCI root bridge memory space.
-   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
-   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operation.
-   @param[in]   Address   The base address of the memory operation. The caller is
-                          responsible for aligning the Address if required.
-   @param[in]   Count     The number of memory operations to perform. Bytes moved is
-                          Width size * Count, starting at Address.
-   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoMemWrite (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  IN     VOID                                   *Buffer
-  );
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
-
-   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width       Signifies the width of the memory operations.
-   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for
-                            aligning the Address if required.
-   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
-                            size * Count, starting at Address.
-   @param[out]  UserBuffer  For read operations, the destination buffer to store the results. For
-                            write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoIoRead (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 UserAddress,
-  IN     UINTN                                  Count,
-  OUT    VOID                                   *UserBuffer
-  );
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
-
-   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width       Signifies the width of the memory operations.
-   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for
-                            aligning the Address if required.
-   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
-                            size * Count, starting at Address.
-   @param[in]   UserBuffer  For read operations, the destination buffer to store the results. For
-                            write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoIoWrite (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 UserAddress,
-  IN     UINTN                                  Count,
-  IN     VOID                                   *UserBuffer
-  );
-
-/**
-   Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI
-   root bridge memory space.
-
-   The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory
-   space to another region of PCI root bridge memory space. This is especially useful for video scroll
-   operation on a memory mapped video buffer.
-   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
-   any alignment and memory width restrictions that a PCI root bridge on a platform might require.
-
-   @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
-   @param[in] Width       Signifies the width of the memory operations.
-   @param[in] DestAddress The destination address of the memory operation. The caller is
-                          responsible for aligning the DestAddress if required.
-   @param[in] SrcAddress  The source address of the memory operation. The caller is
-                          responsible for aligning the SrcAddress if required.
-   @param[in] Count       The number of memory operations to perform. Bytes moved is
-                          Width size * Count, starting at DestAddress and SrcAddress.
-
-   @retval  EFI_SUCCESS             The data was copied from one memory region to another memory region.
-   @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.
-   @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoCopyMem (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 DestAddress,
-  IN     UINT64                                 SrcAddress,
-  IN     UINTN                                  Count
-  );
-
-/**
-   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
-
-   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
-   registers for a PCI controller.
-   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
-   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
-   require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operations.
-   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
-                          moved is Width size * Count, starting at Address.
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPciRead (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  OUT    VOID                                   *Buffer
-  );
-
-/**
-   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
-
-   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
-   registers for a PCI controller.
-   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
-   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
-   require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operations.
-   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
-                          moved is Width size * Count, starting at Address.
-   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPciWrite (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  IN     VOID                                   *Buffer
-  );
-
-/**
-   Provides the PCI controller-specific addresses required to access system memory from a
-   DMA bus master.
-
-   The Map() function provides the PCI controller specific addresses needed to access system
-   memory. This function is used to map system memory for PCI bus master DMA accesses.
-
-   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.
-   @param[in]       HostAddress     The system memory address to map to the PCI controller.
-   @param[in, out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.
-   @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use
-                                    to access the system memory's HostAddress.
-   @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.
-
-   @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.
-   @retval EFI_INVALID_PARAMETER  Operation is invalid.
-   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
-   @retval EFI_INVALID_PARAMETER  NumberOfBytes is NULL.
-   @retval EFI_INVALID_PARAMETER  DeviceAddress is NULL.
-   @retval EFI_INVALID_PARAMETER  Mapping is NULL.
-   @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common buffer.
-   @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoMap (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL            *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,
-  IN     VOID                                       *HostAddress,
-  IN OUT UINTN                                      *NumberOfBytes,
-  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,
-  OUT    VOID                                       **Mapping
-  );
-
-/**
-   Completes the Map() operation and releases any corresponding resources.
-
-   The Unmap() function completes the Map() operation and releases any corresponding resources.
-   If the operation was an EfiPciOperationBusMasterWrite or
-   EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.
-   Any resources used for the mapping are freed.
-
-   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in] Mapping   The mapping value returned from Map().
-
-   @retval EFI_SUCCESS            The range was unmapped.
-   @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().
-   @retval EFI_DEVICE_ERROR       The data was not committed to the target system memory.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoUnmap (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN  VOID                             *Mapping
-  );
-
-/**
-   Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or
-   EfiPciOperationBusMasterCommonBuffer64 mapping.
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param Type        This parameter is not used and must be ignored.
-   @param MemoryType  The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.
-   @param Pages       The number of pages to allocate.
-   @param HostAddress A pointer to store the base system memory address of the allocated range.
-   @param Attributes  The requested bit mask of attributes for the allocated range. Only
-                      the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED,
-                      and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.
-
-   @retval EFI_SUCCESS            The requested memory pages were allocated.
-   @retval EFI_INVALID_PARAMETER  MemoryType is invalid.
-   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
-   @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal attribute bits are
-                                  MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
-   @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoAllocateBuffer (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN  EFI_ALLOCATE_TYPE                Type,
-  IN  EFI_MEMORY_TYPE                  MemoryType,
-  IN  UINTN                            Pages,
-  OUT VOID                             **HostAddress,
-  IN  UINT64                           Attributes
-  );
-
-/**
-   Frees memory that was allocated with AllocateBuffer().
-
-   The FreeBuffer() function frees memory that was allocated with AllocateBuffer().
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param Pages       The number of pages to free.
-   @param HostAddress The base system memory address of the allocated range.
-
-   @retval EFI_SUCCESS            The requested memory pages were freed.
-   @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and Pages
-                                  was not allocated with AllocateBuffer().
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoFreeBuffer (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN  UINTN                            Pages,
-  OUT VOID                             *HostAddress
-  );
-
-/**
-   Flushes all PCI posted write transactions from a PCI host bridge to system memory.
-
-   The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system
-   memory. Posted write transactions are generated by PCI bus masters when they perform write
-   transactions to target addresses in system memory.
-   This function does not flush posted write transactions from any PCI bridges. A PCI controller
-   specific action must be taken to guarantee that the posted write transactions have been flushed from
-   the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with
-   a PCI read transaction from the PCI controller prior to calling Flush().
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-
-   @retval EFI_SUCCESS        The PCI posted write transactions were flushed from the PCI host
-                              bridge to system memory.
-   @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed from the PCI
-                              host bridge due to a hardware error.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoFlush (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This
-  );
-
-/**
-   Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the
-   attributes that a PCI root bridge is currently using.
-
-   The GetAttributes() function returns the mask of attributes that this PCI root bridge supports
-   and the mask of attributes that the PCI root bridge is currently using.
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param Supported   A pointer to the mask of attributes that this PCI root bridge
-                      supports setting with SetAttributes().
-   @param Attributes  A pointer to the mask of attributes that this PCI root bridge is
-                      currently using.
-
-   @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI root
-                                  bridge supports is returned in Supports. If Attributes is
-                                  not NULL, then the attributes that the PCI root bridge is currently
-                                  using is returned in Attributes.
-   @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoGetAttributes (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  OUT UINT64                           *Supported,
-  OUT UINT64                           *Attributes
-  );
-
-/**
-   Sets attributes for a resource range on a PCI root bridge.
-
-   The SetAttributes() function sets the attributes specified in Attributes for the PCI root
-   bridge on the resource range specified by ResourceBase and ResourceLength. Since the
-   granularity of setting these attributes may vary from resource type to resource type, and from
-   platform to platform, the actual resource range and the one passed in by the caller may differ. As a
-   result, this function may set the attributes specified by Attributes on a larger resource range
-   than the caller requested. The actual range is returned in ResourceBase and
-   ResourceLength. The caller is responsible for verifying that the actual range for which the
-   attributes were set is acceptable.
-
-   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]       Attributes      The mask of attributes to set. If the attribute bit
-                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, or
-                                    MEMORY_DISABLE is set, then the resource range is specified by
-                                    ResourceBase and ResourceLength. If
-                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
-                                    MEMORY_DISABLE are not set, then ResourceBase and
-                                    ResourceLength are ignored, and may be NULL.
-   @param[in, out]  ResourceBase    A pointer to the base address of the resource range to be modified
-                                    by the attributes specified by Attributes.
-   @param[in, out]  ResourceLength  A pointer to the length of the resource range to be modified by the
-                                    attributes specified by Attributes.
-
-   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
-   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
-   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoSetAttributes (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN     UINT64                           Attributes,
-  IN OUT UINT64                           *ResourceBase,
-  IN OUT UINT64                           *ResourceLength
-  );
-
-/**
-   Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0
-   resource descriptors.
-
-   There are only two resource descriptor types from the ACPI Specification that may be used to
-   describe the current resources allocated to a PCI root bridge. These are the QWORD Address
-   Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The
-   QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic
-   or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD
-   Address Space Descriptors followed by an End Tag.
-
-   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[out]  Resources   A pointer to the ACPI 2.0 resource descriptors that describe the
-                            current configuration of this PCI root bridge. The storage for the
-                            ACPI 2.0 resource descriptors is allocated by this function. The
-                            caller must treat the return buffer as read-only data, and the buffer
-                            must not be freed by the caller.
-
-   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
-   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
-   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoConfiguration (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  OUT    VOID                             **Resources
-  );
-
-//
-// Memory Controller Pci Root Bridge Io Module Variables
-//
-EFI_METRONOME_ARCH_PROTOCOL *mMetronome;
-
-//
-// Lookup table for increment values based on transfer widths
-//
-UINT8 mInStride[] = {
-  1, // EfiPciWidthUint8
-  2, // EfiPciWidthUint16
-  4, // EfiPciWidthUint32
-  8, // EfiPciWidthUint64
-  0, // EfiPciWidthFifoUint8
-  0, // EfiPciWidthFifoUint16
-  0, // EfiPciWidthFifoUint32
-  0, // EfiPciWidthFifoUint64
-  1, // EfiPciWidthFillUint8
-  2, // EfiPciWidthFillUint16
-  4, // EfiPciWidthFillUint32
-  8  // EfiPciWidthFillUint64
-};
-
-//
-// Lookup table for increment values based on transfer widths
-//
-UINT8 mOutStride[] = {
-  1, // EfiPciWidthUint8
-  2, // EfiPciWidthUint16
-  4, // EfiPciWidthUint32
-  8, // EfiPciWidthUint64
-  1, // EfiPciWidthFifoUint8
-  2, // EfiPciWidthFifoUint16
-  4, // EfiPciWidthFifoUint32
-  8, // EfiPciWidthFifoUint64
-  0, // EfiPciWidthFillUint8
-  0, // EfiPciWidthFillUint16
-  0, // EfiPciWidthFillUint32
-  0  // EfiPciWidthFillUint64
-};
-
-/**
-
-  Construct the Pci Root Bridge Io protocol
-
-  @param Protocol         Point to protocol instance
-  @param HostBridgeHandle Handle of host bridge
-  @param Attri            Attribute of host bridge
-  @param ResAperture      ResourceAperture for host bridge
-
-  @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.
-
-**/
-EFI_STATUS
-RootBridgeConstructor (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *Protocol,
-  IN EFI_HANDLE                         HostBridgeHandle,
-  IN UINT64                             Attri,
-  IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE  *ResAperture
-  )
-{
-  EFI_STATUS                        Status;
-  PCI_ROOT_BRIDGE_INSTANCE          *PrivateData;
-  PCI_RESOURCE_TYPE                 Index;
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol);
-
-  //
-  // The host to PCI bridge. The host memory addresses are direct mapped to PCI
-  // addresses, so there's no need to translate them. IO addresses need
-  // translation however.
-  //
-  PrivateData->MemBase       = ResAperture->MemBase;
-  PrivateData->IoBase        = ResAperture->IoBase;
-  PrivateData->IoTranslation = ResAperture->IoTranslation;
-
-  //
-  // The host bridge only supports 32bit addressing for memory
-  // and standard IA32 16bit io
-  //
-  PrivateData->MemLimit = ResAperture->MemLimit;
-  PrivateData->IoLimit  = ResAperture->IoLimit;
-
-  //
-  // Bus Aperture for this Root Bridge (Possible Range)
-  //
-  PrivateData->BusBase  = ResAperture->BusBase;
-  PrivateData->BusLimit = ResAperture->BusLimit;
-
-  //
-  // Specific for this chipset
-  //
-  for (Index = TypeIo; Index < TypeMax; Index++) {
-    PrivateData->ResAllocNode[Index].Type      = Index;
-    PrivateData->ResAllocNode[Index].Base      = 0;
-    PrivateData->ResAllocNode[Index].Length    = 0;
-    PrivateData->ResAllocNode[Index].Status    = ResNone;
-  }
-
-  PrivateData->RootBridgeAttrib = Attri;
-
-  PrivateData->Supports    = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | \
-                             EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \
-                             EFI_PCI_ATTRIBUTE_VGA_MEMORY | \
-                             EFI_PCI_ATTRIBUTE_VGA_IO_16  | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
-  PrivateData->Attributes  = PrivateData->Supports;
-
-  Protocol->ParentHandle   = HostBridgeHandle;
-
-  Protocol->PollMem        = RootBridgeIoPollMem;
-  Protocol->PollIo         = RootBridgeIoPollIo;
-
-  Protocol->Mem.Read       = RootBridgeIoMemRead;
-  Protocol->Mem.Write      = RootBridgeIoMemWrite;
-
-  Protocol->Io.Read        = RootBridgeIoIoRead;
-  Protocol->Io.Write       = RootBridgeIoIoWrite;
-
-  Protocol->CopyMem        = RootBridgeIoCopyMem;
-
-  Protocol->Pci.Read       = RootBridgeIoPciRead;
-  Protocol->Pci.Write      = RootBridgeIoPciWrite;
-
-  Protocol->Map            = RootBridgeIoMap;
-  Protocol->Unmap          = RootBridgeIoUnmap;
-
-  Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;
-  Protocol->FreeBuffer     = RootBridgeIoFreeBuffer;
-
-  Protocol->Flush          = RootBridgeIoFlush;
-
-  Protocol->GetAttributes  = RootBridgeIoGetAttributes;
-  Protocol->SetAttributes  = RootBridgeIoSetAttributes;
-
-  Protocol->Configuration  = RootBridgeIoConfiguration;
-
-  Protocol->SegmentNumber  = 0;
-
-  Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)&mMetronome);
-  ASSERT_EFI_ERROR (Status);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO.
-
-  The I/O operations are carried out exactly as requested. The caller is responsible
-  for satisfying any alignment and I/O width restrictions that a PI System on a
-  platform might require. For example on some platforms, width requests of
-  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
-  be handled by the driver.
-
-  @param[in] This           A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-  @param[in] OperationType  I/O operation type: IO/MMIO/PCI.
-  @param[in] Width          Signifies the width of the I/O or Memory operation.
-  @param[in] Address        The base address of the I/O operation.
-  @param[in] Count          The number of I/O operations to perform. The number of
-                            bytes moved is Width size * Count, starting at Address.
-  @param[in] Buffer         For read operations, the destination buffer to store the results.
-                            For write operations, the source buffer from which to write data.
-
-  @retval EFI_SUCCESS            The parameters for this request pass the checks.
-  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
-  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
-  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
-                                 and Count is not valid for this PI system.
-
-**/
-EFI_STATUS
-RootBridgeIoCheckParameter (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN OPERATION_TYPE                         OperationType,
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN UINT64                                 Address,
-  IN UINTN                                  Count,
-  IN VOID                                   *Buffer
-  )
-{
-  PCI_ROOT_BRIDGE_INSTANCE                     *PrivateData;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  *PciRbAddr;
-  UINT32                                       Stride;
-  UINT64                                       Base;
-  UINT64                                       Limit;
-
-  //
-  // Check to see if Buffer is NULL
-  //
-  if (Buffer == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Check to see if Width is in the valid range
-  //
-  if ((UINT32)Width >= EfiPciWidthMaximum) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // For FIFO type, the target address won't increase during the access,
-  // so treat Count as 1
-  //
-  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
-    Count = 1;
-  }
-
-  //
-  // Check to see if Width is in the valid range for I/O Port operations
-  //
-  Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
-  if ((OperationType != MemOperation) && (Width == EfiPciWidthUint64)) {
-    ASSERT (FALSE);
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Check to see if Address is aligned
-  //
-  Stride = mInStride[Width];
-  if ((Address & (UINT64)(Stride - 1)) != 0) {
-    return EFI_UNSUPPORTED;
-  }
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
-
-  //
-  // Check to see if any address associated with this transfer exceeds the maximum
-  // allowed address.  The maximum address implied by the parameters passed in is
-  // Address + Size * Count.  If the following condition is met, then the transfer
-  // is not supported.
-  //
-  //    Address + Size * Count > Limit + 1
-  //
-  // Since Limit can be the maximum integer value supported by the CPU and Count
-  // can also be the maximum integer value supported by the CPU, this range
-  // check must be adjusted to avoid all oveflow conditions.
-  //
-  if (OperationType == IoOperation) {
-    Base = PrivateData->IoBase;
-    Limit = PrivateData->IoLimit;
-  } else if (OperationType == MemOperation) {
-    Base = PrivateData->MemBase;
-    Limit = PrivateData->MemLimit;
-  } else {
-    PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;
-    if (PciRbAddr->Bus < PrivateData->BusBase || PciRbAddr->Bus > PrivateData->BusLimit) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    if (PciRbAddr->Device > MAX_PCI_DEVICE_NUMBER || PciRbAddr->Function > MAX_PCI_FUNCTION_NUMBER) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    if (PciRbAddr->ExtendedRegister != 0) {
-      Address = PciRbAddr->ExtendedRegister;
-    } else {
-      Address = PciRbAddr->Register;
-    }
-    Base = 0;
-    Limit = MAX_PCI_REG_ADDRESS;
-  }
-
-  if (Limit < Address) {
-      return EFI_INVALID_PARAMETER;
-  }
-
-  if (Address < Base) {
-      return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Base <= Address <= Limit
-  //
-  if (Address == 0 && Limit == MAX_UINT64) {
-    //
-    // 2^64 bytes are valid to transfer. With Stride == 1, that's simply
-    // impossible to reach in Count; with Stride in {2, 4, 8}, we can divide
-    // both 2^64 and Stride with 2.
-    //
-    if (Stride > 1 && Count > DivU64x32 (BIT63, Stride / 2)) {
-      return EFI_UNSUPPORTED;
-    }
-  } else {
-    //
-    // (Limit - Address) does not wrap, and it is smaller than MAX_UINT64.
-    //
-    if (Count > DivU64x32 (Limit - Address + 1, Stride)) {
-      return EFI_UNSUPPORTED;
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-   Internal help function for read and write memory space.
-
-   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Write         Switch value for Read or Write.
-   @param[in]   Width         Signifies the width of the memory operations.
-   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
-                              moved is Width size * Count, starting at Address.
-   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
-                              write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-RootBridgeIoMemRW (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     BOOLEAN                                Write,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  IN OUT VOID                                   *Buffer
-  )
-{
-  EFI_STATUS                             Status;
-  UINT8                                  InStride;
-  UINT8                                  OutStride;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  OperationWidth;
-  UINT8                                  *Uint8Buffer;
-
-  Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  InStride = mInStride[Width];
-  OutStride = mOutStride[Width];
-  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
-  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
-    if (Write) {
-      switch (OperationWidth) {
-        case EfiPciWidthUint8:
-          MmioWrite8 ((UINTN)Address, *Uint8Buffer);
-          break;
-        case EfiPciWidthUint16:
-          MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
-          break;
-        case EfiPciWidthUint32:
-          MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
-          break;
-        case EfiPciWidthUint64:
-          MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
-          break;
-        default:
-          //
-          // The RootBridgeIoCheckParameter call above will ensure that this
-          // path is not taken.
-          //
-          ASSERT (FALSE);
-          break;
-      }
-    } else {
-      switch (OperationWidth) {
-        case EfiPciWidthUint8:
-          *Uint8Buffer = MmioRead8 ((UINTN)Address);
-          break;
-        case EfiPciWidthUint16:
-          *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
-          break;
-        case EfiPciWidthUint32:
-          *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
-          break;
-        case EfiPciWidthUint64:
-          *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
-          break;
-        default:
-          //
-          // The RootBridgeIoCheckParameter call above will ensure that this
-          // path is not taken.
-          //
-          ASSERT (FALSE);
-          break;
-      }
-    }
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-   Internal help function for read and write IO space.
-
-   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Write         Switch value for Read or Write.
-   @param[in]   Width         Signifies the width of the memory operations.
-   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
-                              moved is Width size * Count, starting at Address.
-   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
-                              write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-RootBridgeIoIoRW (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     BOOLEAN                                Write,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  IN OUT VOID                                   *Buffer
-  )
-{
-  EFI_STATUS                             Status;
-  PCI_ROOT_BRIDGE_INSTANCE               *PrivateData;
-  UINT8                                  InStride;
-  UINT8                                  OutStride;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  OperationWidth;
-  UINT8                                  *Uint8Buffer;
-
-  Status = RootBridgeIoCheckParameter (This, IoOperation, Width, Address, Count, Buffer);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
-  //
-  // The addition below is performed in UINT64 modular arithmetic, in
-  // accordance with the definition of PcdPciIoTranslation in
-  // "ArmPlatformPkg.dec". Meaning, the addition below may in fact *decrease*
-  // Address, implementing a negative offset translation.
-  //
-  Address += PrivateData->IoTranslation;
-
-  InStride = mInStride[Width];
-  OutStride = mOutStride[Width];
-  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
-
-  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
-    if (Write) {
-      switch (OperationWidth) {
-        case EfiPciWidthUint8:
-          MmioWrite8 ((UINTN)Address, *Uint8Buffer);
-          break;
-        case EfiPciWidthUint16:
-          MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
-          break;
-        case EfiPciWidthUint32:
-          MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
-          break;
-        default:
-          //
-          // The RootBridgeIoCheckParameter call above will ensure that this
-          // path is not taken.
-          //
-          ASSERT (FALSE);
-          break;
-      }
-    } else {
-      switch (OperationWidth) {
-        case EfiPciWidthUint8:
-          *Uint8Buffer = MmioRead8 ((UINTN)Address);
-          break;
-        case EfiPciWidthUint16:
-          *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
-          break;
-        case EfiPciWidthUint32:
-          *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
-          break;
-        default:
-          //
-          // The RootBridgeIoCheckParameter call above will ensure that this
-          // path is not taken.
-          //
-          ASSERT (FALSE);
-          break;
-      }
-    }
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-   Internal help function for read and write PCI configuration space.
-
-   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Write         Switch value for Read or Write.
-   @param[in]   Width         Signifies the width of the memory operations.
-   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
-                              moved is Width size * Count, starting at Address.
-   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
-                              write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-RootBridgeIoPciRW (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN BOOLEAN                                Write,
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN UINT64                                 Address,
-  IN UINTN                                  Count,
-  IN OUT VOID                               *Buffer
-  )
-{
-  EFI_STATUS                                   Status;
-  UINT8                                        InStride;
-  UINT8                                        OutStride;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH        OperationWidth;
-  UINT8                                        *Uint8Buffer;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  *PciRbAddr;
-  UINTN                                        PcieRegAddr;
-
-  Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;
-
-  PcieRegAddr = (UINTN) PCI_LIB_ADDRESS (
-                          PciRbAddr->Bus,
-                          PciRbAddr->Device,
-                          PciRbAddr->Function,
-                          (PciRbAddr->ExtendedRegister != 0) ? \
-                            PciRbAddr->ExtendedRegister :
-                            PciRbAddr->Register
-                          );
-
-  InStride = mInStride[Width];
-  OutStride = mOutStride[Width];
-  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
-  for (Uint8Buffer = Buffer; Count > 0; PcieRegAddr += InStride, Uint8Buffer += OutStride, Count--) {
-    if (Write) {
-      switch (OperationWidth) {
-        case EfiPciWidthUint8:
-          PciWrite8 (PcieRegAddr, *Uint8Buffer);
-          break;
-        case EfiPciWidthUint16:
-          PciWrite16 (PcieRegAddr, *((UINT16 *)Uint8Buffer));
-          break;
-        case EfiPciWidthUint32:
-          PciWrite32 (PcieRegAddr, *((UINT32 *)Uint8Buffer));
-          break;
-        default:
-          //
-          // The RootBridgeIoCheckParameter call above will ensure that this
-          // path is not taken.
-          //
-          ASSERT (FALSE);
-          break;
-      }
-    } else {
-      switch (OperationWidth) {
-        case EfiPciWidthUint8:
-          *Uint8Buffer = PciRead8 (PcieRegAddr);
-          break;
-        case EfiPciWidthUint16:
-          *((UINT16 *)Uint8Buffer) = PciRead16 (PcieRegAddr);
-          break;
-        case EfiPciWidthUint32:
-          *((UINT32 *)Uint8Buffer) = PciRead32 (PcieRegAddr);
-          break;
-        default:
-          //
-          // The RootBridgeIoCheckParameter call above will ensure that this
-          // path is not taken.
-          //
-          ASSERT (FALSE);
-          break;
-      }
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-   Polls an address in memory mapped I/O space until an exit condition is met, or
-   a timeout occurs.
-
-   This function provides a standard way to poll a PCI memory location. A PCI memory read
-   operation is performed at the PCI memory address specified by Address for the width specified
-   by Width. The result of this PCI memory read operation is stored in Result. This PCI memory
-   read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &
-   Mask) is equal to Value.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operations.
-   @param[in]   Address   The base address of the memory operations. The caller is
-                          responsible for aligning Address if required.
-   @param[in]   Mask      Mask used for the polling criteria. Bytes above Width in Mask
-                          are ignored. The bits in the bytes below Width which are zero in
-                          Mask are ignored when polling the memory address.
-   @param[in]   Value     The comparison value used for the polling exit criteria.
-   @param[in]   Delay     The number of 100 ns units to poll. Note that timer available may
-                          be of poorer granularity.
-   @param[out]  Result    Pointer to the last value read from the memory location.
-
-   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
-   @retval EFI_INVALID_PARAMETER  Width is invalid.
-   @retval EFI_INVALID_PARAMETER  Result is NULL.
-   @retval EFI_TIMEOUT            Delay expired before a match occurred.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPollMem (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN  UINT64                                 Address,
-  IN  UINT64                                 Mask,
-  IN  UINT64                                 Value,
-  IN  UINT64                                 Delay,
-  OUT UINT64                                 *Result
-  )
-{
-  EFI_STATUS  Status;
-  UINT64      NumberOfTicks;
-  UINT32      Remainder;
-
-  if (Result == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if ((UINT32)Width > EfiPciWidthUint64) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // No matter what, always do a single poll.
-  //
-  Status = This->Mem.Read (This, Width, Address, 1, Result);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-  if ((*Result & Mask) == Value) {
-    return EFI_SUCCESS;
-  }
-
-  if (Delay == 0) {
-    return EFI_SUCCESS;
-
-  } else {
-
-    //
-    // Determine the proper # of metronome ticks to wait for polling the
-    // location.  The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
-    // The "+1" to account for the possibility of the first tick being short
-    // because we started in the middle of a tick.
-    //
-    // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome
-    // protocol definition is updated.
-    //
-    NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPeriod, &Remainder);
-    if (Remainder != 0) {
-      NumberOfTicks += 1;
-    }
-    NumberOfTicks += 1;
-
-    while (NumberOfTicks != 0) {
-
-      mMetronome->WaitForTick (mMetronome, 1);
-
-      Status = This->Mem.Read (This, Width, Address, 1, Result);
-      if (EFI_ERROR (Status)) {
-        return Status;
-      }
-
-      if ((*Result & Mask) == Value) {
-        return EFI_SUCCESS;
-      }
-
-      NumberOfTicks -= 1;
-    }
-  }
-  return EFI_TIMEOUT;
-}
-
-/**
-   Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is
-   satisfied or after a defined duration.
-
-   This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is
-   performed at the PCI I/O address specified by Address for the width specified by Width.
-   The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is
-   repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal
-   to Value.
-
-   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in] Width     Signifies the width of the I/O operations.
-   @param[in] Address   The base address of the I/O operations. The caller is responsible
-                        for aligning Address if required.
-   @param[in] Mask      Mask used for the polling criteria. Bytes above Width in Mask
-                        are ignored. The bits in the bytes below Width which are zero in
-                        Mask are ignored when polling the I/O address.
-   @param[in] Value     The comparison value used for the polling exit criteria.
-   @param[in] Delay     The number of 100 ns units to poll. Note that timer available may
-                        be of poorer granularity.
-   @param[out] Result   Pointer to the last value read from the memory location.
-
-   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
-   @retval EFI_INVALID_PARAMETER  Width is invalid.
-   @retval EFI_INVALID_PARAMETER  Result is NULL.
-   @retval EFI_TIMEOUT            Delay expired before a match occurred.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPollIo (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN  UINT64                                 Address,
-  IN  UINT64                                 Mask,
-  IN  UINT64                                 Value,
-  IN  UINT64                                 Delay,
-  OUT UINT64                                 *Result
-  )
-{
-  EFI_STATUS  Status;
-  UINT64      NumberOfTicks;
-  UINT32      Remainder;
-
-  //
-  // No matter what, always do a single poll.
-  //
-
-  if (Result == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if ((UINT32)Width > EfiPciWidthUint64) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Status = This->Io.Read (This, Width, Address, 1, Result);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-  if ((*Result & Mask) == Value) {
-    return EFI_SUCCESS;
-  }
-
-  if (Delay == 0) {
-    return EFI_SUCCESS;
-
-  } else {
-
-    //
-    // Determine the proper # of metronome ticks to wait for polling the
-    // location.  The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
-    // The "+1" to account for the possibility of the first tick being short
-    // because we started in the middle of a tick.
-    //
-    NumberOfTicks = DivU64x32Remainder (Delay, (UINT32)mMetronome->TickPeriod, &Remainder);
-    if (Remainder != 0) {
-      NumberOfTicks += 1;
-    }
-    NumberOfTicks += 1;
-
-    while (NumberOfTicks != 0) {
-
-      mMetronome->WaitForTick (mMetronome, 1);
-
-      Status = This->Io.Read (This, Width, Address, 1, Result);
-      if (EFI_ERROR (Status)) {
-        return Status;
-      }
-
-      if ((*Result & Mask) == Value) {
-        return EFI_SUCCESS;
-      }
-
-      NumberOfTicks -= 1;
-    }
-  }
-  return EFI_TIMEOUT;
-}
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
-
-   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
-   registers in the PCI root bridge memory space.
-   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
-   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operation.
-   @param[in]   Address   The base address of the memory operation. The caller is
-                          responsible for aligning the Address if required.
-   @param[in]   Count     The number of memory operations to perform. Bytes moved is
-                          Width size * Count, starting at Address.
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoMemRead (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  OUT    VOID                                   *Buffer
-  )
-{
-  return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);
-}
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
-
-   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
-   registers in the PCI root bridge memory space.
-   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
-   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operation.
-   @param[in]   Address   The base address of the memory operation. The caller is
-                          responsible for aligning the Address if required.
-   @param[in]   Count     The number of memory operations to perform. Bytes moved is
-                          Width size * Count, starting at Address.
-   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoMemWrite (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  IN     VOID                                   *Buffer
-  )
-{
-  return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer);
-}
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
-
-   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width       Signifies the width of the memory operations.
-   @param[in]   Address     The base address of the I/O operation. The caller is responsible for
-                            aligning the Address if required.
-   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
-                            size * Count, starting at Address.
-   @param[out]  Buffer      For read operations, the destination buffer to store the results. For
-                            write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoIoRead (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN     UINT64                                 Address,
-  IN     UINTN                                  Count,
-  OUT    VOID                                   *Buffer
-  )
-{
-  return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer);
-}
-
-/**
-   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
-
-   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width       Signifies the width of the memory operations.
-   @param[in]   Address     The base address of the I/O operation. The caller is responsible for
-                            aligning the Address if required.
-   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
-                            size * Count, starting at Address.
-   @param[in]   Buffer       For read operations, the destination buffer to store the results. For
-                            write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoIoWrite (
-  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         *This,
-  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH   Width,
-  IN       UINT64                                  Address,
-  IN       UINTN                                   Count,
-  IN       VOID                                    *Buffer
-  )
-{
-  return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer);
-}
-
-/**
-   Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI
-   root bridge memory space.
-
-   The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory
-   space to another region of PCI root bridge memory space. This is especially useful for video scroll
-   operation on a memory mapped video buffer.
-   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
-   any alignment and memory width restrictions that a PCI root bridge on a platform might require.
-
-   @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
-   @param[in] Width       Signifies the width of the memory operations.
-   @param[in] DestAddress The destination address of the memory operation. The caller is
-                          responsible for aligning the DestAddress if required.
-   @param[in] SrcAddress  The source address of the memory operation. The caller is
-                          responsible for aligning the SrcAddress if required.
-   @param[in] Count       The number of memory operations to perform. Bytes moved is
-                          Width size * Count, starting at DestAddress and SrcAddress.
-
-   @retval  EFI_SUCCESS             The data was copied from one memory region to another memory region.
-   @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.
-   @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoCopyMem (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH        Width,
-  IN UINT64                                       DestAddress,
-  IN UINT64                                       SrcAddress,
-  IN UINTN                                        Count
-  )
-{
-  EFI_STATUS  Status;
-  BOOLEAN     Direction;
-  UINTN       Stride;
-  UINTN       Index;
-  UINT64      Result;
-
-  if ((UINT32)Width > EfiPciWidthUint64) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (DestAddress == SrcAddress) {
-    return EFI_SUCCESS;
-  }
-
-  Stride = (UINTN)(1 << Width);
-
-  Direction = TRUE;
-  if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {
-    Direction   = FALSE;
-    SrcAddress  = SrcAddress  + (Count-1) * Stride;
-    DestAddress = DestAddress + (Count-1) * Stride;
-  }
-
-  for (Index = 0;Index < Count;Index++) {
-    Status = RootBridgeIoMemRead (
-               This,
-               Width,
-               SrcAddress,
-               1,
-               &Result
-               );
-    if (EFI_ERROR (Status)) {
-      return Status;
-    }
-    Status = RootBridgeIoMemWrite (
-               This,
-               Width,
-               DestAddress,
-               1,
-               &Result
-               );
-    if (EFI_ERROR (Status)) {
-      return Status;
-    }
-    if (Direction) {
-      SrcAddress  += Stride;
-      DestAddress += Stride;
-    } else {
-      SrcAddress  -= Stride;
-      DestAddress -= Stride;
-    }
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
-
-   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
-   registers for a PCI controller.
-   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
-   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
-   require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operations.
-   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
-                          moved is Width size * Count, starting at Address.
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPciRead (
-  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN       UINT64                                 Address,
-  IN       UINTN                                  Count,
-  OUT      VOID                                   *Buffer
-  )
-{
-  return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
-}
-
-/**
-   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
-
-   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
-   registers for a PCI controller.
-   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
-   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
-   require.
-
-   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]   Width     Signifies the width of the memory operations.
-   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
-   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
-                          moved is Width size * Count, starting at Address.
-   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
-                          write operations, the source buffer to write data from.
-
-   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
-   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoPciWrite (
-  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
-  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
-  IN       UINT64                                 Address,
-  IN       UINTN                                  Count,
-  IN       VOID                                   *Buffer
-  )
-{
-  return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
-}
-
-/**
-   Provides the PCI controller-specific addresses required to access system memory from a
-   DMA bus master.
-
-   The Map() function provides the PCI controller specific addresses needed to access system
-   memory. This function is used to map system memory for PCI bus master DMA accesses.
-
-   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.
-   @param[in]       HostAddress     The system memory address to map to the PCI controller.
-   @param[in, out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.
-   @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use
-                                    to access the system memory's HostAddress.
-   @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.
-
-   @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.
-   @retval EFI_INVALID_PARAMETER  Operation is invalid.
-   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
-   @retval EFI_INVALID_PARAMETER  NumberOfBytes is NULL.
-   @retval EFI_INVALID_PARAMETER  DeviceAddress is NULL.
-   @retval EFI_INVALID_PARAMETER  Mapping is NULL.
-   @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common buffer.
-   @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.
-   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoMap (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL            *This,
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,
-  IN     VOID                                       *HostAddress,
-  IN OUT UINTN                                      *NumberOfBytes,
-  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,
-  OUT    VOID                                       **Mapping
-  )
-{
-  EFI_STATUS            Status;
-  EFI_PHYSICAL_ADDRESS  PhysicalAddress;
-  MAP_INFO              *MapInfo;
-
-  if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Initialize the return values to their defaults
-  //
-  *Mapping = NULL;
-
-  //
-  // Make sure that Operation is valid
-  //
-  if ((UINT32)Operation >= EfiPciOperationMaximum) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Most PCAT like chipsets can not handle performing DMA above 4GB.
-  // If any part of the DMA transfer being mapped is above 4GB, then
-  // map the DMA transfer to a buffer below 4GB.
-  //
-  PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
-  if ((PhysicalAddress + *NumberOfBytes) > 0x100000000ULL) {
-
-    //
-    // Common Buffer operations can not be remapped.  If the common buffer
-    // if above 4GB, then it is not possible to generate a mapping, so return
-    // an error.
-    //
-    if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {
-      return EFI_UNSUPPORTED;
-    }
-
-    //
-    // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
-    // called later.
-    //
-    Status = gBS->AllocatePool (
-                    EfiBootServicesData,
-                    sizeof(MAP_INFO),
-                    (VOID **)&MapInfo
-                    );
-    if (EFI_ERROR (Status)) {
-      *NumberOfBytes = 0;
-      return Status;
-    }
-
-    //
-    // Return a pointer to the MAP_INFO structure in Mapping
-    //
-    *Mapping = MapInfo;
-
-    //
-    // Initialize the MAP_INFO structure
-    //
-    MapInfo->Operation         = Operation;
-    MapInfo->NumberOfBytes     = *NumberOfBytes;
-    MapInfo->NumberOfPages     = EFI_SIZE_TO_PAGES(*NumberOfBytes);
-    MapInfo->HostAddress       = PhysicalAddress;
-    MapInfo->MappedHostAddress = 0x00000000ffffffff;
-
-    //
-    // Allocate a buffer below 4GB to map the transfer to.
-    //
-    Status = gBS->AllocatePages (
-                    AllocateMaxAddress,
-                    EfiBootServicesData,
-                    MapInfo->NumberOfPages,
-                    &MapInfo->MappedHostAddress
-                    );
-    if (EFI_ERROR (Status)) {
-      gBS->FreePool (MapInfo);
-      *NumberOfBytes = 0;
-      return Status;
-    }
-
-    //
-    // If this is a read operation from the Bus Master's point of view,
-    // then copy the contents of the real buffer into the mapped buffer
-    // so the Bus Master can read the contents of the real buffer.
-    //
-    if (Operation == EfiPciOperationBusMasterRead || Operation == EfiPciOperationBusMasterRead64) {
-      CopyMem (
-        (VOID *)(UINTN)MapInfo->MappedHostAddress,
-        (VOID *)(UINTN)MapInfo->HostAddress,
-        MapInfo->NumberOfBytes
-        );
-    }
-
-    //
-    // The DeviceAddress is the address of the maped buffer below 4GB
-    //
-    *DeviceAddress = MapInfo->MappedHostAddress;
-  } else {
-    //
-    // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress
-    //
-    *DeviceAddress = PhysicalAddress;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-   Completes the Map() operation and releases any corresponding resources.
-
-   The Unmap() function completes the Map() operation and releases any corresponding resources.
-   If the operation was an EfiPciOperationBusMasterWrite or
-   EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.
-   Any resources used for the mapping are freed.
-
-   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in] Mapping   The mapping value returned from Map().
-
-   @retval EFI_SUCCESS            The range was unmapped.
-   @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().
-   @retval EFI_DEVICE_ERROR       The data was not committed to the target system memory.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoUnmap (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN VOID                             *Mapping
-  )
-{
-  MAP_INFO    *MapInfo;
-
-  //
-  // See if the Map() operation associated with this Unmap() required a mapping buffer.
-  // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
-  //
-  if (Mapping != NULL) {
-    //
-    // Get the MAP_INFO structure from Mapping
-    //
-    MapInfo = (MAP_INFO *)Mapping;
-
-    //
-    // If this is a write operation from the Bus Master's point of view,
-    // then copy the contents of the mapped buffer into the real buffer
-    // so the processor can read the contents of the real buffer.
-    //
-    if (MapInfo->Operation == EfiPciOperationBusMasterWrite || MapInfo->Operation == EfiPciOperationBusMasterWrite64) {
-      CopyMem (
-        (VOID *)(UINTN)MapInfo->HostAddress,
-        (VOID *)(UINTN)MapInfo->MappedHostAddress,
-        MapInfo->NumberOfBytes
-        );
-    }
-
-    //
-    // Free the mapped buffer and the MAP_INFO structure.
-    //
-    gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
-    gBS->FreePool (Mapping);
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-   Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or
-   EfiPciOperationBusMasterCommonBuffer64 mapping.
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param Type        This parameter is not used and must be ignored.
-   @param MemoryType  The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.
-   @param Pages       The number of pages to allocate.
-   @param HostAddress A pointer to store the base system memory address of the allocated range.
-   @param Attributes  The requested bit mask of attributes for the allocated range. Only
-                      the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED,
-                      and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.
-
-   @retval EFI_SUCCESS            The requested memory pages were allocated.
-   @retval EFI_INVALID_PARAMETER  MemoryType is invalid.
-   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
-   @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal attribute bits are
-                                  MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
-   @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoAllocateBuffer (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN  EFI_ALLOCATE_TYPE                Type,
-  IN  EFI_MEMORY_TYPE                  MemoryType,
-  IN  UINTN                            Pages,
-  OUT VOID                             **HostAddress,
-  IN  UINT64                           Attributes
-  )
-{
-  EFI_STATUS            Status;
-  EFI_PHYSICAL_ADDRESS  PhysicalAddress;
-
-  //
-  // Validate Attributes
-  //
-  if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
-    return EFI_UNSUPPORTED;
-  }
-
-  //
-  // Check for invalid inputs
-  //
-  if (HostAddress == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
-  //
-  if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Limit allocations to memory below 4GB
-  //
-  PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(0xffffffff);
-
-  Status = gBS->AllocatePages (AllocateMaxAddress, MemoryType, Pages, &PhysicalAddress);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  *HostAddress = (VOID *)(UINTN)PhysicalAddress;
-
-  return EFI_SUCCESS;
-}
-
-/**
-   Frees memory that was allocated with AllocateBuffer().
-
-   The FreeBuffer() function frees memory that was allocated with AllocateBuffer().
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param Pages       The number of pages to free.
-   @param HostAddress The base system memory address of the allocated range.
-
-   @retval EFI_SUCCESS            The requested memory pages were freed.
-   @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and Pages
-                                  was not allocated with AllocateBuffer().
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoFreeBuffer (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN  UINTN                            Pages,
-  OUT VOID                             *HostAddress
-  )
-{
-  return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);
-}
-
-/**
-   Flushes all PCI posted write transactions from a PCI host bridge to system memory.
-
-   The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system
-   memory. Posted write transactions are generated by PCI bus masters when they perform write
-   transactions to target addresses in system memory.
-   This function does not flush posted write transactions from any PCI bridges. A PCI controller
-   specific action must be taken to guarantee that the posted write transactions have been flushed from
-   the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with
-   a PCI read transaction from the PCI controller prior to calling Flush().
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-
-   @retval EFI_SUCCESS        The PCI posted write transactions were flushed from the PCI host
-                              bridge to system memory.
-   @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed from the PCI
-                              host bridge due to a hardware error.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoFlush (
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This
-  )
-{
-  //
-  // not supported yet
-  //
-  return EFI_SUCCESS;
-}
-
-/**
-   Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the
-   attributes that a PCI root bridge is currently using.
-
-   The GetAttributes() function returns the mask of attributes that this PCI root bridge supports
-   and the mask of attributes that the PCI root bridge is currently using.
-
-   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param Supported   A pointer to the mask of attributes that this PCI root bridge
-                      supports setting with SetAttributes().
-   @param Attributes  A pointer to the mask of attributes that this PCI root bridge is
-                      currently using.
-
-   @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI root
-                                  bridge supports is returned in Supports. If Attributes is
-                                  not NULL, then the attributes that the PCI root bridge is currently
-                                  using is returned in Attributes.
-   @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoGetAttributes (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  OUT UINT64                           *Supported,
-  OUT UINT64                           *Attributes
-  )
-{
-  PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
-
-  if (Attributes == NULL && Supported == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Set the return value for Supported and Attributes
-  //
-  if (Supported != NULL) {
-    *Supported  = PrivateData->Supports;
-  }
-
-  if (Attributes != NULL) {
-    *Attributes = PrivateData->Attributes;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-   Sets attributes for a resource range on a PCI root bridge.
-
-   The SetAttributes() function sets the attributes specified in Attributes for the PCI root
-   bridge on the resource range specified by ResourceBase and ResourceLength. Since the
-   granularity of setting these attributes may vary from resource type to resource type, and from
-   platform to platform, the actual resource range and the one passed in by the caller may differ. As a
-   result, this function may set the attributes specified by Attributes on a larger resource range
-   than the caller requested. The actual range is returned in ResourceBase and
-   ResourceLength. The caller is responsible for verifying that the actual range for which the
-   attributes were set is acceptable.
-
-   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[in]       Attributes      The mask of attributes to set. If the attribute bit
-                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, or
-                                    MEMORY_DISABLE is set, then the resource range is specified by
-                                    ResourceBase and ResourceLength. If
-                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
-                                    MEMORY_DISABLE are not set, then ResourceBase and
-                                    ResourceLength are ignored, and may be NULL.
-   @param[in, out]  ResourceBase    A pointer to the base address of the resource range to be modified
-                                    by the attributes specified by Attributes.
-   @param[in, out]  ResourceLength  A pointer to the length of the resource range to be modified by the
-                                    attributes specified by Attributes.
-
-   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
-   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
-   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoSetAttributes (
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
-  IN     UINT64                           Attributes,
-  IN OUT UINT64                           *ResourceBase,
-  IN OUT UINT64                           *ResourceLength
-  )
-{
-  PCI_ROOT_BRIDGE_INSTANCE            *PrivateData;
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
-
-  if (Attributes != 0) {
-    if ((Attributes & (~(PrivateData->Supports))) != 0) {
-      return EFI_UNSUPPORTED;
-    }
-  }
-
-  //
-  // This is a generic driver for a PC-AT class system.  It does not have any
-  // chipset specific knowlegde, so none of the attributes can be set or
-  // cleared.  Any attempt to set attribute that are already set will succeed,
-  // and any attempt to set an attribute that is not supported will fail.
-  //
-  if (Attributes & (~PrivateData->Attributes)) {
-    return EFI_UNSUPPORTED;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-   Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0
-   resource descriptors.
-
-   There are only two resource descriptor types from the ACPI Specification that may be used to
-   describe the current resources allocated to a PCI root bridge. These are the QWORD Address
-   Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The
-   QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic
-   or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD
-   Address Space Descriptors followed by an End Tag.
-
-   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
-   @param[out]  Resources   A pointer to the ACPI 2.0 resource descriptors that describe the
-                            current configuration of this PCI root bridge. The storage for the
-                            ACPI 2.0 resource descriptors is allocated by this function. The
-                            caller must treat the return buffer as read-only data, and the buffer
-                            must not be freed by the caller.
-
-   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
-   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
-   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
-
-**/
-EFI_STATUS
-EFIAPI
-RootBridgeIoConfiguration (
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *This,
-  OUT VOID                                **Resources
-  )
-{
-  PCI_ROOT_BRIDGE_INSTANCE              *PrivateData;
-  UINTN                                 Index;
-
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
-
-  for (Index = 0; Index < TypeMax; Index++) {
-    if (PrivateData->ResAllocNode[Index].Status == ResAllocated) {
-      Configuration.SpaceDesp[Index].AddrRangeMin = PrivateData->ResAllocNode[Index].Base;
-      Configuration.SpaceDesp[Index].AddrRangeMax = PrivateData->ResAllocNode[Index].Base + PrivateData->ResAllocNode[Index].Length - 1;
-      Configuration.SpaceDesp[Index].AddrLen      = PrivateData->ResAllocNode[Index].Length;
-    }
-  }
-
-  *Resources = &Configuration;
-  return EFI_SUCCESS;
-}
-
