/** @file

  These are the common Fault Tolerant Write (FTW) functions that are shared
  by DXE FTW driver and SMM FTW driver.

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "FaultTolerantWrite.h"

//
// Fault Tolerant Write Protocol API
//

/**
  Query the largest block that may be updated in a fault tolerant manner.


  @param This            The pointer to this protocol instance.
  @param BlockSize       A pointer to a caller allocated UINTN that is updated to
                         indicate the size of the largest block that can be updated.

  @return EFI_SUCCESS   The function completed successfully

**/
EFI_STATUS
EFIAPI
FtwGetMaxBlockSize (
  IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL  *This,
  OUT UINTN                             *BlockSize
  )
{
  EFI_FTW_DEVICE  *FtwDevice;

  if (!FeaturePcdGet (PcdFullFtwServiceEnable)) {
    return EFI_UNSUPPORTED;
  }

  FtwDevice = FTW_CONTEXT_FROM_THIS (This);

  *BlockSize = FtwDevice->SpareAreaLength;

  return EFI_SUCCESS;
}

/**
  Allocates space for the protocol to maintain information about writes.
  Since writes must be completed in a fault tolerant manner and multiple
  updates will require more resources to be successful, this function
  enables the protocol to ensure that enough space exists to track
  information about the upcoming writes.

  All writes must be completed or aborted before another fault tolerant write can occur.

  @param This            The pointer to this protocol instance.
  @param CallerId        The GUID identifying the write.
  @param PrivateDataSize The size of the caller's private data
                         that must be recorded for each write.
  @param NumberOfWrites  The number of fault tolerant block writes
                         that will need to occur.

  @return EFI_SUCCESS        The function completed successfully
  @retval EFI_ABORTED        The function could not complete successfully.
  @retval EFI_ACCESS_DENIED  All allocated writes have not been completed.

**/
EFI_STATUS
EFIAPI
FtwAllocate (
  IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL  *This,
  IN EFI_GUID                           *CallerId,
  IN UINTN                              PrivateDataSize,
  IN UINTN                              NumberOfWrites
  )
{
  EFI_STATUS                       Status;
  UINTN                            Offset;
  EFI_FTW_DEVICE                   *FtwDevice;
  EFI_FAULT_TOLERANT_WRITE_HEADER  *FtwHeader;

  FtwDevice = FTW_CONTEXT_FROM_THIS (This);

  Status = WorkSpaceRefresh (FtwDevice);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  //
  // Check if there is enough space for the coming allocation
  //
  if (FTW_WRITE_TOTAL_SIZE (NumberOfWrites, PrivateDataSize) > FtwDevice->FtwWorkSpaceHeader->WriteQueueSize) {
    DEBUG ((DEBUG_ERROR, "Ftw: Allocate() request exceed Workspace, Caller: %g\n", CallerId));
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Find the last write header and record.
  // If the FtwHeader is complete, skip the completed last write header/records
  //
  FtwHeader = FtwDevice->FtwLastWriteHeader;

  //
  // Previous write has not completed, access denied.
  //
  if ((FtwHeader->HeaderAllocated == FTW_VALID_STATE) || (FtwHeader->WritesAllocated == FTW_VALID_STATE)) {
    return EFI_ACCESS_DENIED;
  }

  //
  // If workspace is not enough, then reclaim workspace
  //
  Offset = (UINT8 *)FtwHeader - (UINT8 *)FtwDevice->FtwWorkSpace;
  if (Offset + FTW_WRITE_TOTAL_SIZE (NumberOfWrites, PrivateDataSize) > FtwDevice->FtwWorkSpaceSize) {
    Status = FtwReclaimWorkSpace (FtwDevice, TRUE);
    if (EFI_ERROR (Status)) {
      return EFI_ABORTED;
    }

    FtwHeader = FtwDevice->FtwLastWriteHeader;
  }

  //
  // Prepare FTW write header,
  // overwrite the buffer and write to workspace.
  //
  FtwHeader->WritesAllocated = FTW_INVALID_STATE;
  FtwHeader->Complete        = FTW_INVALID_STATE;
  CopyMem (&FtwHeader->CallerId, CallerId, sizeof (EFI_GUID));
  FtwHeader->NumberOfWrites  = NumberOfWrites;
  FtwHeader->PrivateDataSize = PrivateDataSize;
  FtwHeader->HeaderAllocated = FTW_VALID_STATE;

  Status = WriteWorkSpaceData (
             FtwDevice->FtwFvBlock,
             FtwDevice->WorkBlockSize,
             FtwDevice->FtwWorkSpaceLba,
             FtwDevice->FtwWorkSpaceBase + Offset,
             sizeof (EFI_FAULT_TOLERANT_WRITE_HEADER),
             (UINT8 *)FtwHeader
             );
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  //
  // Update Header->WriteAllocated as VALID
  //
  Status = FtwUpdateFvState (
             FtwDevice->FtwFvBlock,
             FtwDevice->WorkBlockSize,
             FtwDevice->FtwWorkSpaceLba,
             FtwDevice->FtwWorkSpaceBase + Offset,
             WRITES_ALLOCATED
             );
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  DEBUG (
    (DEBUG_INFO,
     "Ftw: Allocate() success, Caller:%g, # %d\n",
     CallerId,
     NumberOfWrites)
    );

  return EFI_SUCCESS;
}

/**
  Write a record with fault tolerant manner.
  Since the content has already backuped in spare block, the write is
  guaranteed to be completed with fault tolerant manner.

  @param This            The pointer to this protocol instance.
  @param Fvb             The FVB protocol that provides services for
                         reading, writing, and erasing the target block.
  @param BlockSize       The size of the block.

  @retval  EFI_SUCCESS          The function completed successfully
  @retval  EFI_ABORTED          The function could not complete successfully

**/
EFI_STATUS
FtwWriteRecord (
  IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL   *This,
  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb,
  IN UINTN                               BlockSize
  )
{
  EFI_STATUS                       Status;
  EFI_FTW_DEVICE                   *FtwDevice;
  EFI_FAULT_TOLERANT_WRITE_HEADER  *Header;
  EFI_FAULT_TOLERANT_WRITE_RECORD  *Record;
  UINTN                            Offset;
  UINTN                            NumberOfWriteBlocks;

  FtwDevice = FTW_CONTEXT_FROM_THIS (This);

  //
  // Spare Complete but Destination not complete,
  // Recover the target block with the spare block.
  //
  Header = FtwDevice->FtwLastWriteHeader;
  Record = FtwDevice->FtwLastWriteRecord;

  //
  // IF target block is working block, THEN Flush Spare Block To Working Block;
  // ELSE flush spare block to target block, which may be boot block after all.
  //
  if (IsWorkingBlock (FtwDevice, Fvb, Record->Lba)) {
    //
    // If target block is working block,
    // it also need to set SPARE_COMPLETED to spare block.
    //
    Offset = (UINT8 *)Record - FtwDevice->FtwWorkSpace;
    Status = FtwUpdateFvState (
               FtwDevice->FtwBackupFvb,
               FtwDevice->SpareBlockSize,
               FtwDevice->FtwSpareLba + FtwDevice->FtwWorkSpaceLbaInSpare,
               FtwDevice->FtwWorkSpaceBaseInSpare + Offset,
               SPARE_COMPLETED
               );
    if (EFI_ERROR (Status)) {
      return EFI_ABORTED;
    }

    Status = FlushSpareBlockToWorkingBlock (FtwDevice);
  } else if (IsBootBlock (FtwDevice, Fvb)) {
    //
    // Update boot block
    //
    Status = FlushSpareBlockToBootBlock (FtwDevice);
  } else {
    //
    // Update blocks other than working block or boot block
    //
    NumberOfWriteBlocks = FTW_BLOCKS ((UINTN)(Record->Offset + Record->Length), BlockSize);
    Status              = FlushSpareBlockToTargetBlock (FtwDevice, Fvb, Record->Lba, BlockSize, NumberOfWriteBlocks);
  }

  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  //
  // Record the DestionationComplete in record
  //
  Offset = (UINT8 *)Record - FtwDevice->FtwWorkSpace;
  Status = FtwUpdateFvState (
             FtwDevice->FtwFvBlock,
             FtwDevice->WorkBlockSize,
             FtwDevice->FtwWorkSpaceLba,
             FtwDevice->FtwWorkSpaceBase + Offset,
             DEST_COMPLETED
             );
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  Record->DestinationComplete = FTW_VALID_STATE;

  //
  // If this is the last Write in these write sequence,
  // set the complete flag of write header.
  //
  if (IsLastRecordOfWrites (Header, Record)) {
    Offset = (UINT8 *)Header - FtwDevice->FtwWorkSpace;
    Status = FtwUpdateFvState (
               FtwDevice->FtwFvBlock,
               FtwDevice->WorkBlockSize,
               FtwDevice->FtwWorkSpaceLba,
               FtwDevice->FtwWorkSpaceBase + Offset,
               WRITES_COMPLETED
               );
    Header->Complete = FTW_VALID_STATE;
    if (EFI_ERROR (Status)) {
      return EFI_ABORTED;
    }
  }

  return EFI_SUCCESS;
}

/**
  Starts a target block update. This function will record data about write
  in fault tolerant storage and will complete the write in a recoverable
  manner, ensuring at all times that either the original contents or
  the modified contents are available.

  @param This            The pointer to this protocol instance.
  @param Lba             The logical block address of the target block.
  @param Offset          The offset within the target block to place the data.
  @param Length          The number of bytes to write to the target block.
  @param PrivateData     A pointer to private data that the caller requires to
                         complete any pending writes in the event of a fault.
  @param FvBlockHandle   The handle of FVB protocol that provides services for
                         reading, writing, and erasing the target block.
  @param Buffer          The data to write.

  @retval EFI_SUCCESS          The function completed successfully
  @retval EFI_ABORTED          The function could not complete successfully.
  @retval EFI_BAD_BUFFER_SIZE  The input data can't fit within the spare block.
                               Offset + *NumBytes > SpareAreaLength.
  @retval EFI_ACCESS_DENIED    No writes have been allocated.
  @retval EFI_OUT_OF_RESOURCES Cannot allocate enough memory resource.
  @retval EFI_NOT_FOUND        Cannot find FVB protocol by handle.

**/
EFI_STATUS
EFIAPI
FtwWrite (
  IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL  *This,
  IN EFI_LBA                            Lba,
  IN UINTN                              Offset,
  IN UINTN                              Length,
  IN VOID                               *PrivateData,
  IN EFI_HANDLE                         FvBlockHandle,
  IN VOID                               *Buffer
  )
{
  EFI_STATUS                          Status;
  EFI_FTW_DEVICE                      *FtwDevice;
  EFI_FAULT_TOLERANT_WRITE_HEADER     *Header;
  EFI_FAULT_TOLERANT_WRITE_RECORD     *Record;
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;
  UINTN                               MyLength;
  UINTN                               MyOffset;
  UINTN                               MyBufferSize;
  UINT8                               *MyBuffer;
  UINTN                               SpareBufferSize;
  UINT8                               *SpareBuffer;
  UINTN                               Index;
  UINT8                               *Ptr;
  EFI_PHYSICAL_ADDRESS                FvbPhysicalAddress;
  UINTN                               BlockSize;
  UINTN                               NumberOfBlocks;
  UINTN                               NumberOfWriteBlocks;
  UINTN                               WriteLength;

  FtwDevice = FTW_CONTEXT_FROM_THIS (This);

  Status = WorkSpaceRefresh (FtwDevice);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  Header = FtwDevice->FtwLastWriteHeader;
  Record = FtwDevice->FtwLastWriteRecord;

  if (IsErasedFlashBuffer ((UINT8 *)Header, sizeof (EFI_FAULT_TOLERANT_WRITE_HEADER))) {
    if (PrivateData == NULL) {
      //
      // Ftw Write Header is not allocated.
      // No additional private data, the private data size is zero. Number of record can be set to 1.
      //
      Status = FtwAllocate (This, &gEfiCallerIdGuid, 0, 1);
      if (EFI_ERROR (Status)) {
        return Status;
      }
    } else {
      //
      // Ftw Write Header is not allocated
      // Additional private data is not NULL, the private data size can't be determined.
      //
      DEBUG ((DEBUG_ERROR, "Ftw: no allocates space for write record!\n"));
      DEBUG ((DEBUG_ERROR, "Ftw: Allocate service should be called before Write service!\n"));
      return EFI_NOT_READY;
    }
  }

  //
  // If Record is out of the range of Header, return access denied.
  //
  if (((UINTN)Record - (UINTN)Header) > FTW_WRITE_TOTAL_SIZE (Header->NumberOfWrites - 1, Header->PrivateDataSize)) {
    return EFI_ACCESS_DENIED;
  }

  //
  // Check the COMPLETE flag of last write header
  //
  if (Header->Complete == FTW_VALID_STATE) {
    return EFI_ACCESS_DENIED;
  }

  if (Record->DestinationComplete == FTW_VALID_STATE) {
    return EFI_ACCESS_DENIED;
  }

  if ((Record->SpareComplete == FTW_VALID_STATE) && (Record->DestinationComplete != FTW_VALID_STATE)) {
    return EFI_NOT_READY;
  }

  //
  // Get the FVB protocol by handle
  //
  Status = FtwGetFvbByHandle (FvBlockHandle, &Fvb);
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  Status = Fvb->GetPhysicalAddress (Fvb, &FvbPhysicalAddress);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Ftw: Write(), Get FVB physical address - %r\n", Status));
    return EFI_ABORTED;
  }

  //
  // Now, one FVB has one type of BlockSize.
  //
  Status = Fvb->GetBlockSize (Fvb, 0, &BlockSize, &NumberOfBlocks);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Ftw: Write(), Get block size - %r\n", Status));
    return EFI_ABORTED;
  }

  NumberOfWriteBlocks = FTW_BLOCKS (Offset + Length, BlockSize);
  DEBUG ((DEBUG_INFO, "Ftw: Write(), BlockSize - 0x%x, NumberOfWriteBlock - 0x%x\n", BlockSize, NumberOfWriteBlocks));
  WriteLength = NumberOfWriteBlocks * BlockSize;

  //
  // Check if the input data can fit within the spare block.
  //
  if (WriteLength > FtwDevice->SpareAreaLength) {
    return EFI_BAD_BUFFER_SIZE;
  }

  //
  // Set BootBlockUpdate FLAG if it's updating boot block.
  //
  if (IsBootBlock (FtwDevice, Fvb)) {
    Record->BootBlockUpdate = FTW_VALID_STATE;
    //
    // Boot Block and Spare Block should have same block size and block numbers.
    //
    ASSERT ((BlockSize == FtwDevice->SpareBlockSize) && (NumberOfWriteBlocks == FtwDevice->NumberOfSpareBlock));
  }

  //
  // Write the record to the work space.
  //
  Record->Lba            = Lba;
  Record->Offset         = Offset;
  Record->Length         = Length;
  Record->RelativeOffset = (INT64)(FvbPhysicalAddress + (UINTN)Lba * BlockSize) - (INT64)FtwDevice->SpareAreaAddress;
  if (PrivateData != NULL) {
    CopyMem ((Record + 1), PrivateData, (UINTN)Header->PrivateDataSize);
  }

  MyOffset = (UINT8 *)Record - FtwDevice->FtwWorkSpace;
  MyLength = FTW_RECORD_SIZE (Header->PrivateDataSize);

  Status = WriteWorkSpaceData (
             FtwDevice->FtwFvBlock,
             FtwDevice->WorkBlockSize,
             FtwDevice->FtwWorkSpaceLba,
             FtwDevice->FtwWorkSpaceBase + MyOffset,
             MyLength,
             (UINT8 *)Record
             );
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  //
  // Record has written to working block, then do the data.
  //
  //
  // Allocate a memory buffer
  //
  MyBufferSize = WriteLength;
  MyBuffer     = AllocatePool (MyBufferSize);
  if (MyBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Read all original data from target block to memory buffer
  //
  Ptr = MyBuffer;
  for (Index = 0; Index < NumberOfWriteBlocks; Index += 1) {
    MyLength = BlockSize;
    Status   = Fvb->Read (Fvb, Lba + Index, 0, &MyLength, Ptr);
    if (EFI_ERROR (Status)) {
      FreePool (MyBuffer);
      return EFI_ABORTED;
    }

    Ptr += MyLength;
  }

  //
  // Overwrite the updating range data with
  // the input buffer content
  //
  CopyMem (MyBuffer + Offset, Buffer, Length);

  //
  // Try to keep the content of spare block
  // Save spare block into a spare backup memory buffer (Sparebuffer)
  //
  SpareBufferSize = FtwDevice->SpareAreaLength;
  SpareBuffer     = AllocatePool (SpareBufferSize);
  if (SpareBuffer == NULL) {
    FreePool (MyBuffer);
    return EFI_OUT_OF_RESOURCES;
  }

  Ptr = SpareBuffer;
  for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) {
    MyLength = FtwDevice->SpareBlockSize;
    Status   = FtwDevice->FtwBackupFvb->Read (
                                          FtwDevice->FtwBackupFvb,
                                          FtwDevice->FtwSpareLba + Index,
                                          0,
                                          &MyLength,
                                          Ptr
                                          );
    if (EFI_ERROR (Status)) {
      FreePool (MyBuffer);
      FreePool (SpareBuffer);
      return EFI_ABORTED;
    }

    Ptr += MyLength;
  }

  //
  // Write the memory buffer to spare block
  // Do not assume Spare Block and Target Block have same block size
  //
  Status = FtwEraseSpareBlock (FtwDevice);
  if (EFI_ERROR (Status)) {
    FreePool (MyBuffer);
    FreePool (SpareBuffer);
    return EFI_ABORTED;
  }

  Ptr = MyBuffer;
  for (Index = 0; MyBufferSize > 0; Index += 1) {
    if (MyBufferSize > FtwDevice->SpareBlockSize) {
      MyLength = FtwDevice->SpareBlockSize;
    } else {
      MyLength = MyBufferSize;
    }

    Status = FtwDevice->FtwBackupFvb->Write (
                                        FtwDevice->FtwBackupFvb,
                                        FtwDevice->FtwSpareLba + Index,
                                        0,
                                        &MyLength,
                                        Ptr
                                        );
    if (EFI_ERROR (Status)) {
      FreePool (MyBuffer);
      FreePool (SpareBuffer);
      return EFI_ABORTED;
    }

    Ptr          += MyLength;
    MyBufferSize -= MyLength;
  }

  //
  // Free MyBuffer
  //
  FreePool (MyBuffer);

  //
  // Set the SpareComplete in the FTW record,
  //
  MyOffset = (UINT8 *)Record - FtwDevice->FtwWorkSpace;
  Status   = FtwUpdateFvState (
               FtwDevice->FtwFvBlock,
               FtwDevice->WorkBlockSize,
               FtwDevice->FtwWorkSpaceLba,
               FtwDevice->FtwWorkSpaceBase + MyOffset,
               SPARE_COMPLETED
               );
  if (EFI_ERROR (Status)) {
    FreePool (SpareBuffer);
    return EFI_ABORTED;
  }

  Record->SpareComplete = FTW_VALID_STATE;

  //
  //  Since the content has already backuped in spare block, the write is
  //  guaranteed to be completed with fault tolerant manner.
  //
  Status = FtwWriteRecord (This, Fvb, BlockSize);
  if (EFI_ERROR (Status)) {
    FreePool (SpareBuffer);
    return EFI_ABORTED;
  }

  //
  // Restore spare backup buffer into spare block , if no failure happened during FtwWrite.
  //
  Status = FtwEraseSpareBlock (FtwDevice);
  if (EFI_ERROR (Status)) {
    FreePool (SpareBuffer);
    return EFI_ABORTED;
  }

  Ptr = SpareBuffer;
  for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) {
    MyLength = FtwDevice->SpareBlockSize;
    Status   = FtwDevice->FtwBackupFvb->Write (
                                          FtwDevice->FtwBackupFvb,
                                          FtwDevice->FtwSpareLba + Index,
                                          0,
                                          &MyLength,
                                          Ptr
                                          );
    if (EFI_ERROR (Status)) {
      FreePool (SpareBuffer);
      return EFI_ABORTED;
    }

    Ptr += MyLength;
  }

  //
  // All success.
  //
  FreePool (SpareBuffer);

  DEBUG (
    (DEBUG_INFO,
     "Ftw: Write() success, (Lba:Offset)=(%lx:0x%x), Length: 0x%x\n",
     Lba,
     Offset,
     Length)
    );

  return EFI_SUCCESS;
}

