On 12/16/14 13:18, Olivier Martin wrote:
> Reviewed-By: Olivier Martin <[email protected]>

Thanks. I had to rework the qemu patchset almost from the ground up, and
this patch needs to be updated too. (The fw_cfg registers will be big
endian. Long discussion on qemu-devel.)

Thanks!
Laszlo

> 
>> -----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
> 


------------------------------------------------------------------------------
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