This new function incorporates the current loop body found in the entry point function, InitializePciHostBridge(). It will be called once for each root bus discovered.
Cc: Jordan Justen <jordan.l.jus...@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <ler...@redhat.com> Regression-tested-by: Gabriel Somlo <so...@cmu.edu> --- OvmfPkg/PciHostBridgeDxe/PciHostBridge.c | 126 ++++++++++++++------ 1 file changed, 89 insertions(+), 37 deletions(-) diff --git a/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c b/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c index c2277bf..7ca0b6e 100644 --- a/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c +++ b/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c @@ -77,6 +77,83 @@ PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = { // /** + Allocate and initialize a root bridge. + + param[in] RootBusNumber The bus number of the root bus (root bridge) to + create. + RootBusNumber is expected to fall into the valid + offset range of mResAperture. + + param[in] HostBridgeHandle The EFI_HANDLE corresponding to the host bridge + that is the parent of the root bridge to create. + HostBridgeHandle is expected to have + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + installed on it. + + param[out] RootBus The private PCI_ROOT_BRIDGE_INSTANCE that has + been created as the result of the function call. + + @retval EFI_SUCCESS Initialization successful. A new + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL has been + created as the child of HostBridgeHandle. A + device path consisting of an ACPI device path + node, with UID = RootBusNumber, has been + installed on the same new handle. + + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. + + @return Error codes from + gBS->InstallMultipleProtocolInterfaces(). +**/ +STATIC +EFI_STATUS +InitRootBridge ( + IN UINT8 RootBusNumber, + IN EFI_HANDLE HostBridgeHandle, + OUT PCI_ROOT_BRIDGE_INSTANCE **RootBus + ) +{ + PCI_ROOT_BRIDGE_INSTANCE *PrivateData; + EFI_STATUS Status; + + PrivateData = AllocateZeroPool (sizeof *PrivateData); + if (PrivateData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + PrivateData->Signature = PCI_ROOT_BRIDGE_SIGNATURE; + + CopyMem (&PrivateData->DevicePath, &mRootBridgeDevicePathTemplate, + sizeof mRootBridgeDevicePathTemplate); + PrivateData->DevicePath.AcpiDevicePath.UID = RootBusNumber; + + // + // The function call below allocates no resources and performs no actions + // that have to be rolled back on later failure. It always succeeds. + // + Status = RootBridgeConstructor (&PrivateData->Io, HostBridgeHandle, + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM, + &mResAperture[RootBusNumber]); + ASSERT_EFI_ERROR (Status); + + Status = gBS->InstallMultipleProtocolInterfaces (&PrivateData->Handle, + &gEfiDevicePathProtocolGuid, &PrivateData->DevicePath, + &gEfiPciRootBridgeIoProtocolGuid, &PrivateData->Io, + NULL); + if (EFI_ERROR (Status)) { + goto FreePrivateData; + } + + *RootBus = PrivateData; + return EFI_SUCCESS; + +FreePrivateData: + FreePool (PrivateData); + return Status; +} + + +/** Entry point of this driver @param ImageHandle Handle of driver image @@ -94,9 +171,9 @@ InitializePciHostBridge ( ) { EFI_STATUS Status; - UINTN Loop2; + UINTN RootBridgeNumber; PCI_HOST_BRIDGE_INSTANCE *HostBridge; - PCI_ROOT_BRIDGE_INSTANCE *PrivateData; + PCI_ROOT_BRIDGE_INSTANCE *RootBus; mDriverImageHandle = ImageHandle; @@ -123,43 +200,18 @@ InitializePciHostBridge ( 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; - - CopyMem (&PrivateData->DevicePath, &mRootBridgeDevicePathTemplate, - sizeof mRootBridgeDevicePathTemplate); - PrivateData->DevicePath.AcpiDevicePath.UID = Loop2; - - RootBridgeConstructor ( - &PrivateData->Io, - HostBridge->HostBridgeHandle, - EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM, - &mResAperture[Loop2] - ); - - Status = gBS->InstallMultipleProtocolInterfaces( - &PrivateData->Handle, - &gEfiDevicePathProtocolGuid, - &PrivateData->DevicePath, - &gEfiPciRootBridgeIoProtocolGuid, - &PrivateData->Io, - NULL - ); + for (RootBridgeNumber = 0; + RootBridgeNumber < HostBridge->RootBridgeNumber; + ++RootBridgeNumber) { + Status = InitRootBridge ( + (UINT8)RootBridgeNumber, + HostBridge->HostBridgeHandle, + &RootBus + ); if (EFI_ERROR (Status)) { - FreePool(PrivateData); - return EFI_DEVICE_ERROR; + return Status; } - - InsertTailList (&HostBridge->Head, &PrivateData->Link); + InsertTailList (&HostBridge->Head, &RootBus->Link); } return EFI_SUCCESS; -- 1.8.3.1 ------------------------------------------------------------------------------ Don't Limit Your Business. Reach for the Cloud. GigeNET's Cloud Solutions provide you with the tools and support that you need to offload your IT needs and focus on growing your business. Configured For All Businesses. Start Your Cloud Today. https://www.gigenetcloud.com/ _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel