MdeModulePkg/FaultTolerantWrite: Consume Variable Flash Info

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3479

Adds support to the UEFI variable fault tolerant write (FTW) drivers
to receive FTW base and size information dynamically via the Variable
Flash Information library.

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
This commit is contained in:
Michael Kubacki 2022-04-05 21:40:17 -04:00 committed by mergify[bot]
parent 4dbebc2d10
commit 8db39c60cd
8 changed files with 63 additions and 60 deletions

View File

@ -26,6 +26,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h> #include <Library/MemoryAllocationLib.h>
#include <Library/ReportStatusCodeLib.h> #include <Library/ReportStatusCodeLib.h>
#include <Library/SafeIntLib.h>
#include <Library/VariableFlashInfoLib.h>
// //
// Flash erase polarity is 1 // Flash erase polarity is 1
@ -708,10 +710,13 @@ InitFtwProtocol (
Since Signature and WriteQueueSize have been known, Crc can be calculated out, Since Signature and WriteQueueSize have been known, Crc can be calculated out,
then the work space header will be fixed. then the work space header will be fixed.
@param[in] WorkSpaceLength Length in bytes of the FTW workspace area.
**/ **/
VOID VOID
InitializeLocalWorkSpaceHeader ( InitializeLocalWorkSpaceHeader (
VOID IN UINTN WorkSpaceLength
); );
/** /**

View File

@ -46,6 +46,8 @@
UefiLib UefiLib
PcdLib PcdLib
ReportStatusCodeLib ReportStatusCodeLib
SafeIntLib
VariableFlashInfoLib
[Guids] [Guids]
# #
@ -65,14 +67,6 @@
[FeaturePcd] [FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## CONSUMES
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## CONSUMES
# #
# gBS->CalculateCrc32() is consumed in EntryPoint. # gBS->CalculateCrc32() is consumed in EntryPoint.
# PI spec said: When the DXE Foundation is notified that the EFI_RUNTIME_ARCH_PROTOCOL # PI spec said: When the DXE Foundation is notified that the EFI_RUNTIME_ARCH_PROTOCOL

View File

@ -52,6 +52,8 @@
ReportStatusCodeLib ReportStatusCodeLib
SmmMemLib SmmMemLib
BaseLib BaseLib
SafeIntLib
VariableFlashInfoLib
[Guids] [Guids]
# #
@ -74,14 +76,6 @@
[FeaturePcd] [FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## CONSUMES
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## CONSUMES
# #
# gBS->CalculateCrc32() is consumed in EntryPoint. # gBS->CalculateCrc32() is consumed in EntryPoint.
# PI spec said: When the DXE Foundation is notified that the EFI_RUNTIME_ARCH_PROTOCOL # PI spec said: When the DXE Foundation is notified that the EFI_RUNTIME_ARCH_PROTOCOL

View File

@ -50,7 +50,9 @@
MmServicesTableLib MmServicesTableLib
PcdLib PcdLib
ReportStatusCodeLib ReportStatusCodeLib
SafeIntLib
StandaloneMmDriverEntryPoint StandaloneMmDriverEntryPoint
VariableFlashInfoLib
[Guids] [Guids]
# #
@ -73,13 +75,5 @@
[FeaturePcd] [FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## CONSUMES
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## CONSUMES
[Depex] [Depex]
TRUE TRUE

View File

@ -987,22 +987,43 @@ InitFtwDevice (
OUT EFI_FTW_DEVICE **FtwData OUT EFI_FTW_DEVICE **FtwData
) )
{ {
EFI_FTW_DEVICE *FtwDevice; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS WorkSpaceAddress;
UINT64 Size;
UINTN FtwWorkingSize;
EFI_FTW_DEVICE *FtwDevice;
FtwWorkingSize = 0;
Status = GetVariableFlashFtwWorkingInfo (&WorkSpaceAddress, &Size);
ASSERT_EFI_ERROR (Status);
Status = SafeUint64ToUintn (Size, &FtwWorkingSize);
// This driver currently assumes the size will be UINTN so assert the value is safe for now.
ASSERT_EFI_ERROR (Status);
// //
// Allocate private data of this driver, // Allocate private data of this driver,
// Including the FtwWorkSpace[FTW_WORK_SPACE_SIZE]. // Including the FtwWorkSpace[FTW_WORK_SPACE_SIZE].
// //
FtwDevice = AllocateZeroPool (sizeof (EFI_FTW_DEVICE) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize)); FtwDevice = AllocateZeroPool (sizeof (EFI_FTW_DEVICE) + FtwWorkingSize);
if (FtwDevice == NULL) { if (FtwDevice == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
FtwDevice->WorkSpaceAddress = WorkSpaceAddress;
FtwDevice->WorkSpaceLength = FtwWorkingSize;
Status = GetVariableFlashFtwSpareInfo (&FtwDevice->SpareAreaAddress, &Size);
ASSERT_EFI_ERROR (Status);
Status = SafeUint64ToUintn (Size, &FtwDevice->SpareAreaLength);
// This driver currently assumes the size will be UINTN so assert the value is safe for now.
ASSERT_EFI_ERROR (Status);
// //
// Initialize other parameters, and set WorkSpace as FTW_ERASED_BYTE. // Initialize other parameters, and set WorkSpace as FTW_ERASED_BYTE.
// //
FtwDevice->WorkSpaceLength = (UINTN)PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
FtwDevice->SpareAreaLength = (UINTN)PcdGet32 (PcdFlashNvStorageFtwSpareSize);
if ((FtwDevice->WorkSpaceLength == 0) || (FtwDevice->SpareAreaLength == 0)) { if ((FtwDevice->WorkSpaceLength == 0) || (FtwDevice->SpareAreaLength == 0)) {
DEBUG ((DEBUG_ERROR, "Ftw: Workspace or Spare block does not exist!\n")); DEBUG ((DEBUG_ERROR, "Ftw: Workspace or Spare block does not exist!\n"));
FreePool (FtwDevice); FreePool (FtwDevice);
@ -1015,16 +1036,6 @@ InitFtwDevice (
FtwDevice->FtwWorkSpaceLba = (EFI_LBA)(-1); FtwDevice->FtwWorkSpaceLba = (EFI_LBA)(-1);
FtwDevice->FtwSpareLba = (EFI_LBA)(-1); FtwDevice->FtwSpareLba = (EFI_LBA)(-1);
FtwDevice->WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFlashNvStorageFtwWorkingBase64);
if (FtwDevice->WorkSpaceAddress == 0) {
FtwDevice->WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashNvStorageFtwWorkingBase);
}
FtwDevice->SpareAreaAddress = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFlashNvStorageFtwSpareBase64);
if (FtwDevice->SpareAreaAddress == 0) {
FtwDevice->SpareAreaAddress = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashNvStorageFtwSpareBase);
}
*FtwData = FtwDevice; *FtwData = FtwDevice;
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -1277,7 +1288,7 @@ InitFtwProtocol (
FtwDevice->FtwLastWriteHeader = NULL; FtwDevice->FtwLastWriteHeader = NULL;
FtwDevice->FtwLastWriteRecord = NULL; FtwDevice->FtwLastWriteRecord = NULL;
InitializeLocalWorkSpaceHeader (); InitializeLocalWorkSpaceHeader (FtwDevice->WorkSpaceLength);
// //
// Refresh the working space data from working block // Refresh the working space data from working block

View File

@ -16,10 +16,13 @@ EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER mWorkingBlockHeader = { ZERO_GUID, 0, 0
Since Signature and WriteQueueSize have been known, Crc can be calculated out, Since Signature and WriteQueueSize have been known, Crc can be calculated out,
then the work space header will be fixed. then the work space header will be fixed.
@param[in] WorkSpaceLength Length in bytes of the FTW workspace area.
**/ **/
VOID VOID
InitializeLocalWorkSpaceHeader ( InitializeLocalWorkSpaceHeader (
VOID IN UINTN WorkSpaceLength
) )
{ {
// //
@ -46,7 +49,7 @@ InitializeLocalWorkSpaceHeader (
&gEdkiiWorkingBlockSignatureGuid, &gEdkiiWorkingBlockSignatureGuid,
sizeof (EFI_GUID) sizeof (EFI_GUID)
); );
mWorkingBlockHeader.WriteQueueSize = PcdGet32 (PcdFlashNvStorageFtwWorkingSize) - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER); mWorkingBlockHeader.WriteQueueSize = WorkSpaceLength - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER);
// //
// Crc is calculated with all the fields except Crc and STATE, so leave them as FTW_ERASED_BYTE. // Crc is calculated with all the fields except Crc and STATE, so leave them as FTW_ERASED_BYTE.

