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 <ardb+tianoc...@kernel.org> Cc: Jiewen Yao <jiewen....@intel.com> Cc: Gerd Hoffmann <kra...@redhat.com> Cc: Leif Lindholm <quic_llind...@quicinc.com> Cc: Sami Mujawar <sami.muja...@arm.com> Cc: Sunil V L <suni...@ventanamicro.com> Cc: Andrei Warkentin <andrei.warken...@intel.com> Signed-off-by: Chao Li <lic...@loongson.cn> --- .../Library/QemuFwCfgLib/QemuFwCfgLibMmio.c | 71 ++++++++++++-- .../Library/QemuFwCfgLib/QemuFwCfgLibMmio.inf | 5 + .../QemuFwCfgLib/QemuFwCfgLibMmioInternal.h | 71 +++++++++++++- .../Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c | 97 ++++++++++++++++--- 4 files changed, 217 insertions(+), 27 deletions(-) diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibMmio.c index 2a2f3e67ac..4da7890fc1 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.<BR> (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/ +#include <Base.h> #include <Uefi.h> +#include <Pi/PiBootMode.h> +#include <Pi/PiHob.h> + #include <Library/BaseLib.h> #include <Library/BaseMemoryLib.h> #include <Library/DebugLib.h> +#include <Library/HobLib.h> #include <Library/IoLib.h> #include <Library/QemuFwCfgLib.h> #include <Library/UefiBootServicesTableLib.h> @@ -27,6 +33,51 @@ READ_BYTES_FUNCTION *InternalQemuFwCfgReadBytes = MmioReadBytes; 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 +94,7 @@ QemuFwCfgIsAvailable ( VOID ) { - return (BOOLEAN)(mFwCfgSelectorAddress != 0 && mFwCfgDataAddress != 0); + return (BOOLEAN)(QemuGetFwCfgSelectorAddress () != 0 && QemuGetFwCfgDataAddress () != 0); } /** @@ -62,7 +113,7 @@ QemuFwCfgSelectItem ( ) { if (QemuFwCfgIsAvailable ()) { - MmioWrite16 (mFwCfgSelectorAddress, SwapBytes16 ((UINT16)QemuFwCfgItem)); + MmioWrite16 (QemuGetFwCfgSelectorAddress (), SwapBytes16 ((UINT16)QemuFwCfgItem)); } } @@ -92,30 +143,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 +219,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 +290,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 b3017aef80..633053aaed 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.<BR> +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -39,11 +40,15 @@ [LibraryClasses] 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 d7d645f700..4fc2ef6eb9 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 @@ -96,6 +98,69 @@ EFIAPI IN UINTN Size ); +/** + 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. **/ diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxe.c index 0536253845..c9744ae5d7 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.<BR> (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR> 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, -- 2.27.0 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#118314): https://edk2.groups.io/g/devel/message/118314 Mute This Topic: https://groups.io/mt/105746791/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-