summaryrefslogtreecommitdiff
path: root/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c')
-rw-r--r--OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c b/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c
new file mode 100644
index 0000000..48d9dcd
--- /dev/null
+++ b/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c
@@ -0,0 +1,88 @@
+/*/@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;
+}