Make this library depend on the FDT client protocol to access the host supplied device tree directly rather than depending on VirtFdtDxe to set them using dynamic PCDs.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <[email protected]> --- ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c | 73 ++++++++++++++++++-- ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf | 12 ++-- 2 files changed, 72 insertions(+), 13 deletions(-) diff --git a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c index 303dc520c6eb..1cb372562b62 100644 --- a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c +++ b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c @@ -20,6 +20,10 @@ #include <Library/IoLib.h> #include <Library/PcdLib.h> #include <Library/QemuFwCfgLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <libfdt.h> + +#include <Protocol/FdtClient.h> STATIC UINTN mFwCfgSelectorAddress; STATIC UINTN mFwCfgDataAddress; @@ -109,14 +113,70 @@ QemuFwCfgIsAvailable ( } -RETURN_STATUS +EFI_STATUS EFIAPI QemuFwCfgInitialize ( - VOID + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) { - mFwCfgSelectorAddress = (UINTN)PcdGet64 (PcdFwCfgSelectorAddress); - mFwCfgDataAddress = (UINTN)PcdGet64 (PcdFwCfgDataAddress); + EFI_STATUS Status; + FDT_CLIENT_PROTOCOL *FdtClient; + CONST VOID *Reg; + UINTN RegElemSize, RegSize; + UINT64 FwCfgSelectorSize; + UINT64 FwCfgDataSize; + UINT64 FwCfgDmaSize; + + Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL, (VOID **)&FdtClient); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = FdtClient->FindCompatibleNodeReg (FdtClient, + "qemu,fw-cfg-mmio", + &Reg, + &RegElemSize, + &RegSize); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (RegElemSize == sizeof (UINT64)); + ASSERT (RegSize == 2 * sizeof (UINT64)); + + mFwCfgDataAddress = fdt64_to_cpu (((UINT64 *)Reg)[0]); + FwCfgDataSize = 8; + mFwCfgSelectorAddress = mFwCfgDataAddress + FwCfgDataSize; + FwCfgSelectorSize = 2; + + // + // The following ASSERT()s express + // + // Address + Size - 1 <= MAX_UINTN + // + // for both registers, that is, that the last byte in each MMIO range is + // expressible as a MAX_UINTN. The form below is mathematically + // equivalent, and it also prevents any unsigned overflow before the + // comparison. + // + ASSERT (mFwCfgSelectorAddress <= MAX_UINTN - FwCfgSelectorSize + 1); + ASSERT (mFwCfgDataAddress <= MAX_UINTN - FwCfgDataSize + 1); + + DEBUG ((EFI_D_INFO, "Found FwCfg @ 0x%Lx/0x%Lx\n", mFwCfgSelectorAddress, + mFwCfgDataAddress)); + + if (fdt64_to_cpu (((UINT64 *)Reg)[1]) >= 0x18) { + mFwCfgDmaAddress = mFwCfgDataAddress + 0x10; + FwCfgDmaSize = 0x08; + + // + // See explanation above. + // + ASSERT (mFwCfgDmaAddress <= MAX_UINTN - FwCfgDmaSize + 1); + + DEBUG ((EFI_D_INFO, "Found FwCfg DMA @ 0x%Lx\n", mFwCfgDmaAddress)); + } if (InternalQemuFwCfgIsAvailable ()) { UINT32 Signature; @@ -128,13 +188,12 @@ QemuFwCfgInitialize ( // For DMA support, we require the DTB to advertise the register, and the // feature bitmap (which we read without DMA) to confirm the feature. // - if (PcdGet64 (PcdFwCfgDmaAddress) != 0) { + if (mFwCfgDmaAddress != 0) { UINT32 Features; QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion); Features = QemuFwCfgRead32 (); if ((Features & BIT1) != 0) { - mFwCfgDmaAddress = PcdGet64 (PcdFwCfgDmaAddress); InternalQemuFwCfgReadBytes = DmaReadBytes; } } @@ -143,7 +202,7 @@ QemuFwCfgInitialize ( mFwCfgDataAddress = 0; } } - return RETURN_SUCCESS; + return EFI_SUCCESS; } diff --git a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf index 298aa6edfb26..a4ae2a3f9d22 100644 --- a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf +++ b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf @@ -20,7 +20,7 @@ [Defines] INF_VERSION = 0x00010005 BASE_NAME = QemuFwCfgLib FILE_GUID = B271F41F-B841-48A9-BA8D-545B4BC2E2BF - MODULE_TYPE = BASE + MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 LIBRARY_CLASS = QemuFwCfgLib|DXE_DRIVER @@ -46,9 +46,9 @@ [LibraryClasses] BaseMemoryLib DebugLib IoLib - PcdLib -[Pcd] - gArmVirtTokenSpaceGuid.PcdFwCfgSelectorAddress - gArmVirtTokenSpaceGuid.PcdFwCfgDataAddress - gArmVirtTokenSpaceGuid.PcdFwCfgDmaAddress +[Protocols] + gFdtClientProtocolGuid + +[Depex] + gFdtClientProtocolGuid -- 2.5.0 _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

