]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/PciBus: Use actual max bus # for subordinary bus #
authorRuiyu Ni <ruiyu.ni@intel.com>
Wed, 23 May 2018 03:28:46 +0000 (11:28 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Fri, 25 May 2018 08:51:17 +0000 (16:51 +0800)
Current code assumes the max bus(0xFF) is under this P2P bridge and
temporarily set it as subordinate bus.
It may cause silicon hangs during PCI enumeration in some specific
case.

Instead, it should get the max bus number from the bus number
resources returned from
PCI_HOST_BRIDGE_RESOURCE_ALLOCATION.StartBusEnumeration() and set it
as subordinate bus.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c

index 976496379ab2bdcf1cdc3189cce107c98eb64aae..126a2f7117ecc6b3022eab106856ce4b7c106f96 100644 (file)
@@ -29,6 +29,43 @@ CHAR16 *mBarTypeStr[] = {
   L"Unknow"\r
   };\r
 \r
+/**\r
+  Retrieve the max bus number that is assigned to the Root Bridge hierarchy.\r
+  It can support the case that there are multiple bus ranges.\r
+\r
+  @param  Bridge           Bridge device instance.\r
+\r
+  @retval                  The max bus number that is assigned to this Root Bridge hierarchy.\r
+\r
+**/\r
+UINT16\r
+PciGetMaxBusNumber (\r
+  IN PCI_IO_DEVICE                      *Bridge\r
+  )\r
+{\r
+  PCI_IO_DEVICE                      *RootBridge;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *BusNumberRanges;\r
+  UINT64                             MaxNumberInRange;\r
+\r
+  //\r
+  // Get PCI Root Bridge device\r
+  //\r
+  RootBridge = Bridge;\r
+  while (RootBridge->Parent != NULL) {\r
+    RootBridge = RootBridge->Parent;\r
+  }\r
+  MaxNumberInRange = 0;\r
+  //\r
+  // Iterate the bus number ranges to get max PCI bus number\r
+  //\r
+  BusNumberRanges = RootBridge->BusNumberRanges;\r
+  while (BusNumberRanges->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
+    MaxNumberInRange = BusNumberRanges->AddrRangeMin + BusNumberRanges->AddrLen - 1;\r
+    BusNumberRanges++;\r
+  }\r
+  return (UINT16) MaxNumberInRange;\r
+}\r
+\r
 /**\r
   Retrieve the PCI Card device BAR information via PciIo interface.\r
 \r
@@ -1193,7 +1230,7 @@ PciScanBus (
           // Temporarily initialize SubBusNumber to maximum bus number to ensure the\r
           // PCI configuration transaction to go through any PPB\r
           //\r
-          Register  = 0xFF;\r
+          Register  = PciGetMaxBusNumber (Bridge);\r
           Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);\r
           Status = PciRootBridgeIo->Pci.Write (\r
                                           PciRootBridgeIo,\r