[edk2-devel] [PATCH RESEND v1 1/2] ArmVirtPkg: Add PCIe host bridge utility lib for ArmVirtPkg

PierreGondois pierre.gondois at arm.com
Tue Jun 15 15:21:27 UTC 2021


From: Sami Mujawar <sami.mujawar at arm.com>

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 at arm.com>
Signed-off-by: Pierre Gondois <Pierre.Gondois at arm.com>
---
 .../ArmVirtPciHostBridgeUtilityLib.c          | 218 ++++++++++++++++++
 .../ArmVirtPciHostBridgeUtilityLib.inf        |  39 ++++
 2 files changed, 257 insertions(+)
 create mode 100644 ArmVirtPkg/Library/ArmVirtPciHostBridgeUtilityLib/ArmVirtPciHostBridgeUtilityLib.c
 create mode 100644 ArmVirtPkg/Library/ArmVirtPciHostBridgeUtilityLib/ArmVirtPciHostBridgeUtilityLib.inf

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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#76523): https://edk2.groups.io/g/devel/message/76523
Mute This Topic: https://groups.io/mt/83558264/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list