From: "maobibo" <maobibo@loongson.cn>
To: Chao Li <lichao@loongson.cn>, devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>,
Jiewen Yao <jiewen.yao@intel.com>,
Jordan Justen <jordan.l.justen@intel.com>,
Gerd Hoffmann <kraxel@redhat.com>,
Dongyan Qian <qiandongyan@loongson.cn>,
Xianglai Li <lixianglai@loongson.cn>
Subject: Re: [edk2-devel] [PATCH v6 31/36] OvmfPkg/LoongArchVirt: Add FdtQemuFwCfgLib
Date: Wed, 10 Jan 2024 09:27:08 +0800 [thread overview]
Message-ID: <7dadc71b-c18b-c84a-f10a-90307e1f1b21@loongson.cn> (raw)
In-Reply-To: <20240105094616.2281979-1-lichao@loongson.cn>
On 2024/1/5 下午5:46, Chao Li wrote:
> This library for PEI phase, and obtains the QemuFwCfg base address by
> directly parsing the FDT, reads and writes the data in QemuFwCfg by
> operating on the QemuFwCfg base address.
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584
>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Bibo Mao <maobibo@loongson.cn>
> Cc: Dongyan Qian <qiandongyan@loongson.cn>
> Signed-off-by: Chao Li <lichao@loongson.cn>
> Co-authored-by: Xianglai Li <lixianglai@loongson.cn>
> Co-authored-by: Bibo Mao <maobibo@loongson.cn>
> ---
> .../FdtQemuFwCfgLib/FdtQemuFwCfgPeiLib.c | 504 ++++++++++++++++++
> .../FdtQemuFwCfgLib/FdtQemuFwCfgPeiLib.inf | 42 ++
> .../FdtQemuFwCfgLib/QemuFwCfgLibInternal.h | 73 +++
> .../Library/FdtQemuFwCfgLib/QemuFwCfgPei.c | 117 ++++
> 4 files changed, 736 insertions(+)
> create mode 100644 OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/FdtQemuFwCfgPeiLib.c
> create mode 100644 OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/FdtQemuFwCfgPeiLib.inf
> create mode 100644 OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/QemuFwCfgLibInternal.h
> create mode 100644 OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/QemuFwCfgPei.c
>
> diff --git a/OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/FdtQemuFwCfgPeiLib.c b/OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/FdtQemuFwCfgPeiLib.c
> new file mode 100644
> index 0000000000..a1f114b327
> --- /dev/null
> +++ b/OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/FdtQemuFwCfgPeiLib.c
> @@ -0,0 +1,504 @@
> +/** @file
> +
> + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Glossary:
> + - FwCfg - firmWare Configure
> + - CTL - Control
> +**/
> +
> +#include <Base.h>
> +#include <Uefi.h>
> +#include <PiPei.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/QemuFwCfgLib.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/HobLib.h>
> +#include <libfdt.h>
> +#include "QemuFwCfgLibInternal.h"
> +
> +EFI_GUID mFwCfgSelectorAddressGuid = FW_CONFIG_SELECTOR_ADDRESS_HOB_GUID;
> +EFI_GUID mFwCfgDataAddressGuid = FW_CONFIG_DATA_ADDRESS_HOB_GUID;
> +
> +STATIC UINTN mFwCfgSelectorAddress;
> +STATIC UINTN mFwCfgDataAddress;
> +
> +/**
> + To get firmware configure selector address.
> +
> + @param VOID
> +
> + @retval firmware configure selector address
> +**/
> +UINTN
> +EFIAPI
> +QemuGetFwCfgSelectorAddress (
> + VOID
> + )
> +{
> + UINTN FwCfgSelectorAddress;
> + EFI_HOB_GUID_TYPE *GuidHob;
> + VOID *DataInHob;
> +
> + FwCfgSelectorAddress = mFwCfgSelectorAddress;
> + GuidHob = NULL;
> + DataInHob = NULL;
> +
> + if (FwCfgSelectorAddress == 0) {
> + GuidHob = GetFirstGuidHob (&mFwCfgSelectorAddressGuid);
> + DataInHob = GET_GUID_HOB_DATA (GuidHob);
> + FwCfgSelectorAddress = (UINT64)(*(UINTN *)DataInHob);
> + }
> +
> + return FwCfgSelectorAddress;
> +}
> +
> +/**
> + To get firmware configure Data address.
> +
> + @param VOID
> +
> + @retval firmware configure data address
> +**/
> +UINTN
> +EFIAPI
> +QemuGetFwCfgDataAddress (
> + VOID
> + )
> +{
> + UINTN FwCfgDataAddress;
> + EFI_HOB_GUID_TYPE *GuidHob;
> + VOID *DataInHob;
> +
> + FwCfgDataAddress = mFwCfgDataAddress;
> + GuidHob = NULL;
> + DataInHob = NULL;
> +
> + if (FwCfgDataAddress == 0) {
> + GuidHob = GetFirstGuidHob (&mFwCfgDataAddressGuid);
> + DataInHob = GET_GUID_HOB_DATA (GuidHob);
> + FwCfgDataAddress = (UINT64)(*(UINTN *)DataInHob);
> + }
> +
> + return FwCfgDataAddress;
> +}
> +
> +/**
> + Selects a firmware configuration item for reading.
> +
> + Following this call, any data read from this item will start from
> + the beginning of the configuration item's data.
> +
> + @param[in] QemuFwCfgItem - Firmware Configuration item to read
> +**/
> +VOID
> +EFIAPI
> +QemuFwCfgSelectItem (
> + IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem
> + )
> +{
> + UINTN FwCfgSelectorAddress;
> +
> + FwCfgSelectorAddress = QemuGetFwCfgSelectorAddress ();
> + MmioWrite16 (FwCfgSelectorAddress, SwapBytes16 ((UINT16)(UINTN)QemuFwCfgItem));
> +}
> +
> +/**
> + Slow READ_BYTES_FUNCTION.
> +
> + @param[in] The size of the data to be read.
> + @param[in] Buffer The buffer that stores the readout data.
> +**/
> +VOID
> +EFIAPI
> +MmioReadBytes (
> + IN UINTN Size,
> + IN VOID *Buffer OPTIONAL
> + )
> +{
> + UINTN Left;
> + UINT8 *Ptr;
> + UINT8 *End;
> + UINTN FwCfgDataAddress;
> +
> + Left = Size & 7;
> +
> + Size -= Left;
> + Ptr = Buffer;
> + End = Ptr + Size;
> +
> + FwCfgDataAddress = QemuGetFwCfgDataAddress ();
> + while (Ptr < End) {
> + *(UINT64 *)Ptr = MmioRead64 (FwCfgDataAddress);
> + Ptr += 8;
> + }
> +
> + if (Left & 4) {
> + *(UINT32 *)Ptr = MmioRead32 (FwCfgDataAddress);
> + Ptr += 4;
> + }
> +
> + if (Left & 2) {
> + *(UINT16 *)Ptr = MmioRead16 (FwCfgDataAddress);
> + Ptr += 2;
> + }
> +
> + if (Left & 1) {
> + *Ptr = MmioRead8 (FwCfgDataAddress);
> + }
> +}
> +
> +/**
> + Slow WRITE_BYTES_FUNCTION.
> +
> + @param[in] The size of the data to be write.
> + @param[in] Buffer The buffer that stores the writein data.
> +**/
> +VOID
> +EFIAPI
> +MmioWriteBytes (
> + IN UINTN Size,
> + IN VOID *Buffer OPTIONAL
> + )
> +{
> + UINTN Idx;
> + UINTN FwCfgDataAddress;
> +
> + FwCfgDataAddress = QemuGetFwCfgDataAddress ();
> + for (Idx = 0; Idx < Size; ++Idx) {
> + MmioWrite8 (FwCfgDataAddress, ((UINT8 *)Buffer)[Idx]);
> + }
> +}
> +
> +/**
> + Reads firmware configuration bytes into a buffer
> +
> + @param[in] Size - Size in bytes to read
> + @param[in] Buffer - Buffer to store data into (OPTIONAL if Size is 0)
> +**/
> +VOID
> +EFIAPI
> +InternalQemuFwCfgReadBytes (
> + IN UINTN Size,
> + IN VOID *Buffer OPTIONAL
> + )
> +{
> + if ((InternalQemuFwCfgDmaIsAvailable ()) &&
> + (Size <= MAX_UINT32))
> + {
> + InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_READ);
> + return;
> + }
> +
> + MmioReadBytes (Size, Buffer);
> +}
> +
> +/**
> + Reads firmware configuration bytes into a buffer
> +
> + If called multiple times, then the data read will
> + continue at the offset of the firmware configuration
> + item where the previous read ended.
> +
> + @param[in] Size - Size in bytes to read
> + @param[in] Buffer - Buffer to store data into
> +**/
> +VOID
> +EFIAPI
> +QemuFwCfgReadBytes (
> + IN UINTN Size,
> + IN VOID *Buffer
> + )
> +{
> + if (InternalQemuFwCfgIsAvailable ()) {
> + InternalQemuFwCfgReadBytes (Size, Buffer);
> + } else {
> + ZeroMem (Buffer, Size);
> + }
> +}
> +
> +/**
> + Write firmware configuration bytes from a buffer
> +
> + If called multiple times, then the data written will
> + continue at the offset of the firmware configuration
> + item where the previous write ended.
> +
> + @param[in] Size - Size in bytes to write
> + @param[in] Buffer - Buffer to read data from
> +**/
> +VOID
> +EFIAPI
> +QemuFwCfgWriteBytes (
> + IN UINTN Size,
> + IN VOID *Buffer
> + )
> +{
> + if (InternalQemuFwCfgIsAvailable ()) {
> + if ((InternalQemuFwCfgDmaIsAvailable ()) &&
> + (Size <= MAX_UINT32))
> + {
> + InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_WRITE);
> + return;
> + }
> +
> + MmioWriteBytes (Size, Buffer);
> + }
> +}
> +
> +/**
> + Skip bytes in the firmware configuration item.
> +
> + Increase the offset of the firmware configuration item without transferring
> + bytes between the item and a caller-provided buffer. Subsequent read, write
> + or skip operations will commence at the increased offset.
> +
> + @param[in] Size Number of bytes to skip.
> +**/
> +VOID
> +EFIAPI
> +QemuFwCfgSkipBytes (
> + IN UINTN Size
> + )
> +{
> + UINTN ChunkSize;
> + UINT8 SkipBuffer[256];
> +
> + if (!InternalQemuFwCfgIsAvailable ()) {
> + return;
> + }
> +
> + if ((InternalQemuFwCfgDmaIsAvailable ()) &&
> + (Size <= MAX_UINT32))
> + {
> + InternalQemuFwCfgDmaBytes ((UINT32)Size, NULL, FW_CFG_DMA_CTL_SKIP);
> + return;
> + }
> +
> + //
> + // Emulate the skip by reading data in chunks, and throwing it away. The
> + // implementation below is suitable even for phases where RAM or dynamic
> + // allocation is not available or appropriate. It also doesn't affect the
> + // static data footprint for client modules. Large skips are not expected,
> + // therefore this fallback is not performance critical. The size of
> + // SkipBuffer is thought not to exert a large pressure on the stack in any
> + // phase.
> + //
> + while (Size > 0) {
> + ChunkSize = MIN (Size, sizeof SkipBuffer);
> + MmioReadBytes (ChunkSize, SkipBuffer);
> + Size -= ChunkSize;
> + }
> +}
> +
> +/**
> + Reads a UINT8 firmware configuration value
> +
> + @return Value of Firmware Configuration item read
> +**/
> +UINT8
> +EFIAPI
> +QemuFwCfgRead8 (
> + VOID
> + )
> +{
> + UINT8 Result;
> +
> + QemuFwCfgReadBytes (sizeof (Result), &Result);
> +
> + return Result;
> +}
> +
> +/**
> + Reads a UINT16 firmware configuration value
> +
> + @return Value of Firmware Configuration item read
> +**/
> +UINT16
> +EFIAPI
> +QemuFwCfgRead16 (
> + VOID
> + )
> +{
> + UINT16 Result;
> +
> + QemuFwCfgReadBytes (sizeof (Result), &Result);
> +
> + return Result;
> +}
> +
> +/**
> + Reads a UINT32 firmware configuration value
> +
> + @return Value of Firmware Configuration item read
> +**/
> +UINT32
> +EFIAPI
> +QemuFwCfgRead32 (
> + VOID
> + )
> +{
> + UINT32 Result;
> +
> + QemuFwCfgReadBytes (sizeof (Result), &Result);
> +
> + return Result;
> +}
> +
> +/**
> + Reads a UINT64 firmware configuration value
> +
> + @return Value of Firmware Configuration item read
> +**/
> +UINT64
> +EFIAPI
> +QemuFwCfgRead64 (
> + VOID
> + )
> +{
> + UINT64 Result;
> +
> + QemuFwCfgReadBytes (sizeof (Result), &Result);
> +
> + return Result;
> +}
> +
> +/**
> + Find the configuration item corresponding to the firmware configuration file.
> +
> + @param[in] Name - Name of file to look up.
> + @param[out] Item - Configuration item corresponding to the file, to be passed
> + to QemuFwCfgSelectItem ().
> + @param[out] Size - Number of bytes in the file.
> +
> + @return RETURN_SUCCESS If file is found.
> + RETURN_NOT_FOUND If file is not found.
> + RETURN_UNSUPPORTED If firmware configuration is unavailable.
> +**/
> +RETURN_STATUS
> +EFIAPI
> +QemuFwCfgFindFile (
> + IN CONST CHAR8 *Name,
> + OUT FIRMWARE_CONFIG_ITEM *Item,
> + OUT UINTN *Size
> + )
> +{
> + UINT32 Count;
> + UINT32 Idx;
> +
> + if (!InternalQemuFwCfgIsAvailable ()) {
> + return RETURN_UNSUPPORTED;
> + }
> +
> + QemuFwCfgSelectItem (QemuFwCfgItemFileDir);
> + Count = SwapBytes32 (QemuFwCfgRead32 ());
> +
> + for (Idx = 0; Idx < Count; ++Idx) {
> + UINT32 FileSize;
> + UINT16 FileSelect;
> + CHAR8 FileName[QEMU_FW_CFG_FNAME_SIZE];
> +
> + FileSize = QemuFwCfgRead32 ();
> + FileSelect = QemuFwCfgRead16 ();
> + QemuFwCfgRead16 (); // skip the field called "reserved"
> + InternalQemuFwCfgReadBytes (sizeof (FileName), FileName);
> +
> + if (AsciiStrCmp (Name, FileName) == 0) {
> + *Item = SwapBytes16 (FileSelect);
> + *Size = SwapBytes32 (FileSize);
> + return RETURN_SUCCESS;
> + }
> + }
> +
> + return RETURN_NOT_FOUND;
> +}
> +
> +/**
> + firmware config initialize.
> +
> + @param VOID
> +
> + @return RETURN_SUCCESS Initialization succeeded.
> +**/
> +RETURN_STATUS
> +EFIAPI
> +FdtQemuFwCfgInitialize (
> + VOID
> + )
> +{
> + VOID *DeviceTreeBase;
> + INT32 Node;
> + INT32 Prev;
> + CONST CHAR8 *Type;
> + INT32 Len;
> + CONST UINT64 *RegProp;
> + UINT64 FwCfgSelectorAddress;
> + UINT64 FwCfgDataAddress;
> + UINT64 FwCfgDataSize;
> +
> + DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
> + ASSERT (DeviceTreeBase != NULL);
> + //
> + // Make sure we have a valid device tree blob
> + //
> + ASSERT (fdt_check_header (DeviceTreeBase) == 0);
> +
> + for (Prev = 0; ; Prev = Node) {
> + Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
> + if (Node < 0) {
> + break;
> + }
> +
> + //
> + // Check for memory node
> + //
> + Type = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
> + if ((Type) &&
> + (AsciiStrnCmp (Type, "qemu,fw-cfg-mmio", Len) == 0))
> + {
> + //
> + // Get the 'reg' property of this node. For now, we will assume
> + // two 8 byte quantities for base and size, respectively.
> + //
> + RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
> + if ((RegProp != 0) &&
> + (Len == (2 * sizeof (UINT64))))
> + {
> + FwCfgDataAddress = SwapBytes64 (RegProp[0]);
> + FwCfgDataSize = 8;
> + FwCfgSelectorAddress = FwCfgDataAddress + FwCfgDataSize;
> +
> + mFwCfgSelectorAddress = FwCfgSelectorAddress;
> + mFwCfgDataAddress = FwCfgDataAddress;
> +
> + BuildGuidDataHob (
> + &mFwCfgSelectorAddressGuid,
> + (VOID *)&FwCfgSelectorAddress,
> + sizeof (UINT64)
> + );
> +
> + BuildGuidDataHob (
> + &mFwCfgDataAddressGuid,
> + (VOID *)&FwCfgDataAddress,
> + sizeof (UINT64)
> + );
> + break;
> + } else {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: Failed to parse FDT QemuCfg node\n",
> + __func__
> + ));
> + break;
> + }
> + }
> + }
> +
> + return RETURN_SUCCESS;
> +}
> diff --git a/OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/FdtQemuFwCfgPeiLib.inf b/OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/FdtQemuFwCfgPeiLib.inf
> new file mode 100644
> index 0000000000..930933ce7d
> --- /dev/null
> +++ b/OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/FdtQemuFwCfgPeiLib.inf
> @@ -0,0 +1,42 @@
> +## @file
> +# initialized fw_cfg library.
> +#
> +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 1.29
> + BASE_NAME = FdtQemuFwCfgPeiLib
> + FILE_GUID = cdf9a9d5-7422-4dcb-b41d-607151ad320b
> + MODULE_TYPE = BASE
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = FtdQemuFwCfgLib|PEIM
> + CONSTRUCTOR = FdtQemuFwCfgInitialize
> +
> +#
> +# VALID_ARCHITECTURES = LOONGARCH64
> +#
> +
> +[Sources]
> + FdtQemuFwCfgPeiLib.c
> + QemuFwCfgPei.c
> +
> +[Packages]
> + EmbeddedPkg/EmbeddedPkg.dec
> + MdePkg/MdePkg.dec
> + OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + FdtLib
> + HobLib
> + IoLib
> + MemoryAllocationLib
> +
> +[Pcd]
> + gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
> diff --git a/OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/QemuFwCfgLibInternal.h b/OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/QemuFwCfgLibInternal.h
> new file mode 100644
> index 0000000000..983d1f4849
> --- /dev/null
> +++ b/OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/QemuFwCfgLibInternal.h
> @@ -0,0 +1,73 @@
> +/** @file
> + fw_cfg library implementation.
> +
> + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Glossary:
> + - FwCfg - firmWare Configure
> +**/
> +
> +#ifndef QEMU_FW_CFG_LIB_INTERNAL_H_
> +#define QEMU_FW_CFG_LIB_INTERNAL_H_
> +
> +#define FW_CONFIG_SELECTOR_ADDRESS_HOB_GUID \
> + { \
> + 0x3cc47b04, 0x0d3e, 0xaa64, { 0x06, 0xa6, 0x4b, 0xdc, 0x9a, 0x2c, 0x61, 0x19 } \
> + }
> +
> +#define FW_CONFIG_DATA_ADDRESS_HOB_GUID \
> + { \
> + 0xef854788, 0x10f3, 0x8e7a, { 0x3e, 0xd0, 0x4d, 0x16, 0xc1, 0x79, 0x55, 0x2f } \
> + }
> +
> +/**
> + Returns a boolean indicating if the firmware configuration interface is
> + available for library-internal purposes.
> +
> + This function never changes fw_cfg state.
> +
> + @retval TRUE The interface is available internally.
> + @retval FALSE The interface is not available internally.
> +**/
> +BOOLEAN
> +InternalQemuFwCfgIsAvailable (
> + VOID
> + );
> +
> +/**
> + Returns a boolean indicating whether QEMU provides the DMA-like access method
> + for fw_cfg.
> +
> + @retval TRUE The DMA-like access method is available.
> + @retval FALSE The DMA-like access method is unavailable.
> +**/
> +BOOLEAN
> +InternalQemuFwCfgDmaIsAvailable (
> + VOID
> + );
> +
> +/**
> + Transfer an array of bytes, or skip a number of bytes, using the DMA
> + interface.
> +
> + @param[in] Size Size in bytes to transfer or skip.
> +
> + @param[in,out] Buffer Buffer to read data into or write data from. Ignored,
> + and may be NULL, if Size is zero, or Control is
> + FW_CFG_DMA_CTL_SKIP.
> +
> + @param[in] Control One of the following:
> + FW_CFG_DMA_CTL_WRITE - write to fw_cfg from Buffer.
> + FW_CFG_DMA_CTL_READ - read from fw_cfg into Buffer.
> + FW_CFG_DMA_CTL_SKIP - skip bytes in fw_cfg.
> +**/
> +VOID
> +InternalQemuFwCfgDmaBytes (
> + IN UINT32 Size,
> + IN OUT VOID *Buffer OPTIONAL,
> + IN UINT32 Control
> + );
> +
> +#endif // QEMU_FW_CFG_LIB_INTERNAL_H_
> diff --git a/OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/QemuFwCfgPei.c b/OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/QemuFwCfgPei.c
> new file mode 100644
> index 0000000000..74e778aac7
> --- /dev/null
> +++ b/OvmfPkg/LoongArchVirt/Library/FdtQemuFwCfgLib/QemuFwCfgPei.c
> @@ -0,0 +1,117 @@
> +/** @file
> + fw_cfg library implementation.
> +
> + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Glossary:
> + - FwCfg - firmWare Configure
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/QemuFwCfgLib.h>
> +
> +#include "QemuFwCfgLibInternal.h"
> +
> +/**
> + Returns a boolean indicating if the firmware configuration interface
> + is available or not.
> +
> + This function may change fw_cfg state.
> +
> + @retval TRUE The interface is available
> + @retval FALSE The interface is not available
> +**/
> +BOOLEAN
> +EFIAPI
> +QemuFwCfgIsAvailable (
> + VOID
> + )
> +{
> + UINT32 Signature;
> + UINT32 Revision;
> +
> + QemuFwCfgSelectItem (QemuFwCfgItemSignature);
> + Signature = QemuFwCfgRead32 ();
> + DEBUG ((DEBUG_INFO, "FW CFG Signature: 0x%x\n", Signature));
> + QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);
> + Revision = QemuFwCfgRead32 ();
> + DEBUG ((DEBUG_INFO, "FW CFG Revision: 0x%x\n", Revision));
> + if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||
> + (Revision < 1))
> + {
> + DEBUG ((DEBUG_INFO, "QemuFwCfg interface not supported.\n"));
> + return FALSE;
> + }
> +
> + DEBUG ((DEBUG_INFO, "QemuFwCfg interface is supported.\n"));
> + return TRUE;
> +}
> +
> +/**
> + Returns a boolean indicating if the firmware configuration interface is
> + available for library-internal purposes.
> +
> + This function never changes fw_cfg state.
> +
> + @retval TRUE The interface is available internally.
> + @retval FALSE The interface is not available internally.
> +**/
> +BOOLEAN
> +InternalQemuFwCfgIsAvailable (
> + VOID
> + )
> +{
> + //
> + // We always return TRUE, because the consumer of this library ought to have
> + // called QemuFwCfgIsAvailable before making other calls which would hit this
> + // path.
> + //
> + return TRUE;
> +}
> +
> +/**
> + Returns a boolean indicating whether QEMU provides the DMA-like access method
> + for fw_cfg.
> +
> + @retval TRUE The DMA-like access method is available.
> + @retval FALSE The DMA-like access method is unavailable.
> +**/
> +BOOLEAN
> +InternalQemuFwCfgDmaIsAvailable (
> + VOID
> + )
> +{
> + return FALSE;
> +}
> +
> +/**
> + Transfer an array of bytes, or skip a number of bytes, using the DMA
> + interface.
> +
> + @param[in] Size Size in bytes to transfer or skip.
> +
> + @param[in, out] Buffer Buffer to read data into or write data from. Ignored,
> + and may be NULL, if Size is zero, or Control is
> + FW_CFG_DMA_CTL_SKIP.
> +
> + @param[in] Control One of the following:
> + FW_CFG_DMA_CTL_WRITE - write to fw_cfg from Buffer.
> + FW_CFG_DMA_CTL_READ - read from fw_cfg into Buffer.
> + FW_CFG_DMA_CTL_SKIP - skip bytes in fw_cfg.
> +**/
> +VOID
> +InternalQemuFwCfgDmaBytes (
> + IN UINT32 Size,
> + IN OUT VOID *Buffer OPTIONAL,
> + IN UINT32 Control
> + )
> +{
> + //
> + // We should never reach here
> + //
> + ASSERT (FALSE);
> + CpuDeadLoop ();
> +}
>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#113502): https://edk2.groups.io/g/devel/message/113502
Mute This Topic: https://groups.io/mt/103540132/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2024-01-10 1:27 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-05 9:41 [edk2-devel] [PATCH v6 00/36] Enable LoongArch virtual machine in edk2 Chao Li
2024-01-05 9:42 ` [edk2-devel] [PATCH v6 01/36] MdePkg: Add the header file named Csr.h for LoongArch64 Chao Li
2024-01-05 9:42 ` [edk2-devel] [PATCH v6 02/36] MdePkg: Add LoongArch64 FPU function set into BaseCpuLib Chao Li
2024-01-05 9:42 ` [edk2-devel] [PATCH v6 03/36] MdePkg: Add LoongArch64 exception function set into BaseLib Chao Li
2024-01-05 9:42 ` [edk2-devel] [PATCH v6 04/36] MdePkg: Add LoongArch64 local interrupt " Chao Li
2024-01-05 9:42 ` [edk2-devel] [PATCH v6 05/36] MdePkg: Add LoongArch Cpucfg function Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 06/36] MdePkg: Add read stable counter operation for LoongArch Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 07/36] MdePkg: Add CSR " Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 08/36] MdePkg: Add IOCSR " Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 09/36] MdePkg: Add a new library named PeiServicesTablePointerLibKs0 Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 10/36] UefiCpuPkg: Add LoongArch64 CPU Timer library Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 11/36] UefiCpuPkg: Add CPU exception library for LoongArch Chao Li
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 12/36] UefiCpuPkg: Add CpuMmuLib.h to UefiCpuPkg Chao Li
2024-01-05 12:49 ` Ni, Ray
2024-01-05 9:43 ` [edk2-devel] [PATCH v6 13/36] UefiCpuPkg: Add LoongArch64CpuMmuLib " Chao Li
2024-01-05 12:50 ` Ni, Ray
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 14/36] UefiCpuPkg: Add multiprocessor library for LoongArch64 Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 15/36] UefiCpuPkg: Add CpuDxe driver " Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 16/36] EmbeddedPkg: Add PcdPrePiCpuIoSize width for LOONGARCH64 Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 17/36] ArmVirtPkg: Move PCD of FDT base address and FDT padding to OvmfPkg Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 18/36] UefiCpuPkg: Add a new CPU IO 2 driver named CpuMmio2Dxe Chao Li
2024-01-06 3:20 ` Ni, Ray
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 19/36] ArmVirtPkg: Enable CpuMmio2Dxe Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 20/36] OvmfPkg/RiscVVirt: " Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 21/36] OvmfPkg/RiscVVirt: Remove PciCpuIo2Dxe from RiscVVirt Chao Li
2024-01-05 9:44 ` [edk2-devel] [PATCH v6 22/36] ArmVirtPkg: Move the FdtSerialPortAddressLib to OvmfPkg Chao Li
2024-01-05 9:45 ` [edk2-devel] [PATCH v6 23/36] ArmVirtPkg: Move two PCD variables into OvmfPkg Chao Li
2024-01-05 9:45 ` [edk2-devel] [PATCH v6 24/36] ArmVirtPkg: Move PlatformBootManagerLib to OvmfPkg Chao Li
2024-01-08 14:02 ` Laszlo Ersek
2024-01-09 6:40 ` Chao Li
2024-01-09 8:00 ` Laszlo Ersek
2024-01-05 9:45 ` [edk2-devel] [PATCH v6 25/36] OvmfPkg/LoongArchVirt: Add stable timer driver Chao Li
2024-01-12 7:05 ` maobibo
2024-01-05 9:45 ` [edk2-devel] [PATCH v6 26/36] OvmfPkg/LoongArchVirt: Add a NULL library named CollectApResouceLibNull Chao Li
2024-01-10 1:24 ` maobibo
2024-01-10 2:47 ` Chao Li
2024-01-10 9:35 ` maobibo
2024-01-05 9:45 ` [edk2-devel] [PATCH v6 27/36] OvmfPkg/LoongArchVirt: Add serial port hook library Chao Li
2024-01-05 9:45 ` [edk2-devel] [PATCH v6 28/36] OvmfPkg/LoongArchVirt: Add the early serial port output library Chao Li
2024-01-10 1:25 ` maobibo
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 29/36] OvmfPkg/LoongArchVirt: Add real time clock library Chao Li
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 30/36] OvmfPkg/LoongArchVirt: Add NorFlashQemuLib Chao Li
2024-01-10 1:26 ` maobibo
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 31/36] OvmfPkg/LoongArchVirt: Add FdtQemuFwCfgLib Chao Li
2024-01-10 1:27 ` maobibo [this message]
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 32/36] OvmfPkg/LoongArchVirt: Add reset system library Chao Li
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 33/36] OvmfPkg/LoongArchVirt: Support SEC phase Chao Li
2024-01-08 6:51 ` maobibo
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 34/36] OvmfPkg/LoongArchVirt: Support PEI phase Chao Li
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 35/36] OvmfPkg/LoongArchVirt: Add build file Chao Li
2024-01-10 1:28 ` maobibo
2024-01-05 9:46 ` [edk2-devel] [PATCH v6 36/36] OvmfPkg/LoongArchVirt: Add self introduction file Chao Li
2024-01-10 1:28 ` maobibo
2024-01-08 1:35 ` [edk2-devel] 回复: [PATCH v6 00/36] Enable LoongArch virtual machine in edk2 gaoliming via groups.io
2024-01-08 2:41 ` Chao Li
[not found] ` <17A76A50519959EC.16812@groups.io>
2024-01-08 3:21 ` [edk2-devel] [PATCH v6 19/36] ArmVirtPkg: Enable CpuMmio2Dxe Chao Li
[not found] ` <17A76A543E440C35.16812@groups.io>
2024-01-08 3:24 ` [edk2-devel] [PATCH v6 22/36] ArmVirtPkg: Move the FdtSerialPortAddressLib to OvmfPkg Chao Li
[not found] ` <17A76A5F07C7435C.16812@groups.io>
2024-01-08 3:24 ` [edk2-devel] [PATCH v6 23/36] ArmVirtPkg: Move two PCD variables into OvmfPkg Chao Li
[not found] ` <17A76A601F9A93F4.25044@groups.io>
2024-01-08 3:25 ` [edk2-devel] [PATCH v6 24/36] ArmVirtPkg: Move PlatformBootManagerLib to OvmfPkg Chao Li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7dadc71b-c18b-c84a-f10a-90307e1f1b21@loongson.cn \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox