]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmVirtPkg: Add PCIe host bridge utility lib for ArmVirtPkg
authorSami Mujawar <sami.mujawar@arm.com>
Tue, 15 Jun 2021 15:21:27 +0000 (16:21 +0100)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 22 Jun 2021 17:04:45 +0000 (17:04 +0000)
PCIe support has been added to Kvmtool Virtual Machine Manager.
The PCI host bridge utility lib is used to retrieve information
about the Root Bridges in a platform.
Therefore, add an instance of PciHostBridgeUtilityLib as this is
required to enable PCIe support for Kvmtool firmware.

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Tested-by: Alexandru Elisei <alexandru.elisei@arm.com>
ArmVirtPkg/Library/ArmVirtPciHostBridgeUtilityLib/ArmVirtPciHostBridgeUtilityLib.c [new file with mode: 0644]
ArmVirtPkg/Library/ArmVirtPciHostBridgeUtilityLib/ArmVirtPciHostBridgeUtilityLib.inf [new file with mode: 0644]

diff --git a/ArmVirtPkg/Library/ArmVirtPciHostBridgeUtilityLib/ArmVirtPciHostBridgeUtilityLib.c b/ArmVirtPkg/Library/ArmVirtPciHostBridgeUtilityLib/ArmVirtPciHostBridgeUtilityLib.c
new file mode 100644 (file)
index 0000000..90962ca
--- /dev/null
@@ -0,0 +1,218 @@
+/** @file\r
+  PCI Host Bridge utility functions for ArmVirt.\r
+\r
+  Copyright (c) 2021, Arm Limited. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <IndustryStandard/Acpi10.h>\r
+#include <IndustryStandard/Pci.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PciHostBridgeLib.h>\r
+#include <Library/PciHostBridgeUtilityLib.h>\r
+#include <Library/PciLib.h>\r
+\r
+#pragma pack(1)\r
+typedef struct {\r
+  ACPI_HID_DEVICE_PATH     AcpiDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL EndDevicePath;\r
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;\r
+#pragma pack ()\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED\r
+CHAR16 *mPciHostBridgeAcpiAddressSpaceTypeStr[] = {\r
+  L"Mem",\r
+  L"I/O",\r
+  L"Bus"\r
+};\r
+\r
+STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath = {\r
+  {\r
+    {\r
+      ACPI_DEVICE_PATH,\r
+      ACPI_DP,\r
+      {\r
+        (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),\r
+        (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)\r
+      }\r
+    },\r
+    EISA_PNP_ID (0x0A03), // HID\r
+    0                    // UID\r
+  },\r
+\r
+  {\r
+    END_DEVICE_PATH_TYPE,\r
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+    {\r
+      END_DEVICE_PATH_LENGTH,\r
+      0\r
+    }\r
+  }\r
+};\r
+\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED\r
+CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {\r
+  L"Mem", L"I/O", L"Bus"\r
+};\r
+\r
+STATIC PCI_ROOT_BRIDGE mRootBridge;\r
+\r
+/**\r
+  Utility function to return all the root bridge instances in an array.\r
+\r
+  @param [out] Count                  The number of root bridge instances.\r
+  @param [in]  Attributes             Initial attributes.\r
+  @param [in]  AllocationAttributes   Allocation attributes.\r
+  @param [in]  DmaAbove4G             DMA above 4GB memory.\r
+  @param [in]  NoExtendedConfigSpace  No Extended Config Space.\r
+  @param [in]  BusMin                 Minimum Bus number, inclusive.\r
+  @param [in]  BusMax                 Maximum Bus number, inclusive.\r
+  @param [in]  Io                     IO aperture.\r
+  @param [in]  Mem                    MMIO aperture.\r
+  @param [in]  MemAbove4G             MMIO aperture above 4G.\r
+  @param [in]  PMem                   Prefetchable MMIO aperture.\r
+  @param [in]  PMemAbove4G            Prefetchable MMIO aperture above 4G.\r
+\r
+  @return                            All the root bridge instances in an array.\r
+**/\r
+PCI_ROOT_BRIDGE *\r
+EFIAPI\r
+PciHostBridgeUtilityGetRootBridges (\r
+  OUT UINTN                    *Count,\r
+  IN  UINT64                   Attributes,\r
+  IN  UINT64                   AllocationAttributes,\r
+  IN  BOOLEAN                  DmaAbove4G,\r
+  IN  BOOLEAN                  NoExtendedConfigSpace,\r
+  IN  UINTN                    BusMin,\r
+  IN  UINTN                    BusMax,\r
+  IN  PCI_ROOT_BRIDGE_APERTURE *Io,\r
+  IN  PCI_ROOT_BRIDGE_APERTURE *Mem,\r
+  IN  PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,\r
+  IN  PCI_ROOT_BRIDGE_APERTURE *PMem,\r
+  IN  PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G\r
+  )\r
+{\r
+  if ((Count == NULL)       ||\r
+      (Io == NULL)          ||\r
+      (Mem == NULL)         ||\r
+      (MemAbove4G == NULL)  ||\r
+      (PMem == NULL)        ||\r
+      (PMemAbove4G == NULL)) {\r
+    return NULL;\r
+  }\r
+\r
+\r
+  *Count = 1;\r
+\r
+  mRootBridge.Segment               = 0;\r
+  mRootBridge.Supports              = Attributes;\r
+  mRootBridge.Attributes            = Attributes;\r
+\r
+  mRootBridge.DmaAbove4G            = DmaAbove4G;\r
+  mRootBridge.NoExtendedConfigSpace = NoExtendedConfigSpace;\r
+  mRootBridge.ResourceAssigned      = FALSE;\r
+\r
+  mRootBridge.AllocationAttributes  = AllocationAttributes;\r
+\r
+  mRootBridge.Bus.Base              = BusMin;\r
+  mRootBridge.Bus.Limit             = BusMax;\r
+  mRootBridge.Io.Base               = Io->Base;\r
+  mRootBridge.Io.Limit              = Io->Limit;\r
+  mRootBridge.Mem.Base              = Mem->Base;\r
+  mRootBridge.Mem.Limit             = Mem->Limit;\r
+  mRootBridge.MemAbove4G.Base       = MemAbove4G->Base;\r
+  mRootBridge.MemAbove4G.Limit      = MemAbove4G->Limit;\r
+  mRootBridge.PMem.Base             = PMem->Base;\r
+  mRootBridge.PMem.Limit            = PMem->Limit;\r
+  mRootBridge.PMemAbove4G.Base      = PMemAbove4G->Base;\r
+  mRootBridge.PMemAbove4G.Limit     = PMemAbove4G->Limit;\r
+\r
+  mRootBridge.DevicePath =\r
+    (EFI_DEVICE_PATH_PROTOCOL*)&mEfiPciRootBridgeDevicePath;\r
+\r
+  return &mRootBridge;\r
+}\r
+\r
+/**\r
+  Utility function to free root bridge instances array from\r
+  PciHostBridgeUtilityGetRootBridges().\r
+\r
+  @param[in] Bridges  The root bridge instances array.\r
+  @param[in] Count    The count of the array.\r
+**/\r
+VOID\r
+EFIAPI\r
+PciHostBridgeUtilityFreeRootBridges (\r
+  IN PCI_ROOT_BRIDGE *Bridges,\r
+  IN UINTN           Count\r
+  )\r
+{\r
+  // Nothing to do here.\r
+}\r
+\r
+/**\r
+  Utility function to inform the platform that the resource conflict happens.\r
+\r
+  @param[in] Configuration  Pointer to PCI I/O and PCI memory resource\r
+                            descriptors. The Configuration contains the\r
+                            resources for all the root bridges. The resource\r
+                            for each root bridge is terminated with END\r
+                            descriptor and an additional END is appended\r
+                            indicating the end of the entire resources. The\r
+                            resource descriptor field values follow the\r
+                            description in\r
+                            EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL\r
+                            .SubmitResources().\r
+**/\r
+VOID\r
+EFIAPI\r
+PciHostBridgeUtilityResourceConflict (\r
+  IN VOID  *Configuration\r
+  )\r
+{\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;\r
+  UINTN                             RootBridgeIndex;\r
+  DEBUG ((DEBUG_ERROR, "PciHostBridge: Resource conflict happens!\n"));\r
+\r
+  RootBridgeIndex = 0;\r
+  Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR*)Configuration;\r
+  while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
+    DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));\r
+    for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {\r
+      ASSERT (Descriptor->ResType <\r
+              ARRAY_SIZE (mPciHostBridgeAcpiAddressSpaceTypeStr)\r
+              );\r
+      DEBUG ((\r
+        DEBUG_ERROR,\r
+        " %s: Length/Alignment = 0x%lx / 0x%lx\n",\r
+        mPciHostBridgeAcpiAddressSpaceTypeStr[Descriptor->ResType],\r
+        Descriptor->AddrLen,\r
+        Descriptor->AddrRangeMax\r
+        ));\r
+      if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
+        DEBUG ((\r
+          DEBUG_ERROR,\r
+          "     Granularity/SpecificFlag = %ld / %02x%s\n",\r
+          Descriptor->AddrSpaceGranularity,\r
+          Descriptor->SpecificFlag,\r
+          ((Descriptor->SpecificFlag &\r
+            EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE\r
+            ) != 0) ? L" (Prefetchable)" : L""\r
+          ));\r
+      }\r
+    }\r
+    //\r
+    // Skip the END descriptor for root bridge\r
+    //\r
+    ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);\r
+    Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR*)(\r
+                   (EFI_ACPI_END_TAG_DESCRIPTOR*)Descriptor + 1\r
+                   );\r
+  }\r
+}\r
diff --git a/ArmVirtPkg/Library/ArmVirtPciHostBridgeUtilityLib/ArmVirtPciHostBridgeUtilityLib.inf b/ArmVirtPkg/Library/ArmVirtPciHostBridgeUtilityLib/ArmVirtPciHostBridgeUtilityLib.inf
new file mode 100644 (file)
index 0000000..80fdd2b
--- /dev/null
@@ -0,0 +1,39 @@
+## @file\r
+#  PciHostBridgeLib utility functions for ArmVirt.\r
+#\r
+#  Copyright (c) 2021, Arm Limited. All rights reserved.\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x0001001B\r
+  BASE_NAME                      = ArmVirtPciHostBridgeUtilityLib\r
+  FILE_GUID                      = 22A8844E-2AE7-4BF1-91FA-6EFDE3FE540C\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PciHostBridgeUtilityLib\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
+  ArmVirtPciHostBridgeUtilityLib.c\r
+\r
+[Packages]\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  MdePkg/MdePkg.dec\r
+  OvmfPkg/OvmfPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  DebugLib\r
+  DevicePathLib\r
+  MemoryAllocationLib\r
+  PciLib\r