Some platform doesn't use CPU(HOST)/Device 1:1 mapping for PCI Bus. But PCI IO doesn't have interface to tell caller (device driver) whether the address returned by GetBarAttributes() is HOST address or device address. UEFI Spec 2.6 addresses this issue by clarifying the address returned is HOST address and caller can use AddrTranslationOffset to calculate the device address.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni <[email protected]> Cc: Benjamin Herrenschmidt <[email protected]> Cc: Andrew Fish <[email protected]> Cc: Jeff Fan <[email protected]> --- MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c index 50ed866..5cee8ca 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c @@ -1774,8 +1774,10 @@ PciIoGetBarAttributes ( OUT VOID **Resources OPTIONAL ) { + EFI_STATUS Status; PCI_IO_DEVICE *PciIoDevice; EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration; EFI_ACPI_END_TAG_DESCRIPTOR *End; PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); @@ -1863,6 +1865,41 @@ PciIoGetBarAttributes ( End = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Descriptor + 1); End->Desc = ACPI_END_TAG_DESCRIPTOR; End->Checksum = 0; + + // + // Get the Address Translation Offset + // + if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { + Status = PciIoDevice->PciRootBridgeIo->Configuration ( + PciIoDevice->PciRootBridgeIo, + (VOID **) &Configuration + ); + if (!EFI_ERROR (Status)) { + while (Configuration->Desc == Descriptor->Desc) { + if ((Configuration->ResType == Descriptor->ResType) && + (Configuration->AddrRangeMin <= Descriptor->AddrRangeMin) && + (Configuration->AddrRangeMin + Configuration->AddrLen >= Descriptor->AddrRangeMin + Descriptor->AddrLen) + ) { + Descriptor->AddrTranslationOffset = Configuration->AddrTranslationOffset; + break; + } + Configuration++; + } + + // + // The resource occupied by BAR should be in the range reported by RootBridge. + // + ASSERT (Configuration->Desc == Descriptor->Desc); + if (Configuration->Desc != Descriptor->Desc) { + Status = EFI_UNSUPPORTED; + } + } + + if (EFI_ERROR (Status)) { + FreePool (Descriptor); + return Status; + } + } } return EFI_SUCCESS; -- 2.7.0.windows.1 _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

