Adding Ray
On 08/17/17 06:50, Eric Song wrote:
> Hi, experts
> If there is 2 root bridges under 1 host bridge on the PCI hierarchy,
> whether EDK2 Pci bus driver can support it ? the answer is YES, but
> some confused things in it.
>
> 1) On BDS phase, ConnectController is called for every root
> bridge, so Pci bus start() will be called for every root bridge.
>
> VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid,
> ConnectRootBridge, NULL);
>
> 2) In PCI bus driver, Pci start() will do enumeration on the
> entire host bridge
>
> PciEnumerator()->PciHostBridgeEnumerator->PciResAlloc->GetNextRootBridge()
>
> That means Do enumeration on entire host bridge for every one root
> bridge. So there are 2 enumerations on entire host bridge for my PCI
> hierarchy.
> What I confused is why do 2 enumerations on entire host bridge by
> every one root bridge. Since BDS connect controller by one root bridge
> , Pci bus driver should enumerate corresponding root bridge, But it do
> the entire host bridge which is the parent of the root bridge. Or BDS
> should connect controller by one host bridge, then it will match the
> pci bus driver s enumeration policy. In a word, I think it is
> illogical for current EDKII code.
>
> Well, the current code execution will do 2 enumerations on host bridge
> for 2 root bridges under 1 host bridge. Even though 2rd enumeration
> would be not full enumeration, but do PciEnumeratorLight(), I think it
> is still not necessary. Whether there is any side effect ? In another
> word, current PCI bus driver enumeration cant be Suitable for 2
> root bridges under 1 host bridge or not? It indeed match the PCI
> hierarchy of 2 host bridges and 1 root bridge under 1 host bridge.
While I don't know the internals of this host bridge-level enumeration,
it is worth looking at:
(a) in what context PciEnumerator() is called, and
(b) how PciEnumerator() works across multiple calls.
Regarding (a): PciEnumerator() is called from
PciBusDriverBindingStart(), that is, when the PciBusDxe driver is
binding a root brirdge. This is the code:
//
// Enumerate the entire host bridge
// After enumeration, a database that records all the device information will
be created
//
//
Status = PciEnumerator (Controller);
Regarding (b): the PciEnumerator() function depends on a global variable
called "gFullEnumeration". This is what we have at the beginning and at
the end of PciEnumerator(), respectively:
//
// If PCI bus has already done the full enumeration, never do it again
//
if (!gFullEnumeration) {
return PciEnumeratorLight (Controller);
}
...
gFullEnumeration = FALSE;
Status = gBS->InstallProtocolInterface (
&HostBridgeHandle,
&gEfiPciEnumerationCompleteProtocolGuid,
EFI_NATIVE_INTERFACE,
NULL
);
The above seems to imply that PciBusDxe needs host bridge-level
information to do its job. This information is apparently collected when
the first root bridge is bound. When binding further root bridges (under
the same host bridge), the same information collecting is not repeated;
PciEnumerator() branches to PciEnumeratorLight() instead.
Hope this helps,
Laszlo
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel