]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/FirmwareVolume/UpdateDriverDxe/FlashUpdate.c
Remove IntelFrameworkModulePkg
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / FirmwareVolume / UpdateDriverDxe / FlashUpdate.c
diff --git a/IntelFrameworkModulePkg/Universal/FirmwareVolume/UpdateDriverDxe/FlashUpdate.c b/IntelFrameworkModulePkg/Universal/FirmwareVolume/UpdateDriverDxe/FlashUpdate.c
deleted file mode 100644 (file)
index e877c05..0000000
+++ /dev/null
@@ -1,1211 +0,0 @@
-/** @file\r
-  Functions in this file will program the image into flash area.\r
-\r
-  Copyright (c) 2002 - 2018, Intel Corporation. All rights reserved.<BR>\r
-\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "UpdateDriver.h"\r
-\r
-/**\r
-  Write a block size data into flash.\r
-\r
-  @param FvbProtocol     Pointer to FVB protocol.\r
-  @param Lba             Logic block index to be updated.\r
-  @param BlockSize       Block size\r
-  @param Buffer          Buffer data to be written.\r
-\r
-  @retval EFI_SUCCESS   Write data successfully.\r
-  @retval other errors  Write data failed.\r
-\r
-**/\r
-EFI_STATUS\r
-UpdateOneBlock (\r
-  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol,\r
-  IN EFI_LBA                            Lba,\r
-  IN UINTN                              BlockSize,\r
-  IN UINT8                              *Buffer\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  UINTN                                 Size;\r
-\r
-  //\r
-  // First erase the block\r
-  //\r
-  Status                = FvbProtocol->EraseBlocks (\r
-                                         FvbProtocol,\r
-                                         Lba,                        // Lba\r
-                                         1,                          // NumOfBlocks\r
-                                         EFI_LBA_LIST_TERMINATOR\r
-                                         );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Write the block\r
-  //\r
-  Size                  = BlockSize;\r
-  Status                = FvbProtocol->Write (\r
-                                         FvbProtocol,\r
-                                         Lba,                        // Lba\r
-                                         0,                          // Offset\r
-                                         &Size,                      // Size\r
-                                         Buffer                      // Buffer\r
-                                         );\r
-  if ((EFI_ERROR (Status)) || (Size != BlockSize)) {\r
-    return Status;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Write buffer data in a flash block.\r
-\r
-  @param FvbProtocol     Pointer to FVB protocol.\r
-  @param Lba             Logic block index to be updated.\r
-  @param Offset          The offset within the block.\r
-  @param Length          Size of buffer to be updated.\r
-  @param BlockSize       Block size.\r
-  @param Buffer          Buffer data to be updated.\r
-\r
-  @retval EFI_SUCCESS   Write data successfully.\r
-  @retval other errors  Write data failed.\r
-\r
-**/\r
-EFI_STATUS\r
-UpdateBufferInOneBlock (\r
-  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol,\r
-  IN EFI_LBA                            Lba,\r
-  IN UINTN                              Offset,\r
-  IN UINTN                              Length,\r
-  IN UINTN                              BlockSize,\r
-  IN UINT8                              *Buffer\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  UINTN                                 Size;\r
-  UINT8                                 *ReservedBuffer;\r
-\r
-  //\r
-  // If we are going to update a whole block\r
-  //\r
-  if ((Offset == 0) && (Length == BlockSize)) {\r
-    Status              = UpdateOneBlock (\r
-                            FvbProtocol,\r
-                            Lba,\r
-                            BlockSize,\r
-                            Buffer\r
-                            );\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // If it is not a full block update, we need to coalesce data in\r
-  // the block that is not going to be updated and new data together.\r
-  //\r
-\r
-  //\r
-  // Allocate a reserved buffer to make up the final buffer for update\r
-  //\r
-  ReservedBuffer        = NULL;\r
-  ReservedBuffer = AllocatePool (BlockSize);\r
-  if (ReservedBuffer == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  //\r
-  // First get the original content of the block\r
-  //\r
-  Size                  = BlockSize;\r
-  Status                = FvbProtocol->Read (\r
-                                         FvbProtocol,\r
-                                         Lba,\r
-                                         0,\r
-                                         &Size,\r
-                                         ReservedBuffer\r
-                                         );\r
-  if ((EFI_ERROR (Status)) || (Size != BlockSize)) {\r
-    FreePool (ReservedBuffer);\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Overwrite the reserved buffer with new content\r
-  //\r
-  CopyMem (ReservedBuffer + Offset, Buffer, Length);\r
-\r
-  Status                = UpdateOneBlock (\r
-                            FvbProtocol,\r
-                            Lba,\r
-                            BlockSize,\r
-                            ReservedBuffer\r
-                            );\r
-\r
-  FreePool (ReservedBuffer);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Get the last write log, and check the status of last write.\r
-  If not complete, restart will be taken.\r
-\r
-  @param FvbHandle       Handle of FVB protocol.\r
-  @param FtwProtocol     FTW protocol instance.\r
-  @param ConfigData      Config data on updating driver.\r
-  @param PrivateDataSize bytes from the private data\r
-                         stored for this write.\r
-  @param PrivateData     A pointer to a buffer. The function will copy.\r
-  @param Lba             The logical block address of the last write.\r
-  @param Offset          The offset within the block of the last write.\r
-  @param Length          The length of the last write.\r
-  @param Pending         A Boolean value with TRUE indicating\r
-                         that the write was completed.\r
-\r
-  @retval EFI_OUT_OF_RESOURCES  No enough memory is allocated.\r
-  @retval EFI_ABORTED           The FTW work space is damaged.\r
-  @retval EFI_NOT_FOUND         The last write is not done by this driver.\r
-  @retval EFI_SUCCESS           Last write log is got.\r
-\r
-**/\r
-EFI_STATUS\r
-RetrieveLastWrite (\r
-  IN EFI_HANDLE                         FvbHandle,\r
-  IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL  *FtwProtocol,\r
-  IN UPDATE_CONFIG_DATA                 *ConfigData,\r
-  IN UINTN                              PrivateDataSize,\r
-  IN OUT UPDATE_PRIVATE_DATA            *PrivateData,\r
-  IN OUT EFI_LBA                        *Lba,\r
-  IN OUT UINTN                          *Offset,\r
-  IN OUT UINTN                          *Length,\r
-  IN OUT BOOLEAN                        *Pending\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  EFI_GUID                              CallerId;\r
-  UINTN                                 PrivateBufferSize;\r
-  BOOLEAN                               Complete;\r
-  VOID                                  *PrivateDataBuffer;\r
-\r
-  //\r
-  // Get the last write\r
-  //\r
-  *Pending              = FALSE;\r
-  PrivateBufferSize     = PrivateDataSize;\r
-  PrivateDataBuffer     = NULL;\r
-  Status                = FtwProtocol->GetLastWrite (\r
-                                         FtwProtocol,\r
-                                         &CallerId,\r
-                                         Lba,\r
-                                         Offset,\r
-                                         Length,\r
-                                         &PrivateBufferSize,\r
-                                         PrivateData,\r
-                                         &Complete\r
-                                         );\r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // If there is no incompleted record, return success.\r
-    //\r
-    if ((Status == EFI_NOT_FOUND) && Complete) {\r
-      return EFI_SUCCESS;\r
-    } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      //\r
-      // If buffer too small, reallocate buffer and call getlastwrite again\r
-      //\r
-      PrivateDataBuffer = AllocatePool (PrivateBufferSize);\r
-\r
-      if (PrivateDataBuffer == NULL) {\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-\r
-      Status            = FtwProtocol->GetLastWrite (\r
-                                         FtwProtocol,\r
-                                         &CallerId,\r
-                                         Lba,\r
-                                         Offset,\r
-                                         Length,\r
-                                         &PrivateBufferSize,\r
-                                         PrivateDataBuffer,\r
-                                         &Complete\r
-                                         );\r
-      if (EFI_ERROR (Status)) {\r
-        FreePool ( PrivateDataBuffer);\r
-        return EFI_ABORTED;\r
-      } else {\r
-        CopyMem (PrivateData, PrivateDataBuffer, PrivateDataSize);\r
-        FreePool (PrivateDataBuffer);\r
-        PrivateDataBuffer = NULL;\r
-      }\r
-    } else {\r
-      return EFI_ABORTED;\r
-    }\r
-  }\r
-\r
-  *Pending              = TRUE;\r
-\r
-  //\r
-  // If the caller is not the update driver, then return.\r
-  // The update driver cannot continue to perform the update\r
-  //\r
-  if (CompareMem (&CallerId, &gEfiCallerIdGuid, sizeof (EFI_GUID)) != 0) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Check the private data and see if it is the one I need.\r
-  //\r
-  if (CompareMem (&(PrivateData->FileGuid), &(ConfigData->FileGuid), sizeof(EFI_GUID)) != 0) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // If the caller is the update driver and complete is not true, then restart().\r
-  //\r
-  if (!Complete) {\r
-    //\r
-    //  Re-start the update\r
-    //\r
-    Status              = FtwProtocol->Restart (\r
-                                         FtwProtocol,\r
-                                         FvbHandle\r
-                                         );\r
-    //\r
-    // If restart() error, then abort().\r
-    //\r
-    if (EFI_ERROR (Status)) {\r
-      FtwProtocol->Abort (FtwProtocol);\r
-      //\r
-      // Now set Pending as FALSE as this record has been cleared\r
-      //\r
-      *Pending          = FALSE;\r
-      return EFI_SUCCESS;\r
-    }\r
-\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Update the whole FV image in fault tolerant write method.\r
-\r
-  @param FvbHandle       Handle of FVB protocol for the updated flash range.\r
-  @param FvbProtocol     FVB protocol.\r
-  @param BlockMap        Block array to specify flash area.\r
-  @param ConfigData      Config data on updating driver.\r
-  @param ImageBuffer     Image buffer to be updated.\r
-  @param ImageSize       Image size.\r
-\r
-  @retval EFI_SUCCESS            FV image is writed into flash.\r
-  @retval EFI_INVALID_PARAMETER  Config data is not valid.\r
-  @retval EFI_NOT_FOUND          FTW protocol doesn't exist.\r
-  @retval EFI_OUT_OF_RESOURCES   No enough backup space.\r
-  @retval EFI_ABORTED            Error happen when update FV.\r
-\r
-**/\r
-EFI_STATUS\r
-FaultTolerantUpdateOnWholeFv (\r
-  IN EFI_HANDLE                         FvbHandle,\r
-  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol,\r
-  IN EFI_FV_BLOCK_MAP_ENTRY             *BlockMap,\r
-  IN UPDATE_CONFIG_DATA                 *ConfigData,\r
-  IN UINT8                              *ImageBuffer,\r
-  IN UINTN                              ImageSize\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  EFI_FAULT_TOLERANT_WRITE_PROTOCOL     *FtwProtocol;\r
-  UINTN                                 MaxBlockSize;\r
-  UINTN                                 FtwMaxBlockSize;\r
-  BOOLEAN                               Pending;\r
-  UPDATE_PRIVATE_DATA                   PrivateData;\r
-  EFI_LBA                               PendingLba;\r
-  EFI_LBA                               Lba;\r
-  UINTN                                 PendingOffset;\r
-  UINTN                                 Offset;\r
-  UINTN                                 PendingLength;\r
-  UINTN                                 Length;\r
-  EFI_FV_BLOCK_MAP_ENTRY                *PtrMap;\r
-  UINTN                                 NumOfBlocks;\r
-  UINTN                                 Index;\r
-  UINT8                                 *UpdateBuffer;\r
-\r
-  if ((ConfigData->UpdateType != UpdateWholeFV)\r
-    || (!ConfigData->FaultTolerant)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Get the FTW protocol\r
-  //\r
-  Status                = gBS->LocateProtocol (\r
-                                 &gEfiFaultTolerantWriteProtocolGuid,\r
-                                 NULL,\r
-                                 (VOID **) &FtwProtocol\r
-                                 );\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Get the maximum block size of the FV, and number of blocks\r
-  // NumOfBlocks will be the NumOfUdpates.\r
-  //\r
-  MaxBlockSize          = 0;\r
-  NumOfBlocks           = 0;\r
-  PtrMap                = BlockMap;\r
-  while (TRUE) {\r
-    if ((PtrMap->NumBlocks == 0) || (PtrMap->Length == 0)) {\r
-      break;\r
-    }\r
-    if (MaxBlockSize < PtrMap->Length) {\r
-      MaxBlockSize      = PtrMap->Length;\r
-    }\r
-    NumOfBlocks         = NumOfBlocks + PtrMap->NumBlocks;\r
-    PtrMap++;\r
-  }\r
-\r
-  FtwProtocol->GetMaxBlockSize (FtwProtocol, &FtwMaxBlockSize);\r
-  //\r
-  // Not enough backup space. return directly\r
-  //\r
-  if (FtwMaxBlockSize < MaxBlockSize) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  PendingLba            = 0;\r
-  PendingOffset         = 0;\r
-  PendingLength         = 0;\r
-  Pending               = FALSE;\r
-\r
-  //\r
-  // Fault Tolerant Write can only support actual fault tolerance if the write\r
-  // is a reclaim operation, which means the data buffer (new and old) are\r
-  // acutally both stored in flash. But for component update write, the data\r
-  // are now in memory. So we cannot actually recover the data after power\r
-  // failure.\r
-  //\r
-  Status                = RetrieveLastWrite (\r
-                            FvbHandle,\r
-                            FtwProtocol,\r
-                            ConfigData,\r
-                            sizeof (UPDATE_PRIVATE_DATA),\r
-                            &PrivateData,\r
-                            &PendingLba,\r
-                            &PendingOffset,\r
-                            &PendingLength,\r
-                            &Pending\r
-                            );\r
-\r
-  if (Pending && (Status == EFI_NOT_FOUND)) {\r
-    //\r
-    // Cannot continue with the write operation\r
-    //\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  if (EFI_ERROR(Status)) {\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  //\r
-  // Currently we start from the pending write if there is any. But as we\r
-  // are going to update a whole FV, we can just abort last write and start\r
-  // from the very begining.\r
-  //\r
-  if (!Pending) {\r
-    //\r
-    // Now allocte the update private data in FTW. If there is pending\r
-    // write, it has already been allocated and no need to allocate here.\r
-    //\r
-    Status              = FtwProtocol->Allocate (\r
-                                         FtwProtocol,\r
-                                         &gEfiCallerIdGuid,\r
-                                         sizeof (UPDATE_PRIVATE_DATA),\r
-                                         NumOfBlocks\r
-                                         );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Perform the update now. If there are pending writes, we need to\r
-  // start from the pending write instead of the very beginning.\r
-  //\r
-  PtrMap                = BlockMap;\r
-  Lba                   = 0;\r
-  Offset                = 0;\r
-  UpdateBuffer          = ImageBuffer;\r
-  CopyMem (\r
-    (VOID *) &PrivateData.FileGuid,\r
-    (VOID *) &ConfigData->FileGuid,\r
-     sizeof (EFI_GUID)\r
-  );\r
-\r
-  while (TRUE) {\r
-    if ((PtrMap->NumBlocks == 0) || (PtrMap->Length == 0)) {\r
-      break;\r
-    }\r
-    Length              = (UINTN)PtrMap->Length;\r
-    for (Index = 0; Index < PtrMap->NumBlocks; Index++) {\r
-\r
-      //\r
-      // Add an extra check here to see if the pending record is correct\r
-      //\r
-      if (Pending && (Lba == PendingLba)) {\r
-        if ((PendingOffset != Offset) || (PendingLength != Length)) {\r
-          //\r
-          // Error.\r
-          //\r
-          Status          = EFI_ABORTED;\r
-          break;\r
-        }\r
-      }\r
-\r
-      if ((!Pending) || (Lba >= PendingLba)) {\r
-        Status            = FtwProtocol->Write (\r
-                                           FtwProtocol,\r
-                                           Lba,                  // Lba\r
-                                           Offset,               // Offset\r
-                                           Length,               // Size\r
-                                           &PrivateData,         // Private Data\r
-                                           FvbHandle,            // FVB handle\r
-                                           UpdateBuffer          // Buffer\r
-                                           );\r
-      }\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        break;\r
-      }\r
-      Lba++;\r
-      UpdateBuffer      = (UINT8 *) ((UINTN)UpdateBuffer + Length);\r
-    }\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-    PtrMap++;\r
-  }\r
-\r
-  return Status;\r
-\r
-}\r
-\r
-/**\r
-  Directly update the whole FV image without fault tolerant write method.\r
-\r
-  @param FvbHandle       Handle of FVB protocol for the updated flash range.\r
-  @param FvbProtocol     FVB protocol.\r
-  @param BlockMap        Block array to specify flash area.\r
-  @param ConfigData      Config data on updating driver.\r
-  @param ImageBuffer     Image buffer to be updated.\r
-  @param ImageSize       Image size.\r
-\r
-  @retval EFI_SUCCESS            FV image is writed into flash.\r
-  @retval EFI_INVALID_PARAMETER  Config data is not valid.\r
-  @retval EFI_ABORTED            Error happen when update FV.\r
-\r
-**/\r
-EFI_STATUS\r
-NonFaultTolerantUpdateOnWholeFv (\r
-  IN EFI_HANDLE                         FvbHandle,\r
-  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol,\r
-  IN EFI_FV_BLOCK_MAP_ENTRY             *BlockMap,\r
-  IN UPDATE_CONFIG_DATA                 *ConfigData,\r
-  IN UINT8                              *ImageBuffer,\r
-  IN UINTN                              ImageSize\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  EFI_FV_BLOCK_MAP_ENTRY                *PtrMap;\r
-  UINTN                                 Index;\r
-  EFI_LBA                               UpdateLba;\r
-  UINT8                                 *UpdateBuffer;\r
-  UINTN                                 UpdateSize;\r
-\r
-  if ((ConfigData->UpdateType != UpdateWholeFV )\r
-    || (ConfigData->FaultTolerant)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Status                = EFI_SUCCESS;\r
-  PtrMap                = BlockMap;\r
-  UpdateLba             = 0;\r
-  UpdateBuffer          = ImageBuffer;\r
-\r
-  //\r
-  // Perform the update now\r
-  //\r
-  while (TRUE) {\r
-    if ((PtrMap->NumBlocks == 0) || (PtrMap->Length == 0)) {\r
-      break;\r
-    }\r
-    UpdateSize          = (UINTN)PtrMap->Length;\r
-    for (Index = 0; Index < PtrMap->NumBlocks; Index++) {\r
-      Status            = UpdateOneBlock (\r
-                            FvbProtocol,\r
-                            UpdateLba,\r
-                            UpdateSize,\r
-                            UpdateBuffer\r
-                            );\r
-      if (EFI_ERROR (Status)) {\r
-        break;\r
-      }\r
-\r
-      UpdateLba++;\r
-      UpdateBuffer      = (UINT8 *) ((UINTN)UpdateBuffer + UpdateSize);\r
-    }\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-    PtrMap++;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Update the whole FV image, and reinsall FVB protocol for the updated FV image.\r
-\r
-  @param FvbHandle       Handle of FVB protocol for the updated flash range.\r
-  @param FvbProtocol     FVB protocol.\r
-  @param ConfigData      Config data on updating driver.\r
-  @param ImageBuffer     Image buffer to be updated.\r
-  @param ImageSize       Image size.\r
-\r
-  @retval EFI_INVALID_PARAMETER  Update type is not UpdateWholeFV.\r
-                                 Or Image size is not same to the size of whole FV.\r
-  @retval EFI_OUT_OF_RESOURCES   No enoug memory is allocated.\r
-  @retval EFI_SUCCESS            FV image is updated, and its FVB protocol is reinstalled.\r
-\r
-**/\r
-EFI_STATUS\r
-PerformUpdateOnWholeFv (\r
-  IN EFI_HANDLE                         FvbHandle,\r
-  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol,\r
-  IN UPDATE_CONFIG_DATA                 *ConfigData,\r
-  IN UINT8                              *ImageBuffer,\r
-  IN UINTN                              ImageSize\r
-)\r
-{\r
-  EFI_STATUS                            Status;\r
-  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;\r
-  EFI_FV_BLOCK_MAP_ENTRY                *BlockMap;\r
-  CHAR16                                *TmpStr;\r
-\r
-  if (ConfigData->UpdateType != UpdateWholeFV) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Get the header of the firmware volume\r
-  //\r
-  FwVolHeader           = NULL;\r
-  FwVolHeader = AllocatePool (((EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (ConfigData->BaseAddress)))->HeaderLength);\r
-  if (FwVolHeader == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  CopyMem (\r
-    FwVolHeader,\r
-    (VOID *) ((UINTN) (ConfigData->BaseAddress)),\r
-    ((EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (ConfigData->BaseAddress)))->HeaderLength\r
-    );\r
-\r
-  //\r
-  // Check if ImageSize is the same as the size of the whole FV\r
-  //\r
-  if ((UINT64)ImageSize != FwVolHeader->FvLength) {\r
-    FreePool (FwVolHeader);\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Print on screen\r
-  //\r
-  TmpStr  = HiiGetString (gHiiHandle, STRING_TOKEN(UPDATE_FIRMWARE_VOLUME), NULL);\r
-  if (TmpStr != NULL) {\r
-    Print (TmpStr, ConfigData->BaseAddress, (FwVolHeader->FvLength + ConfigData->BaseAddress));\r
-    FreePool (TmpStr);\r
-  }\r
-\r
-  DEBUG ((EFI_D_UPDATE, "UpdateDriver: updating whole FV from %08LX to %08LX\n",\r
-    ConfigData->BaseAddress, (FwVolHeader->FvLength + ConfigData->BaseAddress)));\r
-\r
-  //\r
-  // Get the block map of the firmware volume\r
-  //\r
-  BlockMap              = &(FwVolHeader->BlockMap[0]);\r
-\r
-  //\r
-  // It is about the same if we are going to fault tolerantly update\r
-  // a certain FV in our current design. But we divide non-fault tolerant\r
-  // and fault tolerant udpate here for better maintenance as fault\r
-  // tolerance may change and may be done more wisely if we have space.\r
-  //\r
-  if (ConfigData->FaultTolerant) {\r
-    Status              = FaultTolerantUpdateOnWholeFv (\r
-                            FvbHandle,\r
-                            FvbProtocol,\r
-                            BlockMap,\r
-                            ConfigData,\r
-                            ImageBuffer,\r
-                            ImageSize\r
-                            );\r
-  } else {\r
-    Status              = NonFaultTolerantUpdateOnWholeFv (\r
-                            FvbHandle,\r
-                            FvbProtocol,\r
-                            BlockMap,\r
-                            ConfigData,\r
-                            ImageBuffer,\r
-                            ImageSize\r
-                            );\r
-  }\r
-\r
-  FreePool (FwVolHeader);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // As the whole FV has been replaced, the FV driver shall re-parse the\r
-  // firmware volume. So re-install FVB protocol here\r
-  //\r
-  Status                =  gBS->ReinstallProtocolInterface (\r
-                                   FvbHandle,\r
-                                   &gEfiFirmwareVolumeBlockProtocolGuid,\r
-                                   FvbProtocol,\r
-                                   FvbProtocol\r
-                                   );\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Update certain file in the FV.\r
-\r
-  @param FvbHandle       Handle of FVB protocol for the updated flash range.\r
-  @param FvbProtocol     FVB protocol.\r
-  @param ConfigData      Config data on updating driver.\r
-  @param ImageBuffer     Image buffer to be updated.\r
-  @param ImageSize       Image size.\r
-  @param FileType        FFS file type.\r
-  @param FileAttributes  FFS file attribute\r
-\r
-  @retval EFI_INVALID_PARAMETER  Update type is not UpdateFvFile.\r
-                                 Or Image size is not same to the size of whole FV.\r
-  @retval EFI_UNSUPPORTED        PEIM FFS is unsupported to be updated.\r
-  @retval EFI_SUCCESS            The FFS file is added into FV.\r
-\r
-**/\r
-EFI_STATUS\r
-PerformUpdateOnFvFile (\r
-  IN EFI_HANDLE                         FvbHandle,\r
-  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol,\r
-  IN UPDATE_CONFIG_DATA                 *ConfigData,\r
-  IN UINT8                              *ImageBuffer,\r
-  IN UINTN                              ImageSize,\r
-  IN EFI_FV_FILETYPE                    FileType,\r
-  IN EFI_FV_FILE_ATTRIBUTES             FileAttributes\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  EFI_FIRMWARE_VOLUME2_PROTOCOL          *FwVolProtocol;\r
-  EFI_FV_WRITE_FILE_DATA                FileData;\r
-  CHAR16                                *TmpStr;\r
-\r
-  if (ConfigData->UpdateType != UpdateFvFile) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Print on screen\r
-  //\r
-  TmpStr  = HiiGetString (gHiiHandle, STRING_TOKEN(UPDATE_FIRMWARE_VOLUME_FILE), NULL);\r
-  if (TmpStr != NULL) {\r
-    Print (TmpStr, &(ConfigData->FileGuid));\r
-    FreePool (TmpStr);\r
-  }\r
-\r
-  DEBUG ((EFI_D_UPDATE, "UpdateDriver: updating file: %g\n",\r
-    &(ConfigData->FileGuid)));\r
-\r
-  //\r
-  // Get Firmware volume protocol on this FVB protocol\r
-  //\r
-  Status                = gBS->HandleProtocol (\r
-                                  FvbHandle,\r
-                                  &gEfiFirmwareVolume2ProtocolGuid,\r
-                                  (VOID **) &FwVolProtocol\r
-                                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // If it is a PEIM, we need first to rebase it before committing\r
-  // the write to target\r
-  //\r
-  if ((FileType == EFI_FV_FILETYPE_PEI_CORE) || (FileType == EFI_FV_FILETYPE_PEIM )\r
-    || (FileType == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  FileData.NameGuid         = &(ConfigData->FileGuid);\r
-  FileData.Type             = FileType;\r
-  FileData.FileAttributes   = FileAttributes;\r
-  FileData.Buffer           = ImageBuffer;\r
-  FileData.BufferSize       = (UINT32) ImageSize;\r
-\r
-  Status                    = FwVolProtocol->WriteFile (\r
-                                                FwVolProtocol,\r
-                                                1,                        // NumberOfFiles\r
-                                                (EFI_FV_WRITE_POLICY)ConfigData->FaultTolerant,\r
-                                                &FileData\r
-                                                );\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Update the buffer into flash area in fault tolerant write method.\r
-\r
-  @param ImageBuffer     Image buffer to be updated.\r
-  @param SizeLeft        Size of the image buffer.\r
-  @param UpdatedSize     Size of the updated buffer.\r
-  @param ConfigData      Config data on updating driver.\r
-  @param FlashAddress    Flash address to be updated as start address.\r
-  @param FvbProtocol     FVB protocol.\r
-  @param FvbHandle       Handle of FVB protocol for the updated flash range.\r
-\r
-  @retval EFI_SUCCESS            Buffer data is updated into flash.\r
-  @retval EFI_INVALID_PARAMETER  Base flash address is not in FVB flash area.\r
-  @retval EFI_NOT_FOUND          FTW protocol doesn't exist.\r
-  @retval EFI_OUT_OF_RESOURCES   No enough backup space.\r
-  @retval EFI_ABORTED            Error happen when update flash area.\r
-\r
-**/\r
-EFI_STATUS\r
-FaultTolerantUpdateOnPartFv (\r
-  IN       UINT8                         *ImageBuffer,\r
-  IN       UINTN                         SizeLeft,\r
-  IN OUT   UINTN                         *UpdatedSize,\r
-  IN       UPDATE_CONFIG_DATA            *ConfigData,\r
-  IN       EFI_PHYSICAL_ADDRESS          FlashAddress,\r
-  IN       EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol,\r
-  IN       EFI_HANDLE                    FvbHandle\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;\r
-  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeaderTmp;\r
-  EFI_PHYSICAL_ADDRESS                  BaseAddress;\r
-  EFI_PHYSICAL_ADDRESS                  FvBase;\r
-  EFI_PHYSICAL_ADDRESS                  NextBlock;\r
-  EFI_FV_BLOCK_MAP_ENTRY                *BlockMap;\r
-  EFI_FV_BLOCK_MAP_ENTRY                *PtrMap;\r
-  UINTN                                 NumOfUpdates;\r
-  UINTN                                 TotalSize;\r
-  EFI_PHYSICAL_ADDRESS                  StartAddress;\r
-  EFI_FAULT_TOLERANT_WRITE_PROTOCOL     *FtwProtocol;\r
-  UINTN                                 MaxBlockSize;\r
-  UINTN                                 FtwMaxBlockSize;\r
-  BOOLEAN                               Pending;\r
-  UPDATE_PRIVATE_DATA                   PrivateData;\r
-  EFI_LBA                               PendingLba;\r
-  EFI_LBA                               Lba;\r
-  UINTN                                 BlockSize;\r
-  UINTN                                 PendingOffset;\r
-  UINTN                                 Offset;\r
-  UINTN                                 PendingLength;\r
-  UINTN                                 Length;\r
-  UINTN                                 Index;\r
-  UINT8                                 *Image;\r
-\r
-  //\r
-  // Get the block map to update the block one by one\r
-  //\r
-  Status = FvbProtocol->GetPhysicalAddress (\r
-                          FvbProtocol,\r
-                          &FvBase\r
-                          );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  FwVolHeaderTmp = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvBase;\r
-  if ((FlashAddress < FvBase) || (FlashAddress > (FvBase + FwVolHeaderTmp->FvLength))) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)AllocateCopyPool (\r
-                                                FwVolHeaderTmp->HeaderLength,\r
-                                                FwVolHeaderTmp\r
-                                                );\r
-  if (FwVolHeader == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  //\r
-  // For fault tolerant write, we have to know how many blocks we need to\r
-  // update. So we will calculate number of updates and max block size first\r
-  //\r
-  NumOfUpdates          = 0;\r
-  MaxBlockSize          = 0;\r
-  TotalSize             = SizeLeft;\r
-  StartAddress          = FlashAddress;\r
-  BaseAddress           = FvBase;\r
-  BlockMap              = &(FwVolHeader->BlockMap[0]);\r
-  PtrMap                = BlockMap;\r
-\r
-  while (TotalSize > 0) {\r
-    if ((PtrMap->NumBlocks == 0) || (PtrMap->Length == 0)) {\r
-      break;\r
-    }\r
-\r
-    BlockSize           = PtrMap->Length;\r
-    for (Index = 0; Index < PtrMap->NumBlocks; Index++) {\r
-      NextBlock         = BaseAddress + BlockSize;\r
-      //\r
-      // Check if this block need to be updated\r
-      //\r
-      if ((StartAddress >= BaseAddress) && (StartAddress < NextBlock)) {\r
-        //\r
-        // Get the maximum block size\r
-        //\r
-        if (MaxBlockSize < BlockSize) {\r
-          MaxBlockSize  = BlockSize;\r
-        }\r
-\r
-        //\r
-        // This block shall be udpated. So increment number of updates\r
-        //\r
-        NumOfUpdates++;\r
-        Offset          = (UINTN) (StartAddress - BaseAddress);\r
-        Length          = TotalSize;\r
-        if ((Length + Offset ) > BlockSize) {\r
-          Length        = BlockSize - Offset;\r
-        }\r
-\r
-        StartAddress    = StartAddress + Length;\r
-        TotalSize       = TotalSize - Length;\r
-        if (TotalSize <= 0) {\r
-          break;\r
-        }\r
-      }\r
-      BaseAddress       = NextBlock;\r
-    }\r
-    PtrMap++;\r
-  }\r
-\r
-  //\r
-  // Get the FTW protocol\r
-  //\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiFaultTolerantWriteProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &FtwProtocol\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (FwVolHeader);\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  FtwProtocol->GetMaxBlockSize (FtwProtocol, &FtwMaxBlockSize);\r
-\r
-  //\r
-  // Not enough backup space. return directly\r
-  //\r
-  if (FtwMaxBlockSize < MaxBlockSize) {\r
-    FreePool (FwVolHeader);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  PendingLba            = 0;\r
-  PendingOffset         = 0;\r
-  PendingLength         = 0;\r
-  Pending               = FALSE;\r
-\r
-  //\r
-  // Fault Tolerant Write can only support actual fault tolerance if the write\r
-  // is a reclaim operation, which means the data buffer (new and old) are\r
-  // acutally both stored in flash. But for component update write, the data\r
-  // are now in memory. So we cannot actually recover the data after power\r
-  // failure.\r
-  //\r
-  Status = RetrieveLastWrite (\r
-             FvbHandle,\r
-             FtwProtocol,\r
-             ConfigData,\r
-             sizeof (UPDATE_PRIVATE_DATA),\r
-             &PrivateData,\r
-             &PendingLba,\r
-             &PendingOffset,\r
-             &PendingLength,\r
-             &Pending\r
-             );\r
-  if (Pending && (Status == EFI_NOT_FOUND)) {\r
-    //\r
-    // I'm not the owner of the pending fault tolerant write record\r
-    // Cannot continue with the write operation\r
-    //\r
-    FreePool (FwVolHeader);\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  if (EFI_ERROR(Status)) {\r
-    FreePool (FwVolHeader);\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  //\r
-  // Currently we start from the pending write if there is any. But if the\r
-  // caller is exactly the same, and the new data is already a in memory, (it\r
-  // cannot be stored in flash in last write,) we can just abort last write\r
-  // and start from the very begining.\r
-  //\r
-  if (!Pending) {\r
-    //\r
-    // Now allocte the update private data in FTW. If there is pending\r
-    // write, it has already been allocated and no need to allocate here.\r
-    //\r
-    Status = FtwProtocol->Allocate (\r
-                            FtwProtocol,\r
-                            &gEfiCallerIdGuid,\r
-                            sizeof (UPDATE_PRIVATE_DATA),\r
-                            NumOfUpdates\r
-                            );\r
-    if (EFI_ERROR (Status)) {\r
-      FreePool (FwVolHeader);\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Perform the update now. If there are pending writes, we need to\r
-  // start from the pending write instead of the very beginning.\r
-  //\r
-  TotalSize             = SizeLeft;\r
-  Lba                   = 0;\r
-  StartAddress          = FlashAddress;\r
-  BaseAddress           = FvBase;\r
-  PtrMap                = BlockMap;\r
-  Image                 = ImageBuffer;\r
-  CopyMem (\r
-    (VOID *) &PrivateData.FileGuid,\r
-    (VOID *) &ConfigData->FileGuid,\r
-     sizeof (EFI_GUID)\r
-  );\r
-\r
-  while (TotalSize > 0) {\r
-    if ((PtrMap->NumBlocks == 0) || (PtrMap->Length == 0)) {\r
-      break;\r
-    }\r
-\r
-    BlockSize           = (UINTN)PtrMap->Length;\r
-    for (Index = 0;  Index < PtrMap->NumBlocks; Index++) {\r
-      NextBlock         = BaseAddress + BlockSize;\r
-      if ((StartAddress >= BaseAddress) && (StartAddress < NextBlock)) {\r
-        //\r
-        // So we need to update this block\r
-        //\r
-        Offset          = (UINTN) (StartAddress - BaseAddress);\r
-        Length          = TotalSize;\r
-        if ((Length + Offset ) > BlockSize) {\r
-          Length        = BlockSize - Offset;\r
-        }\r
-\r
-        //\r
-        // Add an extra check here to see if the pending record is correct\r
-        //\r
-        if (Pending && (Lba == PendingLba)) {\r
-          if ((PendingOffset != Offset) || (PendingLength != Length)) {\r
-            //\r
-            // Error.\r
-            //\r
-            Status          = EFI_ABORTED;\r
-            break;\r
-          }\r
-        }\r
-\r
-        if ((!Pending) || (Lba >= PendingLba)) {\r
-          DEBUG ((EFI_D_UPDATE, "Update Flash area from %08LX to %08LX\n", StartAddress, (UINT64)StartAddress + Length));\r
-          Status            = FtwProtocol->Write (\r
-                                             FtwProtocol,\r
-                                             Lba,                  // Lba\r
-                                             Offset,               // Offset\r
-                                             Length,               // Size\r
-                                             &PrivateData,         // Private Data\r
-                                             FvbHandle,            // FVB handle\r
-                                             Image                 // Buffer\r
-                                             );\r
-          if (EFI_ERROR (Status)) {\r
-            break;\r
-          }\r
-        }\r
-\r
-        //\r
-        // Now increment StartAddress, ImageBuffer and decrease the\r
-        // left size to prepare for the next block update.\r
-        //\r
-        StartAddress    = StartAddress + Length;\r
-        Image           = Image + Length;\r
-        TotalSize       = TotalSize - Length;\r
-        if (TotalSize <= 0) {\r
-          break;\r
-        }\r
-      }\r
-      BaseAddress       = NextBlock;\r
-      Lba++;\r
-    }\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-    PtrMap++;\r
-  }\r
-\r
-  FreePool (FwVolHeader);\r
-\r
-  *UpdatedSize = SizeLeft - TotalSize;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Directly update the buffer into flash area without fault tolerant write method.\r
-\r
-  @param ImageBuffer     Image buffer to be updated.\r
-  @param SizeLeft        Size of the image buffer.\r
-  @param UpdatedSize     Size of the updated buffer.\r
-  @param FlashAddress    Flash address to be updated as start address.\r
-  @param FvbProtocol     FVB protocol.\r
-  @param FvbHandle       Handle of FVB protocol for the updated flash range.\r
-\r
-  @retval EFI_SUCCESS            Buffer data is updated into flash.\r
-  @retval EFI_INVALID_PARAMETER  Base flash address is not in FVB flash area.\r
-  @retval EFI_OUT_OF_RESOURCES   No enough backup space.\r
-\r
-**/\r
-EFI_STATUS\r
-NonFaultTolerantUpdateOnPartFv (\r
-  IN      UINT8                         *ImageBuffer,\r
-  IN      UINTN                         SizeLeft,\r
-  IN OUT  UINTN                         *UpdatedSize,\r
-  IN      EFI_PHYSICAL_ADDRESS          FlashAddress,\r
-  IN      EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol,\r
-  IN      EFI_HANDLE                    FvbHandle\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;\r
-  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeaderTmp;\r
-  EFI_PHYSICAL_ADDRESS                  BaseAddress;\r
-  EFI_PHYSICAL_ADDRESS                  NextBlock;\r
-  EFI_FV_BLOCK_MAP_ENTRY                *BlockMap;\r
-  UINTN                                 Index;\r
-  UINTN                                 TotalSize;\r
-  UINTN                                 BlockSize;\r
-  EFI_LBA                               Lba;\r
-  UINTN                                 Offset;\r
-  UINTN                                 Length;\r
-  UINT8                                 *Image;\r
-\r
-  //\r
-  // Get the block map to update the block one by one\r
-  //\r
-  Status                = FvbProtocol->GetPhysicalAddress (\r
-                                         FvbProtocol,\r
-                                         &BaseAddress\r
-                                         );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  FwVolHeaderTmp = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)BaseAddress;\r
-  if ((FlashAddress < BaseAddress) || (FlashAddress > ( BaseAddress + FwVolHeaderTmp->FvLength ))) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)AllocateCopyPool (\r
-                                                FwVolHeaderTmp->HeaderLength,\r
-                                                FwVolHeaderTmp\r
-                                                );\r
-  if (FwVolHeader == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Image                 = ImageBuffer;\r
-  TotalSize             = SizeLeft;\r
-  BlockMap              = &(FwVolHeader->BlockMap[0]);\r
-  Lba                   = 0;\r
-\r
-  while (TotalSize > 0) {\r
-    if ((BlockMap->NumBlocks == 0) || (BlockMap->Length == 0)) {\r
-      break;\r
-    }\r
-\r
-    BlockSize           = BlockMap->Length;\r
-    for (Index = 0 ; Index < BlockMap->NumBlocks ; Index++) {\r
-      NextBlock         = BaseAddress + BlockSize;\r
-      if ((FlashAddress >= BaseAddress) && (FlashAddress < NextBlock)) {\r
-        //\r
-        // So we need to update this block\r
-        //\r
-        Offset          = (UINTN) FlashAddress - (UINTN) BaseAddress;\r
-        Length          = TotalSize;\r
-        if ((Length + Offset ) > BlockSize) {\r
-          Length        = BlockSize - Offset;\r
-        }\r
-\r
-        DEBUG ((EFI_D_UPDATE, "Update Flash area from %08LX to %08LX\n", FlashAddress, (UINT64)FlashAddress + Length));\r
-        //\r
-        // Update the block\r
-        //\r
-        Status          = UpdateBufferInOneBlock (\r
-                            FvbProtocol,\r
-                            Lba,\r
-                            Offset,\r
-                            Length,\r
-                            BlockSize,\r
-                            Image\r
-                            );\r
-        if (EFI_ERROR (Status)) {\r
-          FreePool (FwVolHeader);\r
-          return Status;\r
-        }\r
-\r
-        //\r
-        // Now increment FlashAddress, ImageBuffer and decrease the\r
-        // left size to prepare for the next block update.\r
-        //\r
-        FlashAddress    = FlashAddress + Length;\r
-        Image           = Image + Length;\r
-        TotalSize       = TotalSize - Length;\r
-        if (TotalSize <= 0) {\r
-          break;\r
-        }\r
-      }\r
-      BaseAddress       = NextBlock;\r
-      Lba++;\r
-    }\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-    BlockMap++;\r
-  }\r
-\r
-  FreePool (FwVolHeader);\r
-\r
-  *UpdatedSize          = SizeLeft - TotalSize;\r
-\r
-  return EFI_SUCCESS;\r
-}\r