]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwWorkSpace.c
Update Variable driver to depend on full version FaultTolerantWrite protocol, and...
[mirror_edk2.git] / MdeModulePkg / Universal / FirmwareVolume / FaultTolerantWriteDxe / FtwWorkSpace.c
diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwWorkSpace.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwWorkSpace.c
deleted file mode 100644 (file)
index 1dae0d6..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-/** @file\r
-\r
-   Internal functions to operate Working Block Space.\r
-\r
-Copyright (c) 2006 - 2008, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-\r
-#include "FtwLite.h"\r
-\r
-/**\r
-  Check to see if it is a valid work space.\r
-\r
-\r
-  @param WorkingHeader   Pointer of working block header\r
-\r
-  @retval  EFI_SUCCESS    The function completed successfully\r
-  @retval  EFI_ABORTED    The function could not complete successfully.\r
-\r
-**/\r
-BOOLEAN\r
-IsValidWorkSpace (\r
-  IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader\r
-  )\r
-{\r
-  EFI_STATUS                              Status;\r
-  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER WorkingBlockHeader;\r
-\r
-  ASSERT (WorkingHeader != NULL);\r
-  if (WorkingHeader->WorkingBlockValid != FTW_VALID_STATE) {\r
-    DEBUG ((EFI_D_ERROR, "FtwLite: Work block header valid bit check error\n"));\r
-    return FALSE;\r
-  }\r
-  //\r
-  // Check signature with gEfiSystemNvDataFvGuid\r
-  //\r
-  if (!CompareGuid (&gEfiSystemNvDataFvGuid, &WorkingHeader->Signature)) {\r
-    DEBUG ((EFI_D_ERROR, "FtwLite: Work block header signature check error\n"));\r
-    return FALSE;\r
-  }\r
-  //\r
-  // Check the CRC of header\r
-  //\r
-  CopyMem (\r
-    &WorkingBlockHeader,\r
-    WorkingHeader,\r
-    sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)\r
-    );\r
-\r
-  //\r
-  // Filter out the Crc and State fields\r
-  //\r
-  SetMem (\r
-    &WorkingBlockHeader.Crc,\r
-    sizeof (UINT32),\r
-    FTW_ERASED_BYTE\r
-    );\r
-  WorkingBlockHeader.WorkingBlockValid    = FTW_ERASE_POLARITY;\r
-  WorkingBlockHeader.WorkingBlockInvalid  = FTW_ERASE_POLARITY;\r
-\r
-  //\r
-  // Calculate the Crc of woking block header\r
-  //\r
-  Status = gBS->CalculateCrc32 (\r
-                  (UINT8 *) &WorkingBlockHeader,\r
-                  sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),\r
-                  &WorkingBlockHeader.Crc\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  if (WorkingBlockHeader.Crc != WorkingHeader->Crc) {\r
-    DEBUG ((EFI_D_ERROR, "FtwLite: Work block header CRC check error\n"));\r
-    return FALSE;\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-/**\r
-  Initialize a work space when there is no work space.\r
-\r
-\r
-  @param WorkingHeader   Pointer of working block header\r
-\r
-  @retval  EFI_SUCCESS    The function completed successfully\r
-  @retval  EFI_ABORTED    The function could not complete successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-InitWorkSpaceHeader (\r
-  IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  ASSERT (WorkingHeader != NULL);\r
-\r
-  //\r
-  // Here using gEfiSystemNvDataFvGuid as the signature.\r
-  //\r
-  CopyMem (\r
-    &WorkingHeader->Signature,\r
-    &gEfiSystemNvDataFvGuid,\r
-    sizeof (EFI_GUID)\r
-    );\r
-  WorkingHeader->WriteQueueSize = (UINT64) (PcdGet32 (PcdFlashNvStorageFtwWorkingSize) - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER));\r
-\r
-  //\r
-  // Crc is calculated with all the fields except Crc and STATE\r
-  //\r
-  WorkingHeader->WorkingBlockValid    = FTW_ERASE_POLARITY;\r
-  WorkingHeader->WorkingBlockInvalid  = FTW_ERASE_POLARITY;\r
-  SetMem (&WorkingHeader->Crc, sizeof (UINT32), FTW_ERASED_BYTE);\r
-\r
-  //\r
-  // Calculate the CRC value\r
-  //\r
-  Status = gBS->CalculateCrc32 (\r
-                  (UINT8 *) WorkingHeader,\r
-                  sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),\r
-                  &WorkingHeader->Crc\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Restore the WorkingBlockValid flag to VALID state\r
-  //\r
-  WorkingHeader->WorkingBlockValid    = FTW_VALID_STATE;\r
-  WorkingHeader->WorkingBlockInvalid  = FTW_INVALID_STATE;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Update a bit of state on a block device. The location of the bit is\r
-  calculated by the (Lba, Offset, bit). Here bit is determined by the\r
-  the name of a certain bit.\r
-\r
-\r
-  @param FvBlock         FVB Protocol interface to access SrcBlock and DestBlock\r
-  @param Lba             Lba of a block\r
-  @param Offset          Offset on the Lba\r
-  @param NewBit          New value that will override the old value if it can be change\r
-\r
-  @retval  EFI_SUCCESS    A state bit has been updated successfully\r
-  @retval  Others         Access block device error.\r
-                          Notes:\r
-                          Assume all bits of State are inside the same BYTE.\r
-  @retval  EFI_ABORTED    Read block fail\r
-\r
-**/\r
-EFI_STATUS\r
-FtwUpdateFvState (\r
-  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,\r
-  IN EFI_LBA                             Lba,\r
-  IN UINTN                               Offset,\r
-  IN UINT8                               NewBit\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINT8       State;\r
-  UINTN       Length;\r
-\r
-  //\r
-  // Read state from device, assume State is only one byte.\r
-  //\r
-  Length  = sizeof (UINT8);\r
-  Status  = FvBlock->Read (FvBlock, Lba, Offset, &Length, &State);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  State ^= FTW_POLARITY_REVERT;\r
-  State = (UINT8) (State | NewBit);\r
-  State ^= FTW_POLARITY_REVERT;\r
-\r
-  //\r
-  // Write state back to device\r
-  //\r
-  Length  = sizeof (UINT8);\r
-  Status  = FvBlock->Write (FvBlock, Lba, Offset, &Length, &State);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Get the last Write record pointer.\r
-  The last record is the record whose 'complete' state hasn't been set.\r
-  After all, this header may be a EMPTY header entry for next Allocate.\r
-\r
-\r
-  @param FtwLiteDevice   Private data of this driver\r
-  @param FtwLastRecord   Pointer to retrieve the last write record\r
-\r
-  @retval  EFI_SUCCESS      Get the last write record successfully\r
-  @retval  EFI_ABORTED      The FTW work space is damaged\r
-\r
-**/\r
-EFI_STATUS\r
-FtwGetLastRecord (\r
-  IN  EFI_FTW_LITE_DEVICE  *FtwLiteDevice,\r
-  OUT EFI_FTW_LITE_RECORD  **FtwLastRecord\r
-  )\r
-{\r
-  EFI_FTW_LITE_RECORD *Record;\r
-\r
-  *FtwLastRecord = NULL;\r
-  Record = (EFI_FTW_LITE_RECORD *) (FtwLiteDevice->FtwWorkSpaceHeader + 1);\r
-  while (Record->WriteCompleted == FTW_VALID_STATE) {\r
-    //\r
-    // If Offset exceed the FTW work space boudary, return error.\r
-    //\r
-    if ((UINTN) ((UINT8 *) Record - FtwLiteDevice->FtwWorkSpace) > FtwLiteDevice->FtwWorkSpaceSize) {\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    Record++;\r
-  }\r
-  //\r
-  // Last write record is found\r
-  //\r
-  *FtwLastRecord = Record;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Read from working block to refresh the work space in memory.\r
-\r
-\r
-  @param FtwLiteDevice   Point to private data of FTW driver\r
-\r
-  @retval  EFI_SUCCESS    The function completed successfully\r
-  @retval  EFI_ABORTED    The function could not complete successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-WorkSpaceRefresh (\r
-  IN EFI_FTW_LITE_DEVICE  *FtwLiteDevice\r
-  )\r
-{\r
-  EFI_STATUS          Status;\r
-  UINTN               Length;\r
-  UINTN               Offset;\r
-  EFI_FTW_LITE_RECORD *Record;\r
-\r
-  //\r
-  // Initialize WorkSpace as FTW_ERASED_BYTE\r
-  //\r
-  SetMem (\r
-    FtwLiteDevice->FtwWorkSpace,\r
-    FtwLiteDevice->FtwWorkSpaceSize,\r
-    FTW_ERASED_BYTE\r
-    );\r
-\r
-  //\r
-  // Read from working block\r
-  //\r
-  Length = FtwLiteDevice->FtwWorkSpaceSize;\r
-  Status = FtwLiteDevice->FtwFvBlock->Read (\r
-                                        FtwLiteDevice->FtwFvBlock,\r
-                                        FtwLiteDevice->FtwWorkSpaceLba,\r
-                                        FtwLiteDevice->FtwWorkSpaceBase,\r
-                                        &Length,\r
-                                        FtwLiteDevice->FtwWorkSpace\r
-                                        );\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_ABORTED;\r
-  }\r
-  //\r
-  // Refresh the FtwLastRecord\r
-  //\r
-  Status  = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);\r
-\r
-  Record  = FtwLiteDevice->FtwLastRecord;\r
-  Offset  = (UINTN) (UINT8 *) Record - (UINTN) FtwLiteDevice->FtwWorkSpace;\r
-\r
-  //\r
-  // If work space has error or Record is out of the workspace limit, THEN\r
-  //   call reclaim.\r
-  //\r
-  if (EFI_ERROR (Status) || (Offset + FTW_LITE_RECORD_SIZE >= FtwLiteDevice->FtwWorkSpaceSize)) {\r
-    //\r
-    // reclaim work space in working block.\r
-    //\r
-    Status = FtwReclaimWorkSpace (FtwLiteDevice, TRUE);\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "FtwLite: Reclaim workspace - %r\n", Status));\r
-      return EFI_ABORTED;\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Reclaim the work space on the working block.\r
-\r
-\r
-  @param  FtwLiteDevice          Point to private data of FTW driver\r
-  @param  PreserveRecord         Whether get the last record or not\r
-\r
-  @retval EFI_SUCCESS            The function completed successfully\r
-  @retval EFI_OUT_OF_RESOURCES   Allocate memory error\r
-  @retval EFI_ABORTED            The function could not complete successfully\r
-\r
-**/\r
-EFI_STATUS\r
-FtwReclaimWorkSpace (\r
-  IN EFI_FTW_LITE_DEVICE  *FtwLiteDevice,\r
-  IN BOOLEAN              PreserveRecord\r
-  )\r
-{\r
-  EFI_STATUS                              Status;\r
-  UINT8                                   *TempBuffer;\r
-  UINTN                                   TempBufferSize;\r
-  UINT8                                   *Ptr;\r
-  UINTN                                   Length;\r
-  UINTN                                   Index;\r
-  UINTN                                   SpareBufferSize;\r
-  UINT8                                   *SpareBuffer;\r
-  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader;\r
-  EFI_FTW_LITE_RECORD                     *Record;\r
-\r
-  DEBUG ((EFI_D_ERROR, "FtwLite: start to reclaim work space\n"));\r
-\r
-  //\r
-  // Read all original data from working block to a memory buffer\r
-  //\r
-  TempBufferSize = FtwLiteDevice->SpareAreaLength;\r
-  TempBuffer     = AllocateZeroPool (TempBufferSize);\r
-  if (TempBuffer == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Ptr = TempBuffer;\r
-  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
-    Length = FtwLiteDevice->BlockSize;\r
-    Status = FtwLiteDevice->FtwFvBlock->Read (\r
-                                          FtwLiteDevice->FtwFvBlock,\r
-                                          FtwLiteDevice->FtwWorkBlockLba + Index,\r
-                                          0,\r
-                                          &Length,\r
-                                          Ptr\r
-                                          );\r
-    if (EFI_ERROR (Status)) {\r
-      FreePool (TempBuffer);\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    Ptr += Length;\r
-  }\r
-  //\r
-  // Clean up the workspace, remove all the completed records.\r
-  //\r
-  Ptr = TempBuffer +\r
-    ((UINTN) (FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba)) *\r
-    FtwLiteDevice->BlockSize + FtwLiteDevice->FtwWorkSpaceBase;\r
-\r
-  //\r
-  // Clear the content of buffer that will save the new work space data\r
-  //\r
-  SetMem (Ptr, FtwLiteDevice->FtwWorkSpaceSize, FTW_ERASED_BYTE);\r
-\r
-  //\r
-  // Copy EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER to buffer\r
-  //\r
-  CopyMem (\r
-    Ptr,\r
-    FtwLiteDevice->FtwWorkSpaceHeader,\r
-    sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)\r
-    );\r
-  if (PreserveRecord) {\r
-    //\r
-    // Get the last record\r
-    //\r
-    Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);\r
-    Record = FtwLiteDevice->FtwLastRecord;\r
-    if (!EFI_ERROR (Status)                       &&\r
-        Record                 != NULL            &&\r
-        Record->WriteAllocated == FTW_VALID_STATE &&\r
-        Record->WriteCompleted != FTW_VALID_STATE) {\r
-      CopyMem (\r
-        (UINT8 *) Ptr + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),\r
-        Record,\r
-        FTW_LITE_RECORD_SIZE\r
-        );\r
-    }\r
-  }\r
-\r
-  CopyMem (\r
-    FtwLiteDevice->FtwWorkSpace,\r
-    Ptr,\r
-    FtwLiteDevice->FtwWorkSpaceSize\r
-    );\r
-\r
-  Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);\r
-\r
-  //\r
-  // Set the WorkingBlockValid and WorkingBlockInvalid as INVALID\r
-  //\r
-  WorkingBlockHeader                      = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) Ptr;\r
-  WorkingBlockHeader->WorkingBlockValid   = FTW_INVALID_STATE;\r
-  WorkingBlockHeader->WorkingBlockInvalid = FTW_INVALID_STATE;\r
-\r
-  //\r
-  // Try to keep the content of spare block\r
-  // Save spare block into a spare backup memory buffer (Sparebuffer)\r
-  //\r
-  SpareBufferSize = FtwLiteDevice->SpareAreaLength;\r
-  SpareBuffer     = AllocatePool (SpareBufferSize);\r
-  if (SpareBuffer == NULL) {\r
-    FreePool (TempBuffer);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Ptr = SpareBuffer;\r
-  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
-    Length = FtwLiteDevice->BlockSize;\r
-    Status = FtwLiteDevice->FtwBackupFvb->Read (\r
-                                            FtwLiteDevice->FtwBackupFvb,\r
-                                            FtwLiteDevice->FtwSpareLba + Index,\r
-                                            0,\r
-                                            &Length,\r
-                                            Ptr\r
-                                            );\r
-    if (EFI_ERROR (Status)) {\r
-      FreePool (TempBuffer);\r
-      FreePool (SpareBuffer);\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    Ptr += Length;\r
-  }\r
-  //\r
-  // Write the memory buffer to spare block\r
-  //\r
-  Status  = FtwEraseSpareBlock (FtwLiteDevice);\r
-  Ptr     = TempBuffer;\r
-  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
-    Length = FtwLiteDevice->BlockSize;\r
-    Status = FtwLiteDevice->FtwBackupFvb->Write (\r
-                                            FtwLiteDevice->FtwBackupFvb,\r
-                                            FtwLiteDevice->FtwSpareLba + Index,\r
-                                            0,\r
-                                            &Length,\r
-                                            Ptr\r
-                                            );\r
-    if (EFI_ERROR (Status)) {\r
-      FreePool (TempBuffer);\r
-      FreePool (SpareBuffer);\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    Ptr += Length;\r
-  }\r
-  //\r
-  // Free TempBuffer\r
-  //\r
-  FreePool (TempBuffer);\r
-\r
-  //\r
-  // Write the spare block to working block\r
-  //\r
-  Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice);\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (SpareBuffer);\r
-    return Status;\r
-  }\r
-  //\r
-  // Restore spare backup buffer into spare block , if no failure happened during FtwWrite.\r
-  //\r
-  Status  = FtwEraseSpareBlock (FtwLiteDevice);\r
-  Ptr     = SpareBuffer;\r
-  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
-    Length = FtwLiteDevice->BlockSize;\r
-    Status = FtwLiteDevice->FtwBackupFvb->Write (\r
-                                            FtwLiteDevice->FtwBackupFvb,\r
-                                            FtwLiteDevice->FtwSpareLba + Index,\r
-                                            0,\r
-                                            &Length,\r
-                                            Ptr\r
-                                            );\r
-    if (EFI_ERROR (Status)) {\r
-      FreePool (SpareBuffer);\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    Ptr += Length;\r
-  }\r
-\r
-  FreePool (SpareBuffer);\r
-\r
-  DEBUG ((EFI_D_ERROR, "FtwLite: reclaim work space success\n"));\r
-\r
-  return EFI_SUCCESS;\r
-}\r