audk/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c

89 lines
2.2 KiB
C
Raw Normal View History

Ovmf/HardwareInfoLib: Create Pei lib to parse directly from fw-cfg Define the HardwareInfoLib API and create the PeiHardwareInfoLib which implements it, specifically for Pei usage, supporting only static accesses to parse data directly from a fw-cfg file. All list-like APIs are implemented as unsupported and only a fw-cfg wrapper to read hardware info elements is provided. 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> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Nicolas Ojeda Leon <ncoleon@amazon.com>
2022-01-19 10:49:15 +01:00
/*/@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 - 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/DebugLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/HardwareInfoLib.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.Size > MAX_UINTN) || (((UINT64)*ReadIndex + Header.Size) > TotalFileSize)) {
*ReadIndex = TotalFileSize;
return EFI_ABORTED;
}
if ((Header.Type.Value == Type) && (Header.Size <= TypeSize)) {
QemuFwCfgReadBytes ((UINTN)Header.Size, Data);
*ReadIndex += (UINTN)Header.Size;
UpdateDataSize (DataSize, (UINTN)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 ((UINTN)Header.Size);
*ReadIndex += (UINTN)Header.Size;
}
return EFI_END_OF_FILE;
}