public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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]
-=-=-=-=-=-=-=-=-=-=-=-



  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