2021-09-22 23:42:50 +02:00
|
|
|
/** @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>
|
|
|
|
|
2021-12-05 23:54:18 +01:00
|
|
|
#define FVB_MEDIA_BLOCK_SIZE 0x1000
|
2021-09-22 23:42:50 +02:00
|
|
|
|
|
|
|
typedef struct {
|
2021-12-05 23:54:18 +01:00
|
|
|
EFI_FIRMWARE_VOLUME_HEADER FvInfo;
|
|
|
|
EFI_FV_BLOCK_MAP_ENTRY End[1];
|
2021-09-22 23:42:50 +02:00
|
|
|
} EFI_FVB2_MEDIA_INFO;
|
|
|
|
|
|
|
|
//
|
|
|
|
// This data structure contains a template of FV header which is used to restore
|
|
|
|
// Fv header if it's corrupted.
|
|
|
|
//
|
2021-12-05 23:54:18 +01:00
|
|
|
EFI_FVB2_MEDIA_INFO mFvbMediaInfo = {
|
2021-09-22 23:42:50 +02:00
|
|
|
{
|
2021-12-05 23:54:18 +01:00
|
|
|
{ 0, }, // ZeroVector[16]
|
2021-09-22 23:42:50 +02:00
|
|
|
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
|
2021-12-05 23:54:18 +01:00
|
|
|
{ 0, },
|
2021-09-22 23:42:50 +02:00
|
|
|
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
|
|
|
|
)
|
|
|
|
{
|
2021-12-05 23:54:18 +01:00
|
|
|
EFI_STATUS Status;
|
|
|
|
UINT32 NvStorageBase;
|
|
|
|
UINT32 NvStorageSize;
|
|
|
|
UINT32 NvVariableSize;
|
|
|
|
UINT32 FtwWorkingSize;
|
|
|
|
UINT32 FtwSpareSize;
|
|
|
|
EFI_HOB_GUID_TYPE *GuidHob;
|
|
|
|
NV_VARIABLE_INFO *NvVariableInfo;
|
2021-09-22 23:42:50 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// Find SPI flash variable hob
|
|
|
|
//
|
|
|
|
GuidHob = GetFirstGuidHob (&gNvVariableInfoGuid);
|
|
|
|
if (GuidHob == NULL) {
|
|
|
|
ASSERT (FALSE);
|
|
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
2021-12-05 23:54:18 +01:00
|
|
|
|
|
|
|
NvVariableInfo = (NV_VARIABLE_INFO *)GET_GUID_HOB_DATA (GuidHob);
|
2021-09-22 23:42:50 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// 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;
|
|
|
|
}
|
2021-12-05 23:54:18 +01:00
|
|
|
|
|
|
|
Status = PcdSet32S (PcdFlashNvStorageVariableSize, NvVariableSize);
|
2021-09-22 23:42:50 +02:00
|
|
|
ASSERT_EFI_ERROR (Status);
|
2021-12-05 23:54:18 +01:00
|
|
|
Status = PcdSet32S (PcdFlashNvStorageVariableBase, NvStorageBase);
|
2021-09-22 23:42:50 +02:00
|
|
|
ASSERT_EFI_ERROR (Status);
|
2021-12-05 23:54:18 +01:00
|
|
|
Status = PcdSet64S (PcdFlashNvStorageVariableBase64, NvStorageBase);
|
2021-09-22 23:42:50 +02:00
|
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
|
2021-12-05 23:54:18 +01:00
|
|
|
Status = PcdSet32S (PcdFlashNvStorageFtwWorkingSize, FtwWorkingSize);
|
2021-09-22 23:42:50 +02:00
|
|
|
ASSERT_EFI_ERROR (Status);
|
2021-12-05 23:54:18 +01:00
|
|
|
Status = PcdSet32S (PcdFlashNvStorageFtwWorkingBase, NvStorageBase + NvVariableSize);
|
2021-09-22 23:42:50 +02:00
|
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
|
2021-12-05 23:54:18 +01:00
|
|
|
Status = PcdSet32S (PcdFlashNvStorageFtwSpareSize, FtwSpareSize);
|
2021-09-22 23:42:50 +02:00
|
|
|
ASSERT_EFI_ERROR (Status);
|
2021-12-05 23:54:18 +01:00
|
|
|
Status = PcdSet32S (PcdFlashNvStorageFtwSpareBase, NvStorageBase + FtwSpareSize);
|
2021-09-22 23:42:50 +02:00
|
|
|
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
|
|
|
|
)
|
|
|
|
{
|
2021-12-05 23:54:18 +01:00
|
|
|
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
|
|
|
|
UINTN FvSize;
|
2021-09-22 23:42:50 +02:00
|
|
|
|
2021-12-05 23:54:18 +01:00
|
|
|
FvSize = PcdGet32 (PcdFlashNvStorageFtwSpareSize) * 2;
|
2021-09-22 23:42:50 +02:00
|
|
|
FvHeader = &mFvbMediaInfo.FvInfo;
|
|
|
|
FvHeader->FvLength = FvSize;
|
2021-12-05 23:54:18 +01:00
|
|
|
FvHeader->BlockMap[0].NumBlocks = (UINT32)(FvSize / FvHeader->BlockMap[0].Length);
|
|
|
|
FvHeader->Checksum = 0;
|
|
|
|
FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *)FvHeader, FvHeader->HeaderLength);
|
2021-09-22 23:42:50 +02:00
|
|
|
|
|
|
|
return FvHeader;
|
|
|
|
}
|