/**
  Restarts a previously interrupted write. The caller must provide the
  block protocol needed to complete the interrupted write.

  @param This            The pointer to this protocol instance.
  @param FvBlockHandle   The handle of FVB protocol that provides services for
                         reading, writing, and erasing the target block.

  @retval  EFI_SUCCESS          The function completed successfully
  @retval  EFI_ACCESS_DENIED    No pending writes exist
  @retval  EFI_NOT_FOUND        FVB protocol not found by the handle
  @retval  EFI_ABORTED          The function could not complete successfully

**/
EFI_STATUS
EFIAPI
FtwRestart (
  IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL  *This,
  IN EFI_HANDLE                         FvBlockHandle
  )
{
  EFI_STATUS                          Status;
  EFI_FTW_DEVICE                      *FtwDevice;
  EFI_FAULT_TOLERANT_WRITE_HEADER     *Header;
  EFI_FAULT_TOLERANT_WRITE_RECORD     *Record;
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;
  UINTN                               BlockSize;
  UINTN                               NumberOfBlocks;

  FtwDevice = FTW_CONTEXT_FROM_THIS (This);

  Status = WorkSpaceRefresh (FtwDevice);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  Header = FtwDevice->FtwLastWriteHeader;
  Record = FtwDevice->FtwLastWriteRecord;

  //
  // Spare Complete but Destination not complete,
  // Recover the targt block with the spare block.
  //
  Status = FtwGetFvbByHandle (FvBlockHandle, &Fvb);
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  //
  // Now, one FVB has one type of BlockSize
  //
  Status = Fvb->GetBlockSize (Fvb, 0, &BlockSize, &NumberOfBlocks);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Ftw: Restart(), Get block size - %r\n", Status));
    return EFI_ABORTED;
  }

  //
  // Check the COMPLETE flag of last write header
  //
  if (Header->Complete == FTW_VALID_STATE) {
    return EFI_ACCESS_DENIED;
  }

  //
  // Check the flags of last write record
  //
  if (Record->DestinationComplete == FTW_VALID_STATE) {
    return EFI_ACCESS_DENIED;
  }

  if ((Record->SpareComplete != FTW_VALID_STATE)) {
    return EFI_ABORTED;
  }

  //
  //  Since the content has already backuped in spare block, the write is
  //  guaranteed to be completed with fault tolerant manner.
  //
  Status = FtwWriteRecord (This, Fvb, BlockSize);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  //
  // Erase Spare block
  // This is restart, no need to keep spareblock content.
  //
  Status = FtwEraseSpareBlock (FtwDevice);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  DEBUG ((DEBUG_INFO, "%a(): success\n", __func__));
  return EFI_SUCCESS;
}

