On 2015-07-07 08:09:22, Laszlo Ersek wrote: > In this patch we assume that root bus number 0 is always there (same as > before), and scan the rest of the extra root buses, up to and including > 255. When an extra root bus is found, we install the PCI root bridge IO > protocol for the previous root bus (which might be bus 0 or just the > previous extra root bus). > > The root bridge protocol created thus will report the available bus number > range > > [own bus number, next extra root bus number - 1] > > The LHS of this interval will be used for the root bus's own number, and > the rest of the interval (which might encompass 0 additional elements too) > can be used by the PCI bus driver to assign subordinate bus numbers from. > > (Subordinate buses are provided by PCI bridges that hang off the root bus > in question.) > > For MMIO and IO space allocation, all the root buses share the original > [0x8000_0000, 0xFFFF_FFFF] and [0x0, 0xFFFF] ranges, respectively. > > 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 | 95 +++++++++++++++----- > 1 file changed, 71 insertions(+), 24 deletions(-) > > diff --git a/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c > b/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c > index 7dda75f..3486644 100644 > --- a/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c > +++ b/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c > @@ -43,14 +43,6 @@ EFI_PCI_ROOT_BRIDGE_DEVICE_PATH > mRootBridgeDevicePathTemplate = { > } > }; > > -// > -// Hard code: Root Bridge's resource aperture > -// > - > -PCI_ROOT_BRIDGE_RESOURCE_APERTURE mResAperture[1] = { > - {0, 0xff, 0x80000000, 0xffffffff, 0, 0xffff} > -}; > - > EFI_HANDLE mDriverImageHandle; > > PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = { > @@ -80,8 +72,15 @@ PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = { > > 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] MaxSubBusNumber The inclusive maximum bus number that can be > + assigned to any subordinate bus found behind > any > + PCI bridge hanging off this root bus. > + > + The caller is repsonsible for ensuring that > + RootBusNumber <= MaxSubBusNumber. If > + RootBusNumber equals MaxSubBusNumber, then the > + root bus has no room for subordinate buses. > > param[in] HostBridgeHandle The EFI_HANDLE corresponding to the host > bridge > that is the parent of the root bridge to > create. > @@ -108,12 +107,16 @@ STATIC > EFI_STATUS > InitRootBridge ( > IN UINT8 RootBusNumber, > + IN UINT8 MaxSubBusNumber, > IN EFI_HANDLE HostBridgeHandle, > OUT PCI_ROOT_BRIDGE_INSTANCE **RootBus > ) > { > - PCI_ROOT_BRIDGE_INSTANCE *PrivateData; > - EFI_STATUS Status; > + PCI_ROOT_BRIDGE_INSTANCE *PrivateData; > + PCI_ROOT_BRIDGE_RESOURCE_APERTURE ResAperture; > + EFI_STATUS Status; > + > + ASSERT (RootBusNumber <= MaxSubBusNumber); > > PrivateData = AllocateZeroPool (sizeof *PrivateData); > if (PrivateData == NULL) { > @@ -126,13 +129,18 @@ InitRootBridge ( > sizeof mRootBridgeDevicePathTemplate); > PrivateData->DevicePath.AcpiDevicePath.UID = RootBusNumber; > > + ResAperture.BusBase = RootBusNumber; > + ResAperture.BusLimit = MaxSubBusNumber; > + ResAperture.MemBase = BASE_2GB; > + ResAperture.MemLimit = BASE_4GB - 1; > + ResAperture.IoBase = 0; > + ResAperture.IoLimit = MAX_UINT16; > // > // 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]); > + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM, &ResAperture); > ASSERT_EFI_ERROR (Status); > > Status = gBS->InstallMultipleProtocolInterfaces (&PrivateData->Handle, > @@ -143,6 +151,9 @@ InitRootBridge ( > goto FreePrivateData; > } > > + DEBUG ((EFI_D_INFO, > + "%a: installed root bus %d, with room for %d subordinate bus(es)\n", > + __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber)); > *RootBus = PrivateData; > return EFI_SUCCESS; > > @@ -196,6 +207,7 @@ InitializePciHostBridge ( > ) > { > EFI_STATUS Status; > + UINTN LastRootBridgeNumber; > UINTN RootBridgeNumber; > PCI_HOST_BRIDGE_INSTANCE *HostBridge; > PCI_ROOT_BRIDGE_INSTANCE *RootBus; > @@ -224,19 +236,54 @@ InitializePciHostBridge ( > goto FreeHostBridge; > } > > - for (RootBridgeNumber = 0; > - RootBridgeNumber < 1; > + // > + // The "main" root bus is always there. > + // > + LastRootBridgeNumber = 0; > + > + // > + // Scan all other root buses. If function 0 of any device on a bus returns > a > + // VendorId register value different from all-bits-one, then that bus is > + // alive. > + // > + for (RootBridgeNumber = 1; > + RootBridgeNumber < 256;
Do we want to scan all these buses on Xen? > ++RootBridgeNumber) { > - Status = InitRootBridge ( > - (UINT8)RootBridgeNumber, > - HostBridge->HostBridgeHandle, > - &RootBus > - ); > - if (EFI_ERROR (Status)) { > - goto RollbackProtocols; > + UINTN Device; > + > + for (Device = 0; Device <= MAX_PCI_DEVICE_NUMBER; ++Device) { I guess there's no guarantee that device 0 will be present on these buses? -Jordan > + if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0, > + PCI_VENDOR_ID_OFFSET)) != MAX_UINT16) { > + break; > + } > } > - InsertTailList (&HostBridge->Head, &RootBus->Link); > + if (Device <= MAX_PCI_DEVICE_NUMBER) { > + // > + // Found the next root bus. We can now install the *previous* one, > + // because now we know how big a bus number range *that* one has, for > any > + // subordinate buses that might exist behind PCI bridges hanging off > it. > + // > + Status = InitRootBridge ((UINT8)LastRootBridgeNumber, > + (UINT8)(RootBridgeNumber - 1), HostBridge->HostBridgeHandle, > + &RootBus); > + if (EFI_ERROR (Status)) { > + goto RollbackProtocols; > + } > + InsertTailList (&HostBridge->Head, &RootBus->Link); > + LastRootBridgeNumber = RootBridgeNumber; > + } > + } > + > + // > + // Install the last root bus (which might be the only, ie. main, root bus, > if > + // we've found no extra root buses). > + // > + Status = InitRootBridge ((UINT8)LastRootBridgeNumber, 255, > + HostBridge->HostBridgeHandle, &RootBus); > + if (EFI_ERROR (Status)) { > + goto RollbackProtocols; > } > + 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