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

Reply via email to