public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Ojeda Leon, Nicolas" <ncoleon@amazon.com>
To: <devel@edk2.groups.io>
Cc: <atugup@amazon.com>, Nicolas Ojeda Leon <ncoleon@amazon.com>,
	Alexander Graf <graf@amazon.de>,
	Gerd Hoffmann <kraxel@redhat.com>
Subject: [PATCH v2 2/8] Ovmf/HardwareInfoLib: Parse data directly from fw-cfg
Date: Thu, 20 Jan 2022 18:10:15 +0100	[thread overview]
Message-ID: <66b045d70f81c8e1a01269a13e55c5b47b7898c5.1642697671.git.ncoleon@amazon.com> (raw)
In-Reply-To: <cover.1642697670.git.ncoleon@amazon.com>

Create QemuFwCfgHardwareInfoLib which extends the base HardwareInfoLib
and provide fw-cfg wrappers to read hardware info elements out of a
fw-cfg file.

The Hardware Info library is intended to describe non-discoverable
hardware information and share that from the host to the guest in Ovmf
platforms. The QEMU fw-cfg extension for this library provides a first
variation to parse hardware info by reading it directly from a fw-cfg
file. This library offers a wrapper function to the plain
QmeuFwCfgReadBytes which, specifically, parses header-data pairs out
of the binary values in the file. For this purpose, the approach is
incremental, reading the file block by block and outputting the values
only for a specific known hardware type (e.g. PCI host bridges). One
element is returned in each call until the end of the file is reached.

Considering fw-cfg as the first means to transport hardware info from
the host to the guest, this wrapping library offers the possibility
to statically, and in steps, read a specific type of hardware info
elements out of the file. This method reads one hardware element of a
specific type at a time, without the need to pre-allocate memory and
read the whole file or dynamically allocate memory for each new
element found.

As a usage example, the static approach followed by this library
enables early UEFI stages to use and read hardware information
supplied by the host. For instance, in early times of the PEI stage,
hardware information can be parsed out from a fw-cfg file prescinding
from memory services, that may not yet be available, and avoiding
dynamic memory allocations.

Cc: Alexander Graf <graf@amazon.de>
Cc: Gerd Hoffmann <kraxel@redhat.com>

Signed-off-by: Nicolas Ojeda Leon <ncoleon@amazon.com>
---
 .../Library/QemuFwCfgHardwareInfoLib.h        | 59 ++++++++++++
 .../QemuFwCfgHardwareInfoLib.c                | 89 +++++++++++++++++++
 .../QemuFwCfgHardwareInfoLib.inf              | 42 +++++++++
 OvmfPkg/OvmfPkgX64.dsc                        |  1 +
 4 files changed, 191 insertions(+)
 create mode 100644 OvmfPkg/Include/Library/QemuFwCfgHardwareInfoLib.h
 create mode 100644 OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c
 create mode 100644 OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.inf

