diff options
-rw-r--r-- | OvmfPkg/Include/Library/QemuFwCfgLib.h | 20 | ||||
-rw-r--r-- | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCache.c | 176 | ||||
-rw-r--r-- | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCacheInit.c | 262 | ||||
-rw-r--r-- | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h | 107 |
4 files changed, 565 insertions, 0 deletions
diff --git a/OvmfPkg/Include/Library/QemuFwCfgLib.h b/OvmfPkg/Include/Library/QemuFwCfgLib.h index 2ad96c0297..73f4503263 100644 --- a/OvmfPkg/Include/Library/QemuFwCfgLib.h +++ b/OvmfPkg/Include/Library/QemuFwCfgLib.h @@ -12,6 +12,7 @@ #define __FW_CFG_LIB__
#include <IndustryStandard/QemuFwCfg.h>
+#include <Library/PlatformInitLib.h>
/**
Returns a boolean indicating if the firmware configuration interface
@@ -164,4 +165,23 @@ QemuFwCfgFindFile ( OUT UINTN *Size
);
+/**
+ OVMF reads configuration data from QEMU via fw_cfg.
+ For Td-Guest VMM is out of TCB and the configuration data is untrusted.
+ From the security perpective the configuration data shall be measured
+ before it is consumed.
+ This function reads the fw_cfg items and cached them. In the meanwhile these
+ fw_cfg items are measured as well. This is to avoid changing the order when
+ reading the fw_cfg process, which depends on multiple factors(depex, order in
+ the Firmware volume).
+
+ @retval RETURN_SUCCESS - Successfully cache with measurement
+ @retval Others - As the error code indicates
+ */
+RETURN_STATUS
+EFIAPI
+QemuFwCfgInitCache (
+ IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
+ );
+
#endif
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCache.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCache.c new file mode 100644 index 0000000000..f15ae7a6ec --- /dev/null +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCache.c @@ -0,0 +1,176 @@ +/** @file
+ QemuFwCfg cached feature related functions.
+ Copyright (c) 2025, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include "QemuFwCfgLibInternal.h"
+
+/**
+ Get the pointer to the cached fw_cfg item.
+ @param[in] Item The fw_cfg item to be retrieved.
+ @retval FW_CFG_CACHED_ITEM Pointer to the cached fw_cfg item.
+ @retval NULL The fw_cfg item is not cached.
+**/
+FW_CFG_CACHED_ITEM *
+InternalQemuFwCfgItemCached (
+ IN FIRMWARE_CONFIG_ITEM Item
+ )
+{
+ BOOLEAN Cached;
+ FW_CFG_CACHED_ITEM *CachedItem;
+ UINT16 SelectItem;
+ EFI_PEI_HOB_POINTERS Hob;
+ FW_CFG_CACHED_ITEM *FwCfgCachedItem;
+
+ #ifdef TDX_PEI_LESS_BOOT
+ if (InternalQemuFwCfgCheckOvmfWorkArea () == FALSE) {
+ return NULL;
+ }
+
+ #endif
+
+ SelectItem = (UINT16)(UINTN)Item;
+
+ Hob.Raw = GetFirstGuidHob (&gOvmfFwCfgInfoHobGuid);
+ Cached = FALSE;
+ CachedItem = NULL;
+
+ while (Hob.Raw != NULL) {
+ FwCfgCachedItem = GET_GUID_HOB_DATA (Hob);
+ if ((SelectItem == FwCfgCachedItem->FwCfgItem) && (FwCfgCachedItem->DataSize != 0)) {
+ Cached = TRUE;
+ CachedItem = FwCfgCachedItem;
+ break;
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextGuidHob (&gOvmfFwCfgInfoHobGuid, Hob.Raw);
+ }
+
+ return Cached ? CachedItem : NULL;
+}
+
+/**
+ Clear the QEMU_FW_CFG_CACHE_WORK_AREA.
+**/
+VOID
+InternalQemuFwCfgCacheResetWorkArea (
+ VOID
+ )
+{
+ QEMU_FW_CFG_CACHE_WORK_AREA *QemuFwCfgCacheWorkArea;
+
+ QemuFwCfgCacheWorkArea = InternalQemuFwCfgCacheGetWorkArea ();
+ if (QemuFwCfgCacheWorkArea != NULL) {
+ QemuFwCfgCacheWorkArea->FwCfgItem = 0;
+ QemuFwCfgCacheWorkArea->Offset = 0;
+ QemuFwCfgCacheWorkArea->Reading = FALSE;
+ }
+}
+
+/**
+ Check if reading from FwCfgCache is ongoing.
+ @retval TRUE Reading from FwCfgCache is ongoing.
+ @retval FALSE Reading from FwCfgCache is not ongoing.
+**/
+BOOLEAN
+InternalQemuFwCfgCacheReading (
+ VOID
+ )
+{
+ BOOLEAN Reading;
+ QEMU_FW_CFG_CACHE_WORK_AREA *QemuFwCfgCacheWorkArea;
+
+ Reading = FALSE;
+ QemuFwCfgCacheWorkArea = InternalQemuFwCfgCacheGetWorkArea ();
+ if (QemuFwCfgCacheWorkArea != NULL) {
+ Reading = QemuFwCfgCacheWorkArea->Reading;
+ }
+
+ return Reading;
+}
+
+BOOLEAN
+InternalQemuFwCfgCacheSelectItem (
+ IN FIRMWARE_CONFIG_ITEM Item
+ )
+{
+ QEMU_FW_CFG_CACHE_WORK_AREA *QemuFwCfgCacheWorkArea;
+
+ // Walk thru cached fw_items to see if Item is cached.
+ if (InternalQemuFwCfgItemCached (Item) == NULL) {
+ return FALSE;
+ }
+
+ QemuFwCfgCacheWorkArea = InternalQemuFwCfgCacheGetWorkArea ();
+ if (QemuFwCfgCacheWorkArea == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Invalid FwCfg Cache Work Area\n", __func__));
+ return FALSE;
+ }
+
+ QemuFwCfgCacheWorkArea->FwCfgItem = (UINT16)Item;
+ QemuFwCfgCacheWorkArea->Offset = 0;
+ QemuFwCfgCacheWorkArea->Reading = TRUE;
+
+ return TRUE;
+}
+
+/**
+ Read the fw_cfg data from Cache.
+ @param[in] Size Data size to be read
+ @param[in] Buffer Pointer to the buffer to which data is written
+ @retval EFI_SUCCESS - Successfully
+ @retval Others - As the error code indicates
+**/
+EFI_STATUS
+InternalQemuFwCfgCacheReadBytes (
+ IN UINTN Size,
+ IN OUT VOID *Buffer
+ )
+{
+ QEMU_FW_CFG_CACHE_WORK_AREA *QemuFwCfgCacheWorkArea;
+ FW_CFG_CACHED_ITEM *CachedItem;
+ UINTN ReadSize;
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ QemuFwCfgCacheWorkArea = InternalQemuFwCfgCacheGetWorkArea ();
+ if (QemuFwCfgCacheWorkArea == NULL) {
+ return RETURN_NOT_FOUND;
+ }
+
+ if (!QemuFwCfgCacheWorkArea->Reading) {
+ return RETURN_NOT_READY;
+ }
+
+ CachedItem = InternalQemuFwCfgItemCached (QemuFwCfgCacheWorkArea->FwCfgItem);
+ if (CachedItem == NULL) {
+ return RETURN_NOT_FOUND;
+ }
+
+ if (QemuFwCfgCacheWorkArea->Offset >= CachedItem->DataSize) {
+ DEBUG ((DEBUG_ERROR, "%a: Invalid Item Offset(0x%x) in FwCfg Cache\n", __func__, QemuFwCfgCacheWorkArea->Offset));
+ ASSERT (FALSE);
+ return RETURN_ABORTED;
+ }
+
+ if (CachedItem->DataSize - QemuFwCfgCacheWorkArea->Offset > Size) {
+ ReadSize = Size;
+ } else {
+ ReadSize = CachedItem->DataSize - QemuFwCfgCacheWorkArea->Offset;
+ }
+
+ CopyMem (Buffer, (UINT8 *)CachedItem + sizeof (FW_CFG_CACHED_ITEM) + QemuFwCfgCacheWorkArea->Offset, ReadSize);
+ QemuFwCfgCacheWorkArea->Offset += (UINT32)ReadSize;
+
+ DEBUG ((DEBUG_VERBOSE, "%a: found Item 0x%x in FwCfg Cache\n", __func__, QemuFwCfgCacheWorkArea->FwCfgItem));
+ return RETURN_SUCCESS;
+}
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCacheInit.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCacheInit.c new file mode 100644 index 0000000000..25fd1f10d7 --- /dev/null +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCacheInit.c @@ -0,0 +1,262 @@ +/** @file
+ QemuFwCfg cached feature related functions.
+ Copyright (c) 2025, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include "QemuFwCfgLibInternal.h"
+#include <Library/TdxHelperLib.h>
+#include <Library/PrintLib.h>
+#include <Library/TpmMeasurementLib.h>
+#include <IndustryStandard/UefiTcgPlatform.h>
+
+#define EV_POSTCODE_INFO_QEMU_FW_CFG_DATA "QEMU FW CFG"
+#define QEMU_FW_CFG_SIZE sizeof (EV_POSTCODE_INFO_QEMU_FW_CFG_DATA)
+
+#pragma pack(1)
+typedef struct {
+ CHAR8 FileName[QEMU_FW_CFG_FNAME_SIZE];
+ BOOLEAN NeedMeasure;
+ UINT16 FwCfgItem;
+ UINT32 FwCfgSize;
+} CACHE_FW_CFG_STRCUT;
+
+typedef struct {
+ UINT8 FwCfg[QEMU_FW_CFG_SIZE];
+ UINT8 FwCfgFileName[QEMU_FW_CFG_FNAME_SIZE];
+} FW_CFG_EVENT;
+
+#pragma pack()
+
+#define QEMU_FW_CFG_SIGNATURE \
+ "QemuFwCfgSignature"
+
+#define QEMU_FW_CFG_SIGNATURE_SIZE sizeof (UINT32)
+
+#define QEMU_FW_CFG_INTERFACE_VERSION \
+ "QemuFwCfgInterfaceVersion"
+
+#define QEMU_FW_CFG_INTERFACE_VERSION_SIZE sizeof (UINT32)
+
+#define QEMU_FW_CFG_FILE_DIR \
+ "QemuFwCfgFileDri"
+
+#define E820_FWCFG_FILE \
+ "etc/e820"
+
+#define SYSTEM_STATES_FWCFG_FILE \
+ "etc/system-states"
+
+#define EXTRA_PCI_ROOTS_FWCFG_FILE \
+ "etc/extra-pci-roots"
+
+#define EXTRA_PCI_ROOTS_FWCFG_SIZE sizeof (UINT64)
+
+#define BOOT_MENU_FWCFG_NAME "BootMenu"
+
+#define BOOT_MENU_FWCFG_SIZE sizeof (UINT16)
+
+#define BOOT_MENU_WAIT_TIME_FWCFG_FILE \
+ "etc/boot-menu-wait"
+
+#define BOOT_MENU_WAIT_TIME_FWCFG_SIZE sizeof (UINT16)
+
+#define RESERVED_MEMORY_END_FWCFG_FILE \
+ "etc/reserved-memory-end"
+
+#define RESERVED_MEMORY_END_FWCFG_SIZE sizeof (UINT64)
+
+#define PCI_MMIO64_FWCFG_FILE \
+ "opt/ovmf/X-PciMmio64Mb"
+
+#define BOOTORDER_FWCFG_FILE \
+ "bootorder"
+
+#define INVALID_FW_CFG_ITEM 0xFFFF
+
+STATIC CONST CACHE_FW_CFG_STRCUT mCacheFwCfgList[] = {
+ { QEMU_FW_CFG_SIGNATURE, FALSE, QemuFwCfgItemSignature, QEMU_FW_CFG_SIGNATURE_SIZE },
+ { QEMU_FW_CFG_INTERFACE_VERSION, FALSE, QemuFwCfgItemInterfaceVersion, QEMU_FW_CFG_INTERFACE_VERSION_SIZE },
+ { QEMU_FW_CFG_FILE_DIR, FALSE, QemuFwCfgItemFileDir, 0 },
+ { E820_FWCFG_FILE, FALSE, INVALID_FW_CFG_ITEM, 0 },
+ { SYSTEM_STATES_FWCFG_FILE, FALSE, INVALID_FW_CFG_ITEM, 0 },
+ { EXTRA_PCI_ROOTS_FWCFG_FILE, TRUE, INVALID_FW_CFG_ITEM, EXTRA_PCI_ROOTS_FWCFG_SIZE },
+ { BOOT_MENU_FWCFG_NAME, TRUE, QemuFwCfgItemBootMenu, BOOT_MENU_FWCFG_SIZE },
+ { BOOT_MENU_WAIT_TIME_FWCFG_FILE, TRUE, INVALID_FW_CFG_ITEM, BOOT_MENU_WAIT_TIME_FWCFG_SIZE },
+ { RESERVED_MEMORY_END_FWCFG_FILE, TRUE, INVALID_FW_CFG_ITEM, RESERVED_MEMORY_END_FWCFG_SIZE },
+ { PCI_MMIO64_FWCFG_FILE, TRUE, INVALID_FW_CFG_ITEM, 0 },
+ { BOOTORDER_FWCFG_FILE, TRUE, INVALID_FW_CFG_ITEM, 0 },
+};
+
+#define CACHE_FW_CFG_COUNT sizeof (mCacheFwCfgList)/sizeof (mCacheFwCfgList[0])
+
+STATIC
+UINT32
+CalcuateQemuFwCfgFileDirSize (
+ IN FIRMWARE_CONFIG_ITEM FwCfgItem
+ )
+{
+ UINT32 FileCount;
+ UINT32 FileDirSize;
+
+ QemuFwCfgSelectItem (FwCfgItem);
+ FileCount = SwapBytes32 (QemuFwCfgRead32 ());
+ FileDirSize = FileCount * sizeof (FWCFG_FILE) + sizeof (UINT32);
+ return FileDirSize;
+}
+
+STATIC
+EFI_STATUS
+ConstructCacheFwCfgList (
+ IN OUT CACHE_FW_CFG_STRCUT *CacheFwCfgList
+ )
+{
+ UINT32 Index;
+ UINT32 Count;
+ UINTN FwCfgSize;
+ FIRMWARE_CONFIG_ITEM FwCfgItem;
+
+ if (CacheFwCfgList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CopyMem (CacheFwCfgList, mCacheFwCfgList, sizeof (mCacheFwCfgList));
+ Count = CACHE_FW_CFG_COUNT;
+
+ for (Index = 0; Index < Count; Index++) {
+ if (CacheFwCfgList[Index].FwCfgItem == QemuFwCfgItemFileDir) {
+ CacheFwCfgList[Index].FwCfgSize = CalcuateQemuFwCfgFileDirSize (QemuFwCfgItemFileDir);
+ continue;
+ }
+
+ if (CacheFwCfgList[Index].FwCfgItem != INVALID_FW_CFG_ITEM) {
+ continue;
+ }
+
+ if (EFI_ERROR (QemuFwCfgFindFile (CacheFwCfgList[Index].FileName, &FwCfgItem, &FwCfgSize))) {
+ continue;
+ }
+
+ if (FwCfgSize == 0) {
+ continue;
+ }
+
+ if ((CacheFwCfgList[Index].FwCfgSize != 0) && (FwCfgSize != CacheFwCfgList[Index].FwCfgSize)) {
+ continue;
+ }
+
+ CacheFwCfgList[Index].FwCfgItem = (UINT16)FwCfgItem;
+ CacheFwCfgList[Index].FwCfgSize = (UINT32)FwCfgSize;
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+CacheFwCfgInfoWithOptionalMeasurment (
+ IN CACHE_FW_CFG_STRCUT *CacheFwCfgList
+ )
+{
+ UINT32 Index;
+ UINT32 Count;
+ UINT8 *FwCfginfoHobData;
+ FW_CFG_CACHED_ITEM *CachedItem;
+ UINT8 *ItemData;
+ UINT32 FwCfgItemHobSize;
+
+ Count = CACHE_FW_CFG_COUNT;
+
+ for (Index = 0; Index < Count; Index++) {
+ if ((CacheFwCfgList[Index].FwCfgItem == INVALID_FW_CFG_ITEM) || (CacheFwCfgList[Index].FwCfgSize == 0)) {
+ continue;
+ }
+
+ FwCfginfoHobData = NULL;
+ FwCfgItemHobSize = sizeof (FW_CFG_CACHED_ITEM) + CacheFwCfgList[Index].FwCfgSize;
+ FwCfginfoHobData = BuildGuidHob (&gOvmfFwCfgInfoHobGuid, FwCfgItemHobSize);
+ if (FwCfginfoHobData == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: BuildGuidHob Failed with FwCfgItemHobSize(0x%x)\n", __func__, FwCfgItemHobSize));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (FwCfginfoHobData, FwCfgItemHobSize);
+ CachedItem = (FW_CFG_CACHED_ITEM *)FwCfginfoHobData;
+ ItemData = (UINT8 *)CachedItem + sizeof (FW_CFG_CACHED_ITEM);
+
+ QemuFwCfgSelectItem (CacheFwCfgList[Index].FwCfgItem);
+ QemuFwCfgReadBytes (CacheFwCfgList[Index].FwCfgSize, ItemData);
+
+ CachedItem->FwCfgItem = CacheFwCfgList[Index].FwCfgItem;
+ CachedItem->DataSize = CacheFwCfgList[Index].FwCfgSize;
+ DEBUG ((
+ DEBUG_INFO,
+ "Cache FwCfg Name: %a Item:0x%x Size: 0x%x \n",
+ CacheFwCfgList[Index].FileName,
+ CachedItem->FwCfgItem,
+ CachedItem->DataSize
+ ));
+
+ if (CacheFwCfgList[Index].NeedMeasure == FALSE) {
+ continue;
+ }
+
+ if (TdIsEnabled ()) {
+ FW_CFG_EVENT FwCfgEvent;
+ EFI_STATUS Status;
+
+ ZeroMem (&FwCfgEvent, sizeof (FW_CFG_EVENT));
+ CopyMem (&FwCfgEvent.FwCfg, EV_POSTCODE_INFO_QEMU_FW_CFG_DATA, sizeof (EV_POSTCODE_INFO_QEMU_FW_CFG_DATA));
+ CopyMem (&FwCfgEvent.FwCfgFileName, CacheFwCfgList[Index].FileName, QEMU_FW_CFG_FNAME_SIZE);
+
+ Status = TpmMeasureAndLogData (
+ 1,
+ EV_PLATFORM_CONFIG_FLAGS,
+ (VOID *)&FwCfgEvent,
+ sizeof (FwCfgEvent),
+ (VOID *)ItemData,
+ CacheFwCfgList[Index].FwCfgSize
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "TpmMeasureAndLogData failed with %r\n", Status));
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InternalQemuFwCfgInitCache (
+ IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
+ )
+{
+ if (PlatformInfoHob == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PlatformInfoHob->QemuFwCfgCacheWorkArea.FwCfgItem = INVALID_FW_CFG_ITEM;
+ PlatformInfoHob->QemuFwCfgCacheWorkArea.Offset = 0;
+ PlatformInfoHob->QemuFwCfgCacheWorkArea.Reading = FALSE;
+
+ if (!QemuFwCfgIsAvailable ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CACHE_FW_CFG_STRCUT CacheFwCfgList[CACHE_FW_CFG_COUNT];
+
+ if (EFI_ERROR (ConstructCacheFwCfgList (CacheFwCfgList))) {
+ return EFI_ABORTED;
+ }
+
+ if (EFI_ERROR (CacheFwCfgInfoWithOptionalMeasurment (CacheFwCfgList))) {
+ return EFI_ABORTED;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h index 6f7beb6ac1..acbaf0017d 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h @@ -11,6 +11,31 @@ #ifndef __QEMU_FW_CFG_LIB_INTERNAL_H__
#define __QEMU_FW_CFG_LIB_INTERNAL_H__
+#include <Base.h>
+#include <Uefi/UefiMultiPhase.h>
+#include <Uefi/UefiBaseType.h>
+#include <Pi/PiBootMode.h>
+#include <Pi/PiHob.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#pragma pack(1)
+typedef struct {
+ UINT16 FwCfgItem;
+ UINT32 DataSize;
+ // UINT8 *data
+} FW_CFG_CACHED_ITEM;
+
+// Refer to https://www.qemu.org/docs/master/specs/fw_cfg.html
+// The FwCfg File item struct in QemuFwCfgItemFileDir
+typedef struct {
+ UINT32 Size; /* size of referenced fw_cfg item, big-endian */
+ UINT16 Select; /* selector key of fw_cfg item, big-endian */
+ UINT16 Reserved;
+ UINT8 Name[QEMU_FW_CFG_FNAME_SIZE];
+} FWCFG_FILE;
+#pragma pack()
+
/**
Returns a boolean indicating if the firmware configuration interface is
available for library-internal purposes.
@@ -70,4 +95,86 @@ QemuFwCfgIsTdxGuest ( VOID
);
+/**
+ Check if the Ovmf work area is built as HobList before invoking Hob services.
+
+ @retval TRUE Ovmf work area is not NULL and it is built as HobList.
+ @retval FALSE Ovmf work area is NULL or it is not built as HobList.
+**/
+BOOLEAN
+InternalQemuFwCfgCheckOvmfWorkArea (
+ VOID
+ );
+
+/**
+ Read the fw_cfg data from Cache.
+ @retval EFI_SUCCESS - Successfully
+ @retval Others - As the error code indicates
+**/
+EFI_STATUS
+InternalQemuFwCfgCacheReadBytes (
+ IN UINTN Size,
+ IN OUT VOID *Buffer
+ );
+
+/**
+ Select the fw_cfg item for reading from cache. If the fw_cfg item
+ is not cached, then it returns FALSE.
+ @param[in] Item The fw_cfg item to be selected
+ @retval TRUE The fw_cfg item is selected.
+ @retval FALSE The fw_cfg item is not selected.
+**/
+BOOLEAN
+InternalQemuFwCfgCacheSelectItem (
+ IN FIRMWARE_CONFIG_ITEM Item
+ );
+
+/**
+ Get the pointer to the QEMU_FW_CFG_CACHE_WORK_AREA. This data is used as the
+ workarea to record the ongoing fw_cfg item and offset.
+ @retval QEMU_FW_CFG_CACHE_WORK_AREA Pointer to the QEMU_FW_CFG_CACHE_WORK_AREA
+ @retval NULL QEMU_FW_CFG_CACHE_WORK_AREA doesn't exist
+**/
+QEMU_FW_CFG_CACHE_WORK_AREA *
+InternalQemuFwCfgCacheGetWorkArea (
+ VOID
+ );
+
+/**
+ Clear the QEMU_FW_CFG_CACHE_WORK_AREA.
+**/
+VOID
+InternalQemuFwCfgCacheResetWorkArea (
+ VOID
+ );
+
+/**
+ Get the pointer to the cached fw_cfg item.
+ @param[in] Item The fw_cfg item to be retrieved.
+ @retval FW_CFG_CACHED_ITEM Pointer to the cached fw_cfg item.
+ @retval NULL The fw_cfg item is not cached.
+**/
+FW_CFG_CACHED_ITEM *
+InternalQemuFwCfgItemCached (
+ IN FIRMWARE_CONFIG_ITEM Item
+ );
+
+/**
+ Check if reading from FwCfgCache is ongoing.
+ @retval TRUE Reading from FwCfgCache is ongoing.
+ @retval FALSE Reading from FwCfgCache is not ongoing.
+**/
+BOOLEAN
+InternalQemuFwCfgCacheReading (
+ VOID
+ );
+
+/**
+ init the fw_cfg info hob with optional measurement
+**/
+EFI_STATUS
+InternalQemuFwCfgInitCache (
+ IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
+ );
+
#endif
|