/**
  Aborts all previous allocated writes.

  @param This                  The pointer to this protocol instance.

  @retval EFI_SUCCESS          The function completed successfully
  @retval EFI_ABORTED          The function could not complete successfully.
  @retval EFI_NOT_FOUND        No allocated writes exist.

**/
EFI_STATUS
EFIAPI
FtwAbort (
  IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL  *This
  )
{
  EFI_STATUS      Status;
  UINTN           Offset;
  EFI_FTW_DEVICE  *FtwDevice;

  FtwDevice = FTW_CONTEXT_FROM_THIS (This);

  Status = WorkSpaceRefresh (FtwDevice);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  if (FtwDevice->FtwLastWriteHeader->HeaderAllocated != FTW_VALID_STATE) {
    return EFI_NOT_FOUND;
  }

  if (FtwDevice->FtwLastWriteHeader->Complete == FTW_VALID_STATE) {
    return EFI_NOT_FOUND;
  }

  //
  // Update the complete state of the header as VALID and abort.
  //
  Offset = (UINT8 *)FtwDevice->FtwLastWriteHeader - FtwDevice->FtwWorkSpace;
  Status = FtwUpdateFvState (
             FtwDevice->FtwFvBlock,
             FtwDevice->WorkBlockSize,
             FtwDevice->FtwWorkSpaceLba,
             FtwDevice->FtwWorkSpaceBase + Offset,
             WRITES_COMPLETED
             );
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  FtwDevice->FtwLastWriteHeader->Complete = FTW_VALID_STATE;

  DEBUG ((DEBUG_INFO, "%a(): success\n", __func__));
  return EFI_SUCCESS;
}

