diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWrite.h b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWrite.h index 844cf3bee0..a23cb620e2 100644 --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWrite.h +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWrite.h @@ -31,7 +31,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include -#include #include // @@ -766,4 +765,26 @@ WriteWorkSpaceData ( IN UINT8 *Buffer ); +/** + Internal implementation of CRC32. Depending on the execution context + (traditional SMM or DXE vs standalone MM), this function is implemented + via a call to the CalculateCrc32 () boot service, or via a library + call. + + If Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param[in] Buffer A pointer to the buffer on which the 32-bit CRC is + to be computed. + @param[in] Length The number of bytes in the buffer Data. + + @retval Crc32 The 32-bit CRC was computed for the data buffer. + +**/ +UINT32 +FtwCalculateCrc32 ( + IN VOID *Buffer, + IN UINTN Length + ); + #endif diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.c index 094e40f9d8..24e507104b 100644 --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.c +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.c @@ -51,6 +51,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ +#include #include "FaultTolerantWrite.h" EFI_EVENT mFvbRegistration = NULL; @@ -250,3 +251,33 @@ FaultTolerantWriteInitialize ( return EFI_SUCCESS; } + +/** + Internal implementation of CRC32. Depending on the execution context + (traditional SMM or DXE vs standalone MM), this function is implemented + via a call to the CalculateCrc32 () boot service, or via a library + call. + + If Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param[in] Buffer A pointer to the buffer on which the 32-bit CRC is to be computed. + @param[in] Length The number of bytes in the buffer Data. + + @retval Crc32 The 32-bit CRC was computed for the data buffer. + +**/ +UINT32 +FtwCalculateCrc32 ( + IN VOID *Buffer, + IN UINTN Length + ) +{ + EFI_STATUS Status; + UINT32 ReturnValue; + + Status = gBS->CalculateCrc32 (Buffer, Length, &ReturnValue); + ASSERT_EFI_ERROR (Status); + + return ReturnValue; +} diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c index 481fea3f1f..2cc4e177a3 100644 --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c @@ -54,14 +54,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ -#include -#include -#include +#include +#include #include #include #include "FaultTolerantWrite.h" #include "FaultTolerantWriteSmmCommon.h" -#include +#include EFI_EVENT mFvbRegistration = NULL; EFI_FTW_DEVICE *mFtwDevice = NULL; @@ -92,7 +91,7 @@ FtwGetFvbByHandle ( // // To get the SMM FVB protocol interface on the handle // - return gSmst->SmmHandleProtocol ( + return gMmst->MmHandleProtocol ( FvBlockHandle, &gEfiSmmFirmwareVolumeBlockProtocolGuid, (VOID **) FvBlock @@ -119,7 +118,7 @@ FtwGetSarProtocol ( // // Locate Smm Swap Address Range protocol // - Status = gSmst->SmmLocateProtocol ( + Status = gMmst->MmLocateProtocol ( &gEfiSmmSwapAddressRangeProtocolGuid, NULL, SarProtocol @@ -158,7 +157,7 @@ GetFvbCountAndBuffer ( BufferSize = 0; *NumberHandles = 0; *Buffer = NULL; - Status = gSmst->SmmLocateHandle ( + Status = gMmst->MmLocateHandle ( ByProtocol, &gEfiSmmFirmwareVolumeBlockProtocolGuid, NULL, @@ -174,7 +173,7 @@ GetFvbCountAndBuffer ( return EFI_OUT_OF_RESOURCES; } - Status = gSmst->SmmLocateHandle ( + Status = gMmst->MmLocateHandle ( ByProtocol, &gEfiSmmFirmwareVolumeBlockProtocolGuid, NULL, @@ -336,7 +335,7 @@ SmmFaultTolerantWriteHandler ( } CommBufferPayloadSize = TempCommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE; - if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) { + if (!FtwSmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) { DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n")); return EFI_SUCCESS; } @@ -525,13 +524,12 @@ FvbNotificationEvent ( EFI_STATUS Status; EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol; EFI_HANDLE SmmFtwHandle; - EFI_HANDLE FtwHandle; // // Just return to avoid install SMM FaultTolerantWriteProtocol again // if SMM Fault Tolerant Write protocol had been installed. // - Status = gSmst->SmmLocateProtocol ( + Status = gMmst->MmLocateProtocol ( &gEfiSmmFaultTolerantWriteProtocolGuid, NULL, (VOID **) &FtwProtocol @@ -551,7 +549,7 @@ FvbNotificationEvent ( // // Install protocol interface // - Status = gSmst->SmmInstallProtocolInterface ( + Status = gMmst->MmInstallProtocolInterface ( &mFtwDevice->Handle, &gEfiSmmFaultTolerantWriteProtocolGuid, EFI_NATIVE_INTERFACE, @@ -562,20 +560,13 @@ FvbNotificationEvent ( /// /// Register SMM FTW SMI handler /// - Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle); + Status = gMmst->MmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle); ASSERT_EFI_ERROR (Status); // // Notify the Ftw wrapper driver SMM Ftw is ready // - FtwHandle = NULL; - Status = gBS->InstallProtocolInterface ( - &FtwHandle, - &gEfiSmmFaultTolerantWriteProtocolGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - ASSERT_EFI_ERROR (Status); + FtwNotifySmmReady (); return EFI_SUCCESS; } @@ -592,7 +583,7 @@ FvbNotificationEvent ( **/ EFI_STATUS EFIAPI -SmmEndOfDxeCallback ( +MmEndOfDxeCallback ( IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle @@ -603,25 +594,19 @@ SmmEndOfDxeCallback ( } /** - 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 + Shared entry point of the module @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 -SmmFaultTolerantWriteInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable +MmFaultTolerantWriteInitialize ( + VOID ) { EFI_STATUS Status; - VOID *SmmEndOfDxeRegistration; + VOID *MmEndOfDxeRegistration; // // Allocate private data structure for SMM FTW protocol and do some initialization @@ -634,17 +619,17 @@ SmmFaultTolerantWriteInitialize ( // // Register EFI_SMM_END_OF_DXE_PROTOCOL_GUID notify function. // - Status = gSmst->SmmRegisterProtocolNotify ( - &gEfiSmmEndOfDxeProtocolGuid, - SmmEndOfDxeCallback, - &SmmEndOfDxeRegistration + Status = gMmst->MmRegisterProtocolNotify ( + &gEfiMmEndOfDxeProtocolGuid, + MmEndOfDxeCallback, + &MmEndOfDxeRegistration ); ASSERT_EFI_ERROR (Status); // // Register FvbNotificationEvent () notify function. // - Status = gSmst->SmmRegisterProtocolNotify ( + Status = gMmst->MmRegisterProtocolNotify ( &gEfiSmmFirmwareVolumeBlockProtocolGuid, FvbNotificationEvent, &mFvbRegistration diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf index 606cc2266b..1653365bc2 100644 --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf @@ -37,6 +37,7 @@ FtwMisc.c UpdateWorkingBlock.c FaultTolerantWrite.c + FaultTolerantWriteTraditionalMm.c FaultTolerantWriteSmm.c FaultTolerantWrite.h FaultTolerantWriteSmmCommon.h @@ -46,7 +47,7 @@ MdeModulePkg/MdeModulePkg.dec [LibraryClasses] - SmmServicesTableLib + MmServicesTableLib MemoryAllocationLib BaseMemoryLib UefiDriverEntryPoint @@ -73,7 +74,7 @@ ## PRODUCES ## UNDEFINED # SmiHandlerRegister gEfiSmmFaultTolerantWriteProtocolGuid - gEfiSmmEndOfDxeProtocolGuid ## CONSUMES + gEfiMmEndOfDxeProtocolGuid ## CONSUMES [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## CONSUMES diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h index 8ad0015f3c..61293ca864 100644 --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h @@ -77,4 +77,43 @@ typedef struct { UINT8 Data[1]; } SMM_FTW_GET_LAST_WRITE_HEADER; +/** + Shared entry point of the module + + @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 +MmFaultTolerantWriteInitialize ( + VOID + ); + +/** + This function checks if the buffer is valid per processor architecture and + does not overlap with SMRAM. + + @param Buffer The buffer start address to be checked. + @param Length The buffer length to be checked. + + @retval TRUE This buffer is valid per processor architecture and does not + overlap with SMRAM. + @retval FALSE This buffer is not valid per processor architecture or overlaps + with SMRAM. +**/ +BOOLEAN +FtwSmmIsBufferOutsideSmmValid ( + IN EFI_PHYSICAL_ADDRESS Buffer, + IN UINT64 Length + ); + +/** + Notify the system that the SMM FTW driver is ready +**/ +VOID +FtwNotifySmmReady ( + VOID + ); + #endif diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c new file mode 100644 index 0000000000..0981c3c2a9 --- /dev/null +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c @@ -0,0 +1,114 @@ +/** @file + + Parts of the SMM/MM implementation that are specific to traditional MM + +Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2018, Linaro, Ltd. All rights reserved.
+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. + +**/ + +#include +#include +#include "FaultTolerantWrite.h" +#include "FaultTolerantWriteSmmCommon.h" + +/** + This function checks if the buffer is valid per processor architecture and + does not overlap with SMRAM. + + @param Buffer The buffer start address to be checked. + @param Length The buffer length to be checked. + + @retval TRUE This buffer is valid per processor architecture and does not + overlap with SMRAM. + @retval FALSE This buffer is not valid per processor architecture or overlaps + with SMRAM. +**/ +BOOLEAN +FtwSmmIsBufferOutsideSmmValid ( + IN EFI_PHYSICAL_ADDRESS Buffer, + IN UINT64 Length + ) +{ + return SmmIsBufferOutsideSmmValid (Buffer, Length); +} + +/** + Internal implementation of CRC32. Depending on the execution context + (traditional SMM or DXE vs standalone MM), this function is implemented + via a call to the CalculateCrc32 () boot service, or via a library + call. + + If Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param[in] Buffer A pointer to the buffer on which the 32-bit CRC is + to be computed. + @param[in] Length The number of bytes in the buffer Data. + + @retval Crc32 The 32-bit CRC was computed for the data buffer. + +**/ +UINT32 +FtwCalculateCrc32 ( + IN VOID *Buffer, + IN UINTN Length + ) +{ + EFI_STATUS Status; + UINT32 ReturnValue; + + Status = gBS->CalculateCrc32 (Buffer, Length, &ReturnValue); + ASSERT_EFI_ERROR (Status); + + return ReturnValue; +} + +/** + Notify the system that the SMM FTW driver is ready +**/ +VOID +FtwNotifySmmReady ( + VOID + ) +{ + EFI_HANDLE FtwHandle; + EFI_STATUS Status; + + FtwHandle = NULL; + Status = gBS->InstallProtocolInterface ( + &FtwHandle, + &gEfiSmmFaultTolerantWriteProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); +} + +/** + 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 +SmmFaultTolerantWriteInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return MmFaultTolerantWriteInitialize (); +} diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c index 50d3421b88..d09e9719cf 100644 --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c @@ -29,8 +29,6 @@ InitializeLocalWorkSpaceHeader ( VOID ) { - EFI_STATUS Status; - // // Check signature with gEdkiiWorkingBlockSignatureGuid. // @@ -64,12 +62,8 @@ InitializeLocalWorkSpaceHeader ( // // Calculate the Crc of woking block header // - Status = gBS->CalculateCrc32 ( - &mWorkingBlockHeader, - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), - &mWorkingBlockHeader.Crc - ); - ASSERT_EFI_ERROR (Status); + mWorkingBlockHeader.Crc = FtwCalculateCrc32 (&mWorkingBlockHeader, + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)); mWorkingBlockHeader.WorkingBlockValid = FTW_VALID_STATE; mWorkingBlockHeader.WorkingBlockInvalid = FTW_INVALID_STATE;