diff --git a/OvmfPkg/Include/Library/QemuFwCfgHardwareInfoLib.h b/OvmfPkg/Include/Library/QemuFwCfgHardwareInfoLib.h
new file mode 100644
index 0000000000..f6c351a4e4
--- /dev/null
+++ b/OvmfPkg/Include/Library/QemuFwCfgHardwareInfoLib.h
@@ -0,0 +1,59 @@
+/*/@file
+  Qemu fw-cfg wrappers for hardware info parsing.
+  Provides an alternative to parse hardware information from a fw-cfg
+  file without relying on dynamic memory allocations.
+
+  Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+  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.
+**/
+
+#ifndef __QEMU_FW_CFG_HARDWARE_INFO_LIB_H__
+#define __QEMU_FW_CFG_HARDWARE_INFO_LIB_H__
+
+#include "../Library/HardwareInfoLib/HardwareInfoTypesLib.h"
+
+/**
+  Read, if available, the next Type element in the FwCfg file.
+  The FwCfg item must already be selected, this is a wrapper around
+  QemuFwCfgReadBytes and the Data pointer should be set to an existent
+  memory location with TypeSize bytes allocated for the date to be
+  properly written. If a Type element is found in the file which has a
+  size (in the header) greater than TypeSize, it is skipped.
+
+  @param[in]    Type             Hardware Info Type to search for
+  @param[in]    TypeSize         Size (in bytes) of the structure intended to
+                                 be used to dereference the data
+  @param[in]    TotalFileSize    Total size (in bytes) of the FwCfg file from
+                                 which the data is read.
+  @param[out]   Data             Pointer to a memory allocated instance into
+                                 which the data is written to.
+  @param[out]   DataSize         Size in bytes of the actually filled
+                                 data available in the Data object after a
+                                 successful operation
+  @param[inout] ReadIndex        Index of the next byte to be read. Incremented
+                                 accordingly after a read operation to reflect
+                                 up to date status
+
+  @retval EFI_SUCCESS             Next element found and read into Data
+  @retval EFI_INVALID_PARAMETER   Operation failed
+  @retval EFI_END_OF_FILE         End of the file reached, no more elements
+                                  to read.
+**/
+EFI_STATUS
+QemuFwCfgReadNextHardwareInfoByType (
+  IN      HARDWARE_INFO_TYPE  Type,
+  IN      UINTN               TypeSize,
+  IN      UINTN               TotalFileSize,
+  OUT     VOID                *Data,
+  OUT     UINTN               *DataSize         OPTIONAL,
+  IN OUT  UINTN               *ReadIndex
+  );
+
+#endif // __QEMU_FW_CFG_HARDWARE_INFO_LIB_H__
diff --git a/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c b/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c
new file mode 100644
index 0000000000..059da546d1
--- /dev/null
+++ b/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c
@@ -0,0 +1,89 @@
+/*/@file
+  Qemu fw-cfg wrappers for hardware info parsing.
+  Provides an alternative to parse hardware information from a fw-cfg
+  file without relying on dynamic memory allocations.
+
+  Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+  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/DebugLib.h>
+#include <Library/QemuFwCfgLib.h>
+
+#include <Library/QemuFwCfgHardwareInfoLib.h>
+
+/**
+  Update an optional pointer value if possible
+
+  @param[out] DataSize     Pointer to variable to be updated
+  @param[in]  Value        Value to set the pointed variable to.
+**/
+STATIC
+VOID
+UpdateDataSize (
+  OUT UINTN  *DataSize,
+  IN  UINTN  Value
+  )
+{
+  if (DataSize == NULL) {
+    return;
+  }
+
+  *DataSize = Value;
+}
+
+EFI_STATUS
+QemuFwCfgReadNextHardwareInfoByType (
+  IN      HARDWARE_INFO_TYPE  Type,
+  IN      UINTN               TypeSize,
+  IN      UINTN               TotalFileSize,
+  OUT     VOID                *Data,
+  OUT     UINTN               *DataSize         OPTIONAL,
+  IN OUT  UINTN               *ReadIndex
+  )
+{
+  HARDWARE_INFO_HEADER  Header;
+
+  if ((Data == NULL) ||
+      (ReadIndex == NULL) ||
+      (TypeSize == 0) ||
+      (Type == HardwareInfoTypeUndefined) ||
+      (TotalFileSize == 0))
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  UpdateDataSize (DataSize, 0);
+
+  while (*ReadIndex < TotalFileSize) {
+    QemuFwCfgReadBytes (sizeof (Header), &Header);
+    *ReadIndex += sizeof (Header);
+
+    if ((Header.Type.Value == Type) && (Header.Size <= TypeSize)) {
+      QemuFwCfgReadBytes (Header.Size, Data);
+
+      *ReadIndex += Header.Size;
+      UpdateDataSize (DataSize, Header.Size);
+
+      return EFI_SUCCESS;
+    }
+
+    //
+    // Skip the bytes corresponding to the next element as it is
+    // not of the expected type and/or size. The TotalFileSize
+    // and individual elements sizes should match so the size
+    // check is skipped.
+    //
+    QemuFwCfgSkipBytes (Header.Size);
+    *ReadIndex += Header.Size;
+  }
+
+  return EFI_END_OF_FILE;
+}
diff --git a/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.inf b/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.inf
new file mode 100644
index 0000000000..0a2eca3c00
--- /dev/null
+++ b/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.inf
@@ -0,0 +1,42 @@
+## @file
+#  Hardware information library wrappers over Qemu fw-cfg functionality to parse,
+#  in a static manner, non-discoverable hardware information.
+#
+#  Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+#  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                      = QemuFwCfgHardwareInfoLib
+  FILE_GUID                      = 3D5011B3-9CBB-4C0B-88E8-1D758283C659
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = QemuFwCfgHardwareInfoLib
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+[Sources]
+  QemuFwCfgHardwareInfoLib.c
+  HardwareInfoPciHostBridgeLib.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  QemuFwCfgLib
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 4589adff38..fb82fd02eb 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -175,6 +175,7 @@
   SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
   UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
   SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
+  QemuFwCfgHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.inf
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
   QemuFwCfgSimpleParserLib|OvmfPkg/Library/QemuFwCfgSimpleParserLib/QemuFwCfgSimpleParserLib.inf
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
-- 
2.17.1




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879




  parent reply	other threads:[~2022-01-20 17:12 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-20 17:10 [PATCH v2 0/8] Handling of multiple PCI host bridges specified Ojeda Leon, Nicolas
2022-01-20 17:10 ` [PATCH v2 1/8] OvmfPkg/Library: Create base HardwareInfoLib for PCI Host Bridges Ojeda Leon, Nicolas
2022-01-21 10:09   ` Gerd Hoffmann
2022-01-20 17:10 ` Ojeda Leon, Nicolas [this message]
2022-01-20 17:10 ` [PATCH v2 3/8] Ovmf/HardwareInfoLib: Add core to parse heterogenous data Ojeda Leon, Nicolas
2022-01-21 10:09   ` Gerd Hoffmann
2022-01-21 10:48     ` [edk2-devel] " Ojeda Leon, Nicolas
2022-01-21 11:03       ` Gerd Hoffmann
2022-01-21 11:10         ` Ojeda Leon, Nicolas
2022-01-20 17:10 ` [PATCH v2 4/8] Ovmf/PlatformPei: Extend 64-bit MMIO range to fit resources Ojeda Leon, Nicolas
2022-01-21  9:57   ` Gerd Hoffmann
2022-01-20 17:10 ` [PATCH v2 5/8] OvmfPkg/PciHostBridgeUtilityLib: Initialize RootBridges apertures with spec Ojeda Leon, Nicolas
2022-01-20 17:10 ` [PATCH v2 6/8] MdeModulePkg, OvmfPkg: Add Pcd token for PCI pre-populated BARs Ojeda Leon, Nicolas
2022-01-20 17:10 ` [PATCH v2 7/8] MdeModulePkg/Pci MdePkg: Create service to retrieve PCI base addresses Ojeda Leon, Nicolas
2022-01-20 17:10 ` [PATCH v2 8/8] MdeModulePkg/PciBusDxe: Handling of pre-populated PCI BARs Ojeda Leon, Nicolas

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=66b045d70f81c8e1a01269a13e55c5b47b7898c5.1642697671.git.ncoleon@amazon.com \
    --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