qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [edk2 PATCH 02/12] ArmVirtualizationPkg: introduce QemuFwCf


From: Laszlo Ersek
Subject: [Qemu-devel] [edk2 PATCH 02/12] ArmVirtualizationPkg: introduce QemuFwCfgLib instance for DXE drivers
Date: Fri, 28 Nov 2014 00:19:17 +0100

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),
- 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.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <address@hidden>
---
 ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf |  
52 +++++++++++
 ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c   | 
326 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc             |   
1 +
 3 files changed, 379 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..fbc0dfb
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -0,0 +1,326 @@
+/** @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 Idx;
+
+  for (Idx = 0; Idx < Size; ++Idx) {
+    ((UINT8 *)Buffer)[Idx] = 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/VirtioMmioDeviceLib.inf
+  
QemuFwCfgLib|ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
 
   
ArmPlatformLib|ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
   
ArmPlatformSysConfigLib|ArmPlatformPkg/Library/ArmPlatformSysConfigLibNull/ArmPlatformSysConfigLibNull.inf
-- 
1.8.3.1





reply via email to

[Prev in Thread] Current Thread [Next in Thread]