From 748d57d40fa95d98124560a3dd54ce66eb761af0 Mon Sep 17 00:00:00 2001 From: Chao Li Date: Tue, 30 Apr 2024 15:48:09 +0800 Subject: OvmfPkg: Add the way of HOBs in QemuFwCfgLibMmio Added the HOB methods to load and store the QEMU firmware configure address, data address and DMA address, which are not enabled during the DXE stage. Build-tested only (with "ArmVirtQemu.dsc and RiscVVirtQemu.dsc"). BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4755 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Cc: Leif Lindholm Cc: Sami Mujawar Cc: Sunil V L Cc: Andrei Warkentin Signed-off-by: Chao Li --- OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c | 70 +++++++++++++--- OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf | 5 ++ .../QemuFwCfgLib/QemuFwCfgLibMmioInternal.h | 71 +++++++++++++++- OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c | 97 ++++++++++++++++++---- 4 files changed, 216 insertions(+), 27 deletions(-) diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c index 2a2f3e6..6da689b 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c @@ -3,15 +3,21 @@ Copyright (C) 2013 - 2014, Red Hat, Inc. Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.
(C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ +#include #include +#include +#include + #include #include #include +#include #include #include #include @@ -28,6 +34,50 @@ WRITE_BYTES_FUNCTION *InternalQemuFwCfgWriteBytes = MmioWriteBytes; SKIP_BYTES_FUNCTION *InternalQemuFwCfgSkipBytes = MmioSkipBytes; /** + Build firmware configure resource HOB. + + @param[in] FwCfgResource A pointer to firmware configure resource. + + @retval VOID +**/ +VOID +QemuBuildFwCfgResourceHob ( + IN QEMU_FW_CFG_RESOURCE *FwCfgResource + ) +{ + BuildGuidDataHob ( + &gQemuFirmwareResourceHobGuid, + (VOID *)FwCfgResource, + sizeof (QEMU_FW_CFG_RESOURCE) + ); +} + +/** + Get firmware configure resource in HOB. + + @param VOID + + @retval non-NULL The firmware configure resource in HOB. + NULL The firmware configure resource not found. +**/ +QEMU_FW_CFG_RESOURCE * +QemuGetFwCfgResourceHob ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + GuidHob = NULL; + + GuidHob = GetFirstGuidHob (&gQemuFirmwareResourceHobGuid); + if (GuidHob == NULL) { + return NULL; + } + + return (QEMU_FW_CFG_RESOURCE *)GET_GUID_HOB_DATA (GuidHob); +} + +/** Returns a boolean indicating if the firmware configuration interface is available or not. @@ -43,7 +93,7 @@ QemuFwCfgIsAvailable ( VOID ) { - return (BOOLEAN)(mFwCfgSelectorAddress != 0 && mFwCfgDataAddress != 0); + return (BOOLEAN)(QemuGetFwCfgSelectorAddress () != 0 && QemuGetFwCfgDataAddress () != 0); } /** @@ -62,7 +112,7 @@ QemuFwCfgSelectItem ( ) { if (QemuFwCfgIsAvailable ()) { - MmioWrite16 (mFwCfgSelectorAddress, SwapBytes16 ((UINT16)QemuFwCfgItem)); + MmioWrite16 (QemuGetFwCfgSelectorAddress (), SwapBytes16 ((UINT16)QemuFwCfgItem)); } } @@ -92,30 +142,30 @@ MmioReadBytes ( #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) || defined (MDE_CPU_LOONGARCH64) while (Ptr < End) { - *(UINT64 *)Ptr = MmioRead64 (mFwCfgDataAddress); + *(UINT64 *)Ptr = MmioRead64 (QemuGetFwCfgDataAddress ()); Ptr += 8; } if (Left & 4) { - *(UINT32 *)Ptr = MmioRead32 (mFwCfgDataAddress); + *(UINT32 *)Ptr = MmioRead32 (QemuGetFwCfgDataAddress ()); Ptr += 4; } #else while (Ptr < End) { - *(UINT32 *)Ptr = MmioRead32 (mFwCfgDataAddress); + *(UINT32 *)Ptr = MmioRead32 (QemuGetFwCfgDataAddress ()); Ptr += 4; } #endif if (Left & 2) { - *(UINT16 *)Ptr = MmioRead16 (mFwCfgDataAddress); + *(UINT16 *)Ptr = MmioRead16 (QemuGetFwCfgDataAddress ()); Ptr += 2; } if (Left & 1) { - *Ptr = MmioRead8 (mFwCfgDataAddress); + *Ptr = MmioRead8 (QemuGetFwCfgDataAddress ()); } } @@ -168,9 +218,9 @@ DmaTransferBytes ( // This will fire off the transfer. // #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_RISCV64) || defined (MDE_CPU_LOONGARCH64) - MmioWrite64 (mFwCfgDmaAddress, SwapBytes64 ((UINT64)&Access)); + MmioWrite64 (QemuGetFwCfgDmaAddress (), SwapBytes64 ((UINT64)&Access)); #else - MmioWrite32 ((UINT32)(mFwCfgDmaAddress + 4), SwapBytes32 ((UINT32)&Access)); + MmioWrite32 ((UINT32)(QemuGetFwCfgDmaAddress () + 4), SwapBytes32 ((UINT32)&Access)); #endif // @@ -239,7 +289,7 @@ MmioWriteBytes ( UINTN Idx; for (Idx = 0; Idx < Size; ++Idx) { - MmioWrite8 (mFwCfgDataAddress, ((UINT8 *)Buffer)[Idx]); + MmioWrite8 (QemuGetFwCfgDataAddress (), ((UINT8 *)Buffer)[Idx]); } } diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf index b3017ae..633053a 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf @@ -4,6 +4,7 @@ # # Copyright (C) 2013 - 2014, Red Hat, Inc. # Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.
+# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -39,11 +40,15 @@ BaseLib BaseMemoryLib DebugLib + HobLib IoLib UefiBootServicesTableLib [Protocols] gFdtClientProtocolGuid ## CONSUMES +[Guids] + gQemuFirmwareResourceHobGuid + [Depex] gFdtClientProtocolGuid diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmioInternal.h b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmioInternal.h index 8c63cf1..961612f 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmioInternal.h +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmioInternal.h @@ -12,9 +12,11 @@ #ifndef QEMU_FW_CFG_LIB_MMIO_INTERNAL_H_ #define QEMU_FW_CFG_LIB_MMIO_INTERNAL_H_ -extern UINTN mFwCfgSelectorAddress; -extern UINTN mFwCfgDataAddress; -extern UINTN mFwCfgDmaAddress; +typedef struct { + UINTN FwCfgSelectorAddress; + UINTN FwCfgDataAddress; + UINTN FwCfgDmaAddress; +} QEMU_FW_CFG_RESOURCE; /** Reads firmware configuration bytes into a buffer @@ -91,6 +93,69 @@ VOID (EFIAPI *InternalQemuFwCfgSkipBytes)( ); /** + Build firmware configure resource HOB. + + @param[in] FwCfgResource A pointer to firmware configure resource. + + @retval NULL +**/ +VOID +QemuBuildFwCfgResourceHob ( + IN QEMU_FW_CFG_RESOURCE *FwCfgResource + ); + +/** + Get firmware configure resource HOB. + + @param VOID + + @retval FwCfgResource The firmware configure resouce in HOB. +**/ +QEMU_FW_CFG_RESOURCE * +QemuGetFwCfgResourceHob ( + VOID + ); + +/** + To get firmware configure selector address. + + @param VOID + + @retval firmware configure selector address +**/ +UINTN +EFIAPI +QemuGetFwCfgSelectorAddress ( + VOID + ); + +/** + To get firmware configure Data address. + + @param VOID + + @retval firmware configure data address +**/ +UINTN +EFIAPI +QemuGetFwCfgDataAddress ( + VOID + ); + +/** + To get firmware DMA address. + + @param VOID + + @retval firmware DMA address +**/ +UINTN +EFIAPI +QemuGetFwCfgDmaAddress ( + VOID + ); + +/** Slow READ_BYTES_FUNCTION. **/ VOID diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c index 0536253..c9744ae 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c @@ -5,6 +5,7 @@ Copyright (C) 2013 - 2014, Red Hat, Inc. Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.
(C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -20,9 +21,57 @@ #include "QemuFwCfgLibMmioInternal.h" -UINTN mFwCfgSelectorAddress; -UINTN mFwCfgDataAddress; -UINTN mFwCfgDmaAddress; +STATIC UINTN mFwCfgSelectorAddress; +STATIC UINTN mFwCfgDataAddress; +STATIC UINTN mFwCfgDmaAddress; + +/** + To get firmware configure selector address. + + @param VOID + + @retval firmware configure selector address +**/ +UINTN +EFIAPI +QemuGetFwCfgSelectorAddress ( + VOID + ) +{ + return mFwCfgSelectorAddress; +} + +/** + To get firmware configure Data address. + + @param VOID + + @retval firmware configure data address +**/ +UINTN +EFIAPI +QemuGetFwCfgDataAddress ( + VOID + ) +{ + return mFwCfgDataAddress; +} + +/** + To get firmware DMA address. + + @param VOID + + @retval firmware DMA address +**/ +UINTN +EFIAPI +QemuGetFwCfgDmaAddress ( + VOID + ) +{ + return mFwCfgDmaAddress; +} RETURN_STATUS EFIAPI @@ -30,17 +79,37 @@ QemuFwCfgInitialize ( VOID ) { - EFI_STATUS Status; - FDT_CLIENT_PROTOCOL *FdtClient; - CONST UINT64 *Reg; - UINT32 RegSize; - UINTN AddressCells, SizeCells; - UINT64 FwCfgSelectorAddress; - UINT64 FwCfgSelectorSize; - UINT64 FwCfgDataAddress; - UINT64 FwCfgDataSize; - UINT64 FwCfgDmaAddress; - UINT64 FwCfgDmaSize; + EFI_STATUS Status; + FDT_CLIENT_PROTOCOL *FdtClient; + CONST UINT64 *Reg; + UINT32 RegSize; + UINTN AddressCells, SizeCells; + UINT64 FwCfgSelectorAddress; + UINT64 FwCfgSelectorSize; + UINT64 FwCfgDataAddress; + UINT64 FwCfgDataSize; + UINT64 FwCfgDmaAddress; + UINT64 FwCfgDmaSize; + QEMU_FW_CFG_RESOURCE *FwCfgResource; + + // + // Check whether the Qemu firmware configure resources HOB has been created, + // if so use the resources in the HOB. + // + FwCfgResource = QemuGetFwCfgResourceHob (); + if (FwCfgResource != NULL) { + mFwCfgSelectorAddress = FwCfgResource->FwCfgSelectorAddress; + mFwCfgDataAddress = FwCfgResource->FwCfgDataAddress; + mFwCfgDmaAddress = FwCfgResource->FwCfgDmaAddress; + + if (mFwCfgDmaAddress != 0) { + InternalQemuFwCfgReadBytes = DmaReadBytes; + InternalQemuFwCfgWriteBytes = DmaWriteBytes; + InternalQemuFwCfgSkipBytes = DmaSkipBytes; + } + + return RETURN_SUCCESS; + } Status = gBS->LocateProtocol ( &gFdtClientProtocolGuid, -- cgit v1.1