]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmVirtPkg/FdtPciHostBridgeLib: Relocate FdtPciHostBridgeLib to OvmfPkg/Fdt
authorAbner Chang <abner.chang@hpe.com>
Mon, 11 Oct 2021 13:36:28 +0000 (21:36 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 14 Oct 2021 06:25:52 +0000 (06:25 +0000)
Relocate FdtPciHostBridgeLib to OvmfPkg/Fdt, this library is
leverage by both ARM and RISC-V archs. Also use
PcdPciMmio32Translation and PcdPciMmio64Translation
PCDs provided by MdePkg instead of ArmPkg.

Signed-off-by: Abner Chang <abner.chang@hpe.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Daniel Schaefer <daniel.schaefer@hpe.com>
Cc: Sunil V L <sunilvl@ventanamicro.com>
Reviewed-by: Daniel Schaefer <daniel.schaefer@hpe.com>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Jiewen Yao <jiewen.yao@intel.com>
ArmPkg/ArmPkg.dec
ArmVirtPkg/ArmVirtCloudHv.dsc
ArmVirtPkg/ArmVirtKvmTool.dsc
ArmVirtPkg/ArmVirtQemu.dsc
ArmVirtPkg/ArmVirtQemuKernel.dsc
ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c [deleted file]
ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf [deleted file]
OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c [new file with mode: 0644]
OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf [new file with mode: 0644]

index 12584fb3190dba658a694c4df2a3bbe3467d1069..5935663fa9a382704651b3e7ac1b2d7873f1200d 100644 (file)
   #   UINT64 Mmio64CpuBase; // mapping target in 64-bit cpu-physical space\r
   #\r
   #   gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation = IoCpuBase - PcdPciIoBase;\r
-  #   PcdPciMmio32Translation = Mmio32CpuBase - (UINT64)PcdPciMmio32Base;\r
-  #   PcdPciMmio64Translation = Mmio64CpuBase - PcdPciMmio64Base;\r
+  #   gEfiMdePkgTokenSpaceGuid.PcdPciMmio32Translation = Mmio32CpuBase - (UINT64)PcdPciMmio32Base;\r
+  #   gEfiMdePkgTokenSpaceGuid.PcdPciMmio64Translation = Mmio64CpuBase - PcdPciMmio64Base;\r
   #\r
   # because (a) the target address space (ie. the cpu-physical space) is\r
   # 64-bit, and (b) the translation values are meant as offsets for *modular*\r
   #   TranslatedIoAddress     = UntranslatedIoAddress +\r
   #                             gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation;\r
   #   TranslatedMmio32Address = (UINT64)UntranslatedMmio32Address +\r
-  #                             PcdPciMmio32Translation;\r
+  #                             gEfiMdePkgTokenSpaceGuid.PcdPciMmio32Translation;\r
   #   TranslatedMmio64Address = UntranslatedMmio64Address +\r
-  #                             PcdPciMmio64Translation;\r
+  #                             gEfiMdePkgTokenSpaceGuid.PcdPciMmio64Translation;\r
   #\r
   #  The modular arithmetic performed in UINT64 ensures that the translation\r
   #  works correctly regardless of the relation between IoCpuBase and\r
   gArmTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x00000051\r
   gArmTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT32|0x00000053\r
   gArmTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT32|0x00000054\r
-  gArmTokenSpaceGuid.PcdPciMmio32Translation|0x0|UINT64|0x00000055\r
   gArmTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x00000056\r
   gArmTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x00000057\r
-  gArmTokenSpaceGuid.PcdPciMmio64Translation|0x0|UINT64|0x00000058\r
 \r
   #\r
   # Inclusive range of allowed PCI buses.\r
index 2b722917e3d9957346dda25f12056ae673c5c654..e071623476db2a33d949502a7fb83d6c56def75a 100644 (file)
@@ -51,7 +51,7 @@
   FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf\r
   PciPcdProducerLib|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf\r
   PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf\r
-  PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf\r
+  PciHostBridgeLib|OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf\r
   PciHostBridgeUtilityLib|ArmVirtPkg/Library/ArmVirtPciHostBridgeUtilityLib/ArmVirtPciHostBridgeUtilityLib.inf\r
 \r
   TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf\r
index 97fc98d778210d918463112ca30befdc66777c3c..0c5da4427e6bf795eafd1dd2b8496eea45227b9f 100644 (file)
@@ -59,7 +59,7 @@
 \r
   PciPcdProducerLib|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf\r
   PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf\r
-  PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf\r
+  PciHostBridgeLib|OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf\r
   PciHostBridgeUtilityLib|ArmVirtPkg/Library/ArmVirtPciHostBridgeUtilityLib/ArmVirtPciHostBridgeUtilityLib.inf\r
 \r
   TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf\r
index 3cca073009f0745bc3a17e47acae055376fb84ab..209c294fcd9ffeb2af780bb19a028b40443cb3c8 100644 (file)
@@ -79,7 +79,7 @@
   FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf\r
   PciPcdProducerLib|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf\r
   PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf\r
-  PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf\r
+  PciHostBridgeLib|OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf\r
   PciHostBridgeUtilityLib|OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf\r
 \r
 !if $(TPM2_ENABLE) == TRUE\r
index a42e53b0b1317b26015fa7852a9e477d3726081d..10c01a7f34f9e10ce393bf752c671984063e8982 100644 (file)
@@ -77,7 +77,7 @@
   FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf\r
   PciPcdProducerLib|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf\r
   PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf\r
-  PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf\r
+  PciHostBridgeLib|OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf\r
   PciHostBridgeUtilityLib|OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf\r
   TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf\r
   TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLibNull/PeiDxeTpmPlatformHierarchyLib.inf\r
diff --git a/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c
deleted file mode 100644 (file)
index 0099b8e..0000000
+++ /dev/null
@@ -1,417 +0,0 @@
-/** @file\r
-  PCI Host Bridge Library instance for pci-ecam-generic DT nodes\r
-\r
-  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
-\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-#include <PiDxe.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/DxeServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/PciHostBridgeLib.h>\r
-#include <Library/PciHostBridgeUtilityLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-\r
-#include <Protocol/FdtClient.h>\r
-#include <Protocol/PciRootBridgeIo.h>\r
-#include <Protocol/PciHostBridgeResourceAllocation.h>\r
-\r
-//\r
-// We expect the "ranges" property of "pci-host-ecam-generic" to consist of\r
-// records like this.\r
-//\r
-#pragma pack (1)\r
-typedef struct {\r
-  UINT32 Type;\r
-  UINT64 ChildBase;\r
-  UINT64 CpuBase;\r
-  UINT64 Size;\r
-} DTB_PCI_HOST_RANGE_RECORD;\r
-#pragma pack ()\r
-\r
-#define DTB_PCI_HOST_RANGE_RELOCATABLE  BIT31\r
-#define DTB_PCI_HOST_RANGE_PREFETCHABLE BIT30\r
-#define DTB_PCI_HOST_RANGE_ALIASED      BIT29\r
-#define DTB_PCI_HOST_RANGE_MMIO32       BIT25\r
-#define DTB_PCI_HOST_RANGE_MMIO64       (BIT25 | BIT24)\r
-#define DTB_PCI_HOST_RANGE_IO           BIT24\r
-#define DTB_PCI_HOST_RANGE_TYPEMASK     (BIT31 | BIT30 | BIT29 | BIT25 | BIT24)\r
-\r
-STATIC\r
-EFI_STATUS\r
-MapGcdMmioSpace (\r
-  IN    UINT64    Base,\r
-  IN    UINT64    Size\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-\r
-  Status = gDS->AddMemorySpace (EfiGcdMemoryTypeMemoryMappedIo, Base, Size,\r
-                  EFI_MEMORY_UC);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((DEBUG_ERROR,\r
-      "%a: failed to add GCD memory space for region [0x%Lx+0x%Lx)\n",\r
-      __FUNCTION__, Base, Size));\r
-    return Status;\r
-  }\r
-\r
-  Status = gDS->SetMemorySpaceAttributes (Base, Size, EFI_MEMORY_UC);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((DEBUG_ERROR,\r
-      "%a: failed to set memory space attributes for region [0x%Lx+0x%Lx)\n",\r
-      __FUNCTION__, Base, Size));\r
-  }\r
-  return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-ProcessPciHost (\r
-  OUT  UINT64    *IoBase,\r
-  OUT  UINT64    *IoSize,\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
-{\r
-  FDT_CLIENT_PROTOCOL         *FdtClient;\r
-  INT32                       Node;\r
-  UINT64                      ConfigBase, ConfigSize;\r
-  CONST VOID                  *Prop;\r
-  UINT32                      Len;\r
-  UINT32                      RecordIdx;\r
-  EFI_STATUS                  Status;\r
-  UINT64                      IoTranslation;\r
-  UINT64                      Mmio32Translation;\r
-  UINT64                      Mmio64Translation;\r
-\r
-  //\r
-  // The following output arguments are initialized only in\r
-  // order to suppress '-Werror=maybe-uninitialized' warnings\r
-  // *incorrectly* emitted by some gcc versions.\r
-  //\r
-  *IoBase = 0;\r
-  *Mmio32Base = 0;\r
-  *Mmio64Base = MAX_UINT64;\r
-  *BusMin = 0;\r
-  *BusMax = 0;\r
-\r
-  //\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
-  *Mmio32Size = 0;\r
-  *Mmio64Size = 0;\r
-  IoTranslation = 0;\r
-\r
-  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
-                  (VOID **)&FdtClient);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Status = FdtClient->FindCompatibleNode (FdtClient, "pci-host-ecam-generic",\r
-                        &Node);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_INFO,\r
-      "%a: No 'pci-host-ecam-generic' compatible DT node found\n",\r
-      __FUNCTION__));\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  DEBUG_CODE (\r
-    INT32 Tmp;\r
-\r
-    //\r
-    // A DT can legally describe multiple PCI host bridges, but we are not\r
-    // equipped to deal with that. So assert that there is only one.\r
-    //\r
-    Status = FdtClient->FindNextCompatibleNode (FdtClient,\r
-                          "pci-host-ecam-generic", Node, &Tmp);\r
-    ASSERT (Status == EFI_NOT_FOUND);\r
-  );\r
-\r
-  Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg", &Prop, &Len);\r
-  if (EFI_ERROR (Status) || Len != 2 * sizeof (UINT64)) {\r
-    DEBUG ((EFI_D_ERROR, "%a: 'reg' property not found or invalid\n",\r
-      __FUNCTION__));\r
-    return EFI_PROTOCOL_ERROR;\r
-  }\r
-\r
-  //\r
-  // Fetch the ECAM window.\r
-  //\r
-  ConfigBase = SwapBytes64 (((CONST UINT64 *)Prop)[0]);\r
-  ConfigSize = SwapBytes64 (((CONST UINT64 *)Prop)[1]);\r
-\r
-  //\r
-  // Fetch the bus range (note: inclusive).\r
-  //\r
-  Status = FdtClient->GetNodeProperty (FdtClient, Node, "bus-range", &Prop,\r
-                        &Len);\r
-  if (EFI_ERROR (Status) || Len != 2 * sizeof (UINT32)) {\r
-    DEBUG ((EFI_D_ERROR, "%a: 'bus-range' not found or invalid\n",\r
-      __FUNCTION__));\r
-    return EFI_PROTOCOL_ERROR;\r
-  }\r
-  *BusMin = SwapBytes32 (((CONST UINT32 *)Prop)[0]);\r
-  *BusMax = SwapBytes32 (((CONST UINT32 *)Prop)[1]);\r
-\r
-  //\r
-  // Sanity check: the config space must accommodate all 4K register bytes of\r
-  // all 8 functions of all 32 devices of all buses.\r
-  //\r
-  if (*BusMax < *BusMin || *BusMax - *BusMin == MAX_UINT32 ||\r
-      DivU64x32 (ConfigSize, SIZE_4KB * 8 * 32) < *BusMax - *BusMin + 1) {\r
-    DEBUG ((EFI_D_ERROR, "%a: invalid 'bus-range' and/or 'reg'\n",\r
-      __FUNCTION__));\r
-    return EFI_PROTOCOL_ERROR;\r
-  }\r
-\r
-  //\r
-  // Iterate over "ranges".\r
-  //\r
-  Status = FdtClient->GetNodeProperty (FdtClient, Node, "ranges", &Prop, &Len);\r
-  if (EFI_ERROR (Status) || Len == 0 ||\r
-      Len % sizeof (DTB_PCI_HOST_RANGE_RECORD) != 0) {\r
-    DEBUG ((EFI_D_ERROR, "%a: 'ranges' not found or invalid\n", __FUNCTION__));\r
-    return EFI_PROTOCOL_ERROR;\r
-  }\r
-\r
-  for (RecordIdx = 0; RecordIdx < Len / sizeof (DTB_PCI_HOST_RANGE_RECORD);\r
-       ++RecordIdx) {\r
-    CONST DTB_PCI_HOST_RANGE_RECORD *Record;\r
-\r
-    Record = (CONST DTB_PCI_HOST_RANGE_RECORD *)Prop + RecordIdx;\r
-    switch (SwapBytes32 (Record->Type) & DTB_PCI_HOST_RANGE_TYPEMASK) {\r
-    case DTB_PCI_HOST_RANGE_IO:\r
-      *IoBase = SwapBytes64 (Record->ChildBase);\r
-      *IoSize = SwapBytes64 (Record->Size);\r
-      IoTranslation = SwapBytes64 (Record->CpuBase) - *IoBase;\r
-\r
-      ASSERT (PcdGet64 (PcdPciIoTranslation) == IoTranslation);\r
-      break;\r
-\r
-    case DTB_PCI_HOST_RANGE_MMIO32:\r
-      *Mmio32Base = SwapBytes64 (Record->ChildBase);\r
-      *Mmio32Size = SwapBytes64 (Record->Size);\r
-      Mmio32Translation = SwapBytes64 (Record->CpuBase) - *Mmio32Base;\r
-\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) == Mmio32Translation);\r
-\r
-      if (Mmio32Translation != 0) {\r
-        DEBUG ((EFI_D_ERROR, "%a: unsupported nonzero MMIO32 translation "\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 || *Mmio32Size == 0) {\r
-    DEBUG ((EFI_D_ERROR, "%a: %a space empty\n", __FUNCTION__,\r
-      (*IoSize == 0) ? "IO" : "MMIO32"));\r
-    return EFI_PROTOCOL_ERROR;\r
-  }\r
-\r
-  //\r
-  // The dynamic PCD PcdPciExpressBaseAddress should have already been set,\r
-  // and should match the value we found in the DT node.\r
-  //\r
-  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 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
-\r
-  // Map the ECAM space in the GCD memory map\r
-  Status = MapGcdMmioSpace (ConfigBase, ConfigSize);\r
-  ASSERT_EFI_ERROR (Status);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Map the MMIO window that provides I/O access - the PCI host bridge code\r
-  // is not aware of this translation and so it will only map the I/O view\r
-  // in the GCD I/O map.\r
-  //\r
-  Status = MapGcdMmioSpace (*IoBase + IoTranslation, *IoSize);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Return all the root bridge instances in an array.\r
-\r
-  @param Count  Return the count of root bridge instances.\r
-\r
-  @return All the root bridge instances in an array.\r
-          The array should be passed into PciHostBridgeFreeRootBridges()\r
-          when it's not used.\r
-**/\r
-PCI_ROOT_BRIDGE *\r
-EFIAPI\r
-PciHostBridgeGetRootBridges (\r
-  UINTN *Count\r
-  )\r
-{\r
-  UINT64                   IoBase, IoSize;\r
-  UINT64                   Mmio32Base, Mmio32Size;\r
-  UINT64                   Mmio64Base, Mmio64Size;\r
-  UINT32                   BusMin, BusMax;\r
-  EFI_STATUS               Status;\r
-  UINT64                   Attributes;\r
-  UINT64                   AllocationAttributes;\r
-  PCI_ROOT_BRIDGE_APERTURE Io;\r
-  PCI_ROOT_BRIDGE_APERTURE Mem;\r
-  PCI_ROOT_BRIDGE_APERTURE MemAbove4G;\r
-  PCI_ROOT_BRIDGE_APERTURE PMem;\r
-  PCI_ROOT_BRIDGE_APERTURE PMemAbove4G;\r
-\r
-  if (PcdGet64 (PcdPciExpressBaseAddress) == 0) {\r
-    DEBUG ((EFI_D_INFO, "%a: PCI host bridge not present\n", __FUNCTION__));\r
-\r
-    *Count = 0;\r
-    return NULL;\r
-  }\r
-\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
-    *Count = 0;\r
-    return NULL;\r
-  }\r
-\r
-  ZeroMem (&Io, sizeof (Io));\r
-  ZeroMem (&Mem, sizeof (Mem));\r
-  ZeroMem (&MemAbove4G, sizeof (MemAbove4G));\r
-  ZeroMem (&PMem, sizeof (PMem));\r
-  ZeroMem (&PMemAbove4G, sizeof (PMemAbove4G));\r
-\r
-  Attributes           = EFI_PCI_ATTRIBUTE_ISA_IO_16 |\r
-                         EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |\r
-                         EFI_PCI_ATTRIBUTE_VGA_IO_16  |\r
-                         EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;\r
-\r
-  AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM;\r
-\r
-  Io.Base              = IoBase;\r
-  Io.Limit             = IoBase + IoSize - 1;\r
-  Mem.Base             = Mmio32Base;\r
-  Mem.Limit            = Mmio32Base + Mmio32Size - 1;\r
-\r
-  if (sizeof (UINTN) == sizeof (UINT64)) {\r
-    MemAbove4G.Base    = Mmio64Base;\r
-    MemAbove4G.Limit   = Mmio64Base + Mmio64Size - 1;\r
-    if (Mmio64Size > 0) {\r
-      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
-    MemAbove4G.Base    = MAX_UINT64;\r
-    MemAbove4G.Limit   = 0;\r
-  }\r
-\r
-  //\r
-  // No separate ranges for prefetchable and non-prefetchable BARs\r
-  //\r
-  PMem.Base            = MAX_UINT64;\r
-  PMem.Limit           = 0;\r
-  PMemAbove4G.Base     = MAX_UINT64;\r
-  PMemAbove4G.Limit    = 0;\r
-\r
-  return PciHostBridgeUtilityGetRootBridges (\r
-    Count,\r
-    Attributes,\r
-    AllocationAttributes,\r
-    TRUE,\r
-    FALSE,\r
-    BusMin,\r
-    BusMax,\r
-    &Io,\r
-    &Mem,\r
-    &MemAbove4G,\r
-    &PMem,\r
-    &PMemAbove4G\r
-    );\r
-}\r
-\r
-/**\r
-  Free the root bridge instances array returned from\r
-  PciHostBridgeGetRootBridges().\r
-\r
-  @param Bridges The root bridge instances array.\r
-  @param Count   The count of the array.\r
-**/\r
-VOID\r
-EFIAPI\r
-PciHostBridgeFreeRootBridges (\r
-  PCI_ROOT_BRIDGE *Bridges,\r
-  UINTN           Count\r
-  )\r
-{\r
-  PciHostBridgeUtilityFreeRootBridges (Bridges, Count);\r
-}\r
-\r
-/**\r
-  Inform the platform that the resource conflict happens.\r
-\r
-  @param HostBridgeHandle Handle of the Host Bridge.\r
-  @param Configuration    Pointer to PCI I/O and PCI memory resource\r
-                          descriptors. The Configuration contains the resources\r
-                          for all the root bridges. The resource for each root\r
-                          bridge is terminated with END descriptor and an\r
-                          additional END is appended indicating the end of the\r
-                          entire resources. The resource descriptor field\r
-                          values follow the description in\r
-                          EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL\r
-                          .SubmitResources().\r
-**/\r
-VOID\r
-EFIAPI\r
-PciHostBridgeResourceConflict (\r
-  EFI_HANDLE                        HostBridgeHandle,\r
-  VOID                              *Configuration\r
-  )\r
-{\r
-  PciHostBridgeUtilityResourceConflict (Configuration);\r
-}\r
diff --git a/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
deleted file mode 100644 (file)
index f149693..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-## @file\r
-#  PCI Host Bridge Library instance for pci-ecam-generic DT nodes\r
-#\r
-#  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
-#\r
-#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-#\r
-#\r
-##\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = FdtPciHostBridgeLib\r
-  FILE_GUID                      = 59fcb139-2558-4cf0-8d7c-ebac499da727\r
-  MODULE_TYPE                    = DXE_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = PciHostBridgeLib\r
-\r
-#\r
-# The following information is for reference only and not required by the build\r
-# tools.\r
-#\r
-#  VALID_ARCHITECTURES           = AARCH64 ARM\r
-#\r
-\r
-[Sources]\r
-  FdtPciHostBridgeLib.c\r
-\r
-[Packages]\r
-  ArmPkg/ArmPkg.dec\r
-  ArmVirtPkg/ArmVirtPkg.dec\r
-  EmbeddedPkg/EmbeddedPkg.dec\r
-  MdeModulePkg/MdeModulePkg.dec\r
-  MdePkg/MdePkg.dec\r
-  OvmfPkg/OvmfPkg.dec\r
-\r
-[LibraryClasses]\r
-  BaseMemoryLib\r
-  DebugLib\r
-  DevicePathLib\r
-  DxeServicesTableLib\r
-  MemoryAllocationLib\r
-  PciHostBridgeUtilityLib\r
-  PciPcdProducerLib\r
-\r
-[FixedPcd]\r
-  gArmTokenSpaceGuid.PcdPciMmio32Translation\r
-  gArmTokenSpaceGuid.PcdPciMmio64Translation\r
-\r
-[Pcd]\r
-  gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation\r
-  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress\r
-\r
-[Depex]\r
-  gFdtClientProtocolGuid\r
diff --git a/OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c b/OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c
new file mode 100644 (file)
index 0000000..0099b8e
--- /dev/null
@@ -0,0 +1,417 @@
+/** @file\r
+  PCI Host Bridge Library instance for pci-ecam-generic DT nodes\r
+\r
+  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+#include <PiDxe.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PciHostBridgeLib.h>\r
+#include <Library/PciHostBridgeUtilityLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include <Protocol/FdtClient.h>\r
+#include <Protocol/PciRootBridgeIo.h>\r
+#include <Protocol/PciHostBridgeResourceAllocation.h>\r
+\r
+//\r
+// We expect the "ranges" property of "pci-host-ecam-generic" to consist of\r
+// records like this.\r
+//\r
+#pragma pack (1)\r
+typedef struct {\r
+  UINT32 Type;\r
+  UINT64 ChildBase;\r
+  UINT64 CpuBase;\r
+  UINT64 Size;\r
+} DTB_PCI_HOST_RANGE_RECORD;\r
+#pragma pack ()\r
+\r
+#define DTB_PCI_HOST_RANGE_RELOCATABLE  BIT31\r
+#define DTB_PCI_HOST_RANGE_PREFETCHABLE BIT30\r
+#define DTB_PCI_HOST_RANGE_ALIASED      BIT29\r
+#define DTB_PCI_HOST_RANGE_MMIO32       BIT25\r
+#define DTB_PCI_HOST_RANGE_MMIO64       (BIT25 | BIT24)\r
+#define DTB_PCI_HOST_RANGE_IO           BIT24\r
+#define DTB_PCI_HOST_RANGE_TYPEMASK     (BIT31 | BIT30 | BIT29 | BIT25 | BIT24)\r
+\r
+STATIC\r
+EFI_STATUS\r
+MapGcdMmioSpace (\r
+  IN    UINT64    Base,\r
+  IN    UINT64    Size\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  Status = gDS->AddMemorySpace (EfiGcdMemoryTypeMemoryMappedIo, Base, Size,\r
+                  EFI_MEMORY_UC);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR,\r
+      "%a: failed to add GCD memory space for region [0x%Lx+0x%Lx)\n",\r
+      __FUNCTION__, Base, Size));\r
+    return Status;\r
+  }\r
+\r
+  Status = gDS->SetMemorySpaceAttributes (Base, Size, EFI_MEMORY_UC);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR,\r
+      "%a: failed to set memory space attributes for region [0x%Lx+0x%Lx)\n",\r
+      __FUNCTION__, Base, Size));\r
+  }\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+ProcessPciHost (\r
+  OUT  UINT64    *IoBase,\r
+  OUT  UINT64    *IoSize,\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
+{\r
+  FDT_CLIENT_PROTOCOL         *FdtClient;\r
+  INT32                       Node;\r
+  UINT64                      ConfigBase, ConfigSize;\r
+  CONST VOID                  *Prop;\r
+  UINT32                      Len;\r
+  UINT32                      RecordIdx;\r
+  EFI_STATUS                  Status;\r
+  UINT64                      IoTranslation;\r
+  UINT64                      Mmio32Translation;\r
+  UINT64                      Mmio64Translation;\r
+\r
+  //\r
+  // The following output arguments are initialized only in\r
+  // order to suppress '-Werror=maybe-uninitialized' warnings\r
+  // *incorrectly* emitted by some gcc versions.\r
+  //\r
+  *IoBase = 0;\r
+  *Mmio32Base = 0;\r
+  *Mmio64Base = MAX_UINT64;\r
+  *BusMin = 0;\r
+  *BusMax = 0;\r
+\r
+  //\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
+  *Mmio32Size = 0;\r
+  *Mmio64Size = 0;\r
+  IoTranslation = 0;\r
+\r
+  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
+                  (VOID **)&FdtClient);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = FdtClient->FindCompatibleNode (FdtClient, "pci-host-ecam-generic",\r
+                        &Node);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_INFO,\r
+      "%a: No 'pci-host-ecam-generic' compatible DT node found\n",\r
+      __FUNCTION__));\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  DEBUG_CODE (\r
+    INT32 Tmp;\r
+\r
+    //\r
+    // A DT can legally describe multiple PCI host bridges, but we are not\r
+    // equipped to deal with that. So assert that there is only one.\r
+    //\r
+    Status = FdtClient->FindNextCompatibleNode (FdtClient,\r
+                          "pci-host-ecam-generic", Node, &Tmp);\r
+    ASSERT (Status == EFI_NOT_FOUND);\r
+  );\r
+\r
+  Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg", &Prop, &Len);\r
+  if (EFI_ERROR (Status) || Len != 2 * sizeof (UINT64)) {\r
+    DEBUG ((EFI_D_ERROR, "%a: 'reg' property not found or invalid\n",\r
+      __FUNCTION__));\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
+\r
+  //\r
+  // Fetch the ECAM window.\r
+  //\r
+  ConfigBase = SwapBytes64 (((CONST UINT64 *)Prop)[0]);\r
+  ConfigSize = SwapBytes64 (((CONST UINT64 *)Prop)[1]);\r
+\r
+  //\r
+  // Fetch the bus range (note: inclusive).\r
+  //\r
+  Status = FdtClient->GetNodeProperty (FdtClient, Node, "bus-range", &Prop,\r
+                        &Len);\r
+  if (EFI_ERROR (Status) || Len != 2 * sizeof (UINT32)) {\r
+    DEBUG ((EFI_D_ERROR, "%a: 'bus-range' not found or invalid\n",\r
+      __FUNCTION__));\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
+  *BusMin = SwapBytes32 (((CONST UINT32 *)Prop)[0]);\r
+  *BusMax = SwapBytes32 (((CONST UINT32 *)Prop)[1]);\r
+\r
+  //\r
+  // Sanity check: the config space must accommodate all 4K register bytes of\r
+  // all 8 functions of all 32 devices of all buses.\r
+  //\r
+  if (*BusMax < *BusMin || *BusMax - *BusMin == MAX_UINT32 ||\r
+      DivU64x32 (ConfigSize, SIZE_4KB * 8 * 32) < *BusMax - *BusMin + 1) {\r
+    DEBUG ((EFI_D_ERROR, "%a: invalid 'bus-range' and/or 'reg'\n",\r
+      __FUNCTION__));\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
+\r
+  //\r
+  // Iterate over "ranges".\r
+  //\r
+  Status = FdtClient->GetNodeProperty (FdtClient, Node, "ranges", &Prop, &Len);\r
+  if (EFI_ERROR (Status) || Len == 0 ||\r
+      Len % sizeof (DTB_PCI_HOST_RANGE_RECORD) != 0) {\r
+    DEBUG ((EFI_D_ERROR, "%a: 'ranges' not found or invalid\n", __FUNCTION__));\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
+\r
+  for (RecordIdx = 0; RecordIdx < Len / sizeof (DTB_PCI_HOST_RANGE_RECORD);\r
+       ++RecordIdx) {\r
+    CONST DTB_PCI_HOST_RANGE_RECORD *Record;\r
+\r
+    Record = (CONST DTB_PCI_HOST_RANGE_RECORD *)Prop + RecordIdx;\r
+    switch (SwapBytes32 (Record->Type) & DTB_PCI_HOST_RANGE_TYPEMASK) {\r
+    case DTB_PCI_HOST_RANGE_IO:\r
+      *IoBase = SwapBytes64 (Record->ChildBase);\r
+      *IoSize = SwapBytes64 (Record->Size);\r
+      IoTranslation = SwapBytes64 (Record->CpuBase) - *IoBase;\r
+\r
+      ASSERT (PcdGet64 (PcdPciIoTranslation) == IoTranslation);\r
+      break;\r
+\r
+    case DTB_PCI_HOST_RANGE_MMIO32:\r
+      *Mmio32Base = SwapBytes64 (Record->ChildBase);\r
+      *Mmio32Size = SwapBytes64 (Record->Size);\r
+      Mmio32Translation = SwapBytes64 (Record->CpuBase) - *Mmio32Base;\r
+\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) == Mmio32Translation);\r
+\r
+      if (Mmio32Translation != 0) {\r
+        DEBUG ((EFI_D_ERROR, "%a: unsupported nonzero MMIO32 translation "\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 || *Mmio32Size == 0) {\r
+    DEBUG ((EFI_D_ERROR, "%a: %a space empty\n", __FUNCTION__,\r
+      (*IoSize == 0) ? "IO" : "MMIO32"));\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
+\r
+  //\r
+  // The dynamic PCD PcdPciExpressBaseAddress should have already been set,\r
+  // and should match the value we found in the DT node.\r
+  //\r
+  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 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
+\r
+  // Map the ECAM space in the GCD memory map\r
+  Status = MapGcdMmioSpace (ConfigBase, ConfigSize);\r
+  ASSERT_EFI_ERROR (Status);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Map the MMIO window that provides I/O access - the PCI host bridge code\r
+  // is not aware of this translation and so it will only map the I/O view\r
+  // in the GCD I/O map.\r
+  //\r
+  Status = MapGcdMmioSpace (*IoBase + IoTranslation, *IoSize);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Return all the root bridge instances in an array.\r
+\r
+  @param Count  Return the count of root bridge instances.\r
+\r
+  @return All the root bridge instances in an array.\r
+          The array should be passed into PciHostBridgeFreeRootBridges()\r
+          when it's not used.\r
+**/\r
+PCI_ROOT_BRIDGE *\r
+EFIAPI\r
+PciHostBridgeGetRootBridges (\r
+  UINTN *Count\r
+  )\r
+{\r
+  UINT64                   IoBase, IoSize;\r
+  UINT64                   Mmio32Base, Mmio32Size;\r
+  UINT64                   Mmio64Base, Mmio64Size;\r
+  UINT32                   BusMin, BusMax;\r
+  EFI_STATUS               Status;\r
+  UINT64                   Attributes;\r
+  UINT64                   AllocationAttributes;\r
+  PCI_ROOT_BRIDGE_APERTURE Io;\r
+  PCI_ROOT_BRIDGE_APERTURE Mem;\r
+  PCI_ROOT_BRIDGE_APERTURE MemAbove4G;\r
+  PCI_ROOT_BRIDGE_APERTURE PMem;\r
+  PCI_ROOT_BRIDGE_APERTURE PMemAbove4G;\r
+\r
+  if (PcdGet64 (PcdPciExpressBaseAddress) == 0) {\r
+    DEBUG ((EFI_D_INFO, "%a: PCI host bridge not present\n", __FUNCTION__));\r
+\r
+    *Count = 0;\r
+    return NULL;\r
+  }\r
+\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
+    *Count = 0;\r
+    return NULL;\r
+  }\r
+\r
+  ZeroMem (&Io, sizeof (Io));\r
+  ZeroMem (&Mem, sizeof (Mem));\r
+  ZeroMem (&MemAbove4G, sizeof (MemAbove4G));\r
+  ZeroMem (&PMem, sizeof (PMem));\r
+  ZeroMem (&PMemAbove4G, sizeof (PMemAbove4G));\r
+\r
+  Attributes           = EFI_PCI_ATTRIBUTE_ISA_IO_16 |\r
+                         EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |\r
+                         EFI_PCI_ATTRIBUTE_VGA_IO_16  |\r
+                         EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;\r
+\r
+  AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM;\r
+\r
+  Io.Base              = IoBase;\r
+  Io.Limit             = IoBase + IoSize - 1;\r
+  Mem.Base             = Mmio32Base;\r
+  Mem.Limit            = Mmio32Base + Mmio32Size - 1;\r
+\r
+  if (sizeof (UINTN) == sizeof (UINT64)) {\r
+    MemAbove4G.Base    = Mmio64Base;\r
+    MemAbove4G.Limit   = Mmio64Base + Mmio64Size - 1;\r
+    if (Mmio64Size > 0) {\r
+      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
+    MemAbove4G.Base    = MAX_UINT64;\r
+    MemAbove4G.Limit   = 0;\r
+  }\r
+\r
+  //\r
+  // No separate ranges for prefetchable and non-prefetchable BARs\r
+  //\r
+  PMem.Base            = MAX_UINT64;\r
+  PMem.Limit           = 0;\r
+  PMemAbove4G.Base     = MAX_UINT64;\r
+  PMemAbove4G.Limit    = 0;\r
+\r
+  return PciHostBridgeUtilityGetRootBridges (\r
+    Count,\r
+    Attributes,\r
+    AllocationAttributes,\r
+    TRUE,\r
+    FALSE,\r
+    BusMin,\r
+    BusMax,\r
+    &Io,\r
+    &Mem,\r
+    &MemAbove4G,\r
+    &PMem,\r
+    &PMemAbove4G\r
+    );\r
+}\r
+\r
+/**\r
+  Free the root bridge instances array returned from\r
+  PciHostBridgeGetRootBridges().\r
+\r
+  @param Bridges The root bridge instances array.\r
+  @param Count   The count of the array.\r
+**/\r
+VOID\r
+EFIAPI\r
+PciHostBridgeFreeRootBridges (\r
+  PCI_ROOT_BRIDGE *Bridges,\r
+  UINTN           Count\r
+  )\r
+{\r
+  PciHostBridgeUtilityFreeRootBridges (Bridges, Count);\r
+}\r
+\r
+/**\r
+  Inform the platform that the resource conflict happens.\r
+\r
+  @param HostBridgeHandle Handle of the Host Bridge.\r
+  @param Configuration    Pointer to PCI I/O and PCI memory resource\r
+                          descriptors. The Configuration contains the resources\r
+                          for all the root bridges. The resource for each root\r
+                          bridge is terminated with END descriptor and an\r
+                          additional END is appended indicating the end of the\r
+                          entire resources. The resource descriptor field\r
+                          values follow the description in\r
+                          EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL\r
+                          .SubmitResources().\r
+**/\r
+VOID\r
+EFIAPI\r
+PciHostBridgeResourceConflict (\r
+  EFI_HANDLE                        HostBridgeHandle,\r
+  VOID                              *Configuration\r
+  )\r
+{\r
+  PciHostBridgeUtilityResourceConflict (Configuration);\r
+}\r
diff --git a/OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf b/OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
new file mode 100644 (file)
index 0000000..f015480
--- /dev/null
@@ -0,0 +1,53 @@
+## @file\r
+#  PCI Host Bridge Library instance for pci-ecam-generic DT nodes\r
+#\r
+#  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = FdtPciHostBridgeLib\r
+  FILE_GUID                      = 59fcb139-2558-4cf0-8d7c-ebac499da727\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PciHostBridgeLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build\r
+# tools.\r
+#\r
+#  VALID_ARCHITECTURES           = AARCH64 ARM\r
+#\r
+\r
+[Sources]\r
+  FdtPciHostBridgeLib.c\r
+\r
+[Packages]\r
+  EmbeddedPkg/EmbeddedPkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  MdePkg/MdePkg.dec\r
+  OvmfPkg/OvmfPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  DebugLib\r
+  DevicePathLib\r
+  DxeServicesTableLib\r
+  MemoryAllocationLib\r
+  PciHostBridgeUtilityLib\r
+  PciPcdProducerLib\r
+\r
+[FixedPcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdPciMmio32Translation\r
+  gEfiMdePkgTokenSpaceGuid.PcdPciMmio64Translation\r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation\r
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress\r
+\r
+[Depex]\r
+  gFdtClientProtocolGuid\r