]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/PlatformInitLib: Add PlatformReservationConflictCB
authorGerd Hoffmann <kraxel@redhat.com>
Tue, 17 Jan 2023 12:16:28 +0000 (13:16 +0100)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 17 Jan 2023 16:36:59 +0000 (16:36 +0000)
Add PlatformReservationConflictCB() callback function for use with
PlatformScanE820().  It checks whenever the 64bit PCI MMIO window
overlaps with a reservation from qemu.  If so move down the MMIO window
to resolve the conflict.

Write any actions done (moving mmio window) to the firmware log with
INFO loglevel.

This happens on (virtual) AMD machines with 1TB address space,
because the AMD IOMMU uses an address window just below 1TB.

Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4251
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
OvmfPkg/Library/PlatformInitLib/MemDetect.c

index c24105c329334f3563d98a95c8a5bfd89c3ad78d..6c30566db937188e359dec8bcb1c16abe5222538 100644 (file)
@@ -216,6 +216,51 @@ PlatformAddHobCB (
   }\r
 }\r
 \r
+/**\r
+  Check whenever the 64bit PCI MMIO window overlaps with a reservation\r
+  from qemu.  If so move down the MMIO window to resolve the conflict.\r
+\r
+  This happens on (virtual) AMD machines with 1TB address space,\r
+  because the AMD IOMMU uses an address window just below 1TB.\r
+**/\r
+STATIC\r
+VOID\r
+PlatformReservationConflictCB (\r
+  IN     EFI_E820_ENTRY64       *E820Entry,\r
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob\r
+  )\r
+{\r
+  UINT64  IntersectionBase;\r
+  UINT64  IntersectionEnd;\r
+  UINT64  NewBase;\r
+\r
+  IntersectionBase = MAX (\r
+                       E820Entry->BaseAddr,\r
+                       PlatformInfoHob->PcdPciMmio64Base\r
+                       );\r
+  IntersectionEnd = MIN (\r
+                      E820Entry->BaseAddr + E820Entry->Length,\r
+                      PlatformInfoHob->PcdPciMmio64Base +\r
+                      PlatformInfoHob->PcdPciMmio64Size\r
+                      );\r
+\r
+  if (IntersectionBase >= IntersectionEnd) {\r
+    return;  // no overlap\r
+  }\r
+\r
+  NewBase = E820Entry->BaseAddr - PlatformInfoHob->PcdPciMmio64Size;\r
+  NewBase = NewBase & ~(PlatformInfoHob->PcdPciMmio64Size - 1);\r
+\r
+  DEBUG ((\r
+    DEBUG_INFO,\r
+    "%a: move mmio: 0x%Lx => %Lx\n",\r
+    __FUNCTION__,\r
+    PlatformInfoHob->PcdPciMmio64Base,\r
+    NewBase\r
+    ));\r
+  PlatformInfoHob->PcdPciMmio64Base = NewBase;\r
+}\r
+\r
 /**\r
   Iterate over the entries in QEMU's fw_cfg E820 RAM map, call the\r
   passed callback for each entry.\r
@@ -653,6 +698,7 @@ PlatformDynamicMmioWindow (
     DEBUG ((DEBUG_INFO, "%a:   MMIO Space 0x%Lx (%Ld GB)\n", __func__, MmioSpace, RShiftU64 (MmioSpace, 30)));\r
     PlatformInfoHob->PcdPciMmio64Size = MmioSpace;\r
     PlatformInfoHob->PcdPciMmio64Base = AddrSpace - MmioSpace;\r
+    PlatformScanE820 (PlatformReservationConflictCB, PlatformInfoHob);\r
   } else {\r
     DEBUG ((DEBUG_INFO, "%a: using classic mmio window\n", __func__));\r
   }\r