#include <Library/UefiDriverEntryPoint.h>\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/ReportStatusCodeLib.h>\r
\r
//\r
IN UINT8 *Buffer\r
);\r
\r
+/**\r
+ Internal implementation of CRC32. Depending on the execution context\r
+ (traditional SMM or DXE vs standalone MM), this function is implemented\r
+ via a call to the CalculateCrc32 () boot service, or via a library\r
+ call.\r
+\r
+ If Buffer is NULL, then ASSERT().\r
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+ @param[in] Buffer A pointer to the buffer on which the 32-bit CRC is\r
+ to be computed.\r
+ @param[in] Length The number of bytes in the buffer Data.\r
+\r
+ @retval Crc32 The 32-bit CRC was computed for the data buffer.\r
+\r
+**/\r
+UINT32\r
+FtwCalculateCrc32 (\r
+ IN VOID *Buffer,\r
+ IN UINTN Length\r
+ );\r
+\r
#endif\r
\r
**/\r
\r
+#include <Library/UefiBootServicesTableLib.h>\r
#include "FaultTolerantWrite.h"\r
EFI_EVENT mFvbRegistration = NULL;\r
\r
\r
return EFI_SUCCESS;\r
}\r
+\r
+/**\r
+ Internal implementation of CRC32. Depending on the execution context\r
+ (traditional SMM or DXE vs standalone MM), this function is implemented\r
+ via a call to the CalculateCrc32 () boot service, or via a library\r
+ call.\r
+\r
+ If Buffer is NULL, then ASSERT().\r
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+ @param[in] Buffer A pointer to the buffer on which the 32-bit CRC is to be computed.\r
+ @param[in] Length The number of bytes in the buffer Data.\r
+\r
+ @retval Crc32 The 32-bit CRC was computed for the data buffer.\r
+\r
+**/\r
+UINT32\r
+FtwCalculateCrc32 (\r
+ IN VOID *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 ReturnValue;\r
+\r
+ Status = gBS->CalculateCrc32 (Buffer, Length, &ReturnValue);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return ReturnValue;\r
+}\r
\r
**/\r
\r
-#include <PiSmm.h>\r
-#include <Library/SmmServicesTableLib.h>\r
-#include <Library/SmmMemLib.h>\r
+#include <PiMm.h>\r
+#include <Library/MmServicesTableLib.h>\r
#include <Library/BaseLib.h>\r
#include <Protocol/SmmSwapAddressRange.h>\r
#include "FaultTolerantWrite.h"\r
#include "FaultTolerantWriteSmmCommon.h"\r
-#include <Protocol/SmmEndOfDxe.h>\r
+#include <Protocol/MmEndOfDxe.h>\r
\r
EFI_EVENT mFvbRegistration = NULL;\r
EFI_FTW_DEVICE *mFtwDevice = NULL;\r
//\r
// To get the SMM FVB protocol interface on the handle\r
//\r
- return gSmst->SmmHandleProtocol (\r
+ return gMmst->MmHandleProtocol (\r
FvBlockHandle,\r
&gEfiSmmFirmwareVolumeBlockProtocolGuid,\r
(VOID **) FvBlock\r
//\r
// Locate Smm Swap Address Range protocol\r
//\r
- Status = gSmst->SmmLocateProtocol (\r
+ Status = gMmst->MmLocateProtocol (\r
&gEfiSmmSwapAddressRangeProtocolGuid,\r
NULL,\r
SarProtocol\r
BufferSize = 0;\r
*NumberHandles = 0;\r
*Buffer = NULL;\r
- Status = gSmst->SmmLocateHandle (\r
+ Status = gMmst->MmLocateHandle (\r
ByProtocol,\r
&gEfiSmmFirmwareVolumeBlockProtocolGuid,\r
NULL,\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- Status = gSmst->SmmLocateHandle (\r
+ Status = gMmst->MmLocateHandle (\r
ByProtocol,\r
&gEfiSmmFirmwareVolumeBlockProtocolGuid,\r
NULL,\r
}\r
CommBufferPayloadSize = TempCommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE;\r
\r
- if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {\r
+ if (!FtwSmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {\r
DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n"));\r
return EFI_SUCCESS;\r
}\r
EFI_STATUS Status;\r
EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;\r
EFI_HANDLE SmmFtwHandle;\r
- EFI_HANDLE FtwHandle;\r
\r
//\r
// Just return to avoid install SMM FaultTolerantWriteProtocol again\r
// if SMM Fault Tolerant Write protocol had been installed.\r
//\r
- Status = gSmst->SmmLocateProtocol (\r
+ Status = gMmst->MmLocateProtocol (\r
&gEfiSmmFaultTolerantWriteProtocolGuid,\r
NULL,\r
(VOID **) &FtwProtocol\r
//\r
// Install protocol interface\r
//\r
- Status = gSmst->SmmInstallProtocolInterface (\r
+ Status = gMmst->MmInstallProtocolInterface (\r
&mFtwDevice->Handle,\r
&gEfiSmmFaultTolerantWriteProtocolGuid,\r
EFI_NATIVE_INTERFACE,\r
///\r
/// Register SMM FTW SMI handler\r
///\r
- Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle);\r
+ Status = gMmst->MmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle);\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
// Notify the Ftw wrapper driver SMM Ftw is ready\r
//\r
- FtwHandle = NULL;\r
- Status = gBS->InstallProtocolInterface (\r
- &FtwHandle,\r
- &gEfiSmmFaultTolerantWriteProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+ FtwNotifySmmReady ();\r
\r
return EFI_SUCCESS;\r
}\r
**/\r
EFI_STATUS\r
EFIAPI\r
-SmmEndOfDxeCallback (\r
+MmEndOfDxeCallback (\r
IN CONST EFI_GUID *Protocol,\r
IN VOID *Interface,\r
IN EFI_HANDLE Handle\r
}\r
\r
/**\r
- This function is the entry point of the Fault Tolerant Write driver.\r
-\r
- @param[in] ImageHandle A handle for the image that is initializing this driver\r
- @param[in] SystemTable A pointer to the EFI system table\r
+ Shared entry point of the module\r
\r
@retval EFI_SUCCESS The initialization finished successfully.\r
@retval EFI_OUT_OF_RESOURCES Allocate memory error\r
@retval EFI_INVALID_PARAMETER Workspace or Spare block does not exist\r
-\r
**/\r
EFI_STATUS\r
-EFIAPI\r
-SmmFaultTolerantWriteInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
+MmFaultTolerantWriteInitialize (\r
+ VOID\r
)\r
{\r
EFI_STATUS Status;\r
- VOID *SmmEndOfDxeRegistration;\r
+ VOID *MmEndOfDxeRegistration;\r
\r
//\r
// Allocate private data structure for SMM FTW protocol and do some initialization\r
//\r
// Register EFI_SMM_END_OF_DXE_PROTOCOL_GUID notify function.\r
//\r
- Status = gSmst->SmmRegisterProtocolNotify (\r
- &gEfiSmmEndOfDxeProtocolGuid,\r
- SmmEndOfDxeCallback,\r
- &SmmEndOfDxeRegistration\r
+ Status = gMmst->MmRegisterProtocolNotify (\r
+ &gEfiMmEndOfDxeProtocolGuid,\r
+ MmEndOfDxeCallback,\r
+ &MmEndOfDxeRegistration\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
// Register FvbNotificationEvent () notify function.\r
//\r
- Status = gSmst->SmmRegisterProtocolNotify (\r
+ Status = gMmst->MmRegisterProtocolNotify (\r
&gEfiSmmFirmwareVolumeBlockProtocolGuid,\r
FvbNotificationEvent,\r
&mFvbRegistration\r
FtwMisc.c\r
UpdateWorkingBlock.c\r
FaultTolerantWrite.c\r
+ FaultTolerantWriteTraditionalMm.c\r
FaultTolerantWriteSmm.c\r
FaultTolerantWrite.h\r
FaultTolerantWriteSmmCommon.h\r
MdeModulePkg/MdeModulePkg.dec\r
\r
[LibraryClasses]\r
- SmmServicesTableLib\r
+ MmServicesTableLib\r
MemoryAllocationLib\r
BaseMemoryLib\r
UefiDriverEntryPoint\r
## PRODUCES\r
## UNDEFINED # SmiHandlerRegister\r
gEfiSmmFaultTolerantWriteProtocolGuid\r
- gEfiSmmEndOfDxeProtocolGuid ## CONSUMES\r
+ gEfiMmEndOfDxeProtocolGuid ## CONSUMES\r
\r
[FeaturePcd]\r
gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## CONSUMES\r
UINT8 Data[1];\r
} SMM_FTW_GET_LAST_WRITE_HEADER;\r
\r
+/**\r
+ Shared entry point of the module\r
+\r
+ @retval EFI_SUCCESS The initialization finished successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Allocate memory error\r
+ @retval EFI_INVALID_PARAMETER Workspace or Spare block does not exist\r
+\r
+**/\r
+EFI_STATUS\r
+MmFaultTolerantWriteInitialize (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ This function checks if the buffer is valid per processor architecture and\r
+ does not overlap with SMRAM.\r
+\r
+ @param Buffer The buffer start address to be checked.\r
+ @param Length The buffer length to be checked.\r
+\r
+ @retval TRUE This buffer is valid per processor architecture and does not\r
+ overlap with SMRAM.\r
+ @retval FALSE This buffer is not valid per processor architecture or overlaps\r
+ with SMRAM.\r
+**/\r
+BOOLEAN\r
+FtwSmmIsBufferOutsideSmmValid (\r
+ IN EFI_PHYSICAL_ADDRESS Buffer,\r
+ IN UINT64 Length\r
+ );\r
+\r
+/**\r
+ Notify the system that the SMM FTW driver is ready\r
+**/\r
+VOID\r
+FtwNotifySmmReady (\r
+ VOID\r
+ );\r
+\r
#endif\r
--- /dev/null
+/** @file\r
+\r
+ Parts of the SMM/MM implementation that are specific to traditional MM\r
+\r
+Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved. <BR>\r
+Copyright (c) 2018, Linaro, Ltd. All rights reserved. <BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Library/SmmMemLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include "FaultTolerantWrite.h"\r
+#include "FaultTolerantWriteSmmCommon.h"\r
+\r
+/**\r
+ This function checks if the buffer is valid per processor architecture and\r
+ does not overlap with SMRAM.\r
+\r
+ @param Buffer The buffer start address to be checked.\r
+ @param Length The buffer length to be checked.\r
+\r
+ @retval TRUE This buffer is valid per processor architecture and does not\r
+ overlap with SMRAM.\r
+ @retval FALSE This buffer is not valid per processor architecture or overlaps\r
+ with SMRAM.\r
+**/\r
+BOOLEAN\r
+FtwSmmIsBufferOutsideSmmValid (\r
+ IN EFI_PHYSICAL_ADDRESS Buffer,\r
+ IN UINT64 Length\r
+ )\r
+{\r
+ return SmmIsBufferOutsideSmmValid (Buffer, Length);\r
+}\r
+\r
+/**\r
+ Internal implementation of CRC32. Depending on the execution context\r
+ (traditional SMM or DXE vs standalone MM), this function is implemented\r
+ via a call to the CalculateCrc32 () boot service, or via a library\r
+ call.\r
+\r
+ If Buffer is NULL, then ASSERT().\r
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+ @param[in] Buffer A pointer to the buffer on which the 32-bit CRC is\r
+ to be computed.\r
+ @param[in] Length The number of bytes in the buffer Data.\r
+\r
+ @retval Crc32 The 32-bit CRC was computed for the data buffer.\r
+\r
+**/\r
+UINT32\r
+FtwCalculateCrc32 (\r
+ IN VOID *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 ReturnValue;\r
+\r
+ Status = gBS->CalculateCrc32 (Buffer, Length, &ReturnValue);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return ReturnValue;\r
+}\r
+\r
+/**\r
+ Notify the system that the SMM FTW driver is ready\r
+**/\r
+VOID\r
+FtwNotifySmmReady (\r
+ VOID\r
+ )\r
+{\r
+ EFI_HANDLE FtwHandle;\r
+ EFI_STATUS Status;\r
+\r
+ FtwHandle = NULL;\r
+ Status = gBS->InstallProtocolInterface (\r
+ &FtwHandle,\r
+ &gEfiSmmFaultTolerantWriteProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+/**\r
+ This function is the entry point of the Fault Tolerant Write driver.\r
+\r
+ @param[in] ImageHandle A handle for the image that is initializing this driver\r
+ @param[in] SystemTable A pointer to the EFI system table\r
+\r
+ @retval EFI_SUCCESS The initialization finished successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Allocate memory error\r
+ @retval EFI_INVALID_PARAMETER Workspace or Spare block does not exist\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmFaultTolerantWriteInitialize (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ return MmFaultTolerantWriteInitialize ();\r
+}\r
VOID\r
)\r
{\r
- EFI_STATUS Status;\r
-\r
//\r
// Check signature with gEdkiiWorkingBlockSignatureGuid.\r
//\r
//\r
// Calculate the Crc of woking block header\r
//\r
- Status = gBS->CalculateCrc32 (\r
- &mWorkingBlockHeader,\r
- sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),\r
- &mWorkingBlockHeader.Crc\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+ mWorkingBlockHeader.Crc = FtwCalculateCrc32 (&mWorkingBlockHeader,\r
+ sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER));\r
\r
mWorkingBlockHeader.WorkingBlockValid = FTW_VALID_STATE;\r
mWorkingBlockHeader.WorkingBlockInvalid = FTW_INVALID_STATE;\r