4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Implement the Fault Tolerant Write (FTW) protocol based on SMM FTW
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync module.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2011, Intel Corporation. All rights reserved. <BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynchttp://opensource.org/licenses/bsd-license.php
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "FaultTolerantWriteSmmDxe.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_HANDLE mHandle = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINTN mPrivateDataSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_FAULT_TOLERANT_WRITE_PROTOCOL mFaultTolerantWriteDriver = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FtwGetMaxBlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FtwAllocate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FtwWrite,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FtwRestart,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FtwAbort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FtwGetLastWrite
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Initialize the communicate buffer using DataSize and Function number.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] CommunicateBuffer The communicate buffer. Caller should free it after use.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] DataPtr Points to the data in the communicate buffer. Caller should not free it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DataSize The payload size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Function The function number used to initialize the communicate header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncInitCommunicateBuffer (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT VOID **CommunicateBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT VOID **DataPtr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DataSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Function
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SMM_FTW_COMMUNICATE_FUNCTION_HEADER *SmmFtwFunctionHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The whole buffer size: SMM_COMMUNICATE_HEADER_SIZE + SMM_FTW_COMMUNICATE_HEADER_SIZE + DataSize.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmCommunicateHeader = AllocateZeroPool (DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_FTW_COMMUNICATE_HEADER_SIZE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (SmmCommunicateHeader != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Prepare data buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmFaultTolerantWriteProtocolGuid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmCommunicateHeader->MessageLength = DataSize + SMM_FTW_COMMUNICATE_HEADER_SIZE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmFtwFunctionHeader = (SMM_FTW_COMMUNICATE_FUNCTION_HEADER *) SmmCommunicateHeader->Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmFtwFunctionHeader->Function = Function;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *CommunicateBuffer = SmmCommunicateHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DataPtr != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *DataPtr = SmmFtwFunctionHeader->Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Send the data in communicate buffer to SMI handler and get response.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] SmmCommunicateHeader The communicate buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DataSize The payload size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSendCommunicateBuffer (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN DataSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN CommSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SMM_FTW_COMMUNICATE_FUNCTION_HEADER *SmmFtwFunctionHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CommSize = DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_FTW_COMMUNICATE_HEADER_SIZE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = mSmmCommunication->Communicate (mSmmCommunication, SmmCommunicateHeader, &CommSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmFtwFunctionHeader = (SMM_FTW_COMMUNICATE_FUNCTION_HEADER *) SmmCommunicateHeader->Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return SmmFtwFunctionHeader->ReturnStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get the FvbBaseAddress and FvbAttributes from the FVB handle FvbHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] FvbHandle The handle of FVB protocol that provides services.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] FvbBaseAddress The base address of the FVB attached with FvbHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] FvbAttributes The attributes of the FVB attached with FvbHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The function completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others The function could not complete successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncConvertFvbHandle (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE FvbHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_PHYSICAL_ADDRESS *FvbBaseAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_FVB_ATTRIBUTES_2 *FvbAttributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->HandleProtocol (FvbHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **) &Fvb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Fvb->GetPhysicalAddress (Fvb, FvbBaseAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Fvb->GetAttributes (Fvb, FvbAttributes);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get the size of the largest block that can be updated in a fault-tolerant manner.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Indicates a pointer to the calling context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] BlockSize A pointer to a caller-allocated UINTN that is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync updated to indicate the size of the largest block
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync that can be updated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The function completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED The function could not complete successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncFtwGetMaxBlockSize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINTN *BlockSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN PayloadSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER *SmmFtwBlockSizeHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the communicate buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PayloadSize = sizeof (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFtwBlockSizeHeader, PayloadSize, FTW_FUNCTION_GET_MAX_BLOCK_SIZE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send data to SMM.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get data from SMM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *BlockSize = SmmFtwBlockSizeHeader->BlockSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SmmCommunicateHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Allocates space for the protocol to maintain information about writes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Since writes must be completed in a fault-tolerant manner and multiple
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync writes require more resources to be successful, this function
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync enables the protocol to ensure that enough space exists to track
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync information about upcoming writes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This A pointer to the calling context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] CallerId The GUID identifying the write.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PrivateDataSize The size of the caller's private data that must be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync recorded for each write.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] NumberOfWrites The number of fault tolerant block writes that will
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync need to occur.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The function completed successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED The function could not complete successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ACCESS_DENIED Not all allocated writes have been completed. All
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync writes must be completed or aborted before another
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fault tolerant write can occur.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncFtwAllocate (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_GUID *CallerId,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN PrivateDataSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN NumberOfWrites
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN PayloadSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SMM_FTW_ALLOCATE_HEADER *SmmFtwAllocateHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the communicate buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PayloadSize = sizeof (SMM_FTW_ALLOCATE_HEADER);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFtwAllocateHeader, PayloadSize, FTW_FUNCTION_ALLOCATE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyGuid (&SmmFtwAllocateHeader->CallerId, CallerId);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmFtwAllocateHeader->PrivateDataSize = PrivateDataSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmFtwAllocateHeader->NumberOfWrites = NumberOfWrites;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send data to SMM.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR( Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mPrivateDataSize = PrivateDataSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SmmCommunicateHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Starts a target block update. This records information about the write
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in fault tolerant storage, and will complete the write in a recoverable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync manner, ensuring at all times that either the original contents or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the modified contents are available.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This The calling context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Lba The logical block address of the target block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Offset The offset within the target block to place the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Length The number of bytes to write to the target block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PrivateData A pointer to private data that the caller requires
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to complete any pending writes in the event of a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fault.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] FvBlockHandle The handle of FVB protocol that provides services
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for reading, writing, and erasing the target block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Buffer The data to write.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The function completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED The function could not complete successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BAD_BUFFER_SIZE The write would span a block boundary, which is not
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a valid action.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ACCESS_DENIED No writes have been allocated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY The last write has not been completed. Restart()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync must be called to complete it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncFtwWrite (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_LBA Lba,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Offset,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *PrivateData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE FvBlockHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN PayloadSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SMM_FTW_WRITE_HEADER *SmmFtwWriteHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the communicate buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PayloadSize = OFFSET_OF (SMM_FTW_WRITE_HEADER, Data) + Length;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrivateData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The private data buffer size should be the same one in FtwAllocate API.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PayloadSize += mPrivateDataSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFtwWriteHeader, PayloadSize, FTW_FUNCTION_WRITE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // FvBlockHandle can not be used in SMM environment. Here we get the FVB protocol first, then get FVB base address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // and its attribute. Send these information to SMM handler, the SMM handler will find the proper FVB to write data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = ConvertFvbHandle (FvBlockHandle, &SmmFtwWriteHeader->FvbBaseAddress, &SmmFtwWriteHeader->FvbAttributes);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SmmCommunicateHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmFtwWriteHeader->Lba = Lba;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmFtwWriteHeader->Offset = Offset;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmFtwWriteHeader->Length = Length;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (SmmFtwWriteHeader->Data, Buffer, Length);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrivateData == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmFtwWriteHeader->PrivateDataSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmFtwWriteHeader->PrivateDataSize = mPrivateDataSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&SmmFtwWriteHeader->Data[Length], PrivateData, mPrivateDataSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send data to SMM.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SmmCommunicateHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Restarts a previously interrupted write. The caller must provide the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync block protocol needed to complete the interrupted write.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This The calling context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] FvBlockHandle The handle of FVB protocol that provides services.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The function completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED The function could not complete successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ACCESS_DENIED No pending writes exist.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncFtwRestart (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE FvBlockHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN PayloadSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SMM_FTW_RESTART_HEADER *SmmFtwRestartHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the communicate buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PayloadSize = sizeof (SMM_FTW_RESTART_HEADER);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFtwRestartHeader, PayloadSize, FTW_FUNCTION_RESTART);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // FvBlockHandle can not be used in SMM environment. Here we get the FVB protocol first, then get FVB base address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // and its attribute. Send these information to SMM handler, the SMM handler will find the proper FVB to write data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = ConvertFvbHandle (FvBlockHandle, &SmmFtwRestartHeader->FvbBaseAddress, &SmmFtwRestartHeader->FvbAttributes);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SmmCommunicateHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send data to SMM.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SmmCommunicateHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Aborts all previously allocated writes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This The calling context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The function completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED The function could not complete successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND No allocated writes exist.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncFtwAbort (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the communicate buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, NULL, 0, FTW_FUNCTION_ABORT);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send data to SMM.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SendCommunicateBuffer (SmmCommunicateHeader, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SmmCommunicateHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Starts a target block update. This function records information about the write
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in fault-tolerant storage and completes the write in a recoverable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync manner, ensuring at all times that either the original contents or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the modified contents are available.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Indicates a pointer to the calling context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] CallerId The GUID identifying the last write.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Lba The logical block address of the last write.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Offset The offset within the block of the last write.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Length The length of the last write.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] PrivateDataSize On input, the size of the PrivateData buffer. On
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync output, the size of the private data stored for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync this write.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] PrivateData A pointer to a buffer. The function will copy
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateDataSize bytes from the private data stored
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for this write.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Complete A Boolean value with TRUE indicating that the write
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync was completed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The function completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED The function could not complete successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND No allocated writes exist.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncFtwGetLastWrite (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_GUID *CallerId,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_LBA *Lba,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINTN *Offset,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINTN *Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINTN *PrivateDataSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT VOID *PrivateData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT BOOLEAN *Complete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN PayloadSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SMM_FTW_GET_LAST_WRITE_HEADER *SmmFtwGetLastWriteHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the communicate buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PayloadSize = OFFSET_OF (SMM_FTW_GET_LAST_WRITE_HEADER, Data) + *PrivateDataSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFtwGetLastWriteHeader, PayloadSize, FTW_FUNCTION_GET_LAST_WRITE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmFtwGetLastWriteHeader->PrivateDataSize = *PrivateDataSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send data to SMM.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get data from SMM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *PrivateDataSize = SmmFtwGetLastWriteHeader->PrivateDataSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Lba = SmmFtwGetLastWriteHeader->Lba;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Offset = SmmFtwGetLastWriteHeader->Offset;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Length = SmmFtwGetLastWriteHeader->Length;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Complete = SmmFtwGetLastWriteHeader->Complete;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyGuid (CallerId, &SmmFtwGetLastWriteHeader->CallerId);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (PrivateData, SmmFtwGetLastWriteHeader->Data, *PrivateDataSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SmmCommunicateHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SMM Fault Tolerant Write Protocol notification event handler.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Install Fault Tolerant Write Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Event Event whose notification function is being invoked.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context Pointer to the notification function's context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSmmFtwReady (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EVENT Event,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Just return to avoid install SMM FaultTolerantWriteProtocol again
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // if Fault Tolerant Write protocol had been installed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->LocateProtocol (&gEfiFaultTolerantWriteProtocolGuid, NULL, (VOID **)&FtwProtocol);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install protocol interface
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->InstallProtocolInterface (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiFaultTolerantWriteProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_NATIVE_INTERFACE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mFaultTolerantWriteDriver
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CloseEvent (Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The driver entry point for Fault Tolerant Write driver.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The function does the necessary initialization work.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ImageHandle The firmware allocated handle for the UEFI image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SystemTable A pointer to the EFI system table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS This funtion always return EFI_SUCCESS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncFaultTolerantWriteSmmInitialize (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SYSTEM_TABLE *SystemTable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID *SmmFtwRegistration;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Smm FTW driver is ready
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiCreateProtocolNotifyEvent (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiSmmFaultTolerantWriteProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TPL_CALLBACK,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmFtwReady,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &SmmFtwRegistration
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync