From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web09.10876.1623770506222508900 for ; Tue, 15 Jun 2021 08:21:46 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: arm.com, ip: 217.140.110.172, mailfrom: pierre.gondois@arm.com) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id CBC0BD6E; Tue, 15 Jun 2021 08:21:45 -0700 (PDT) Received: from e120189.arm.com (unknown [10.57.7.205]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 439F43F70D; Tue, 15 Jun 2021 08:21:44 -0700 (PDT) From: "PierreGondois" To: Laszlo Ersek , Ard Biesheuvel , Sami Mujawar , devel@edk2.groups.io Cc: Leif Lindholm Subject: [PATCH RESEND v1 1/2] ArmVirtPkg: Add PCIe host bridge utility lib for ArmVirtPkg Date: Tue, 15 Jun 2021 16:21:27 +0100 Message-Id: <20210615152128.25565-2-Pierre.Gondois@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210615152128.25565-1-Pierre.Gondois@arm.com> References: <20210615152128.25565-1-Pierre.Gondois@arm.com> From: Sami Mujawar 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 Signed-off-by: Pierre Gondois --- .../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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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