1) Use FeatureFlag PcdPciBusHotplugDeviceSupport to merge LightPciLib.c with PcdLib.c.
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / PciBus / Dxe / PciLib.c
index 11a0c29..a4d3577 100644 (file)
@@ -25,7 +25,7 @@ Revision History
 \r
 #include "pcibus.h"\r
 \r
-EFI_PCI_HOTPLUG_REQUEST_PROTOCOL gPciHotPlugRequest = {\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL gPciHotPlugRequest = {\r
   PciHotPlugRequestNotify\r
 };\r
 \r
@@ -49,6 +49,10 @@ Returns:
 {\r
   EFI_HANDLE  Handle;\r
 \r
+  if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+    return;\r
+  }\r
+\r
   Handle = NULL;\r
   *Status = gBS->InstallProtocolInterface (\r
                   &Handle,\r
@@ -78,6 +82,10 @@ Returns:
 {\r
   EFI_STATUS  Status;\r
 \r
+  if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+    return;\r
+  }\r
+\r
   if (IS_CARDBUS_BRIDGE (&PciIoDevice->Parent->Pci)) {\r
 \r
     Status = gBS->InstallProtocolInterface (\r
@@ -109,6 +117,10 @@ Returns:
 {\r
   EFI_STATUS  Status;\r
 \r
+  if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+    return;\r
+  }\r
+\r
   Status = gBS->OpenProtocol (\r
                   PciIoDevice->Handle,\r
                   &gEfiPciHotplugDeviceGuid,\r
@@ -152,6 +164,10 @@ Returns:
 {\r
   UINT32  Address;\r
 \r
+  if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+    return;\r
+  }\r
+\r
   //\r
   // Read PciBar information from the bar register\r
   //\r
@@ -239,6 +255,10 @@ Returns:
   LIST_ENTRY      *CurrentLink;\r
   LIST_ENTRY      *LastLink;\r
 \r
+  if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
   CurrentLink = Bridge->ChildList.ForwardLink;\r
 \r
   while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
@@ -286,6 +306,396 @@ EFI_STATUS
 PciHostBridgeResourceAllocator (\r
   IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
   )\r
+{\r
+  if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+    return PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (\r
+             PciResAlloc\r
+             );\r
+  } else {\r
+    return PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (\r
+             PciResAlloc\r
+             );\r
+  }  \r
+}\r
+\r
+\r
+EFI_STATUS\r
+PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (\r
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\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:    EFI_NOT_FOUND - add return value to function comment\r
+// TODO:    EFI_OUT_OF_RESOURCES - add return value 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
+  PCI_IO_DEVICE                   *RootBridgeDev;\r
+  EFI_HANDLE                      RootBridgeHandle;\r
+  VOID                            *AcpiConfig;\r
+  EFI_STATUS                      Status;\r
+  UINT64                          IoBase;\r
+  UINT64                          Mem32Base;\r
+  UINT64                          PMem32Base;\r
+  UINT64                          Mem64Base;\r
+  UINT64                          PMem64Base;\r
+  UINT64                          MaxOptionRomSize;\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
+  PCI_RESOURCE_NODE               IoPool;\r
+  PCI_RESOURCE_NODE               Mem32Pool;\r
+  PCI_RESOURCE_NODE               PMem32Pool;\r
+  PCI_RESOURCE_NODE               Mem64Pool;\r
+  PCI_RESOURCE_NODE               PMem64Pool;\r
+  REPORT_STATUS_CODE_LIBRARY_DEVICE_HANDLE_EXTENDED_DATA  ExtendedData;\r
+\r
+  //\r
+  // Initialize resource pool\r
+  //\r
+  \r
+  InitializeResourcePool (&IoPool, PciBarTypeIo16);\r
+  InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);\r
+  InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);\r
+  InitializeResourcePool (&Mem64Pool, PciBarTypeMem64);\r
+  InitializeResourcePool (&PMem64Pool, PciBarTypePMem64);\r
+\r
+  RootBridgeDev     = NULL;\r
+  RootBridgeHandle  = 0;\r
+\r
+  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\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
+    // Get host bridge handle for status report\r
+    //\r
+    ExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;\r
+\r
+    //\r
+    // Create the entire system resource map from the information collected by\r
+    // enumerator. Several resource tree was created\r
+    //\r
+\r
+    IoBridge = CreateResourceNode (\r
+                RootBridgeDev,\r
+                0,\r
+                0xFFF,\r
+                0,\r
+                PciBarTypeIo16,\r
+                PciResUsageTypical\r
+                );\r
+\r
+    Mem32Bridge = CreateResourceNode (\r
+                    RootBridgeDev,\r
+                    0,\r
+                    0xFFFFF,\r
+                    0,\r
+                    PciBarTypeMem32,\r
+                    PciResUsageTypical\r
+                    );\r
+\r
+    PMem32Bridge = CreateResourceNode (\r
+                    RootBridgeDev,\r
+                    0,\r
+                    0xFFFFF,\r
+                    0,\r
+                    PciBarTypePMem32,\r
+                    PciResUsageTypical\r
+                    );\r
+\r
+    Mem64Bridge = CreateResourceNode (\r
+                    RootBridgeDev,\r
+                    0,\r
+                    0xFFFFF,\r
+                    0,\r
+                    PciBarTypeMem64,\r
+                    PciResUsageTypical\r
+                    );\r
+\r
+    PMem64Bridge = CreateResourceNode (\r
+                    RootBridgeDev,\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
+              RootBridgeDev,\r
+              IoBridge,\r
+              Mem32Bridge,\r
+              PMem32Bridge,\r
+              Mem64Bridge,\r
+              PMem64Bridge\r
+              );\r
+\r
+    //\r
+    // Get the max ROM size that the root bridge can process\r
+    //\r
+    RootBridgeDev->RomSize = Mem32Bridge->Length;\r
+\r
+    //\r
+    // Get Max Option Rom size for current root bridge\r
+    //\r
+    MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);\r
+\r
+    //\r
+    // Enlarger the mem32 resource to accomdate the option rom\r
+    // if the mem32 resource is not enough to hold the rom\r
+    //\r
+    if (MaxOptionRomSize > Mem32Bridge->Length) {\r
+\r
+      Mem32Bridge->Length     = MaxOptionRomSize;\r
+      RootBridgeDev->RomSize  = MaxOptionRomSize;\r
+\r
+      //\r
+      // Alignment should be adjusted as well\r
+      //\r
+      if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {\r
+        Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r
+      }\r
+    }\r
+    \r
+    //\r
+    // Based on the all the resource tree, contruct ACPI resource node to\r
+    // submit the resource aperture to pci host bridge protocol\r
+    //\r
+    Status = ConstructAcpiResourceRequestor (\r
+              RootBridgeDev,\r
+              IoBridge,\r
+              Mem32Bridge,\r
+              PMem32Bridge,\r
+              Mem64Bridge,\r
+              PMem64Bridge,\r
+              &AcpiConfig\r
+              );\r
+\r
+    //\r
+    // Insert these resource nodes into the database\r
+    //\r
+    InsertResourceNode (&IoPool, IoBridge);\r
+    InsertResourceNode (&Mem32Pool, Mem32Bridge);\r
+    InsertResourceNode (&PMem32Pool, PMem32Bridge);\r
+    InsertResourceNode (&Mem64Pool, Mem64Bridge);\r
+    InsertResourceNode (&PMem64Pool, PMem64Bridge);\r
+\r
+    if (Status == EFI_SUCCESS) {\r
+      //\r
+      // Submit the resource requirement\r
+      //\r
+      Status = PciResAlloc->SubmitResources (\r
+                              PciResAlloc,\r
+                              RootBridgeDev->Handle,\r
+                              AcpiConfig\r
+                              );\r
+    }\r
+    //\r
+    // Free acpi resource node\r
+    //\r
+    if (AcpiConfig) {\r
+      gBS->FreePool (AcpiConfig);\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Destroy all the resource tree\r
+      //\r
+      DestroyResourceTree (&IoPool);\r
+      DestroyResourceTree (&Mem32Pool);\r
+      DestroyResourceTree (&PMem32Pool);\r
+      DestroyResourceTree (&Mem64Pool);\r
+      DestroyResourceTree (&PMem64Pool);\r
+      return Status;\r
+    }\r
+  }\r
+  //\r
+  // End while\r
+  //\r
+\r
+  //\r
+  // Notify pci bus driver starts to program the resource\r
+  //\r
+  Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Allocation failed, then return\r
+    //\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  //\r
+  // Raise the EFI_IOB_PCI_RES_ALLOC status code\r
+  //\r
+  REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+        EFI_PROGRESS_CODE,\r
+        EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC,\r
+        (VOID *) &ExtendedData,\r
+        sizeof (ExtendedData)\r
+        );\r
+\r
+  //\r
+  // Notify pci bus driver starts to program the resource\r
+  //\r
+  NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources);\r
+\r
+  RootBridgeDev     = NULL;\r
+\r
+  RootBridgeHandle  = 0;\r
+\r
+  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\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
+    // Get acpi resource node for all the resource types\r
+    //\r
+    AcpiConfig = NULL;\r
+    Status = PciResAlloc->GetProposedResources (\r
+                            PciResAlloc,\r
+                            RootBridgeDev->Handle,\r
+                            &AcpiConfig\r
+                            );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // Get the resource base by interpreting acpi resource node\r
+    //\r
+    //\r
+    GetResourceBase (\r
+      AcpiConfig,\r
+      &IoBase,\r
+      &Mem32Base,\r
+      &PMem32Base,\r
+      &Mem64Base,\r
+      &PMem64Base\r
+      );\r
+\r
+    //\r
+    // Process option rom for this root bridge\r
+    //\r
+    Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);\r
+\r
+    //\r
+    // Create the entire system resource map from the information collected by\r
+    // enumerator. Several resource tree was created\r
+    //\r
+    Status = GetResourceMap (\r
+              RootBridgeDev,\r
+              &IoBridge,\r
+              &Mem32Bridge,\r
+              &PMem32Bridge,\r
+              &Mem64Bridge,\r
+              &PMem64Bridge,\r
+              &IoPool,\r
+              &Mem32Pool,\r
+              &PMem32Pool,\r
+              &Mem64Pool,\r
+              &PMem64Pool\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
+    if (AcpiConfig != NULL) {\r
+      gBS->FreePool (AcpiConfig);\r
+    }\r
+  }\r
+\r
+  //\r
+  // Destroy all the resource tree\r
+  //\r
+  DestroyResourceTree (&IoPool);\r
+  DestroyResourceTree (&Mem32Pool);\r
+  DestroyResourceTree (&PMem32Pool);\r
+  DestroyResourceTree (&Mem64Pool);\r
+  DestroyResourceTree (&PMem64Pool);\r
+\r
+  //\r
+  // Notify the resource allocation phase is to end\r
+  //\r
+  NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (\r
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
@@ -787,6 +1197,7 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+\r
 EFI_STATUS\r
 PciScanBus (\r
   IN PCI_IO_DEVICE                      *Bridge,\r
@@ -794,6 +1205,204 @@ PciScanBus (
   OUT UINT8                             *SubBusNumber,\r
   OUT UINT8                             *PaddedBusRange\r
   )\r
+{\r
+  if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+    return PciScanBus_WithHotPlugDeviceSupport (\r
+      Bridge, \r
+      StartBusNumber, \r
+      SubBusNumber, \r
+      PaddedBusRange\r
+      );\r
+  } else {\r
+    return PciScanBus_WithoutHotPlugDeviceSupport (\r
+      Bridge, \r
+      StartBusNumber, \r
+      SubBusNumber, \r
+      PaddedBusRange\r
+      );\r
+  }\r
+}\r
+\r
+\r
+EFI_STATUS\r
+PciScanBus_WithoutHotPlugDeviceSupport (\r
+  IN PCI_IO_DEVICE                      *Bridge,\r
+  IN UINT8                              StartBusNumber,\r
+  OUT UINT8                             *SubBusNumber,\r
+  OUT UINT8                             *PaddedBusRange\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:    PaddedBusRange - 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
+  PCI_IO_DEVICE                   *PciDevice;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+  PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
+  SecondBus       = 0;\r
+  Register        = 0;\r
+\r
+  ResetAllPpbBusReg (Bridge, StartBusNumber);\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
+      Status = PciDevicePresent (\r
+                PciRootBridgeIo,\r
+                &Pci,\r
+                StartBusNumber,\r
+                Device,\r
+                Func\r
+                );\r
+\r
+      if (!EFI_ERROR (Status)   && \r
+          (IS_PCI_BRIDGE (&Pci) ||\r
+          IS_CARDBUS_BRIDGE (&Pci))) {\r
+\r
+        //\r
+        // Get the bridge information\r
+        //\r
+        Status = PciSearchDevice (\r
+                  Bridge,\r
+                  &Pci,\r
+                  StartBusNumber,\r
+                  Device,\r
+                  Func,\r
+                  &PciDevice\r
+                  );\r
+\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+\r
+        (*SubBusNumber)++;\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 = PciRootBridgeIo->Pci.Write (\r
+                                        PciRootBridgeIo,\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 = PciRootBridgeIo->Pci.Write (\r
+                                        PciRootBridgeIo,\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
+          // Temporarily initialize SubBusNumber to maximum bus number to ensure the\r
+          // PCI configuration transaction to go through any PPB\r
+          //\r
+          Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
+          Register  = 0xFF;\r
+          Status = PciRootBridgeIo->Pci.Write (\r
+                                          PciRootBridgeIo,\r
+                                          EfiPciWidthUint8,\r
+                                          Address,\r
+                                          1,\r
+                                          &Register\r
+                                          );\r
+\r
+          PreprocessController (\r
+            PciDevice,\r
+            PciDevice->BusNumber,\r
+            PciDevice->DeviceNumber,\r
+            PciDevice->FunctionNumber,\r
+            EfiPciBeforeChildBusEnumeration\r
+            );\r
+\r
+          Status = PciScanBus (\r
+                    PciDevice,\r
+                    (UINT8) (SecondBus),\r
+                    SubBusNumber,\r
+                    PaddedBusRange\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 = PciRootBridgeIo->Pci.Write (\r
+                                        PciRootBridgeIo,\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
+PciScanBus_WithHotPlugDeviceSupport (\r
+  IN PCI_IO_DEVICE                      *Bridge,\r
+  IN UINT8                              StartBusNumber,\r
+  OUT UINT8                             *SubBusNumber,\r
+  OUT UINT8                             *PaddedBusRange\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
@@ -1175,6 +1784,10 @@ Returns:
   PCI_IO_DEVICE *RootBridgeDev;\r
   EFI_STATUS    Status;\r
 \r
+  if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
   RootBridgeHandle = NULL;\r
 \r
   while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
@@ -1271,55 +1884,63 @@ Returns:
     //\r
   }\r
 \r
-  //                                                            \r
-  // Notify the bus allocation phase is finished for the first time\r
-  //                                                            \r
-  NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
-    \r
-                  \r
-  if (gPciHotPlugInit != NULL) {\r
-    //\r
-    // Wait for all HPC initialized\r
-    //\r
-    Status = AllRootHPCInitialized (STALL_1_SECOND * 15);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
-    //\r
-    // Notify the bus allocation phase is about to start for the 2nd time\r
-    //\r
-    NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
-  \r
-    RootBridgeHandle = NULL;\r
-    while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+  if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
 \r
+    //                                                            \r
+    // Notify the bus allocation phase is finished for the first time\r
+    //                                                            \r
+    NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
+      \r
+                    \r
+    if (gPciHotPlugInit != NULL) {\r
       //\r
-      // if a root bridge instance is found, create root bridge device for it\r
+      // Wait for all HPC initialized\r
       //\r
+      Status = AllRootHPCInitialized (STALL_1_SECOND * 15);\r
 \r
-      RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
-\r
-      if (RootBridgeDev == NULL) {\r
-        return EFI_OUT_OF_RESOURCES;\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
       }\r
 \r
       //\r
-      // Enumerate all the buses under this root bridge\r
+      // Notify the bus allocation phase is about to start for the 2nd time\r
       //\r
+      NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
+    \r
+      RootBridgeHandle = NULL;\r
+      while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
 \r
-      Status = PciRootBridgeEnumerator (\r
-                PciResAlloc,\r
-                RootBridgeDev\r
-                );\r
+        //\r
+        // if a root bridge instance is found, create root bridge device for it\r
+        //\r
 \r
-      DestroyRootBridge (RootBridgeDev);\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
+        RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r
+\r
+        if (RootBridgeDev == NULL) {\r
+          return EFI_OUT_OF_RESOURCES;\r
+        }\r
+\r
+        //\r
+        // Enumerate all the buses under this root bridge\r
+        //\r
+\r
+        Status = PciRootBridgeEnumerator (\r
+                  PciResAlloc,\r
+                  RootBridgeDev\r
+                  );\r
+\r
+        DestroyRootBridge (RootBridgeDev);\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
       }\r
+        \r
+      //\r
+      // Notify the bus allocation phase is to end\r
+      //\r
+      NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
     }\r
-      \r
+  } else {\r
     //\r
     // Notify the bus allocation phase is to end\r
     //\r