On 07/03/20 01:03, Andrew Fish via groups.io wrote:
PciHostBridgeDxe calls the PciHostBridgeGetRootBridges() function fromOn Jul 2, 2020, at 3:54 PM, King Sumo <kingsumos@...> wrote:It looks like the above request for "D4000000 - FE0FFFFF” overlaps with an existing mapping (E0000000, F0000000). The edk2 has something called GCD (Global Coherency Domain) that is kind of like malloc for MMIO space, and what part of the CPU address has DRAM. So it looks like 2 device think they own (E0000000, F0000000), and there can be only one. You may be getting lucky that your hardware works, but something seems miss configured.
the platform's "PciHostBridgeLib" instance. The function outputs an
array of PCI_ROOT_BRIDGE structures that describe the PCI root bridges
on the system, including the various resource apertures for each bridge
(expressed as device address ranges).
Then PciHostBridgeDxe tries to allocate the described apertures from the
according resource type GCD spaces (after translating the address ranges
in question from device addresses to host addresses).
The attempt to allocate any one such aperture consists of three steps,
(1) make sure the GCD memory map covers the aperture with compatible
descriptor(s), (2) set the aperture range to uncacheable (for MMIO only;
not defined for IO), (3) actually allocate the aperture.
In step (1), there's a slight trick. We don't call gDS->AddIoSpace() /
gDS->AddMemorySpace() indiscriminately, because the platform may have
populated the GCD memory space / IO space maps before, such that there
could be a (partial or complete) overlap with the aperture being added.
Therefore the internal AddIoSpace() and AddMemoryMappedIoSpace()
functions are idempotent. They contrast every existent GCD space
descriptor with the aperture being added (including gaps, that is,
"nonexistent" type descriptors). For the case when both ranges are fully
distinct, nothing is done. If there is a partial or full overlap, and
the descriptor is "nonexistent", then the intersection is added with
gDS->AddIoSpace() / gDS->AddMemorySpace(). If there is a partial or full
overlap, and the descriptor type is *not* "nonexistent", then the
intersection's *compatibility* is checked, against the requested type
and capabilities of the aperture.
The above procedure ensures that, for any given resource aperture, the
GCD IO or memory space map covers the aperture, with nonzero (that is,
possibly more than one!) adjacent descriptor entries, such that each
descriptor intersecting with the aperture has compatible type and
capabilities with the aperture.
In turn, the error message seen above reports a platform misconfiguration.
It reports that the GCD memory space map already has an entry (a
descriptor) at [E0000000, F0000000), with type 1 (that is,
"EfiGcdMemoryTypeReserved" -- see "MdePkg/Include/Pi/PiDxeCis.h"). The
capabilities of this range are 0x8700_0000_0002_600F
At the same time, the platform's PciHostBridgeLib instance reported a
root bridge with an MMIO aperture at [D4000000, FE100000), with
This is a conflict. The capabilities don't even matter (we don't even
check whether the existent GCD descriptor's capabilities are a superset
of the aperture's), because the aperture requires GCD memory type
EfiGcdMemoryTypeMemoryMappedIo, but the GCD descriptor has type
In brief, the failure is due to the platform reporting a PCI root bridge
aperture such that it overlaps an area that is already listed as
"reserved" in the GCD memory space map. So this is a platform bug;
either in the "PciHostBridgeLib" instance, or in the module that
populates the GCD memory space map.