summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg
diff options
context:
space:
mode:
authorRuiyu Ni <ruiyu.ni@intel.com>2018-05-23 11:28:46 +0800
committerRuiyu Ni <ruiyu.ni@intel.com>2018-05-25 16:51:17 +0800
commit03ac238b1fe40cfbb1424bf72e2ac8276345e03c (patch)
treecdfd9fab2e73ee94d9c16f3f6d1665ac7e0e641a /MdeModulePkg
parent7dc7c7435e9030ad07ad7bc7d136a3997bd0b182 (diff)
downloadedk2-03ac238b1fe40cfbb1424bf72e2ac8276345e03c.tar.gz
edk2-03ac238b1fe40cfbb1424bf72e2ac8276345e03c.tar.bz2
edk2-03ac238b1fe40cfbb1424bf72e2ac8276345e03c.zip
MdeModulePkg/PciBus: Use actual max bus # for subordinary bus #
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>
Diffstat (limited to 'MdeModulePkg')
-rw-r--r--MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
index 976496379a..126a2f7117 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
@@ -30,6 +30,43 @@ CHAR16 *mBarTypeStr[] = {
};
/**
+ Retrieve the max bus number that is assigned to the Root Bridge hierarchy.
+ It can support the case that there are multiple bus ranges.
+
+ @param Bridge Bridge device instance.
+
+ @retval The max bus number that is assigned to this Root Bridge hierarchy.
+
+**/
+UINT16
+PciGetMaxBusNumber (
+ IN PCI_IO_DEVICE *Bridge
+ )
+{
+ PCI_IO_DEVICE *RootBridge;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BusNumberRanges;
+ UINT64 MaxNumberInRange;
+
+ //
+ // Get PCI Root Bridge device
+ //
+ RootBridge = Bridge;
+ while (RootBridge->Parent != NULL) {
+ RootBridge = RootBridge->Parent;
+ }
+ MaxNumberInRange = 0;
+ //
+ // Iterate the bus number ranges to get max PCI bus number
+ //
+ BusNumberRanges = RootBridge->BusNumberRanges;
+ while (BusNumberRanges->Desc != ACPI_END_TAG_DESCRIPTOR) {
+ MaxNumberInRange = BusNumberRanges->AddrRangeMin + BusNumberRanges->AddrLen - 1;
+ BusNumberRanges++;
+ }
+ return (UINT16) MaxNumberInRange;
+}
+
+/**
Retrieve the PCI Card device BAR information via PciIo interface.
@param PciIoDevice PCI Card device instance.
@@ -1193,7 +1230,7 @@ PciScanBus (
// Temporarily initialize SubBusNumber to maximum bus number to ensure the
// PCI configuration transaction to go through any PPB
//
- Register = 0xFF;
+ Register = PciGetMaxBusNumber (Bridge);
Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
Status = PciRootBridgeIo->Pci.Write (
PciRootBridgeIo,