On 02/24/16 03:46, Ni, Ruiyu wrote:
> Laszlo,
> 
> PciBus summarize all the resource requirements for a root bridge,
> and submit the resource requirement summary to PciHostBridge driver.
> So the allocations occur for each root bridge, but not for each BAR.
>  
> 
> For the Add[Io/Memory]Space operations, I see two options:
> 1. A flag to tell PciHostBridge the resources have been already added
> by platform. PciHostBridge only adds the resources when the flag is
> not set.
> 
> 2. PciHostBridge guarantees the resources reported by each root 
> bridge have been added. Part of the resources may have been added.
> PciHostBridge adds the remaining part.
> 
> I prefer option 2 because it doesn’t need an additional flag –
> additional flag means additional interface.
> 
> You strongly prefer option 1?

No, my preference for option 1 is not strong. Option 2 can be certainly
accommodated in OvmfPkg, so if option 2 is your preference, I suggest we
go with that.

> For the Allocate[Io/Memory]Space operation, I think we might be aligned:
> 
> For each root bridge (not each BAR, but I think BAR or root bridge 
> doesn’t bother you),

Actually, that difference is crucial. See below.

> PciHostBridge calls Allocate[Io/Memory]Space to
> allocate the required resources. If allocation fails, 
> PciHostBridgeResourceConflict() is called to inform platform.
> 
> But we do have some small differences for the allocation:
> 
> The current allocation algorithm uses EfiGcdAllocateAddress. You could
> check PciHostBridge.c:
> 
> AllocateResource() function for the detailed implementation. It’s
> different from what you suggested:
> 
> EfiGcdAllocateMaxAddressSearchTopDown. Do you think it matters?

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.

(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().

Unfortunately, the allocation failure in (iv) would be a bug in the
driver -- the two root bridges want to *share* the [3.0GB, 3.5GB) MMIO
range between them, and the driver should permit it. It is not a
resource conflict between the root bridges, but a valid configuration on
QEMU.

Thanks
Laszlo



> 
>  
> 
> Regards,
> 
> Ray
> 
>  
> 
> *From:*Laszlo Ersek [mailto:[email protected]]
> *Sent:* Tuesday, February 23, 2016 4:49 PM
> *To:* Ni, Ruiyu <[email protected]>; Marcel Apfelbaum <[email protected]>
> *Cc:* Justen, Jordan L <[email protected]>;
> [email protected]; Tian, Feng <[email protected]>; Fan, Jeff
> <[email protected]>; Marcel Apfelbaum (GMail address)
> <[email protected]>
> *Subject:* Re: [edk2] [Patch V4 4/4] MdeModulePkg: Add generic
> PciHostBridgeDxe driver.
> 
>  
> 
> (Adding Marcel's gmail address -- I think that's the one he is
> subscribed to edk2-devel with.)
> 
> On 02/23/16 06:13, Ni, Ruiyu wrote:
>> Marcel,
>> I see two requirements from your mail:
>> 1. non-continuously resources: root bridge #1 uses [2G, 2.4G) and [2.8G, 3G) 
>> while
>>   root bridge #2 uses [2.4G, 2.8G)
>> 2. sharable resources among root bridges: All root bridges in same pci 
>> segment
>>   can share one common range of resources.
>> 
>> Requirement #1 is not supported by MdeModulePkg/PciBus driver and I guess
>> it's not the urgent requirement and doesn't block OVMF PciHostBridge porting.
> 
> That's correct.
> 
>> Requirement #2 can be interpreted as it's valid when the resources claimed by
>> different root bridges overlap. No matter which segment they belong to.
>>   
>> The overlap can be like root bridge #1 claims [2G, 2.4G) while root bridge #2
>> claims [2.2G, 2.6G) -- [2.2G, 2.4G) is shared by both root bridges.
>> In such case, PCI devices under root bridge #1 can only use resources [2G, 
>> 2.4G)
>> and root bridge #2 can only use [2.2G, 2.6G). GCD services can guarantee 
>> there
>> is no resource conflict -- if [2.2G, 2.3G) is used by one device under root 
>> bridge #1,
>> it won't be used by device under root bridge #2.
> 
> Correct as well.
> 
>> 
>> An extreme case is both root bridges claim [2G, 3G) which is the OVMF case.
> 
> Right.
> 
>> So the change to PciHostBridgeDxe can be:
>> 1. Checks whether the resources claimed by the root bridges are already 
>> added,
>> and call AddMemorySpace/AddIoSpace for those resource ranges which haven't
>> been added.
> 
> Do you mean that PciHostBridgeDxe would determine "gaps" in the memory
> space map / IO space map, by calling GetMemorySpaceMap() and
> GetIoSpaceMap(), and taking the intersection of each map with the
> bridge's corresponding aperture(s)?
> 
> I can imagine this, but I don't readily understand how this is useful.
> Probably as a basis for the next step:
> 
>> 2. Call AllocateMemorySpace/AllocateIoSpace to occupy these resources in GCD.
>> The Allocation shouldn't fail, otherwise it's a fatal error and 
>> PciHostBridgeDxe driver
>> will assert and exit.
> 
> I understand how step (1) is the basis for step (2) -- one can only
> allocate from the memory & IO space maps what has been added to them
> earlier --, but I don't understand how step (2) is supposed to help with
> overlapping apertures. Assuming the allocation is made with
> EfiGcdAllocateAddress, then a conflict for the shared range [2.2G, 2.4G)
> -- using your example at the top -- will be reported.
> 
> Furthermore, I'm not sure why the entire aperture for a root bridge
> should be allocated up-front. I thought the allocations occur only for
> specific BARs -- is that incorrect?
> 
> For OVMF's purposes, the following would be ideal:
> 
> (a) PciHostBridgeDxe should let the platform populate the memory and IO
> space maps as appropriate. This could happen in several ways, for
> example: (i) creation of resource descriptor HOBs during PEI, from which
> the DXE core would prime the memory and IO space maps, or (ii) in the
> constructor of the PciHostBridgeLib instance that the platform links
> into PciHostBridgeDxe.
> 
> (b) no explicit overlap checks whatsoever between root bridge apertures
> 
> (c) when a BAR is being allocated, allocate the right type of resource
> with GcdAllocateType = EfiGcdAllocateMaxAddressSearchTopDown.
> 
> Start the top-down search from the highest address in the bridge's
> aperture. If the allocation fails completely (i.e., no free room from
> the aperture's top, down to zero), report failure.
> 
> If the allocation succeeds, but the allocation address is below the base
> address of the bridge's aperture, *undo* the allocation, and report
> failure again.
> 
> Otherwise, the BAR allocation succeeds.
> 
> 
> The above strategy would give full flexibility to the platform, and it
> would ensure that no BAR is allocated outside the respective bridge
> aperture. It would handle overlaps between apertures automatically.
> 
> It would also handle the case transparently when a bridge aperture is a
> *proper superset* of what is available in the GCD memory space map. For
> example, assume the GCD memory space map only has MMIO added at [3.0G,
> 3.5G), and "nothing" at [2.0G, 3.0G) -- a gap. Then a bridge aperture of
> [2.0G, 3.5G) would "just work", without changing the GCD memory space
> map. GCD would satisfy BAR allocations from [3.0G, 3.5G), and any
> addresses allocated from that range would *also* satisfy the bridge
> aperture, automatically.
> 
> Do you see any problems with the idea in (a) through (c)?
> 
> Thank you
> Laszlo
> 

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to