]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c
Ovmf/HardwareInfoLib: Create Pei lib to parse directly from fw-cfg
[mirror_edk2.git] / OvmfPkg / Library / HardwareInfoLib / QemuFwCfgHardwareInfoLib.c
diff --git a/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c b/OvmfPkg/Library/HardwareInfoLib/QemuFwCfgHardwareInfoLib.c
new file mode 100644 (file)
index 0000000..48d9dcd
--- /dev/null
@@ -0,0 +1,88 @@
+/*/@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