summaryrefslogtreecommitdiffstats
path: root/UefiPayloadPkg/FvbRuntimeDxe/FvbInfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'UefiPayloadPkg/FvbRuntimeDxe/FvbInfo.c')
-rw-r--r--UefiPayloadPkg/FvbRuntimeDxe/FvbInfo.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/UefiPayloadPkg/FvbRuntimeDxe/FvbInfo.c b/UefiPayloadPkg/FvbRuntimeDxe/FvbInfo.c
new file mode 100644
index 0000000000..78b6b81f66
--- /dev/null
+++ b/UefiPayloadPkg/FvbRuntimeDxe/FvbInfo.c
@@ -0,0 +1,151 @@
+/** @file
+
+ Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Guid/SystemNvDataGuid.h>
+#include <Guid/NvVariableInfoGuid.h>
+#include <Library/HobLib.h>
+
+#define FVB_MEDIA_BLOCK_SIZE 0x1000
+
+typedef struct {
+ EFI_FIRMWARE_VOLUME_HEADER FvInfo;
+ EFI_FV_BLOCK_MAP_ENTRY End[1];
+} EFI_FVB2_MEDIA_INFO;
+
+//
+// This data structure contains a template of FV header which is used to restore
+// Fv header if it's corrupted.
+//
+EFI_FVB2_MEDIA_INFO mFvbMediaInfo = {
+ {
+ {0,}, // ZeroVector[16]
+ EFI_SYSTEM_NV_DATA_FV_GUID,
+ 0,
+ EFI_FVH_SIGNATURE,
+ 0x0004feff, // check PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+ 0, // CheckSum which will be calucated dynamically.
+ 0, // ExtHeaderOffset
+ {0,},
+ EFI_FVH_REVISION,
+ {
+ {
+ 0,
+ FVB_MEDIA_BLOCK_SIZE,
+ }
+ }
+ },
+ {
+ {
+ 0,
+ 0
+ }
+ }
+};
+
+/**
+ Initialize the variable store
+
+ @retval EFI_SUCCESS if initialize the store success.
+
+**/
+EFI_STATUS
+InitVariableStore (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 NvStorageBase;
+ UINT32 NvStorageSize;
+ UINT32 NvVariableSize;
+ UINT32 FtwWorkingSize;
+ UINT32 FtwSpareSize;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ NV_VARIABLE_INFO *NvVariableInfo;
+
+ //
+ // Find SPI flash variable hob
+ //
+ GuidHob = GetFirstGuidHob (&gNvVariableInfoGuid);
+ if (GuidHob == NULL) {
+ ASSERT (FALSE);
+ return EFI_NOT_FOUND;
+ }
+ NvVariableInfo = (NV_VARIABLE_INFO *) GET_GUID_HOB_DATA (GuidHob);
+
+ //
+ // Get variable region base and size.
+ //
+ NvStorageSize = NvVariableInfo->VariableStoreSize;
+ NvStorageBase = NvVariableInfo->VariableStoreBase;
+
+ //
+ // NvStorageBase needs to be 4KB aligned, NvStorageSize needs to be 8KB * n
+ //
+ if (((NvStorageBase & (SIZE_4KB - 1)) != 0) || ((NvStorageSize & (SIZE_8KB - 1)) != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FtwSpareSize = NvStorageSize / 2;
+ FtwWorkingSize = 0x2000;
+ NvVariableSize = NvStorageSize / 2 - FtwWorkingSize;
+ DEBUG ((DEBUG_INFO, "NvStorageBase:0x%x, NvStorageSize:0x%x\n", NvStorageBase, NvStorageSize));
+
+ if (NvVariableSize >= 0x80000000) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = PcdSet32S(PcdFlashNvStorageVariableSize, NvVariableSize);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet32S(PcdFlashNvStorageVariableBase, NvStorageBase);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet64S(PcdFlashNvStorageVariableBase64, NvStorageBase);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PcdSet32S(PcdFlashNvStorageFtwWorkingSize, FtwWorkingSize);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet32S(PcdFlashNvStorageFtwWorkingBase, NvStorageBase + NvVariableSize);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PcdSet32S(PcdFlashNvStorageFtwSpareSize, FtwSpareSize);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet32S(PcdFlashNvStorageFtwSpareBase, NvStorageBase + FtwSpareSize);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Get a heathy FV header used for variable store recovery
+
+ @retval The FV header.
+
+**/
+EFI_FIRMWARE_VOLUME_HEADER *
+GetFvHeaderTemplate (
+ VOID
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ UINTN FvSize;
+
+ FvSize = PcdGet32(PcdFlashNvStorageFtwSpareSize) * 2;
+ FvHeader = &mFvbMediaInfo.FvInfo;
+ FvHeader->FvLength = FvSize;
+ FvHeader->BlockMap[0].NumBlocks = (UINT32) (FvSize / FvHeader->BlockMap[0].Length);
+ FvHeader->Checksum = 0;
+ FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength);
+
+ return FvHeader;
+}
+