]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmVirtPkg/FdtPciHostBridgeLib: add MMIO64 support
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Sun, 21 Aug 2016 16:51:04 +0000 (18:51 +0200)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Fri, 2 Sep 2016 20:41:01 +0000 (21:41 +0100)
If the pci-host-ecam-generic DT node describes a 64-bit MMIO region,
account for it in the PCI_ROOT_BRIDGE description that we return to
the generic PciHostBridgeDxe implementation, which will be able to
allocate BARs from it without any further changes.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Ref: https://tianocore.acgmultimedia.com/show_bug.cgi?id=65

ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c
ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf

index 7fe81ee09d873be442ac5d125c7c962737ec6b9a..bb3742386c63cf78667c27436102b019f13ffeff 100644 (file)
@@ -87,8 +87,10 @@ EFI_STATUS
 ProcessPciHost (\r
   OUT  UINT64    *IoBase,\r
   OUT  UINT64    *IoSize,\r
-  OUT  UINT64    *MmioBase,\r
-  OUT  UINT64    *MmioSize,\r
+  OUT  UINT64    *Mmio32Base,\r
+  OUT  UINT64    *Mmio32Size,\r
+  OUT  UINT64    *Mmio64Base,\r
+  OUT  UINT64    *Mmio64Size,\r
   OUT  UINT32    *BusMin,\r
   OUT  UINT32    *BusMax\r
   )\r
@@ -101,7 +103,8 @@ ProcessPciHost (
   UINT32                      RecordIdx;\r
   EFI_STATUS                  Status;\r
   UINT64                      IoTranslation;\r
-  UINT64                      MmioTranslation;\r
+  UINT64                      Mmio32Translation;\r
+  UINT64                      Mmio64Translation;\r
 \r
   //\r
   // The following output arguments are initialized only in\r
@@ -109,17 +112,19 @@ ProcessPciHost (
   // *incorrectly* emitted by some gcc versions.\r
   //\r
   *IoBase = 0;\r
-  *MmioBase = 0;\r
+  *Mmio32Base = 0;\r
+  *Mmio64Base = MAX_UINT64;\r
   *BusMin = 0;\r
   *BusMax = 0;\r
 \r
   //\r
-  // *IoSize, *MmioSize and IoTranslation are initialized to zero because the\r
+  // *IoSize, *Mmio##Size and IoTranslation are initialized to zero because the\r
   // logic below requires it. However, since they are also affected by the issue\r
   // reported above, they are initialized early.\r
   //\r
   *IoSize = 0;\r
-  *MmioSize = 0;\r
+  *Mmio32Size = 0;\r
+  *Mmio64Size = 0;\r
   IoTranslation = 0;\r
 \r
   Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
@@ -209,28 +214,43 @@ ProcessPciHost (
       break;\r
 \r
     case DTB_PCI_HOST_RANGE_MMIO32:\r
-      *MmioBase = SwapBytes64 (Record->ChildBase);\r
-      *MmioSize = SwapBytes64 (Record->Size);\r
-      MmioTranslation = SwapBytes64 (Record->CpuBase) - *MmioBase;\r
+      *Mmio32Base = SwapBytes64 (Record->ChildBase);\r
+      *Mmio32Size = SwapBytes64 (Record->Size);\r
+      Mmio32Translation = SwapBytes64 (Record->CpuBase) - *Mmio32Base;\r
 \r
-      if (*MmioBase > MAX_UINT32 || *MmioSize > MAX_UINT32 ||\r
-          *MmioBase + *MmioSize > SIZE_4GB) {\r
+      if (*Mmio32Base > MAX_UINT32 || *Mmio32Size > MAX_UINT32 ||\r
+          *Mmio32Base + *Mmio32Size > SIZE_4GB) {\r
         DEBUG ((EFI_D_ERROR, "%a: MMIO32 space invalid\n", __FUNCTION__));\r
         return EFI_PROTOCOL_ERROR;\r
       }\r
 \r
-      ASSERT (PcdGet64 (PcdPciMmio32Translation) == MmioTranslation);\r
+      ASSERT (PcdGet64 (PcdPciMmio32Translation) == Mmio32Translation);\r
 \r
-      if (MmioTranslation != 0) {\r
+      if (Mmio32Translation != 0) {\r
         DEBUG ((EFI_D_ERROR, "%a: unsupported nonzero MMIO32 translation "\r
-          "0x%Lx\n", __FUNCTION__, MmioTranslation));\r
+          "0x%Lx\n", __FUNCTION__, Mmio32Translation));\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+\r
+      break;\r
+\r
+    case DTB_PCI_HOST_RANGE_MMIO64:\r
+      *Mmio64Base = SwapBytes64 (Record->ChildBase);\r
+      *Mmio64Size = SwapBytes64 (Record->Size);\r
+      Mmio64Translation = SwapBytes64 (Record->CpuBase) - *Mmio64Base;\r
+\r
+      ASSERT (PcdGet64 (PcdPciMmio64Translation) == Mmio64Translation);\r
+\r
+      if (Mmio64Translation != 0) {\r
+        DEBUG ((EFI_D_ERROR, "%a: unsupported nonzero MMIO64 translation "\r
+          "0x%Lx\n", __FUNCTION__, Mmio64Translation));\r
         return EFI_UNSUPPORTED;\r
       }\r
 \r
       break;\r
     }\r
   }\r
-  if (*IoSize == 0 || *MmioSize == 0) {\r
+  if (*IoSize == 0 || *Mmio32Size == 0) {\r
     DEBUG ((EFI_D_ERROR, "%a: %a space empty\n", __FUNCTION__,\r
       (*IoSize == 0) ? "IO" : "MMIO32"));\r
     return EFI_PROTOCOL_ERROR;\r
@@ -243,9 +263,9 @@ ProcessPciHost (
   ASSERT (PcdGet64 (PcdPciExpressBaseAddress) == ConfigBase);\r
 \r
   DEBUG ((EFI_D_INFO, "%a: Config[0x%Lx+0x%Lx) Bus[0x%x..0x%x] "\r
-    "Io[0x%Lx+0x%Lx)@0x%Lx Mem[0x%Lx+0x%Lx)@0x0\n", __FUNCTION__, ConfigBase,\r
-    ConfigSize, *BusMin, *BusMax, *IoBase, *IoSize, IoTranslation, *MmioBase,\r
-    *MmioSize));\r
+    "Io[0x%Lx+0x%Lx)@0x%Lx Mem32[0x%Lx+0x%Lx)@0x0 Mem64[0x%Lx+0x%Lx)@0x0\n",\r
+    __FUNCTION__, ConfigBase, ConfigSize, *BusMin, *BusMax, *IoBase, *IoSize,\r
+    IoTranslation, *Mmio32Base, *Mmio32Size, *Mmio64Base, *Mmio64Size));\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -268,6 +288,7 @@ PciHostBridgeGetRootBridges (
 {\r
   UINT64              IoBase, IoSize;\r
   UINT64              Mmio32Base, Mmio32Size;\r
+  UINT64              Mmio64Base, Mmio64Size;\r
   UINT32              BusMin, BusMax;\r
   EFI_STATUS          Status;\r
 \r
@@ -278,8 +299,8 @@ PciHostBridgeGetRootBridges (
     return NULL;\r
   }\r
 \r
-  Status = ProcessPciHost (&IoBase, &IoSize, &Mmio32Base, &Mmio32Size, &BusMin,\r
-             &BusMax);\r
+  Status = ProcessPciHost (&IoBase, &IoSize, &Mmio32Base, &Mmio32Size,\r
+             &Mmio64Base, &Mmio64Size, &BusMin, &BusMax);\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "%a: failed to discover PCI host bridge: %r\n",\r
       __FUNCTION__, Status));\r
@@ -308,8 +329,23 @@ PciHostBridgeGetRootBridges (
   mRootBridge.Io.Limit              = IoBase + IoSize - 1;\r
   mRootBridge.Mem.Base              = Mmio32Base;\r
   mRootBridge.Mem.Limit             = Mmio32Base + Mmio32Size - 1;\r
-  mRootBridge.MemAbove4G.Base       = MAX_UINT64;\r
-  mRootBridge.MemAbove4G.Limit      = 0;\r
+\r
+  if (sizeof (UINTN) == sizeof (UINT64)) {\r
+    mRootBridge.MemAbove4G.Base       = Mmio64Base;\r
+    mRootBridge.MemAbove4G.Limit      = Mmio64Base + Mmio64Size - 1;\r
+    if (Mmio64Size > 0) {\r
+      mRootBridge.AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE;\r
+    }\r
+  } else {\r
+    //\r
+    // UEFI mandates a 1:1 virtual-to-physical mapping, so on a 32-bit\r
+    // architecture such as ARM, we will not be able to access 64-bit MMIO\r
+    // BARs unless they are allocated below 4 GB. So ignore the range above\r
+    // 4 GB in this case.\r
+    //\r
+    mRootBridge.MemAbove4G.Base       = MAX_UINT64;\r
+    mRootBridge.MemAbove4G.Limit      = 0;\r
+  }\r
 \r
   //\r
   // No separate ranges for prefetchable and non-prefetchable BARs\r
index fc1d37fb3c23f543cdb724bad8a05cfcdac84360..0995f4b7a156ea9c38db86f0593d86d31d98a39a 100644 (file)
@@ -47,6 +47,7 @@
 \r
 [FixedPcd]\r
   gArmTokenSpaceGuid.PcdPciMmio32Translation\r
+  gArmTokenSpaceGuid.PcdPciMmio64Translation\r
 \r
 [Pcd]\r
   gArmTokenSpaceGuid.PcdPciIoTranslation\r