--- /dev/null
+/*/@file\r
+ Qemu fw-cfg wrappers for hardware info parsing.\r
+ Provides an alternative to parse hardware information from a fw-cfg\r
+ file without relying on dynamic memory allocations.\r
+\r
+ Copyright 2021 - 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/QemuFwCfgLib.h>\r
+\r
+#include <Library/HardwareInfoLib.h>\r
+\r
+/**\r
+ Update an optional pointer value if possible\r
+\r
+ @param[out] DataSize Pointer to variable to be updated\r
+ @param[in] Value Value to set the pointed variable to.\r
+**/\r
+STATIC\r
+VOID\r
+UpdateDataSize (\r
+ OUT UINTN *DataSize,\r
+ IN UINTN Value\r
+ )\r
+{\r
+ if (DataSize == NULL) {\r
+ return;\r
+ }\r
+\r
+ *DataSize = Value;\r
+}\r
+\r
+EFI_STATUS\r
+QemuFwCfgReadNextHardwareInfoByType (\r
+ IN HARDWARE_INFO_TYPE Type,\r
+ IN UINTN TypeSize,\r
+ IN UINTN TotalFileSize,\r
+ OUT VOID *Data,\r
+ OUT UINTN *DataSize OPTIONAL,\r
+ IN OUT UINTN *ReadIndex\r
+ )\r
+{\r
+ HARDWARE_INFO_HEADER Header;\r
+\r
+ if ((Data == NULL) ||\r
+ (ReadIndex == NULL) ||\r
+ (TypeSize == 0) ||\r
+ (Type == HardwareInfoTypeUndefined) ||\r
+ (TotalFileSize == 0))\r
+ {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ UpdateDataSize (DataSize, 0);\r
+\r
+ while (*ReadIndex < TotalFileSize) {\r
+ QemuFwCfgReadBytes (sizeof (Header), &Header);\r
+ *ReadIndex += sizeof (Header);\r
+\r
+ if ((Header.Size > MAX_UINTN) || (((UINT64)*ReadIndex + Header.Size) > TotalFileSize)) {\r
+ *ReadIndex = TotalFileSize;\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ if ((Header.Type.Value == Type) && (Header.Size <= TypeSize)) {\r
+ QemuFwCfgReadBytes ((UINTN)Header.Size, Data);\r
+\r
+ *ReadIndex += (UINTN)Header.Size;\r
+ UpdateDataSize (DataSize, (UINTN)Header.Size);\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Skip the bytes corresponding to the next element as it is\r
+ // not of the expected type and/or size. The TotalFileSize\r
+ // and individual elements sizes should match so the size\r
+ // check is skipped.\r
+ //\r
+ QemuFwCfgSkipBytes ((UINTN)Header.Size);\r
+ *ReadIndex += (UINTN)Header.Size;\r
+ }\r
+\r
+ return EFI_END_OF_FILE;\r
+}\r