This is similar to the initialization in
OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.c.
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
---
OvmfPkg/PlatformPei/PlatformPei.inf | 1 +
OvmfPkg/PlatformPei/Vars.c | 161 ++++++++++++++++++++++++++++++++++++
2 files changed, 162 insertions(+)
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 0eaf27e553..7a7f5c23b0 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -50,6 +50,7 @@
[LibraryClasses]
BaseLib
+ BaseMemoryLib
DebugLib
HobLib
IoLib
diff --git a/OvmfPkg/PlatformPei/Vars.c b/OvmfPkg/PlatformPei/Vars.c
index 563f847a55..452b06e399 100644
--- a/OvmfPkg/PlatformPei/Vars.c
+++ b/OvmfPkg/PlatformPei/Vars.c
@@ -15,18 +15,172 @@
**/
#include <PiPei.h>
+#include <Guid/VariableFormat.h>
+#include <Guid/SystemNvDataGuid.h>
#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include "Platform.h"
+typedef struct {
+
+ EFI_FIRMWARE_VOLUME_HEADER FvHdr;
+ EFI_FV_BLOCK_MAP_ENTRY EndBlockMap;
+ VARIABLE_STORE_HEADER VarHdr;
+
+} FVB_FV_HDR_AND_VARS_TEMPLATE;
+
#define OVMF_FVB_BLOCK_SIZE (FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize))
#define OVMF_FVB_SIZE (2 * FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize))
#define OVMF_FV_HEADER_LENGTH OFFSET_OF (FVB_FV_HDR_AND_VARS_TEMPLATE, VarHdr)
+/**
+ Check the integrity of firmware volume header.
+
+ @param[in] FwVolHeader - A pointer to a firmware volume header
+
+ @retval EFI_SUCCESS - The firmware volume is consistent
+ @retval EFI_NOT_FOUND - The firmware volume has been corrupted.
+
+**/
+STATIC EFI_STATUS
+ValidateFvHeader (
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
+ )
+{
+ UINT16 Checksum;
+
+ //
+ // Verify the header revision, header signature, length
+ // Length of FvBlock cannot be 2**64-1
+ // HeaderLength cannot be an odd number
+ //
+ if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||
+ (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
+ (FwVolHeader->FvLength != OVMF_FVB_SIZE) ||
+ (FwVolHeader->HeaderLength != OVMF_FV_HEADER_LENGTH)
+ ) {
+ DEBUG ((EFI_D_INFO, "EMU Variable FVB: Basic FV headers were invalid\n"));
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Verify the header checksum
+ //
+ Checksum = CalculateSum16((VOID*) FwVolHeader, FwVolHeader->HeaderLength);
+
+ if (Checksum != 0) {
+ DEBUG ((EFI_D_INFO, "EMU Variable FVB: FV checksum was invalid\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Initializes the FV Header and Variable Store Header
+ to support variable operations.
+
+ @param[in] Ptr - Location to initialize the headers
+
+**/
+STATIC VOID
+InitializeFvAndVariableStoreHeaders (
+ IN VOID *Ptr
+ )
+{
+ //
+ // Templates for authenticated variable FV header
+ //
+ STATIC FVB_FV_HDR_AND_VARS_TEMPLATE FvAndAuthenticatedVarTemplate = {
+ { // EFI_FIRMWARE_VOLUME_HEADER FvHdr;
+ // UINT8 ZeroVector[16];
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ // EFI_GUID FileSystemGuid;
+ EFI_SYSTEM_NV_DATA_FV_GUID,
+
+ // UINT64 FvLength;
+ OVMF_FVB_SIZE,
+
+ // UINT32 Signature;
+ EFI_FVH_SIGNATURE,
+
+ // EFI_FVB_ATTRIBUTES_2 Attributes;
+ 0x4feff,
+
+ // UINT16 HeaderLength;
+ OVMF_FV_HEADER_LENGTH,
+
+ // UINT16 Checksum;
+ 0,
+
+ // UINT16 ExtHeaderOffset;
+ 0,
+
+ // UINT8 Reserved[1];
+ {0},
+
+ // UINT8 Revision;
+ EFI_FVH_REVISION,
+
+ // EFI_FV_BLOCK_MAP_ENTRY BlockMap[1];
+ {
+ {
+ 2, // UINT32 NumBlocks;
+ OVMF_FVB_BLOCK_SIZE // UINT32 Length;
+ }
+ }
+ },
+ // EFI_FV_BLOCK_MAP_ENTRY EndBlockMap;
+ { 0, 0 }, // End of block map
+ { // VARIABLE_STORE_HEADER VarHdr;
+ // EFI_GUID Signature; // need authenticated variables for secure boot
+ EFI_AUTHENTICATED_VARIABLE_GUID,
+
+ // UINT32 Size;
+ (
+ FixedPcdGet32 (PcdVariableStoreSize) -
+ OFFSET_OF (FVB_FV_HDR_AND_VARS_TEMPLATE, VarHdr)
+ ),
+
+ // UINT8 Format;
+ VARIABLE_STORE_FORMATTED,
+
+ // UINT8 State;
+ VARIABLE_STORE_HEALTHY,
+
+ // UINT16 Reserved;
+ 0,
+
+ // UINT32 Reserved1;
+ 0
+ }
+ };
+
+ EFI_FIRMWARE_VOLUME_HEADER *Fv;
+
+ //
+ // Copy the template structure into the location
+ //
+ CopyMem (
+ Ptr,
+ (VOID*) &FvAndAuthenticatedVarTemplate,
+ sizeof (FvAndAuthenticatedVarTemplate)
+ );
+
+ //
+ // Update the checksum for the FV header
+ //
+ Fv = (EFI_FIRMWARE_VOLUME_HEADER*) Ptr;
+ Fv->Checksum = CalculateCheckSum16 (Ptr, Fv->HeaderLength);
+}
+
+
VOID
ReserveEmuVariableNvStore (
)
@@ -57,6 +211,13 @@ ReserveEmuVariableNvStore (
PcdStatus = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore);
ASSERT_RETURN_ERROR (PcdStatus);
+ VOID *Ptr = (VOID*)(UINTN) VariableStore;
+
+ if (EFI_ERROR (ValidateFvHeader (Ptr))) {
+ SetMem (Ptr, OVMF_FVB_SIZE, 0xff);
+ InitializeFvAndVariableStoreHeaders (Ptr);
+ }
+
//
// Initialize the main FV header and variable store header
//
--
2.11.0
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel