On Wed, 2 Jan 2019 at 14:14, Jagadeesh Ujja <jagadeesh.u...@arm.com> wrote: > > Adapt the FaultTolerantWriteDxe driver to be used as a MM_STANDALONE > driver to provide UEFI fault tolerant write protocol functionality > for variable reclaim operation on EFI variables stored on a NOR flash > that is only accessible to code executing in MM Standalone mode. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Jagadeesh Ujja <jagadeesh.u...@arm.com> > --- > MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf > | 1 + > MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c > | 203 +++++++++++++++----- > > MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf > | 101 ++++++++++ > MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c > | 27 +-- > 4 files changed, 271 insertions(+), 61 deletions(-) > > diff --git > a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf > b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf > index dcde58d..026bc60 100644 > --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf > +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf > @@ -77,6 +77,7 @@ > gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase ## > SOMETIMES_CONSUMES > gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 ## > CONSUMES > gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## > CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdStandaloneMmVariableEnabled > > # > # gBS->CalculateCrc32() is consumed in EntryPoint. > diff --git > a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c > b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c > index 481fea3..33f99e6 100644 > --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c > +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c > @@ -44,6 +44,7 @@ > This driver need to make sure the CommBuffer is not in the SMRAM range. > > Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> > +Copyright (c) 2018, ARM Limited. All rights reserved.<BR> > This program and the accompanying materials > are licensed and made available under the terms and conditions of the BSD > License > which accompanies this distribution. The full text of the license may be > found at > @@ -55,13 +56,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > **/ > > #include <PiSmm.h> > +#include <PiMm.h> > #include <Library/SmmServicesTableLib.h> > #include <Library/SmmMemLib.h> > +#include <Library/StandaloneMmMemLib.h> > #include <Library/BaseLib.h> > #include <Protocol/SmmSwapAddressRange.h> > #include "FaultTolerantWrite.h" > #include "FaultTolerantWriteSmmCommon.h" > #include <Protocol/SmmEndOfDxe.h> > +#include <Library/StandaloneMmServicesTableLib.h> > > EFI_EVENT mFvbRegistration = NULL; > EFI_FTW_DEVICE *mFtwDevice = NULL; > @@ -92,11 +96,19 @@ FtwGetFvbByHandle ( > // > // To get the SMM FVB protocol interface on the handle > // > - return gSmst->SmmHandleProtocol ( > - FvBlockHandle, > - &gEfiSmmFirmwareVolumeBlockProtocolGuid, > - (VOID **) FvBlock > - ); > + if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) { > + return gSmst->SmmHandleProtocol ( > + FvBlockHandle, > + &gEfiSmmFirmwareVolumeBlockProtocolGuid, > + (VOID **) FvBlock > + ); > + } else { > + return gMmst->MmHandleProtocol ( > + FvBlockHandle, > + &gEfiSmmFirmwareVolumeBlockProtocolGuid, > + (VOID **) FvBlock > + ); > + } > } > > /** > @@ -119,11 +131,19 @@ FtwGetSarProtocol ( > // > // Locate Smm Swap Address Range protocol > // > - Status = gSmst->SmmLocateProtocol ( > - &gEfiSmmSwapAddressRangeProtocolGuid, > - NULL, > - SarProtocol > - ); > + if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) { > + Status = gSmst->SmmLocateProtocol ( > + &gEfiSmmSwapAddressRangeProtocolGuid, > + NULL, > + SarProtocol > + ); > + } else { > + Status = gMmst->MmLocateProtocol ( > + &gEfiSmmSwapAddressRangeProtocolGuid, > + NULL, > + SarProtocol > + ); > + } > return Status; > } > > @@ -158,13 +178,23 @@ GetFvbCountAndBuffer ( > BufferSize = 0; > *NumberHandles = 0; > *Buffer = NULL; > - Status = gSmst->SmmLocateHandle ( > - ByProtocol, > - &gEfiSmmFirmwareVolumeBlockProtocolGuid, > - NULL, > - &BufferSize, > - *Buffer > - ); > + if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) { > + Status = gSmst->SmmLocateHandle ( > + ByProtocol, > + &gEfiSmmFirmwareVolumeBlockProtocolGuid, > + NULL, > + &BufferSize, > + *Buffer > + ); > + } else { > + Status = gMmst->MmLocateHandle ( > + ByProtocol, > + &gEfiSmmFirmwareVolumeBlockProtocolGuid, > + NULL, > + &BufferSize, > + *Buffer > + ); > + } > if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) { > return EFI_NOT_FOUND; > } > @@ -173,15 +203,23 @@ GetFvbCountAndBuffer ( > if (*Buffer == NULL) { > return EFI_OUT_OF_RESOURCES; > } > - > - Status = gSmst->SmmLocateHandle ( > - ByProtocol, > - &gEfiSmmFirmwareVolumeBlockProtocolGuid, > - NULL, > - &BufferSize, > - *Buffer > - ); > - > + if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) { > + Status = gSmst->SmmLocateHandle ( > + ByProtocol, > + &gEfiSmmFirmwareVolumeBlockProtocolGuid, > + NULL, > + &BufferSize, > + *Buffer > + ); > + } else { > + Status = gMmst->MmLocateHandle ( > + ByProtocol, > + &gEfiSmmFirmwareVolumeBlockProtocolGuid, > + NULL, > + &BufferSize, > + *Buffer > + ); > + } > *NumberHandles = BufferSize / sizeof(EFI_HANDLE); > if (EFI_ERROR(Status)) { > *NumberHandles = 0; > @@ -335,10 +373,16 @@ SmmFaultTolerantWriteHandler ( > return EFI_SUCCESS; > } > CommBufferPayloadSize = TempCommBufferSize - > SMM_FTW_COMMUNICATE_HEADER_SIZE; > - > - if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) { > - DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM > or overflow!\n")); > - return EFI_SUCCESS; > + if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) { > + if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) > { > + DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM > or overflow!\n")); > + return EFI_SUCCESS; > + } > + } else { > + if (!MmIsBufferOutsideMmValid ((UINTN)CommBuffer, TempCommBufferSize)) { > + DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM > or overflow!\n")); > + return EFI_SUCCESS; > + } > } > > SmmFtwFunctionHeader = (SMM_FTW_COMMUNICATE_FUNCTION_HEADER *)CommBuffer; > @@ -531,11 +575,19 @@ FvbNotificationEvent ( > // Just return to avoid install SMM FaultTolerantWriteProtocol again > // if SMM Fault Tolerant Write protocol had been installed. > // > - Status = gSmst->SmmLocateProtocol ( > - &gEfiSmmFaultTolerantWriteProtocolGuid, > - NULL, > - (VOID **) &FtwProtocol > - ); > + if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) { > + Status = gSmst->SmmLocateProtocol ( > + &gEfiSmmFaultTolerantWriteProtocolGuid, > + NULL, > + (VOID **) &FtwProtocol > + ); > + } else { > + Status = gMmst->MmLocateProtocol ( > + &gEfiSmmFaultTolerantWriteProtocolGuid, > + NULL, > + (VOID **) &FtwProtocol > + ); > + } > if (!EFI_ERROR (Status)) { > return EFI_SUCCESS; > } > @@ -551,31 +603,45 @@ FvbNotificationEvent ( > // > // Install protocol interface > // > - Status = gSmst->SmmInstallProtocolInterface ( > - &mFtwDevice->Handle, > - &gEfiSmmFaultTolerantWriteProtocolGuid, > - EFI_NATIVE_INTERFACE, > - &mFtwDevice->FtwInstance > - ); > + if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) { > + Status = gSmst->SmmInstallProtocolInterface ( > + &mFtwDevice->Handle, > + &gEfiSmmFaultTolerantWriteProtocolGuid, > + EFI_NATIVE_INTERFACE, > + &mFtwDevice->FtwInstance > + ); > + } else { > + Status = gMmst->MmInstallProtocolInterface ( > + &mFtwDevice->Handle, > + &gEfiSmmFaultTolerantWriteProtocolGuid, > + EFI_NATIVE_INTERFACE, > + &mFtwDevice->FtwInstance > + ); > + } > ASSERT_EFI_ERROR (Status); > > /// > /// Register SMM FTW SMI handler > /// > - Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, > &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle); > - ASSERT_EFI_ERROR (Status); > + if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) { > + Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, > &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle); > + ASSERT_EFI_ERROR (Status); > > - // > - // Notify the Ftw wrapper driver SMM Ftw is ready > - // > - FtwHandle = NULL; > - Status = gBS->InstallProtocolInterface ( > + // > + // Notify the Ftw wrapper driver SMM Ftw is ready > + // > + FtwHandle = NULL; > + Status = gBS->InstallProtocolInterface ( > &FtwHandle, > &gEfiSmmFaultTolerantWriteProtocolGuid, > EFI_NATIVE_INTERFACE, > NULL > ); > - ASSERT_EFI_ERROR (Status); > + ASSERT_EFI_ERROR (Status); > + } else { > + Status = gMmst->MmiHandlerRegister (SmmFaultTolerantWriteHandler, > &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle); > + ASSERT_EFI_ERROR (Status); > + } > > return EFI_SUCCESS; > } > @@ -655,3 +721,42 @@ SmmFaultTolerantWriteInitialize ( > > return EFI_SUCCESS; > } > + > +/** > + This function is the entry point of the Fault Tolerant Write driver. > + > + @param[in] ImageHandle A handle for the image that is initializing > this driver > + @param[in] SystemTable A pointer to the EFI system table > + > + @retval EFI_SUCCESS The initialization finished successfully. > + @retval EFI_OUT_OF_RESOURCES Allocate memory error > + @retval EFI_INVALID_PARAMETER Workspace or Spare block does not exist > + > +**/ > +EFI_STATUS > +EFIAPI > +StandaloneMmFaultTolerantWriteInitialize ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_MM_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + // > + // Allocate private data structure for SMM FTW protocol and do some > initialization > + // > + Status = InitFtwDevice (&mFtwDevice); > + if (EFI_ERROR(Status)) { > + return Status; > + } > + Status = gMmst->MmRegisterProtocolNotify ( > + &gEfiSmmFirmwareVolumeBlockProtocolGuid, > + FvbNotificationEvent, > + &mFvbRegistration > + ); > + ASSERT_EFI_ERROR (Status); > + > + FvbNotificationEvent (NULL, NULL, NULL); > + > + return EFI_SUCCESS; > +} > diff --git > a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf > > b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf > new file mode 100644 > index 0000000..615f688 > --- /dev/null > +++ > b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf > @@ -0,0 +1,101 @@ > +## @file > +# Fault Tolerant Write Smm Driver. > +# > +# This driver installs SMM Fault Tolerant Write (FTW) protocol, which > provides fault > +# tolerant write capability in SMM environment for block devices. Its > implementation > +# depends on the full functionality SMM FVB protocol that support read, > write/erase > +# flash access. > +# > +# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> > +# Copyright (c) 2018, ARM Limited. All rights reserved.<BR> > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the BSD > License > +# which accompanies this distribution. The full text of the license may be > found at > +# http://opensource.org/licenses/bsd-license.php > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR > IMPLIED. > +# > +## > + > +[Defines] > + INF_VERSION = 0x0001001A > + BASE_NAME = FaultTolerantWriteMmStandalone > + MODULE_UNI_FILE = SmmFaultTolerantWriteDxe.uni > + FILE_GUID = 470CB248-E8AC-473c-BB4F-81069A1FE6FD > + MODULE_TYPE = MM_STANDALONE > + VERSION_STRING = 1.0 > + PI_SPECIFICATION_VERSION = 0x00010032 > + ENTRY_POINT = StandaloneMmFaultTolerantWriteInitialize > + > +# > +# The following information is for reference only and not required by the > build tools. > +# > +# VALID_ARCHITECTURES = IA32 X64 AARCH64 > +# > + > +[Sources] > + FtwMisc.c > + UpdateWorkingBlock.c > + FaultTolerantWrite.c > + FaultTolerantWriteSmm.c > + FaultTolerantWrite.h > + FaultTolerantWriteSmmCommon.h > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + StandaloneMmPkg/StandaloneMmPkg.dec > + > +[LibraryClasses] > + MemoryAllocationLib > + BaseMemoryLib > + DebugLib > + PcdLib > + ReportStatusCodeLib > + MemLib > + StandaloneMmDriverEntryPoint > + BaseLib > + MmServicesTableLib > + > +[Guids] > + # > + # Signature in EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER > + # > + ## CONSUMES ## GUID > + ## PRODUCES ## GUID > + gEdkiiWorkingBlockSignatureGuid > + > +[Protocols] > + gEfiSmmSwapAddressRangeProtocolGuid | > gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## SOMETIMES_CONSUMES > + ## NOTIFY > + ## CONSUMES > + gEfiSmmFirmwareVolumeBlockProtocolGuid > + ## PRODUCES > + ## UNDEFINED # SmiHandlerRegister > + gEfiSmmFaultTolerantWriteProtocolGuid > + gEfiSmmEndOfDxeProtocolGuid ## CONSUMES > + > +[FeaturePcd] > + gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## CONSUMES > + > +[Pcd] > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase ## > SOMETIMES_CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 ## > CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## > CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase ## > SOMETIMES_CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 ## > CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## > CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdStandaloneMmVariableEnabled > +# > +# gBS->CalculateCrc32() is consumed in EntryPoint. > +# PI spec said: When the DXE Foundation is notified that the > EFI_RUNTIME_ARCH_PROTOCOL > +# has been installed, then the Boot Service CalculateCrc32() is available. > +# So add gEfiRuntimeArchProtocolGuid Depex here. > +# > +[Depex] > + TRUE > + #gEfiSmmFirmwareVolumeBlockProtocolGuid AND gEfiRuntimeArchProtocolGuid > + > +[UserExtensions.TianoCore."ExtraFiles"] > + SmmFaultTolerantWriteDxeExtra.uni > diff --git > a/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c > b/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c > index 50d3421..9c98e57 100644 > --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c > +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c > @@ -3,6 +3,7 @@ > Internal functions to operate Working Block Space. > > Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> > +Copyright (c) 2018, ARM Limited. All rights reserved.<BR> > This program and the accompanying materials > are licensed and made available under the terms and conditions of the BSD > License > which accompanies this distribution. The full text of the license may be > found at > @@ -57,19 +58,21 @@ InitializeLocalWorkSpaceHeader ( > ); > mWorkingBlockHeader.WriteQueueSize = PcdGet32 > (PcdFlashNvStorageFtwWorkingSize) - 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. > - // > + if (!PcdGetBool (PcdStandaloneMmVariableEnabled)) { > + // > + // Crc is calculated with all the fields except Crc and STATE, so leave > them as FTW_ERASED_BYTE. > + // > > - // > - // Calculate the Crc of woking block header > - // > - Status = gBS->CalculateCrc32 ( > - &mWorkingBlockHeader, > - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), > - &mWorkingBlockHeader.Crc > - ); > - ASSERT_EFI_ERROR (Status); > + // > + // Calculate the Crc of woking block header > + // > + Status = gBS->CalculateCrc32 ( > + &mWorkingBlockHeader, > + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), > + &mWorkingBlockHeader.Crc > + ); > + ASSERT_EFI_ERROR (Status); > + } >
You cannot just remove this CRC32 calculation, can you? _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel