On 02/24/16 11:06, Ni, Ruiyu wrote: >> -----Original Message----- >> From: Laszlo Ersek [mailto:ler...@redhat.com] >> Sent: Wednesday, February 24, 2016 5:40 PM >> To: Ni, Ruiyu <ruiyu...@intel.com>; Marcel Apfelbaum <mar...@redhat.com> >> Cc: Justen, Jordan L <jordan.l.jus...@intel.com>; edk2-de...@ml01.01.org; >> Tian, Feng <feng.t...@intel.com>; Fan, Jeff <jeff....@intel.com>; Marcel >> Apfelbaum (GMail address) <marcel.apfelb...@gmail.com> >> Subject: Re: [edk2] [Patch V4 4/4] MdeModulePkg: Add generic >> PciHostBridgeDxe driver.
[snip] >> EfiGcdAllocateAddress is correct if the driver allocates memory space >> (or IO space) for the *entire root bridge aperture*. >> >> My suggestion with EfiGcdAllocateMaxAddressSearchTopDown was for the >> allocation of an *individual BAR*. >> >> So, if the driver is supposed to allocate the *entire bridge aperture* >> in one fell swoop, then EfiGcdAllocateAddress is correct. >> >> *However*, this only takes us back to the original question of >> overlapping apertures, between separate bridges! >> >> Consider the following example. You have two root bridges, and the >> 32-bit MMIO aperture for each is [3.0GB, 3.5GB). >> >> (i) According to option #2 above, the *first* gDS->AddMemorySpace() >> operation will ensure that the [3.0GB, 3.5GB) range *exists* as MMIO in >> the GCD memory space map. Fine. >> >> (ii) Then the logic in PciHostBridgeDxe will determine, for the *second* >> root bridge, according to option #2, that the [3.0GB, 3.5GB) range >> *already* exists as MMIO in the GCD memory space map, without gaps. So >> there will be no need for another gDS->AddMemorySpace() call. This is >> fine as well. >> >> (iii) Then the driver *allocates* the [3.0GB, 3.5GB) MMIO range for the >> *first* root bridge, with the gDS->AllocateMemorySpace() call. It works >> perfectly. > > No. The driver does *NOT* allocate [3G, 3.5G) for root bridge #0. > It just allocates the resource that is really required by root bridge #0. > for example, [3G, 3.3G). Ah! Now I finally understand it! The PCI bus driver first collects the *cumulative* resource requirements for *all* of the devices behind the root bridge (i.e., it consolidates all of the BARs into a single range, paying attention to the size and alignment requirements of the individual BARs), and *then* that allocation request is submitted to the PCI host bridge driver. It makes perfect sense. >> (iv) Then the driver tries to allocate the same [3.0GB, 3.5GB) MMIO >> range for the *second* root bridge, with another >> gDS->AllocateMemorySpace() call. This fails, because that range is no >> longer free! Hence the driver calls PciHostBridgeResourceConflict(). >> > > When the real requirement for root bridge #1 is <= 0.2G, the allocation > still succeeds. > Though the driver uses EfiGcdAllocateAddress type, it tries different > base address to allocate. So it ultimately searches to 3.3G as a valid > base address for allocation. > When the real requirement for root bridge #1 is > 0.2G, the allocation > fails. That's a fatal error which will call PciHostBridgeResourceConflict(). Yep, it makes perfect sense now. (I think the 0.2GB constant above has to do with powers-of-two alignment & size requirements for the root bridge itself, right?) Thanks for educating me about this! I think if we go with option #2 for the IO and memory space *addition*, then I can complete the rebase of OvmfPkg to the new driver. Please go ahead with option #2 for PciHostBridgeDxe, as your time allows. Thank you! Laszlo _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel