MdeModulePkg/FaultTolerantWriteDxe: factor out boot service accesses
In preparation of providing a standalone MM based FTW driver, move the existing SMM driver to the new MM services table, and factor out some pieces that are specific to the traditional driver, mainly related to the use of UEFI boot services, which are not accessible to standalone MM drivers. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Jian J Wang <jian.j.wang@intel.com> Regression-tested-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
		@@ -31,7 +31,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
				
			|||||||
#include <Library/UefiDriverEntryPoint.h>
 | 
					#include <Library/UefiDriverEntryPoint.h>
 | 
				
			||||||
#include <Library/BaseMemoryLib.h>
 | 
					#include <Library/BaseMemoryLib.h>
 | 
				
			||||||
#include <Library/MemoryAllocationLib.h>
 | 
					#include <Library/MemoryAllocationLib.h>
 | 
				
			||||||
#include <Library/UefiBootServicesTableLib.h>
 | 
					 | 
				
			||||||
#include <Library/ReportStatusCodeLib.h>
 | 
					#include <Library/ReportStatusCodeLib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@@ -766,4 +765,26 @@ WriteWorkSpaceData (
 | 
				
			|||||||
  IN UINT8                              *Buffer
 | 
					  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
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,6 +51,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
**/
 | 
					**/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Library/UefiBootServicesTableLib.h>
 | 
				
			||||||
#include "FaultTolerantWrite.h"
 | 
					#include "FaultTolerantWrite.h"
 | 
				
			||||||
