]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c
Add PciBus & IdeBus
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / PciBus / Dxe / PciEnumerator.c
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c
new file mode 100644 (file)
index 0000000..e7a05a2
--- /dev/null
@@ -0,0 +1,2168 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  PciEnumerator.c\r
+\r
+Abstract:\r
+\r
+  PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+#include "PciEnumerator.h"\r
+#include "PciResourceSupport.h"\r
+#include "PciOptionRomSupport.h"\r
+\r
+EFI_STATUS\r
+PciEnumerator (\r
+  IN EFI_HANDLE                    Controller\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine is used to enumerate entire pci bus system\r
+  in a given platform\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    Controller - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+  EFI_HANDLE                                        HostBridgeHandle;\r
+  EFI_STATUS                                        Status;\r
+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL                   *PciRootBridgeIo;\r
+\r
+  //\r
+  // If PCI bus has already done the full enumeration, never do it again\r
+  //\r
+  if (!gFullEnumeration) {\r
+    return PciEnumeratorLight (Controller);\r
+  }\r
+\r
+  //\r
+  // If this host bridge has been already enumerated, then return successfully\r
+  //\r
+  if (RootBridgeExisted (Controller)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Get the rootbridge Io protocol to find the host bridge handle\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiPciRootBridgeIoProtocolGuid,\r
+                  (VOID **) &PciRootBridgeIo,\r
+                  gPciBusDriverBinding.DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Get the host bridge handle\r
+  //\r
+  HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
+\r
+  //\r
+  // Get the pci host bridge resource allocation protocol\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  HostBridgeHandle,\r
+                  &gEfiPciHostBridgeResourceAllocationProtocolGuid,\r
+                  (VOID **) &PciResAlloc,\r
+                  gPciBusDriverBinding.DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Notify the pci bus enumeration is about to begin\r
+  //\r
+  NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration);\r
+\r
+  //\r
+  // Start the bus allocation phase\r
+  //\r
+  Status = PciHostBridgeEnumerator (PciResAlloc);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Submit the resource request\r
+  //\r
+  Status = PciHostBridgeResourceAllocator (PciResAlloc);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Process P2C\r
+  //\r
+  Status = PciHostBridgeP2CProcess (PciResAlloc);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Process attributes for devices on this host bridge\r
+  //\r
+  Status = PciHostBridgeDeviceAttribute (PciResAlloc);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  gFullEnumeration = FALSE;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciRootBridgeEnumerator (\r
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc,\r
+  IN PCI_IO_DEVICE                                     *RootBridgeDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciResAlloc - add argument and description to function comment\r
+// TODO:    RootBridgeDev - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *pConfiguration;\r
+  UINT8                             SubBusNumber;\r
+  UINT8                             StartBusNumber;\r
+  UINT8                             PaddedBusRange;\r
+  EFI_HANDLE                        RootBridgeHandle;\r
+\r
+  SubBusNumber    = 0;\r
+  StartBusNumber  = 0;\r
+  PaddedBusRange  = 0;\r
+\r
+  //\r
+  // Get the root bridge handle\r
+  //\r
+  RootBridgeHandle = RootBridgeDev->Handle;\r
+\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_BUS_ENUM,\r
+    RootBridgeDev->DevicePath\r
+    );\r
+\r
+  //\r
+  // Get the Bus information\r
+  //\r
+  Status = PciResAlloc->StartBusEnumeration (\r
+                          PciResAlloc,\r
+                          RootBridgeHandle,\r
+                          (VOID **) &pConfiguration\r
+                          );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Get the bus number to start with\r
+  //\r
+  StartBusNumber = (UINT8) (pConfiguration->AddrRangeMin);\r
+\r
+  //\r
+  // Initialize the subordinate bus number\r
+  //\r
+  SubBusNumber = StartBusNumber;\r
+\r
+  //\r
+  // Assign bus number\r
+  //\r
+  Status = PciScanBus (\r
+            RootBridgeDev,\r
+            (UINT8) (pConfiguration->AddrRangeMin),\r
+            &SubBusNumber,\r
+            &PaddedBusRange\r
+            );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+\r
+  //\r
+  // Assign max bus number scanned\r
+  //\r
+  pConfiguration->AddrLen = SubBusNumber - StartBusNumber + 1 + PaddedBusRange;\r
+\r
+  //\r
+  // Set bus number\r
+  //\r
+  Status = PciResAlloc->SetBusNumbers (\r
+                          PciResAlloc,\r
+                          RootBridgeHandle,\r
+                          pConfiguration\r
+                          );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+ProcessOptionRom (\r
+  IN PCI_IO_DEVICE *Bridge,\r
+  IN UINT64        RomBase,\r
+  IN UINT64        MaxLength\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine is used to process option rom on a certain root bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    Bridge - add argument and description to function comment\r
+// TODO:    RomBase - add argument and description to function comment\r
+// TODO:    MaxLength - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  LIST_ENTRY      *CurrentLink;\r
+  PCI_IO_DEVICE   *Temp;\r
+  EFI_STATUS      Status;\r
+\r
+  //\r
+  // Go through bridges to reach all devices\r
+  //\r
+  CurrentLink = Bridge->ChildList.ForwardLink;\r
+  while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+    if (!IsListEmpty (&Temp->ChildList)) {\r
+\r
+      //\r
+      // Go further to process the option rom under this bridge\r
+      //\r
+      Status = ProcessOptionRom (Temp, RomBase, MaxLength);\r
+    }\r
+\r
+    if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) {\r
+\r
+      //\r
+      // Load and process the option rom\r
+      //\r
+      Status = LoadOpRomImage (Temp, RomBase);\r
+      if (Status == EFI_SUCCESS) {\r
+        Status = ProcessOpRomImage (Temp);\r
+      }\r
+    }\r
+\r
+    CurrentLink = CurrentLink->ForwardLink;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciAssignBusNumber (\r
+  IN PCI_IO_DEVICE                      *Bridge,\r
+  IN UINT8                              StartBusNumber,\r
+  OUT UINT8                             *SubBusNumber\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine is used to assign bus number to the given PCI bus system\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    Bridge - add argument and description to function comment\r
+// TODO:    StartBusNumber - add argument and description to function comment\r
+// TODO:    SubBusNumber - add argument and description to function comment\r
+// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  EFI_STATUS                      Status;\r
+  PCI_TYPE00                      Pci;\r
+  UINT8                           Device;\r
+  UINT8                           Func;\r
+  UINT64                          Address;\r
+  UINTN                           SecondBus;\r
+  UINT16                          Register;\r
+  UINT8                           Register8;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+  PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
+\r
+  SecondBus       = 0;\r
+  Register        = 0;\r
+\r
+  *SubBusNumber = StartBusNumber;\r
+\r
+  //\r
+  // First check to see whether the parent is ppb\r
+  //\r
+  for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
+    for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
+\r
+      //\r
+      // Check to see whether a pci device is present\r
+      //\r
+\r
+      Status = PciDevicePresent (\r
+                PciRootBridgeIo,\r
+                &Pci,\r
+                StartBusNumber,\r
+                Device,\r
+                Func\r
+                );\r
+\r
+      if (!EFI_ERROR (Status)   &&\r
+          (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {\r
+\r
+        //\r
+        // Reserved one bus for cardbus bridge\r
+        //\r
+        SecondBus = ++(*SubBusNumber);\r
+\r
+        Register  = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
+\r
+        Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
+\r
+        Status = PciRootBridgeIoWrite (\r
+                                        PciRootBridgeIo,\r
+                                        &Pci,\r
+                                        EfiPciWidthUint16,\r
+                                        Address,\r
+                                        1,\r
+                                        &Register\r
+                                        );\r
+\r
+        //\r
+        // Initialize SubBusNumber to SecondBus\r
+        //\r
+        Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
+        Status = PciRootBridgeIoWrite (\r
+                                        PciRootBridgeIo,\r
+                                        &Pci,\r
+                                        EfiPciWidthUint8,\r
+                                        Address,\r
+                                        1,\r
+                                        SubBusNumber\r
+                                        );\r
+        //\r
+        // If it is PPB, resursively search down this bridge\r
+        //\r
+        if (IS_PCI_BRIDGE (&Pci)) {\r
+\r
+          Register8 = 0xFF;\r
+          Status = PciRootBridgeIoWrite (\r
+                                          PciRootBridgeIo,\r
+                                          &Pci,\r
+                                          EfiPciWidthUint8,\r
+                                          Address,\r
+                                          1,\r
+                                          &Register8\r
+                                          );\r
+\r
+          Status = PciAssignBusNumber (\r
+                    Bridge,\r
+                    (UINT8) (SecondBus),\r
+                    SubBusNumber\r
+                    );\r
+\r
+          if (EFI_ERROR (Status)) {\r
+            return EFI_DEVICE_ERROR;\r
+          }\r
+        }\r
+\r
+        //\r
+        // Set the current maximum bus number under the PPB\r
+        //\r
+\r
+        Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
+\r
+        Status = PciRootBridgeIoWrite (\r
+                                        PciRootBridgeIo,\r
+                                        &Pci,\r
+                                        EfiPciWidthUint8,\r
+                                        Address,\r
+                                        1,\r
+                                        SubBusNumber\r
+                                        );\r
+\r
+      }\r
+\r
+      if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
+\r
+        //\r
+        // Skip sub functions, this is not a multi function device\r
+        //\r
+\r
+        Func = PCI_MAX_FUNC;\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DetermineRootBridgeAttributes (\r
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
+  IN PCI_IO_DEVICE                                    *RootBridgeDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine is used to determine the root bridge attribute by interfacing\r
+  the host bridge resource allocation protocol.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciResAlloc - add argument and description to function comment\r
+// TODO:    RootBridgeDev - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  UINT64      Attributes;\r
+  EFI_STATUS  Status;\r
+  EFI_HANDLE  RootBridgeHandle;\r
+\r
+  Attributes        = 0;\r
+  RootBridgeHandle  = RootBridgeDev->Handle;\r
+\r
+  //\r
+  // Get root bridge attribute by calling into pci host bridge resource allocation protocol\r
+  //\r
+  Status = PciResAlloc->GetAllocAttributes (\r
+                          PciResAlloc,\r
+                          RootBridgeHandle,\r
+                          &Attributes\r
+                          );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Here is the point where PCI bus driver calls HOST bridge allocation protocol\r
+  // Currently we hardcoded for ea815\r
+  //\r
+\r
+  if (Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) {\r
+    RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED;\r
+  }\r
+\r
+  if (Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) {\r
+    RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;\r
+  }\r
+\r
+  RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;\r
+  RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
+  RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+UINT64\r
+GetMaxOptionRomSize (\r
+  IN PCI_IO_DEVICE   *Bridge\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+    Get Max Option Rom size on this bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    Bridge - add argument and description to function comment\r
+{\r
+  LIST_ENTRY      *CurrentLink;\r
+  PCI_IO_DEVICE   *Temp;\r
+  UINT64          MaxOptionRomSize;\r
+  UINT64          TempOptionRomSize;\r
+\r
+  MaxOptionRomSize = 0;\r
+\r
+  //\r
+  // Go through bridges to reach all devices\r
+  //\r
+  CurrentLink = Bridge->ChildList.ForwardLink;\r
+  while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+    if (!IsListEmpty (&Temp->ChildList)) {\r
+\r
+      //\r
+      // Get max option rom size under this bridge\r
+      //\r
+      TempOptionRomSize = GetMaxOptionRomSize (Temp);\r
+\r
+      //\r
+      // Compare with the option rom size of the bridge\r
+      // Get the larger one\r
+      //\r
+      if (Temp->RomSize > TempOptionRomSize) {\r
+        TempOptionRomSize = Temp->RomSize;\r
+      }\r
+\r
+    } else {\r
+\r
+      //\r
+      // For devices get the rom size directly\r
+      //\r
+      TempOptionRomSize = Temp->RomSize;\r
+    }\r
+\r
+    //\r
+    // Get the largest rom size on this bridge\r
+    //\r
+    if (TempOptionRomSize > MaxOptionRomSize) {\r
+      MaxOptionRomSize = TempOptionRomSize;\r
+    }\r
+\r
+    CurrentLink = CurrentLink->ForwardLink;\r
+  }\r
+\r
+  return MaxOptionRomSize;\r
+}\r
+\r
+EFI_STATUS\r
+PciHostBridgeDeviceAttribute (\r
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+    Process attributes of devices on this host bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciResAlloc - add argument and description to function comment\r
+// TODO:    EFI_NOT_FOUND - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  EFI_HANDLE    RootBridgeHandle;\r
+  PCI_IO_DEVICE *RootBridgeDev;\r
+  EFI_STATUS    Status;\r
+\r
+  RootBridgeHandle = NULL;\r
+\r
+  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+\r
+    //\r
+    // Get RootBridg Device by handle\r
+    //\r
+    RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
+\r
+    if (RootBridgeDev == NULL) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+\r
+    //\r
+    // Set the attributes for devcies behind the Root Bridge\r
+    //\r
+    Status = DetermineDeviceAttribute (RootBridgeDev);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetResourceAllocationStatus (\r
+  VOID        *AcpiConfig,\r
+  OUT UINT64  *IoResStatus,\r
+  OUT UINT64  *Mem32ResStatus,\r
+  OUT UINT64  *PMem32ResStatus,\r
+  OUT UINT64  *Mem64ResStatus,\r
+  OUT UINT64  *PMem64ResStatus\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+    Get resource allocation status from the ACPI pointer\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    AcpiConfig - add argument and description to function comment\r
+// TODO:    IoResStatus - add argument and description to function comment\r
+// TODO:    Mem32ResStatus - add argument and description to function comment\r
+// TODO:    PMem32ResStatus - add argument and description to function comment\r
+// TODO:    Mem64ResStatus - add argument and description to function comment\r
+// TODO:    PMem64ResStatus - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+  UINT8                             *Temp;\r
+  UINT64                            ResStatus;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;\r
+\r
+  Temp = (UINT8 *) AcpiConfig;\r
+\r
+  while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
+\r
+    ptr       = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;\r
+    ResStatus = ptr->AddrTranslationOffset;\r
+\r
+    switch (ptr->ResType) {\r
+    case 0:\r
+      if (ptr->AddrSpaceGranularity == 32) {\r
+        if (ptr->SpecificFlag == 0x06) {\r
+          //\r
+          // Pmem32\r
+          //\r
+          *PMem32ResStatus = ResStatus;\r
+        } else {\r
+          //\r
+          // Mem32\r
+          //\r
+          *Mem32ResStatus = ResStatus;\r
+        }\r
+      }\r
+\r
+      if (ptr->AddrSpaceGranularity == 64) {\r
+        if (ptr->SpecificFlag == 0x06) {\r
+          //\r
+          // PMem64\r
+          //\r
+          *PMem64ResStatus = ResStatus;\r
+        } else {\r
+          //\r
+          // Mem64\r
+          //\r
+          *Mem64ResStatus = ResStatus;\r
+        }\r
+      }\r
+\r
+      break;\r
+\r
+    case 1:\r
+      //\r
+      // Io\r
+      //\r
+      *IoResStatus = ResStatus;\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+\r
+    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+RejectPciDevice (\r
+  IN PCI_IO_DEVICE       *PciDevice\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+    Remove a PCI device from device pool and mark its bar\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciDevice - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_ABORTED - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_ABORTED - add return value to function comment\r
+{\r
+  PCI_IO_DEVICE   *Bridge;\r
+  PCI_IO_DEVICE   *Temp;\r
+  LIST_ENTRY      *CurrentLink;\r
+\r
+  //\r
+  // Remove the padding resource from a bridge\r
+  //\r
+  if ( IS_PCI_BRIDGE(&PciDevice->Pci) && \\r
+       PciDevice->ResourcePaddingDescriptors ) {\r
+    gBS->FreePool (PciDevice->ResourcePaddingDescriptors);\r
+    PciDevice->ResourcePaddingDescriptors = NULL;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Skip RB and PPB\r
+  //\r
+  if (IS_PCI_BRIDGE (&PciDevice->Pci) || (!PciDevice->Parent)) {\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) {\r
+    //\r
+    // Get the root bridge device\r
+    //\r
+    Bridge = PciDevice;\r
+    while (Bridge->Parent) {\r
+      Bridge = Bridge->Parent;\r
+    }\r
+\r
+    RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice);\r
+\r
+    //\r
+    // Mark its bar\r
+    //\r
+    InitializeP2C (PciDevice);\r
+  }\r
+\r
+  //\r
+  // Remove the device\r
+  //\r
+  Bridge      = PciDevice->Parent;\r
+  CurrentLink = Bridge->ChildList.ForwardLink;\r
+  while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+    if (Temp == PciDevice) {\r
+      InitializePciDevice (Temp);\r
+      RemoveEntryList (CurrentLink);\r
+      FreePciDevice (Temp);\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    CurrentLink = CurrentLink->ForwardLink;\r
+  }\r
+\r
+  return EFI_ABORTED;\r
+}\r
+\r
+BOOLEAN\r
+IsRejectiveDevice (\r
+  IN  PCI_RESOURCE_NODE   *PciResNode\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+    Determine whethter a PCI device can be rejected\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciResNode - add argument and description to function comment\r
+{\r
+  PCI_IO_DEVICE *Temp;\r
+\r
+  Temp = PciResNode->PciDev;\r
+\r
+  //\r
+  // Ensure the device is present\r
+  //\r
+  if (!Temp) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // PPB and RB should go ahead\r
+  //\r
+  if (IS_PCI_BRIDGE (&Temp->Pci) || (!Temp->Parent)) {\r
+    return TRUE;\r
+  }\r
+\r
+  //\r
+  // Skip device on Bus0\r
+  //\r
+  if ((Temp->Parent) && (Temp->BusNumber == 0)) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Skip VGA\r
+  //\r
+  if (IS_PCI_VGA (&Temp->Pci)) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+PCI_RESOURCE_NODE *\r
+GetLargerConsumerDevice (\r
+  IN  PCI_RESOURCE_NODE   *PciResNode1,\r
+  IN  PCI_RESOURCE_NODE   *PciResNode2\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+    Get the larger resource consumer\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciResNode1 - add argument and description to function comment\r
+// TODO:    PciResNode2 - add argument and description to function comment\r
+{\r
+  if (!PciResNode2) {\r
+    return PciResNode1;\r
+  }\r
+\r
+  if ((IS_PCI_BRIDGE(&(PciResNode2->PciDev->Pci)) || !(PciResNode2->PciDev->Parent)) \\r
+       && (PciResNode2->ResourceUsage != PciResUsagePadding) )\r
+  {\r
+    return PciResNode1;\r
+  }\r
+\r
+  if (!PciResNode1) {\r
+    return PciResNode2;\r
+  }\r
+\r
+  if ((PciResNode1->Length) > (PciResNode2->Length)) {\r
+    return PciResNode1;\r
+  }\r
+\r
+  return PciResNode2;\r
+\r
+}\r
+\r
+PCI_RESOURCE_NODE *\r
+GetMaxResourceConsumerDevice (\r
+  IN  PCI_RESOURCE_NODE   *ResPool\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+    Get the max resource consumer in the host resource pool\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    ResPool - add argument and description to function comment\r
+{\r
+  PCI_RESOURCE_NODE *Temp;\r
+  LIST_ENTRY        *CurrentLink;\r
+  PCI_RESOURCE_NODE *PciResNode;\r
+  PCI_RESOURCE_NODE *PPBResNode;\r
+\r
+  PciResNode  = NULL;\r
+\r
+  CurrentLink = ResPool->ChildList.ForwardLink;\r
+  while (CurrentLink && CurrentLink != &ResPool->ChildList) {\r
+\r
+    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+    if (!IsRejectiveDevice (Temp)) {\r
+      CurrentLink = CurrentLink->ForwardLink;\r
+      continue;\r
+    }\r
+\r
+    if ((IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (!Temp->PciDev->Parent)) \\r
+          && (Temp->ResourceUsage != PciResUsagePadding))\r
+    {\r
+      PPBResNode  = GetMaxResourceConsumerDevice (Temp);\r
+      PciResNode  = GetLargerConsumerDevice (PciResNode, PPBResNode);\r
+    } else {\r
+      PciResNode = GetLargerConsumerDevice (PciResNode, Temp);\r
+    }\r
+\r
+    CurrentLink = CurrentLink->ForwardLink;\r
+  }\r
+\r
+  return PciResNode;\r
+}\r
+\r
+EFI_STATUS\r
+PciHostBridgeAdjustAllocation (\r
+  IN  PCI_RESOURCE_NODE   *IoPool,\r
+  IN  PCI_RESOURCE_NODE   *Mem32Pool,\r
+  IN  PCI_RESOURCE_NODE   *PMem32Pool,\r
+  IN  PCI_RESOURCE_NODE   *Mem64Pool,\r
+  IN  PCI_RESOURCE_NODE   *PMem64Pool,\r
+  IN  UINT64              IoResStatus,\r
+  IN  UINT64              Mem32ResStatus,\r
+  IN  UINT64              PMem32ResStatus,\r
+  IN  UINT64              Mem64ResStatus,\r
+  IN  UINT64              PMem64ResStatus\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+    Adjust host bridge allocation so as to reduce resource requirement\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    IoPool - add argument and description to function comment\r
+// TODO:    Mem32Pool - add argument and description to function comment\r
+// TODO:    PMem32Pool - add argument and description to function comment\r
+// TODO:    Mem64Pool - add argument and description to function comment\r
+// TODO:    PMem64Pool - add argument and description to function comment\r
+// TODO:    IoResStatus - add argument and description to function comment\r
+// TODO:    Mem32ResStatus - add argument and description to function comment\r
+// TODO:    PMem32ResStatus - add argument and description to function comment\r
+// TODO:    Mem64ResStatus - add argument and description to function comment\r
+// TODO:    PMem64ResStatus - add argument and description to function comment\r
+// TODO:    EFI_ABORTED - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_ABORTED - add return value to function comment\r
+{\r
+  BOOLEAN                               AllocationAjusted;\r
+  PCI_RESOURCE_NODE                     *PciResNode;\r
+  PCI_RESOURCE_NODE                     *ResPool[5];\r
+  PCI_IO_DEVICE                         *RemovedPciDev[5];\r
+  UINT64                                ResStatus[5];\r
+  UINTN                                 RemovedPciDevNum;\r
+  UINTN                                 DevIndex;\r
+  UINTN                                 ResType;\r
+  EFI_STATUS                            Status;\r
+  REPORT_STATUS_CODE_LIBRARY_RESOURCE_ALLOC_FAILURE_ERROR_DATA AllocFailExtendedData;\r
+\r
+  PciResNode = NULL;\r
+  ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *));\r
+  RemovedPciDevNum  = 0;\r
+\r
+  ResPool[0]        = IoPool;\r
+  ResPool[1]        = Mem32Pool;\r
+  ResPool[2]        = PMem32Pool;\r
+  ResPool[3]        = Mem64Pool;\r
+  ResPool[4]        = PMem64Pool;\r
+\r
+  ResStatus[0]      = IoResStatus;\r
+  ResStatus[1]      = Mem32ResStatus;\r
+  ResStatus[2]      = PMem32ResStatus;\r
+  ResStatus[3]      = Mem64ResStatus;\r
+  ResStatus[4]      = PMem64ResStatus;\r
+\r
+  AllocationAjusted = FALSE;\r
+\r
+  for (ResType = 0; ResType < 5; ResType++) {\r
+\r
+    if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) {\r
+      continue;\r
+    }\r
+\r
+    if (ResStatus[ResType] == EFI_RESOURCE_NONEXISTENT) {\r
+      //\r
+      // Hostbridge hasn't this resource type\r
+      //\r
+      return EFI_ABORTED;\r
+    }\r
+\r
+    //\r
+    // Hostbridge hasn't enough resource\r
+    //\r
+    PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]);\r
+    if (!PciResNode) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Check if the device has been removed before\r
+    //\r
+    for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) {\r
+      if (PciResNode->PciDev == RemovedPciDev[DevIndex]) {\r
+        continue;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Remove the device if it isn't in the array\r
+    //\r
+    Status = RejectPciDevice (PciResNode->PciDev);\r
+    if (Status == EFI_SUCCESS) {\r
+\r
+      //\r
+      // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code\r
+      //\r
+      //\r
+      // Have no way to get ReqRes, AllocRes & Bar here\r
+      //\r
+      ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));\r
+      AllocFailExtendedData.DevicePathSize = sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
+      AllocFailExtendedData.DevicePath     = (UINT8 *) PciResNode->PciDev->DevicePath;\r
+      AllocFailExtendedData.Bar            = PciResNode->Bar;\r
+\r
+      REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+            EFI_PROGRESS_CODE,\r
+            EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,\r
+            (VOID *) &AllocFailExtendedData,\r
+            sizeof (AllocFailExtendedData)\r
+            );\r
+\r
+      //\r
+      // Add it to the array and indicate at least a device has been rejected\r
+      //\r
+      RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev;\r
+      AllocationAjusted                 = TRUE;\r
+    }\r
+  }\r
+  //\r
+  // End for\r
+  //\r
+\r
+  if (AllocationAjusted) {\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    return EFI_ABORTED;\r
+  }\r
+}\r
+\r
+EFI_STATUS\r
+ConstructAcpiResourceRequestor (\r
+  IN PCI_IO_DEVICE      *Bridge,\r
+  IN PCI_RESOURCE_NODE  *IoNode,\r
+  IN PCI_RESOURCE_NODE  *Mem32Node,\r
+  IN PCI_RESOURCE_NODE  *PMem32Node,\r
+  IN PCI_RESOURCE_NODE  *Mem64Node,\r
+  IN PCI_RESOURCE_NODE  *PMem64Node,\r
+  OUT VOID              **pConfig\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    Bridge - add argument and description to function comment\r
+// TODO:    IoNode - add argument and description to function comment\r
+// TODO:    Mem32Node - add argument and description to function comment\r
+// TODO:    PMem32Node - add argument and description to function comment\r
+// TODO:    Mem64Node - add argument and description to function comment\r
+// TODO:    PMem64Node - add argument and description to function comment\r
+// TODO:    pConfig - add argument and description to function comment\r
+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  UINT8                             NumConfig;\r
+  UINT8                             Aperture;\r
+  UINT8                             *Configuration;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
+  EFI_ACPI_END_TAG_DESCRIPTOR       *PtrEnd;\r
+\r
+  NumConfig = 0;\r
+  Aperture  = 0;\r
+\r
+  *pConfig  = NULL;\r
+\r
+  //\r
+  // if there is io request, add to the io aperture\r
+  //\r
+  if (ResourceRequestExisted (IoNode)) {\r
+    NumConfig++;\r
+    Aperture |= 0x01;\r
+  }\r
+\r
+  //\r
+  // if there is mem32 request, add to the mem32 aperture\r
+  //\r
+  if (ResourceRequestExisted (Mem32Node)) {\r
+    NumConfig++;\r
+    Aperture |= 0x02;\r
+  }\r
+\r
+  //\r
+  // if there is pmem32 request, add to the pmem32 aperture\r
+  //\r
+  if (ResourceRequestExisted (PMem32Node)) {\r
+    NumConfig++;\r
+    Aperture |= 0x04;\r
+  }\r
+\r
+  //\r
+  // if there is mem64 request, add to the mem64 aperture\r
+  //\r
+  if (ResourceRequestExisted (Mem64Node)) {\r
+    NumConfig++;\r
+    Aperture |= 0x08;\r
+  }\r
+\r
+  //\r
+  // if there is pmem64 request, add to the pmem64 aperture\r
+  //\r
+  if (ResourceRequestExisted (PMem64Node)) {\r
+    NumConfig++;\r
+    Aperture |= 0x10;\r
+  }\r
+\r
+  if (NumConfig != 0) {\r
+\r
+    //\r
+    // If there is at least one type of resource request,\r
+    // allocate a acpi resource node\r
+    //\r
+    Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+    if (Configuration == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    ZeroMem (\r
+      Configuration,\r
+      sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)\r
+      );\r
+\r
+    Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
+\r
+    //\r
+    // Deal with io aperture\r
+    //\r
+    if (Aperture & 0x01) {\r
+      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+      //\r
+      // Io\r
+      //\r
+      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_IO;\r
+      //\r
+      // non ISA range\r
+      //\r
+      Ptr->SpecificFlag = 1;\r
+      Ptr->AddrLen      = IoNode->Length;\r
+      Ptr->AddrRangeMax = IoNode->Alignment;\r
+\r
+      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+    }\r
+    //\r
+    // Deal with mem32 aperture\r
+    //\r
+    if (Aperture & 0x02) {\r
+      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+      //\r
+      // Mem\r
+      //\r
+      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+      //\r
+      // Nonprefechable\r
+      //\r
+      Ptr->SpecificFlag = 0;\r
+      //\r
+      // 32 bit\r
+      //\r
+      Ptr->AddrSpaceGranularity = 32;\r
+      Ptr->AddrLen      = Mem32Node->Length;\r
+      Ptr->AddrRangeMax = Mem32Node->Alignment;\r
+\r
+      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+    }\r
+\r
+    //\r
+    // Deal with Pmem32 aperture\r
+    //\r
+    if (Aperture & 0x04) {\r
+      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+      //\r
+      // Mem\r
+      //\r
+      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+      //\r
+      // prefechable\r
+      //\r
+      Ptr->SpecificFlag = 0x6;\r
+      //\r
+      // 32 bit\r
+      //\r
+      Ptr->AddrSpaceGranularity = 32;\r
+      Ptr->AddrLen      = PMem32Node->Length;\r
+      Ptr->AddrRangeMax = PMem32Node->Alignment;\r
+\r
+      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+    }\r
+    //\r
+    // Deal with mem64 aperture\r
+    //\r
+    if (Aperture & 0x08) {\r
+      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+      //\r
+      // Mem\r
+      //\r
+      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+      //\r
+      // nonprefechable\r
+      //\r
+      Ptr->SpecificFlag = 0;\r
+      //\r
+      // 64 bit\r
+      //\r
+      Ptr->AddrSpaceGranularity = 64;\r
+      Ptr->AddrLen      = Mem64Node->Length;\r
+      Ptr->AddrRangeMax = Mem64Node->Alignment;\r
+\r
+      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+    }\r
+    //\r
+    // Deal with Pmem64 aperture\r
+    //\r
+    if (Aperture & 0x10) {\r
+      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+      //\r
+      // Mem\r
+      //\r
+      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+      //\r
+      // prefechable\r
+      //\r
+      Ptr->SpecificFlag = 0x06;\r
+      //\r
+      // 64 bit\r
+      //\r
+      Ptr->AddrSpaceGranularity = 64;\r
+      Ptr->AddrLen      = PMem64Node->Length;\r
+      Ptr->AddrRangeMax = PMem64Node->Alignment;\r
+\r
+      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+    }\r
+\r
+    //\r
+    // put the checksum\r
+    //\r
+    PtrEnd            = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);\r
+\r
+    PtrEnd->Desc      = ACPI_END_TAG_DESCRIPTOR;\r
+    PtrEnd->Checksum  = 0;\r
+\r
+  } else {\r
+\r
+    //\r
+    // If there is no resource request\r
+    //\r
+    Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+    if (Configuration == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    ZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+\r
+    Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration);\r
+    Ptr->Desc         = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+\r
+    PtrEnd            = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+    PtrEnd->Desc      = ACPI_END_TAG_DESCRIPTOR;\r
+    PtrEnd->Checksum  = 0;\r
+  }\r
+\r
+  *pConfig = Configuration;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetResourceBase (\r
+  IN VOID     *pConfig,\r
+  OUT UINT64  *IoBase,\r
+  OUT UINT64  *Mem32Base,\r
+  OUT UINT64  *PMem32Base,\r
+  OUT UINT64  *Mem64Base,\r
+  OUT UINT64  *PMem64Base\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    pConfig - add argument and description to function comment\r
+// TODO:    IoBase - add argument and description to function comment\r
+// TODO:    Mem32Base - add argument and description to function comment\r
+// TODO:    PMem32Base - add argument and description to function comment\r
+// TODO:    Mem64Base - add argument and description to function comment\r
+// TODO:    PMem64Base - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  UINT8                             *Temp;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
+  UINT64                            ResStatus;\r
+\r
+  *IoBase     = 0xFFFFFFFFFFFFFFFFULL;\r
+  *Mem32Base  = 0xFFFFFFFFFFFFFFFFULL;\r
+  *PMem32Base = 0xFFFFFFFFFFFFFFFFULL;\r
+  *Mem64Base  = 0xFFFFFFFFFFFFFFFFULL;\r
+  *PMem64Base = 0xFFFFFFFFFFFFFFFFULL;\r
+\r
+  Temp        = (UINT8 *) pConfig;\r
+\r
+  while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
+\r
+    Ptr       = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;\r
+    ResStatus = Ptr->AddrTranslationOffset;\r
+\r
+    if (ResStatus == EFI_RESOURCE_SATISFIED) {\r
+\r
+      switch (Ptr->ResType) {\r
+\r
+      //\r
+      // Memory type aperture\r
+      //\r
+      case 0:\r
+\r
+        //\r
+        // Check to see the granularity\r
+        //\r
+        if (Ptr->AddrSpaceGranularity == 32) {\r
+          if (Ptr->SpecificFlag & 0x06) {\r
+            *PMem32Base = Ptr->AddrRangeMin;\r
+          } else {\r
+            *Mem32Base = Ptr->AddrRangeMin;\r
+          }\r
+        }\r
+\r
+        if (Ptr->AddrSpaceGranularity == 64) {\r
+          if (Ptr->SpecificFlag & 0x06) {\r
+            *PMem64Base = Ptr->AddrRangeMin;\r
+          } else {\r
+            *Mem64Base = Ptr->AddrRangeMin;\r
+          }\r
+        }\r
+        break;\r
+\r
+      case 1:\r
+\r
+        //\r
+        // Io type aperture\r
+        //\r
+        *IoBase = Ptr->AddrRangeMin;\r
+        break;\r
+\r
+      default:\r
+        break;\r
+\r
+      }\r
+      //\r
+      // End switch\r
+      //\r
+    }\r
+    //\r
+    // End for\r
+    //\r
+    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciBridgeEnumerator (\r
+  IN PCI_IO_DEVICE                                     *BridgeDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    BridgeDev - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  UINT8               SubBusNumber;\r
+  UINT8               StartBusNumber;\r
+  EFI_PCI_IO_PROTOCOL *PciIo;\r
+  EFI_STATUS          Status;\r
+\r
+  SubBusNumber    = 0;\r
+  StartBusNumber  = 0;\r
+  PciIo           = &(BridgeDev->PciIo);\r
+  Status          = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = PciAssignBusNumber (\r
+            BridgeDev,\r
+            StartBusNumber,\r
+            &SubBusNumber\r
+            );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = PciBridgeResourceAllocator (BridgeDev);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = DetermineDeviceAttribute (BridgeDev);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+PciBridgeResourceAllocator (\r
+  IN PCI_IO_DEVICE  *Bridge\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    Bridge - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  PCI_RESOURCE_NODE *IoBridge;\r
+  PCI_RESOURCE_NODE *Mem32Bridge;\r
+  PCI_RESOURCE_NODE *PMem32Bridge;\r
+  PCI_RESOURCE_NODE *Mem64Bridge;\r
+  PCI_RESOURCE_NODE *PMem64Bridge;\r
+  UINT64            IoBase;\r
+  UINT64            Mem32Base;\r
+  UINT64            PMem32Base;\r
+  UINT64            Mem64Base;\r
+  UINT64            PMem64Base;\r
+  EFI_STATUS        Status;\r
+\r
+  IoBridge = CreateResourceNode (\r
+              Bridge,\r
+              0,\r
+              0xFFF,\r
+              0,\r
+              PciBarTypeIo16,\r
+              PciResUsageTypical\r
+              );\r
+\r
+  Mem32Bridge = CreateResourceNode (\r
+                  Bridge,\r
+                  0,\r
+                  0xFFFFF,\r
+                  0,\r
+                  PciBarTypeMem32,\r
+                  PciResUsageTypical\r
+                  );\r
+\r
+  PMem32Bridge = CreateResourceNode (\r
+                  Bridge,\r
+                  0,\r
+                  0xFFFFF,\r
+                  0,\r
+                  PciBarTypePMem32,\r
+                  PciResUsageTypical\r
+                  );\r
+\r
+  Mem64Bridge = CreateResourceNode (\r
+                  Bridge,\r
+                  0,\r
+                  0xFFFFF,\r
+                  0,\r
+                  PciBarTypeMem64,\r
+                  PciResUsageTypical\r
+                  );\r
+\r
+  PMem64Bridge = CreateResourceNode (\r
+                  Bridge,\r
+                  0,\r
+                  0xFFFFF,\r
+                  0,\r
+                  PciBarTypePMem64,\r
+                  PciResUsageTypical\r
+                  );\r
+\r
+  //\r
+  // Create resourcemap by going through all the devices subject to this root bridge\r
+  //\r
+  Status = CreateResourceMap (\r
+            Bridge,\r
+            IoBridge,\r
+            Mem32Bridge,\r
+            PMem32Bridge,\r
+            Mem64Bridge,\r
+            PMem64Bridge\r
+            );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = GetResourceBaseFromBridge (\r
+            Bridge,\r
+            &IoBase,\r
+            &Mem32Base,\r
+            &PMem32Base,\r
+            &Mem64Base,\r
+            &PMem64Base\r
+            );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Program IO resources\r
+  //\r
+  ProgramResource (\r
+    IoBase,\r
+    IoBridge\r
+    );\r
+\r
+  //\r
+  // Program Mem32 resources\r
+  //\r
+  ProgramResource (\r
+    Mem32Base,\r
+    Mem32Bridge\r
+    );\r
+\r
+  //\r
+  // Program PMem32 resources\r
+  //\r
+  ProgramResource (\r
+    PMem32Base,\r
+    PMem32Bridge\r
+    );\r
+\r
+  //\r
+  // Program Mem64 resources\r
+  //\r
+  ProgramResource (\r
+    Mem64Base,\r
+    Mem64Bridge\r
+    );\r
+\r
+  //\r
+  // Program PMem64 resources\r
+  //\r
+  ProgramResource (\r
+    PMem64Base,\r
+    PMem64Bridge\r
+    );\r
+\r
+  DestroyResourceTree (IoBridge);\r
+  DestroyResourceTree (Mem32Bridge);\r
+  DestroyResourceTree (PMem32Bridge);\r
+  DestroyResourceTree (PMem64Bridge);\r
+  DestroyResourceTree (Mem64Bridge);\r
+\r
+  gBS->FreePool (IoBridge);\r
+  gBS->FreePool (Mem32Bridge);\r
+  gBS->FreePool (PMem32Bridge);\r
+  gBS->FreePool (PMem64Bridge);\r
+  gBS->FreePool (Mem64Bridge);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetResourceBaseFromBridge (\r
+  IN  PCI_IO_DEVICE *Bridge,\r
+  OUT UINT64        *IoBase,\r
+  OUT UINT64        *Mem32Base,\r
+  OUT UINT64        *PMem32Base,\r
+  OUT UINT64        *Mem64Base,\r
+  OUT UINT64        *PMem64Base\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    Bridge - add argument and description to function comment\r
+// TODO:    IoBase - add argument and description to function comment\r
+// TODO:    Mem32Base - add argument and description to function comment\r
+// TODO:    PMem32Base - add argument and description to function comment\r
+// TODO:    Mem64Base - add argument and description to function comment\r
+// TODO:    PMem64Base - add argument and description to function comment\r
+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  if (!Bridge->Allocated) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  *IoBase     = gAllOne;\r
+  *Mem32Base  = gAllOne;\r
+  *PMem32Base = gAllOne;\r
+  *Mem64Base  = gAllOne;\r
+  *PMem64Base = gAllOne;\r
+\r
+  if (IS_PCI_BRIDGE (&Bridge->Pci)) {\r
+\r
+    if (Bridge->PciBar[PPB_IO_RANGE].Length) {\r
+      *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress;\r
+    }\r
+\r
+    if (Bridge->PciBar[PPB_MEM32_RANGE].Length) {\r
+      *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress;\r
+    }\r
+\r
+    if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) {\r
+      *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress;\r
+    }\r
+\r
+    if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) {\r
+      *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress;\r
+    } else {\r
+      *PMem64Base = gAllOne;\r
+    }\r
+\r
+  }\r
+\r
+  if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) {\r
+    if (Bridge->PciBar[P2C_IO_1].Length) {\r
+      *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress;\r
+    } else {\r
+      if (Bridge->PciBar[P2C_IO_2].Length) {\r
+        *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress;\r
+      }\r
+    }\r
+\r
+    if (Bridge->PciBar[P2C_MEM_1].Length) {\r
+      if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) {\r
+        *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;\r
+      }\r
+\r
+      if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) {\r
+        *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;\r
+      }\r
+    }\r
+\r
+    if (Bridge->PciBar[P2C_MEM_2].Length) {\r
+      if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) {\r
+        *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;\r
+      }\r
+\r
+      if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) {\r
+        *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+NotifyPhase (\r
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE       Phase\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciResAlloc - add argument and description to function comment\r
+// TODO:    Phase - add argument and description to function comment\r
+// TODO:    EFI_NOT_FOUND - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  EFI_HANDLE                      HostBridgeHandle;\r
+  EFI_HANDLE                      RootBridgeHandle;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+  EFI_STATUS                      Status;\r
+\r
+  HostBridgeHandle  = NULL;\r
+  RootBridgeHandle  = NULL;\r
+  if (gPciPlatformProtocol != NULL) {\r
+    //\r
+    // Get Host Bridge Handle.\r
+    //\r
+    PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);\r
+\r
+    //\r
+    // Get the rootbridge Io protocol to find the host bridge handle\r
+    //\r
+    Status = gBS->HandleProtocol (\r
+                    RootBridgeHandle,\r
+                    &gEfiPciRootBridgeIoProtocolGuid,\r
+                    (VOID **) &PciRootBridgeIo\r
+                    );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+\r
+    HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
+\r
+    //\r
+    // Call PlatformPci::PhaseNotify() if the protocol is present.\r
+    //\r
+    gPciPlatformProtocol->PhaseNotify (\r
+                            gPciPlatformProtocol,\r
+                            HostBridgeHandle,\r
+                            Phase,\r
+                            ChipsetEntry\r
+                            );\r
+  }\r
+\r
+  Status = PciResAlloc->NotifyPhase (\r
+                          PciResAlloc,\r
+                          Phase\r
+                          );\r
+\r
+  if (gPciPlatformProtocol != NULL) {\r
+    //\r
+    // Call PlatformPci::PhaseNotify() if the protocol is present.\r
+    //\r
+    gPciPlatformProtocol->PhaseNotify (\r
+                            gPciPlatformProtocol,\r
+                            HostBridgeHandle,\r
+                            Phase,\r
+                            ChipsetExit\r
+                            );\r
+\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PreprocessController (\r
+  IN PCI_IO_DEVICE                                    *Bridge,\r
+  IN UINT8                                            Bus,\r
+  IN UINT8                                            Device,\r
+  IN UINT8                                            Func,\r
+  IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE     Phase\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    Bridge - add argument and description to function comment\r
+// TODO:    Bus - add argument and description to function comment\r
+// TODO:    Device - add argument and description to function comment\r
+// TODO:    Func - add argument and description to function comment\r
+// TODO:    Phase - add argument and description to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS       RootBridgePciAddress;\r
+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc;\r
+  EFI_HANDLE                                        RootBridgeHandle;\r
+  EFI_HANDLE                                        HostBridgeHandle;\r
+  EFI_STATUS                                        Status;\r
+\r
+  //\r
+  // Get the host bridge handle\r
+  //\r
+  HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle;\r
+\r
+  //\r
+  // Get the pci host bridge resource allocation protocol\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  HostBridgeHandle,\r
+                  &gEfiPciHostBridgeResourceAllocationProtocolGuid,\r
+                  (VOID **) &PciResAlloc,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Get Root Brige Handle\r
+  //\r
+  while (Bridge->Parent) {\r
+    Bridge = Bridge->Parent;\r
+  }\r
+\r
+  RootBridgeHandle                      = Bridge->Handle;\r
+\r
+  RootBridgePciAddress.Register         = 0;\r
+  RootBridgePciAddress.Function         = Func;\r
+  RootBridgePciAddress.Device           = Device;\r
+  RootBridgePciAddress.Bus              = Bus;\r
+  RootBridgePciAddress.ExtendedRegister = 0;\r
+\r
+  if (gPciPlatformProtocol != NULL) {\r
+    //\r
+    // Call PlatformPci::PrepController() if the protocol is present.\r
+    //\r
+    gPciPlatformProtocol->PlatformPrepController (\r
+                            gPciPlatformProtocol,\r
+                            HostBridgeHandle,\r
+                            RootBridgeHandle,\r
+                            RootBridgePciAddress,\r
+                            Phase,\r
+                            ChipsetEntry\r
+                            );\r
+  }\r
+\r
+  Status = PciResAlloc->PreprocessController (\r
+                          PciResAlloc,\r
+                          RootBridgeHandle,\r
+                          RootBridgePciAddress,\r
+                          Phase\r
+                          );\r
+\r
+  if (gPciPlatformProtocol != NULL) {\r
+    //\r
+    // Call PlatformPci::PrepController() if the protocol is present.\r
+    //\r
+    gPciPlatformProtocol->PlatformPrepController (\r
+                            gPciPlatformProtocol,\r
+                            HostBridgeHandle,\r
+                            RootBridgeHandle,\r
+                            RootBridgePciAddress,\r
+                            Phase,\r
+                            ChipsetExit\r
+                            );\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciHotPlugRequestNotify (\r
+  IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,\r
+  IN EFI_PCI_HOTPLUG_OPERATION        Operation,\r
+  IN EFI_HANDLE                       Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL         * RemainingDevicePath OPTIONAL,\r
+  IN OUT UINT8                        *NumberOfChildren,\r
+  IN OUT EFI_HANDLE                   * ChildHandleBuffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Hot plug request notify.\r
+\r
+Arguments:\r
+\r
+  This                 - A pointer to the hot plug request protocol.\r
+  Operation            - The operation.\r
+  Controller           - A pointer to the controller.\r
+  RemainningDevicePath - A pointer to the device path.\r
+  NumberOfChildren     - A the number of child handle in the ChildHandleBuffer.\r
+  ChildHandleBuffer    - A pointer to the array contain the child handle.\r
+\r
+Returns:\r
+\r
+  Status code.\r
+\r
+--*/\r
+// TODO:    RemainingDevicePath - add argument and description to function comment\r
+// TODO:    EFI_NOT_FOUND - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  PCI_IO_DEVICE       *Bridge;\r
+  PCI_IO_DEVICE       *Temp;\r
+  EFI_PCI_IO_PROTOCOL *PciIo;\r
+  UINTN               Index;\r
+  EFI_HANDLE          RootBridgeHandle;\r
+  EFI_STATUS          Status;\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiPciIoProtocolGuid,\r
+                  (VOID **) &PciIo,\r
+                  gPciBusDriverBinding.DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);\r
+\r
+  //\r
+  // Get root bridge handle\r
+  //\r
+  Temp = Bridge;\r
+  while (Temp->Parent) {\r
+    Temp = Temp->Parent;\r
+  }\r
+\r
+  RootBridgeHandle = Temp->Handle;\r
+\r
+  if (Operation == EfiPciHotPlugRequestAdd) {\r
+\r
+    if (NumberOfChildren != NULL) {\r
+      *NumberOfChildren = 0;\r
+    }\r
+\r
+    if (IsListEmpty (&Bridge->ChildList)) {\r
+\r
+      Status = PciBridgeEnumerator (Bridge);\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+    }\r
+\r
+    Status = StartPciDevicesOnBridge (\r
+              RootBridgeHandle,\r
+              Bridge,\r
+              RemainingDevicePath,\r
+              NumberOfChildren,\r
+              ChildHandleBuffer\r
+              );\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (Operation == EfiPciHotplugRequestRemove) {\r
+\r
+    if (*NumberOfChildren == 0) {\r
+      //\r
+      // Remove all devices on the bridge\r
+      //\r
+      Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge);\r
+      return Status;\r
+\r
+    }\r
+\r
+    for (Index = 0; Index < *NumberOfChildren; Index++) {\r
+      //\r
+      // De register all the pci device\r
+      //\r
+      Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]);\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+    }\r
+    //\r
+    // End for\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+SearchHostBridgeHandle (\r
+  IN EFI_HANDLE RootBridgeHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    RootBridgeHandle - add argument and description to function comment\r
+{\r
+  EFI_HANDLE                      HostBridgeHandle;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+  UINTN                           Index;\r
+  EFI_STATUS                      Status;\r
+\r
+  //\r
+  // Get the rootbridge Io protocol to find the host bridge handle\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  RootBridgeHandle,\r
+                  &gEfiPciRootBridgeIoProtocolGuid,\r
+                  (VOID **) &PciRootBridgeIo,\r
+                  gPciBusDriverBinding.DriverBindingHandle,\r
+                  RootBridgeHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return FALSE;\r
+  }\r
+\r
+  HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
+  for (Index = 0; Index < gPciHostBridgeNumber; Index++) {\r
+    if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+AddHostBridgeEnumerator (\r
+  IN EFI_HANDLE HostBridgeHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    HostBridgeHandle - add argument and description to function comment\r
+// TODO:    EFI_ABORTED - add return value to function comment\r
+// TODO:    EFI_ABORTED - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  UINTN Index;\r
+\r
+  if (!HostBridgeHandle) {\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  for (Index = 0; Index < gPciHostBridgeNumber; Index++) {\r
+    if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {\r
+      return EFI_ABORTED;\r
+    }\r
+  }\r
+\r
+  if (Index < PCI_MAX_HOST_BRIDGE_NUM) {\r
+    gPciHostBrigeHandles[Index] = HostBridgeHandle;\r
+    gPciHostBridgeNumber++;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r