View File

@ -16,6 +16,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/HobLib.h> #include <Library/HobLib.h>
#include <Library/SafeIntLib.h>
#include <Library/VariableFlashInfoLib.h>
EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = { EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
@ -212,25 +214,31 @@ PeimFaultTolerantWriteInitialize (
EFI_PHYSICAL_ADDRESS SpareAreaAddress; EFI_PHYSICAL_ADDRESS SpareAreaAddress;
UINTN SpareAreaLength; UINTN SpareAreaLength;
EFI_PHYSICAL_ADDRESS WorkSpaceInSpareArea; EFI_PHYSICAL_ADDRESS WorkSpaceInSpareArea;
UINT64 Size;
FAULT_TOLERANT_WRITE_LAST_WRITE_DATA FtwLastWrite; FAULT_TOLERANT_WRITE_LAST_WRITE_DATA FtwLastWrite;
FtwWorkingBlockHeader = NULL; FtwWorkingBlockHeader = NULL;
FtwLastWriteHeader = NULL; FtwLastWriteHeader = NULL;
FtwLastWriteRecord = NULL; FtwLastWriteRecord = NULL;
WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFlashNvStorageFtwWorkingBase64); SpareAreaAddress = 0;
if (WorkSpaceAddress == 0) { SpareAreaLength = 0;
WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashNvStorageFtwWorkingBase); WorkSpaceAddress = 0;
} WorkSpaceLength = 0;
WorkSpaceLength = (UINTN)PcdGet32 (PcdFlashNvStorageFtwWorkingSize); Status = GetVariableFlashFtwWorkingInfo (&WorkSpaceAddress, &Size);
ASSERT_EFI_ERROR (Status);
SpareAreaAddress = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFlashNvStorageFtwSpareBase64); Status = SafeUint64ToUintn (Size, &WorkSpaceLength);
if (SpareAreaAddress == 0) { // This driver currently assumes the size will be UINTN so assert the value is safe for now.
SpareAreaAddress = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashNvStorageFtwSpareBase); ASSERT_EFI_ERROR (Status);
}
SpareAreaLength = (UINTN)PcdGet32 (PcdFlashNvStorageFtwSpareSize); Status = GetVariableFlashFtwSpareInfo (&SpareAreaAddress, &Size);
ASSERT_EFI_ERROR (Status);
Status = SafeUint64ToUintn (Size, &SpareAreaLength);
// This driver currently assumes the size will be UINTN so assert the value is safe for now.
ASSERT_EFI_ERROR (Status);
// //
// The address of FTW working base and spare base must not be 0. // The address of FTW working base and spare base must not be 0.

View File

@ -39,6 +39,8 @@
HobLib HobLib
BaseMemoryLib BaseMemoryLib
PcdLib PcdLib
SafeIntLib
VariableFlashInfoLib
[Guids] [Guids]
## SOMETIMES_PRODUCES ## HOB ## SOMETIMES_PRODUCES ## HOB
@ -47,14 +49,6 @@
gEdkiiWorkingBlockSignatureGuid ## SOMETIMES_CONSUMES ## GUID gEdkiiWorkingBlockSignatureGuid ## SOMETIMES_CONSUMES ## GUID
gEfiSystemNvDataFvGuid ## SOMETIMES_CONSUMES ## GUID gEfiSystemNvDataFvGuid ## SOMETIMES_CONSUMES ## GUID
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## CONSUMES
[Depex] [Depex]
TRUE TRUE