Reviewed-By: Olivier Martin <[email protected]>

> -----Original Message-----
> From: Laszlo Ersek [mailto:[email protected]]
> Sent: 11 December 2014 02:46
> To: [email protected]; [email protected];
> [email protected]; [email protected]
> Subject: [edk2] [PATCH v3 02/13] ArmVirtualizationPkg: introduce
> QemuFwCfgLib instance for DXE drivers
> 
> After reviewing OvmfPkg's use of its own QemuFwCfgLib instances, it is
> clear that its only pre-DXE fw_cfg dependency concerns S3 support (the
> QemuFwCfgS3Enabled() call in "PlatformPei/Platform.c").
> 
> For ARM guests, S3 is in the distant future, but we can see several
> shorter term applications for fw_cfg that all reside in DXE:
> - controlling boot order (to be implemented in PlatformBdsLib for Intel
>   BDS),
> - supporting -kernel / -initrd / -append boot on QEMU (to be
> implemented
>   in PlatformBdsLib for Intel BDS, similarly),
> - loading and linking ACPI tables,
> - installing SMBIOS tables.
> 
> Therefore it makes sense to add a simple MMIO-based fw_cfg client
> library
> to ArmVirtualizationPkg that for the moment is only available to
> DXE_DRIVER modules.
> 
> Because MMIO accesses are costly on KVM/ARM,
> InternalQemuFwCfgReadBytes()
> accesses the fw_cfg data register in full words. This speeds up
> transfers
> almost linearly.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Laszlo Ersek <[email protected]>
> ---
> 
> Notes:
>     v3:
>     - full word access to fw_cfg data register
>     - mention '-kernel' booting in commit message
> 
> 
> ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.i
> nf |  52 ++++++++++
> 
> ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
> | 358
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
> |   1 +
>  3 files changed, 411 insertions(+)
> 
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib
> .inf
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib
> .inf
> new file mode 100644
> index 0000000..21ab2bf
> --- /dev/null
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib
> .inf
> @@ -0,0 +1,52 @@
> +## @file
> +#
> +#  Stateful, implicitly initialized fw_cfg library.
> +#
> +#  Copyright (C) 2013 - 2014, Red Hat, Inc.
> +#  Copyright (c) 2008 - 2012, Intel Corporation. All rights
> reserved.<BR>
> +#
> +#  This program and the accompanying materials are licensed and made
> available
> +#  under the terms and conditions of the BSD License which accompanies
> this
> +#  distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS
> OR
> +#  IMPLIED.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = QemuFwCfgLib
> +  FILE_GUID                      = B271F41F-B841-48A9-BA8D-
> 545B4BC2E2BF
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = QemuFwCfgLib|DXE_DRIVER
> +
> +  CONSTRUCTOR                    = QemuFwCfgInitialize
> +
> +#
> +# The following information is for reference only and not required by
> the build
> +# tools.
> +#
> +#  VALID_ARCHITECTURES           = ARM AARCH64
> +#
> +
> +[Sources]
> +  QemuFwCfgLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +  ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  IoLib
> +  PcdLib
> +
> +[Pcd]
> +  gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress
> +  gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib
> .c
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib
> .c
> new file mode 100644
> index 0000000..dc7506f
> --- /dev/null
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib
> .c
> @@ -0,0 +1,358 @@
> +/** @file
> +
> +  Stateful and implicitly initialized fw_cfg library implementation.
> +
> +  Copyright (C) 2013 - 2014, Red Hat, Inc.
> +  Copyright (c) 2011 - 2013, Intel Corporation. All rights
> reserved.<BR>
> +
> +  This program and the accompanying materials are licensed and made
> available
> +  under the terms and conditions of the BSD License which accompanies
> this
> +  distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS, WITHOUT
> +  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
> IMPLIED.
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/QemuFwCfgLib.h>
> +
> +STATIC UINTN mFwCfgSelectorAddress;
> +STATIC UINTN mFwCfgDataAddress;
> +
> +
> +/**
> +  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
> +EFIAPI
> +InternalQemuFwCfgIsAvailable (
> +  VOID
> +  )
> +{
> +  return (BOOLEAN)(mFwCfgSelectorAddress != 0 && mFwCfgDataAddress !=
> 0);
> +}
> +
> +
> +/**
> +  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
> +  )
> +{
> +  return InternalQemuFwCfgIsAvailable ();
> +}
> +
> +
> +RETURN_STATUS
> +EFIAPI
> +QemuFwCfgInitialize (
> +  VOID
> +  )
> +{
> +  mFwCfgSelectorAddress = (UINTN)PcdGet64 (PcdFwCfgSelectorAddress);
> +  mFwCfgDataAddress     = (UINTN)PcdGet64 (PcdFwCfgDataAddress);
> +
> +  if (InternalQemuFwCfgIsAvailable ()) {
> +    UINT32 Signature;
> +
> +    QemuFwCfgSelectItem (QemuFwCfgItemSignature);
> +    Signature = QemuFwCfgRead32 ();
> +    if (Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) {
> +      mFwCfgSelectorAddress = 0;
> +      mFwCfgDataAddress     = 0;
> +    }
> +  }
> +  return RETURN_SUCCESS;
> +}
> +
> +
> +/**
> +  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
> +  )
> +{
> +  if (InternalQemuFwCfgIsAvailable ()) {
> +    MmioWrite16 (mFwCfgSelectorAddress, (UINT16)QemuFwCfgItem);
> +  }
> +}
> +
> +
> +/**
> +  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)
> +
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +InternalQemuFwCfgReadBytes (
> +  IN UINTN Size,
> +  IN VOID  *Buffer OPTIONAL
> +  )
> +{
> +  UINTN Left;
> +  UINT8 *Ptr;
> +  UINT8 *End;
> +
> +#ifdef MDE_CPU_AARCH64
> +  Left = Size & 7;
> +#else
> +  Left = Size & 3;
> +#endif
> +
> +  Size -= Left;
> +  Ptr = Buffer;
> +  End = Ptr + Size;
> +
> +#ifdef MDE_CPU_AARCH64
> +  while (Ptr < End) {
> +    *(UINT64 *)Ptr = MmioRead64 (mFwCfgDataAddress);
> +    Ptr += 8;
> +  }
> +  if (Left & 4) {
> +    *(UINT32 *)Ptr = MmioRead32 (mFwCfgDataAddress);
> +    Ptr += 4;
> +  }
> +#else
> +  while (Ptr < End) {
> +    *(UINT32 *)Ptr = MmioRead32 (mFwCfgDataAddress);
> +    Ptr += 4;
> +  }
> +#endif
> +
> +  if (Left & 2) {
> +    *(UINT16 *)Ptr = MmioRead16 (mFwCfgDataAddress);
> +    Ptr += 2;
> +  }
> +  if (Left & 1) {
> +    *Ptr = MmioRead8 (mFwCfgDataAddress);
> +  }
> +}
> +
> +
> +/**
> +  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 ()) {
> +    UINTN Idx;
> +
> +    for (Idx = 0; Idx < Size; ++Idx) {
> +      MmioWrite8 (mFwCfgDataAddress, ((UINT8 *)Buffer)[Idx]);
> +    }
> +  }
> +}
> +
> +
> +/**
> +  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.
> +
> +  @retval RETURN_SUCCESS      If file is found.
> +  @retval RETURN_NOT_FOUND    If file is not found.
> +  @retval 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  FName[QEMU_FW_CFG_FNAME_SIZE];
> +
> +    FileSize   = QemuFwCfgRead32 ();
> +    FileSelect = QemuFwCfgRead16 ();
> +    QemuFwCfgRead16 (); // skip the field called "reserved"
> +    InternalQemuFwCfgReadBytes (sizeof (FName), FName);
> +
> +    if (AsciiStrCmp (Name, FName) == 0) {
> +      *Item = SwapBytes16 (FileSelect);
> +      *Size = SwapBytes32 (FileSize);
> +      return RETURN_SUCCESS;
> +    }
> +  }
> +
> +  return RETURN_NOT_FOUND;
> +}
> +
> +
> +/**
> +  Determine if S3 support is explicitly enabled.
> +
> +  @retval TRUE   if S3 support is explicitly enabled.
> +          FALSE  otherwise. This includes unavailability of the
> firmware
> +                 configuration interface.
> +**/
> +BOOLEAN
> +EFIAPI
> +QemuFwCfgS3Enabled (
> +  VOID
> +  )
> +{
> +  return FALSE;
> +}
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
> b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
> index 1f3ddea..60f7d7f 100644
> --- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
> @@ -42,6 +42,7 @@
>    # Virtio Support
>    VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
> 
> VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevic
> eLib.inf
> +
> QemuFwCfgLib|ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/Q
> emuFwCfgLib.inf
> 
> 
> ArmPlatformLib|ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualiz
> ationPlatformLib/ArmVirtualizationPlatformLib.inf
> 
> ArmPlatformSysConfigLib|ArmPlatformPkg/Library/ArmPlatformSysConfigLibN
> ull/ArmPlatformSysConfigLibNull.inf
> --
> 1.8.3.1
> 
> 
> 
> -----------------------------------------------------------------------
> -------
> Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
> from Actuate! Instantly Supercharge Your Business Reports and
> Dashboards
> with Interactivity, Sharing, Native Excel Exports, App Integration &
> more
> Get technology previously reserved for billion-dollar corporations,
> FREE
> http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.c
> lktrk
> _______________________________________________
> edk2-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/edk2-devel





------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to