From 77e9b3a7c68cea4eeb64af85e4f695f278172314 Mon Sep 17 00:00:00 2001 From: Abner Chang Date: Mon, 11 Oct 2021 21:27:00 +0800 Subject: ArmVirtPkg/FdtPciPcdProducerLib: Relocate PciPcdProducerLib to OvmfPkg Relocate PciPcdProducerLib to OvmfPkg/Fdt, this library is leverage by both ARM and RISC-V archs. Add OvmfPkg/Fdt maintainers in Maintainers.txt Signed-off-by: Abner Chang Cc: Ard Biesheuvel Cc: Leif Lindholm Cc: Sami Mujawar Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Daniel Schaefer Cc: Sunil V L Reviewed-by: Daniel Schaefer Reviewed-by: Sunil V L Acked-by: Gerd Hoffmann Cc: Jiewen Yao --- .../FdtPciPcdProducerLib/FdtPciPcdProducerLib.c | 149 +++++++++++++++++++++ .../FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf | 42 ++++++ 2 files changed, 191 insertions(+) create mode 100644 OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c create mode 100644 OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf (limited to 'OvmfPkg/Fdt') diff --git a/OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c b/OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c new file mode 100644 index 0000000000..2520101017 --- /dev/null +++ b/OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c @@ -0,0 +1,149 @@ +/** @file + FDT client library for consumers of PCI related dynamic PCDs + + Copyright (c) 2016, Linaro Ltd. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include + +#include + +// +// We expect the "ranges" property of "pci-host-ecam-generic" to consist of +// records like this. +// +#pragma pack (1) +typedef struct { + UINT32 Type; + UINT64 ChildBase; + UINT64 CpuBase; + UINT64 Size; +} DTB_PCI_HOST_RANGE_RECORD; +#pragma pack () + +#define DTB_PCI_HOST_RANGE_RELOCATABLE BIT31 +#define DTB_PCI_HOST_RANGE_PREFETCHABLE BIT30 +#define DTB_PCI_HOST_RANGE_ALIASED BIT29 +#define DTB_PCI_HOST_RANGE_MMIO32 BIT25 +#define DTB_PCI_HOST_RANGE_MMIO64 (BIT25 | BIT24) +#define DTB_PCI_HOST_RANGE_IO BIT24 +#define DTB_PCI_HOST_RANGE_TYPEMASK (BIT31 | BIT30 | BIT29 | BIT25 | BIT24) + +STATIC +RETURN_STATUS +GetPciIoTranslation ( + IN FDT_CLIENT_PROTOCOL *FdtClient, + IN INT32 Node, + OUT UINT64 *IoTranslation + ) +{ + UINT32 RecordIdx; + CONST VOID *Prop; + UINT32 Len; + EFI_STATUS Status; + UINT64 IoBase; + + // + // Iterate over "ranges". + // + Status = FdtClient->GetNodeProperty (FdtClient, Node, "ranges", &Prop, &Len); + if (EFI_ERROR (Status) || Len == 0 || + Len % sizeof (DTB_PCI_HOST_RANGE_RECORD) != 0) { + DEBUG ((EFI_D_ERROR, "%a: 'ranges' not found or invalid\n", __FUNCTION__)); + return RETURN_PROTOCOL_ERROR; + } + + for (RecordIdx = 0; RecordIdx < Len / sizeof (DTB_PCI_HOST_RANGE_RECORD); + ++RecordIdx) { + CONST DTB_PCI_HOST_RANGE_RECORD *Record; + UINT32 Type; + + Record = (CONST DTB_PCI_HOST_RANGE_RECORD *)Prop + RecordIdx; + Type = SwapBytes32 (Record->Type) & DTB_PCI_HOST_RANGE_TYPEMASK; + if (Type == DTB_PCI_HOST_RANGE_IO) { + IoBase = SwapBytes64 (Record->ChildBase); + *IoTranslation = SwapBytes64 (Record->CpuBase) - IoBase; + + return RETURN_SUCCESS; + } + } + return RETURN_NOT_FOUND; +} + +RETURN_STATUS +EFIAPI +FdtPciPcdProducerLibConstructor ( + VOID + ) +{ + UINT64 PciExpressBaseAddress; + FDT_CLIENT_PROTOCOL *FdtClient; + CONST UINT64 *Reg; + UINT32 RegSize; + EFI_STATUS Status; + INT32 Node; + RETURN_STATUS RetStatus; + UINT64 IoTranslation; + RETURN_STATUS PcdStatus; + + PciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress); + if (PciExpressBaseAddress != MAX_UINT64) { + // + // Assume that the fact that PciExpressBaseAddress has been changed from + // its default value of MAX_UINT64 implies that this code has been + // executed already, in the context of another module. That means we can + // assume that PcdPciIoTranslation has been discovered from the DT node + // as well. + // + return EFI_SUCCESS; + } + + Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL, + (VOID **)&FdtClient); + ASSERT_EFI_ERROR (Status); + + PciExpressBaseAddress = 0; + Status = FdtClient->FindCompatibleNode (FdtClient, "pci-host-ecam-generic", + &Node); + + if (!EFI_ERROR (Status)) { + Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg", + (CONST VOID **)&Reg, &RegSize); + + if (!EFI_ERROR (Status) && RegSize == 2 * sizeof (UINT64)) { + PciExpressBaseAddress = SwapBytes64 (*Reg); + + PcdStatus = PcdSetBoolS (PcdPciDisableBusEnumeration, FALSE); + ASSERT_RETURN_ERROR (PcdStatus); + + IoTranslation = 0; + RetStatus = GetPciIoTranslation (FdtClient, Node, &IoTranslation); + if (!RETURN_ERROR (RetStatus)) { + PcdStatus = PcdSet64S (PcdPciIoTranslation, IoTranslation); + ASSERT_RETURN_ERROR (PcdStatus); + } else { + // + // Support for I/O BARs is not mandatory, and so it does not make sense + // to abort in the general case. So leave it up to the actual driver to + // complain about this if it wants to, and just issue a warning here. + // + DEBUG ((EFI_D_WARN, + "%a: 'pci-host-ecam-generic' device encountered with no I/O range\n", + __FUNCTION__)); + } + } + } + + PcdStatus = PcdSet64S (PcdPciExpressBaseAddress, PciExpressBaseAddress); + ASSERT_RETURN_ERROR (PcdStatus); + + return RETURN_SUCCESS; +} diff --git a/OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf b/OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf new file mode 100644 index 0000000000..0f5156615b --- /dev/null +++ b/OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf @@ -0,0 +1,42 @@ +#/** @file +# FDT client library for consumers of PCI related dynamic PCDs +# +# Copyright (c) 2016, Linaro Ltd. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FdtPciPcdProducerLib + FILE_GUID = D584275B-BF1E-4DF8-A53D-980F5645C5E7 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PciPcdProducerLib|DXE_DRIVER UEFI_DRIVER + CONSTRUCTOR = FdtPciPcdProducerLibConstructor + +[Sources] + FdtPciPcdProducerLib.c + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PcdLib + UefiBootServicesTableLib + +[Protocols] + gFdtClientProtocolGuid ## CONSUMES + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation ## PRODUCES + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## PRODUCES + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration ## PRODUCES + +[Depex] + gFdtClientProtocolGuid -- cgit v1.2.3