EFI_EVENT                                 mFvbRegistration = NULL;
 | 
					EFI_EVENT                                 mFvbRegistration = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -250,3 +251,33 @@ FaultTolerantWriteInitialize (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  return EFI_SUCCESS;
 | 
					  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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,14 +54,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
**/
 | 
					**/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <PiSmm.h>
 | 
					#include <PiMm.h>
 | 
				
			||||||
#include <Library/SmmServicesTableLib.h>
 | 
					#include <Library/MmServicesTableLib.h>
 | 
				
			||||||
#include <Library/SmmMemLib.h>
 | 
					 | 
				
			||||||
#include <Library/BaseLib.h>
 | 
					#include <Library/BaseLib.h>
 | 
				
			||||||
#include <Protocol/SmmSwapAddressRange.h>
 | 
					#include <Protocol/SmmSwapAddressRange.h>
 | 
				
			||||||
#include "FaultTolerantWrite.h"
 | 
					#include "FaultTolerantWrite.h"
 | 
				
			||||||
#include "FaultTolerantWriteSmmCommon.h"
 | 
					#include "FaultTolerantWriteSmmCommon.h"
 | 
				
			||||||
#include <Protocol/SmmEndOfDxe.h>
 | 
					#include <Protocol/MmEndOfDxe.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EFI_EVENT                                 mFvbRegistration = NULL;
 | 
					EFI_EVENT                                 mFvbRegistration = NULL;
 | 
				
			||||||
EFI_FTW_DEVICE                            *mFtwDevice      = NULL;
 | 
					EFI_FTW_DEVICE                            *mFtwDevice      = NULL;
 | 
				
			||||||
@@ -92,7 +91,7 @@ FtwGetFvbByHandle (
 | 
				
			|||||||
  //
 | 
					  //
 | 
				
			||||||
  // To get the SMM FVB protocol interface on the handle
 | 
					  // To get the SMM FVB protocol interface on the handle
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  return gSmst->SmmHandleProtocol (
 | 
					  return gMmst->MmHandleProtocol (
 | 
				
			||||||
                  FvBlockHandle,
 | 
					                  FvBlockHandle,
 | 
				
			||||||
                  &gEfiSmmFirmwareVolumeBlockProtocolGuid,
 | 
					                  &gEfiSmmFirmwareVolumeBlockProtocolGuid,
 | 
				
			||||||
                  (VOID **) FvBlock
 | 
					                  (VOID **) FvBlock
 | 
				
			||||||
@@ -119,7 +118,7 @@ FtwGetSarProtocol (
 | 
				
			|||||||
  //
 | 
					  //
 | 
				
			||||||
  // Locate Smm Swap Address Range protocol
 | 
					  // Locate Smm Swap Address Range protocol
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  Status = gSmst->SmmLocateProtocol (
 | 
					  Status = gMmst->MmLocateProtocol (
 | 
				
			||||||
                    &gEfiSmmSwapAddressRangeProtocolGuid,
 | 
					                    &gEfiSmmSwapAddressRangeProtocolGuid,
 | 
				
			||||||
                    NULL,
 | 
					                    NULL,
 | 
				
			||||||
                    SarProtocol
 | 
					                    SarProtocol
 | 
				
			||||||
@@ -158,7 +157,7 @@ GetFvbCountAndBuffer (
 | 
				
			|||||||
  BufferSize     = 0;
 | 
					  BufferSize     = 0;
 | 
				
			||||||
  *NumberHandles = 0;
 | 
					  *NumberHandles = 0;
 | 
				
			||||||
  *Buffer        = NULL;
 | 
					  *Buffer        = NULL;
 | 
				
			||||||
  Status = gSmst->SmmLocateHandle (
 | 
					  Status = gMmst->MmLocateHandle (
 | 
				
			||||||
                    ByProtocol,
 | 
					                    ByProtocol,
 | 
				
			||||||
                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
 | 
					                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
 | 
				
			||||||
                    NULL,
 | 
					                    NULL,
 | 
				
			||||||
@@ -174,7 +173,7 @@ GetFvbCountAndBuffer (
 | 
				
			|||||||
    return EFI_OUT_OF_RESOURCES;
 | 
					    return EFI_OUT_OF_RESOURCES;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Status = gSmst->SmmLocateHandle (
 | 
					  Status = gMmst->MmLocateHandle (
 | 
				
			||||||
                    ByProtocol,
 | 
					                    ByProtocol,
 | 
				
			||||||
                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
 | 
					                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
 | 
				
			||||||
                    NULL,
 | 
					                    NULL,
 | 
				
			||||||
@@ -336,7 +335,7 @@ SmmFaultTolerantWriteHandler (
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  CommBufferPayloadSize = TempCommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE;
 | 
					  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"));
 | 
					    DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n"));
 | 
				
			||||||
    return EFI_SUCCESS;
 | 
					    return EFI_SUCCESS;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -525,13 +524,12 @@ FvbNotificationEvent (
 | 
				
			|||||||
  EFI_STATUS                              Status;
 | 
					  EFI_STATUS                              Status;
 | 
				
			||||||
  EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL   *FtwProtocol;
 | 
					  EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL   *FtwProtocol;
 | 
				
			||||||
  EFI_HANDLE                              SmmFtwHandle;
 | 
					  EFI_HANDLE                              SmmFtwHandle;
 | 
				
			||||||
  EFI_HANDLE                              FtwHandle;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // Just return to avoid install SMM FaultTolerantWriteProtocol again
 | 
					  // Just return to avoid install SMM FaultTolerantWriteProtocol again
 | 
				
			||||||
  // if SMM Fault Tolerant Write protocol had been installed.
 | 
					  // if SMM Fault Tolerant Write protocol had been installed.
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  Status = gSmst->SmmLocateProtocol (
 | 
					  Status = gMmst->MmLocateProtocol (
 | 
				
			||||||
                    &gEfiSmmFaultTolerantWriteProtocolGuid,
 | 
					                    &gEfiSmmFaultTolerantWriteProtocolGuid,
 | 
				
			||||||
                    NULL,
 | 
					                    NULL,
 | 
				
			||||||
                    (VOID **) &FtwProtocol
 | 
					                    (VOID **) &FtwProtocol
 | 
				
			||||||
@@ -551,7 +549,7 @@ FvbNotificationEvent (
 | 
				
			|||||||
  //
 | 
					  //
 | 
				
			||||||
  // Install protocol interface
 | 
					  // Install protocol interface
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  Status = gSmst->SmmInstallProtocolInterface (
 | 
					  Status = gMmst->MmInstallProtocolInterface (
 | 
				
			||||||
                    &mFtwDevice->Handle,
 | 
					                    &mFtwDevice->Handle,
 | 
				
			||||||
                    &gEfiSmmFaultTolerantWriteProtocolGuid,
 | 
					                    &gEfiSmmFaultTolerantWriteProtocolGuid,
 | 
				
			||||||
                    EFI_NATIVE_INTERFACE,
 | 
					                    EFI_NATIVE_INTERFACE,
 | 
				
			||||||
@@ -562,20 +560,13 @@ FvbNotificationEvent (
 | 
				
			|||||||
  ///
 | 
					  ///
 | 
				
			||||||
  /// Register SMM FTW SMI handler
 | 
					  /// Register SMM FTW SMI handler
 | 
				
			||||||
  ///
 | 
					  ///
 | 
				
			||||||
  Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle);
 | 
					  Status = gMmst->MmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle);
 | 
				
			||||||
  ASSERT_EFI_ERROR (Status);
 | 
					  ASSERT_EFI_ERROR (Status);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // Notify the Ftw wrapper driver SMM Ftw is ready
 | 
					  // Notify the Ftw wrapper driver SMM Ftw is ready
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  FtwHandle = NULL;
 | 
					  FtwNotifySmmReady ();
 | 
				
			||||||
  Status = gBS->InstallProtocolInterface (
 | 
					 | 
				
			||||||
                  &FtwHandle,
 | 
					 | 
				
			||||||
                  &gEfiSmmFaultTolerantWriteProtocolGuid,
 | 
					 | 
				
			||||||
                  EFI_NATIVE_INTERFACE,
 | 
					 | 
				
			||||||
                  NULL
 | 
					 | 
				
			||||||
                  );
 | 
					 | 
				
			||||||
  ASSERT_EFI_ERROR (Status);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return EFI_SUCCESS;
 | 
					  return EFI_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -592,7 +583,7 @@ FvbNotificationEvent (
 | 
				
			|||||||
**/
 | 
					**/
 | 
				
			||||||
EFI_STATUS
 | 
					EFI_STATUS
 | 
				
			||||||
EFIAPI
 | 
					EFIAPI
 | 
				
			||||||
SmmEndOfDxeCallback (
 | 
					MmEndOfDxeCallback (
 | 
				
			||||||
  IN CONST EFI_GUID                       *Protocol,
 | 
					  IN CONST EFI_GUID                       *Protocol,
 | 
				
			||||||
  IN VOID                                 *Interface,
 | 
					  IN VOID                                 *Interface,
 | 
				
			||||||
  IN EFI_HANDLE                           Handle
 | 
					  IN EFI_HANDLE                           Handle
 | 
				
			||||||
@@ -603,25 +594,19 @@ SmmEndOfDxeCallback (
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
  This function is the entry point of the Fault Tolerant Write driver.
 | 
					  Shared entry point of the module
 | 
				
			||||||
 | 
					 | 
				
			||||||
  @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_SUCCESS           The initialization finished successfully.
 | 
				
			||||||
  @retval EFI_OUT_OF_RESOURCES  Allocate memory error
 | 
					  @retval EFI_OUT_OF_RESOURCES  Allocate memory error
 | 
				
			||||||
  @retval EFI_INVALID_PARAMETER Workspace or Spare block does not exist
 | 
					  @retval EFI_INVALID_PARAMETER Workspace or Spare block does not exist
 | 
				
			||||||
 | 
					 | 
				
			||||||
**/
 | 
					**/
 | 
				
			||||||
EFI_STATUS
 | 
					EFI_STATUS
 | 
				
			||||||
EFIAPI
 | 
					MmFaultTolerantWriteInitialize (
 | 
				
			||||||
SmmFaultTolerantWriteInitialize (
 | 
					  VOID
 | 
				
			||||||
  IN EFI_HANDLE                           ImageHandle,
 | 
					 | 
				
			||||||
  IN EFI_SYSTEM_TABLE                     *SystemTable
 | 
					 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  EFI_STATUS                              Status;
 | 
					  EFI_STATUS                              Status;
 | 
				
			||||||
  VOID                                    *SmmEndOfDxeRegistration;
 | 
					  VOID                                    *MmEndOfDxeRegistration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // Allocate private data structure for SMM FTW protocol and do some initialization
 | 
					  // 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.
 | 
					  // Register EFI_SMM_END_OF_DXE_PROTOCOL_GUID notify function.
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  Status = gSmst->SmmRegisterProtocolNotify (
 | 
					  Status = gMmst->MmRegisterProtocolNotify (
 | 
				
			||||||
                    &gEfiSmmEndOfDxeProtocolGuid,
 | 
					                    &gEfiMmEndOfDxeProtocolGuid,
 | 
				
			||||||
                    SmmEndOfDxeCallback,
 | 
					                    MmEndOfDxeCallback,
 | 
				
			||||||
                    &SmmEndOfDxeRegistration
 | 
					                    &MmEndOfDxeRegistration
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
  ASSERT_EFI_ERROR (Status);
 | 
					  ASSERT_EFI_ERROR (Status);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // Register FvbNotificationEvent () notify function.
 | 
					  // Register FvbNotificationEvent () notify function.
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  Status = gSmst->SmmRegisterProtocolNotify (
 | 
					  Status = gMmst->MmRegisterProtocolNotify (
 | 
				
			||||||
                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
 | 
					                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
 | 
				
			||||||
                    FvbNotificationEvent,
 | 
					                    FvbNotificationEvent,
 | 
				
			||||||
                    &mFvbRegistration
 | 
					                    &mFvbRegistration
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,7 @@
 | 
				
			|||||||
  FtwMisc.c
 | 
					  FtwMisc.c
 | 
				
			||||||
  UpdateWorkingBlock.c
 | 
					  UpdateWorkingBlock.c
 | 
				
			||||||
  FaultTolerantWrite.c
 | 
					  FaultTolerantWrite.c
 | 
				
			||||||
 | 
					  FaultTolerantWriteTraditionalMm.c
 | 
				
			||||||
  FaultTolerantWriteSmm.c
 | 
					  FaultTolerantWriteSmm.c
 | 
				
			||||||
  FaultTolerantWrite.h
 | 
					  FaultTolerantWrite.h
 | 
				
			||||||
  FaultTolerantWriteSmmCommon.h
 | 
					  FaultTolerantWriteSmmCommon.h
 | 
				
			||||||
@@ -46,7 +47,7 @@
 | 
				
			|||||||
  MdeModulePkg/MdeModulePkg.dec
 | 
					  MdeModulePkg/MdeModulePkg.dec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[LibraryClasses]
 | 
					[LibraryClasses]
 | 
				
			||||||
  SmmServicesTableLib
 | 
					  MmServicesTableLib
 | 
				
			||||||
  MemoryAllocationLib
 | 
					  MemoryAllocationLib
 | 
				
			||||||
  BaseMemoryLib
 | 
					  BaseMemoryLib
 | 
				
			||||||
  UefiDriverEntryPoint
 | 
					  UefiDriverEntryPoint
 | 
				
			||||||
@@ -73,7 +74,7 @@
 | 
				
			|||||||
  ## PRODUCES
 | 
					  ## PRODUCES
 | 
				
			||||||
  ## UNDEFINED # SmiHandlerRegister
 | 
					  ## UNDEFINED # SmiHandlerRegister
 | 
				
			||||||
  gEfiSmmFaultTolerantWriteProtocolGuid
 | 
					  gEfiSmmFaultTolerantWriteProtocolGuid
 | 
				
			||||||
  gEfiSmmEndOfDxeProtocolGuid                      ## CONSUMES
 | 
					  gEfiMmEndOfDxeProtocolGuid                      ## CONSUMES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[FeaturePcd]
 | 
					[FeaturePcd]
 | 
				
			||||||
  gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable    ## CONSUMES
 | 
					  gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable    ## CONSUMES
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -77,4 +77,43 @@ typedef struct {
 | 
				
			|||||||
  UINT8                                 Data[1];
 | 
					  UINT8                                 Data[1];
 | 
				
			||||||
} SMM_FTW_GET_LAST_WRITE_HEADER;
 | 
					} 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
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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. <BR>
 | 
				
			||||||
 | 
					Copyright (c) 2018, Linaro, Ltd. 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Library/SmmMemLib.h>
 | 
				
			||||||
 | 
					#include <Library/UefiBootServicesTableLib.h>
 | 
				
			||||||
 | 
					#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 ();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -29,8 +29,6 @@ InitializeLocalWorkSpaceHeader (
 | 
				
			|||||||
  VOID
 | 
					  VOID
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  EFI_STATUS                              Status;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  // Check signature with gEdkiiWorkingBlockSignatureGuid.
 | 
					  // Check signature with gEdkiiWorkingBlockSignatureGuid.
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
@@ -64,12 +62,8 @@ InitializeLocalWorkSpaceHeader (
 | 
				
			|||||||
  //
 | 
					  //
 | 
				
			||||||
  // Calculate the Crc of woking block header
 | 
					  // Calculate the Crc of woking block header
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  Status = gBS->CalculateCrc32 (
 | 
					  mWorkingBlockHeader.Crc = FtwCalculateCrc32 (&mWorkingBlockHeader,
 | 
				
			||||||
                  &mWorkingBlockHeader,
 | 
					                              sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER));
 | 
				
			||||||
                  sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
 | 
					 | 
				
			||||||
                  &mWorkingBlockHeader.Crc
 | 
					 | 
				
			||||||
                  );
 | 
					 | 
				
			||||||
  ASSERT_EFI_ERROR (Status);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mWorkingBlockHeader.WorkingBlockValid    = FTW_VALID_STATE;
 | 
					  mWorkingBlockHeader.WorkingBlockValid    = FTW_VALID_STATE;
 | 
				
			||||||
  mWorkingBlockHeader.WorkingBlockInvalid  = FTW_INVALID_STATE;
 | 
					  mWorkingBlockHeader.WorkingBlockInvalid  = FTW_INVALID_STATE;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user