Hi !

I have a situation where the mapping from the CPU address space to the
PCI MMIO space isn't 1:1

To give an example, I have, let's say, a 2G MMIO window to PCI, which
can generate PCI addresses 0x8000_0000..0xffff_ffff by accessing CPU
address 0x100_8000_0000..0x100_ffff_ffff.

So far, I have done the translation inside my Pci Root IO protocol. IE,
all the resources are in term of PCI addresses, and when doing Read()
or Write(), my implementation will apply the appropriate offset to the
actual MMIO access.

So far it works fine for everything ... except when confronted to a
driver that uses GetBarAttributes() from the PCI IO protocol.

This is typically the case of GOP drivers which use this in order to
get the framebuffer address.

In that case, the PciBusDxe returns a resource containing the PCI
address, which isn't usable as a CPU address directly and thus things
break horribly.

Sadly it doesn't seem like the UEFI spec caters well to that non-1:1
mapping (which is quite common outside of the x86 world), and doesn't
really sat what GetBarAttributes() is supposed to return. However,
practically, for GOP drivers (and possibly others) to work, we need to
return a CPU physical address, so we need to *translate* the BAR value.

Unfortunately, I haven't found any way for my root bridge to intercept
this and perform the translation. The Root IO protocol is standard so
cannot be easily modified to handle this. The resource allocation
protocol is not, so could be extended, but by the time we get those
GetBarAttributes() call, there is no remaining reference to that
protocol around that I can find (but I may have missed something).
Ideally, if it stuck around, it would be handy to have a hook in there
to "adjust" the resource returned by GetBarAttribtues().

Another way would be to actually use the AddressTranslationOffset field
of the ACPI resource descriptor. IE, the PciBusDxe resource allocation
code could make use of that field to maintain an offset associated with
the BAR value internally in the PCI_IO_DEVICE to be able to perform
such adjustments.

Unfortunately, it appears that the current implementation already
hijacks that field for user uses.

Note that just playing with the MMU to punch a hole at 8000_0000 in the
CPU address space and route that to PCI won't fly very high unless I'm
ready to limit the 32-bit space drastically. The machines I'm playing
with can have 3 or 4 PCI Host Bridge per chip, each of them having a
completely separate aperture.

Any recommendation on what is the best approach here ? I'd rather not
completely duplicate & hack the PciBusDxe, so the less invasive change
would be the best here...

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

Reply via email to