/**
  Starts a target block update. This records information about the write
  in fault tolerant storage and will complete the write in a recoverable
  manner, ensuring at all times that either the original contents or
  the modified contents are available.

  @param This            The pointer to this protocol instance.
  @param CallerId        The GUID identifying the last write.
  @param Lba             The logical block address of the last write.
  @param Offset          The offset within the block of the last write.
  @param Length          The length of the last write.
  @param PrivateDataSize bytes from the private data
                         stored for this write.
  @param PrivateData     A pointer to a buffer. The function will copy
  @param Complete        A Boolean value with TRUE indicating
                         that the write was completed.

  @retval EFI_SUCCESS           The function completed successfully
  @retval EFI_ABORTED           The function could not complete successfully
  @retval EFI_NOT_FOUND         No allocated writes exist
  @retval EFI_BUFFER_TOO_SMALL  Input buffer is not larget enough

**/
EFI_STATUS
EFIAPI
FtwGetLastWrite (
  IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL  *This,
  OUT EFI_GUID                          *CallerId,
  OUT EFI_LBA                           *Lba,
  OUT UINTN                             *Offset,
  OUT UINTN                             *Length,
  IN OUT UINTN                          *PrivateDataSize,
  OUT VOID                              *PrivateData,
  OUT BOOLEAN                           *Complete
  )
{
  EFI_STATUS                       Status;
  EFI_FTW_DEVICE                   *FtwDevice;
  EFI_FAULT_TOLERANT_WRITE_HEADER  *Header;
  EFI_FAULT_TOLERANT_WRITE_RECORD  *Record;

  if (!FeaturePcdGet (PcdFullFtwServiceEnable)) {
    return EFI_UNSUPPORTED;
  }

  FtwDevice = FTW_CONTEXT_FROM_THIS (This);

  Status = WorkSpaceRefresh (FtwDevice);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  Header = FtwDevice->FtwLastWriteHeader;
  Record = FtwDevice->FtwLastWriteRecord;

  //
  // If Header is incompleted and the last record has completed, then
  // call Abort() to set the Header->Complete FLAG.
  //
  if ((Header->Complete != FTW_VALID_STATE) &&
      (Record->DestinationComplete == FTW_VALID_STATE) &&
      IsLastRecordOfWrites (Header, Record)
      )
  {
    Status    = FtwAbort (This);
    *Complete = TRUE;
    return EFI_NOT_FOUND;
  }

  //
  // If there is no write header/record, return not found.
  //
  if (Header->HeaderAllocated != FTW_VALID_STATE) {
    *Complete = TRUE;
    return EFI_NOT_FOUND;
  }

  //
  // If this record SpareComplete has not set, then it can not restart.
  //
  if (Record->SpareComplete != FTW_VALID_STATE) {
    Status = GetPreviousRecordOfWrites (Header, &Record);
    if (EFI_ERROR (Status)) {
      FtwAbort (This);
      *Complete = TRUE;
      return EFI_NOT_FOUND;
    }

    ASSERT (Record != NULL);
  }

  //
  // Fill all the requested values
  //
  CopyMem (CallerId, &Header->CallerId, sizeof (EFI_GUID));
  *Lba      = Record->Lba;
  *Offset   = (UINTN)Record->Offset;
  *Length   = (UINTN)Record->Length;
  *Complete = (BOOLEAN)(Record->DestinationComplete == FTW_VALID_STATE);

  if (*PrivateDataSize < Header->PrivateDataSize) {
    *PrivateDataSize = (UINTN)Header->PrivateDataSize;
    PrivateData      = NULL;
    Status           = EFI_BUFFER_TOO_SMALL;
  } else {
    *PrivateDataSize = (UINTN)Header->PrivateDataSize;
    CopyMem (PrivateData, Record + 1, *PrivateDataSize);
    Status = EFI_SUCCESS;
  }

  DEBUG ((DEBUG_INFO, "%a(): success\n", __func__));

  return Status;
}
