\r
Internal functions to operate Working Block Space.\r
\r
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
-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
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
VOID\r
)\r
{\r
- EFI_STATUS Status;\r
-\r
//\r
- // Check signature with gEfiSystemNvDataFvGuid.\r
+ // Check signature with gEdkiiWorkingBlockSignatureGuid.\r
//\r
- if (CompareGuid (&gEfiSystemNvDataFvGuid, &mWorkingBlockHeader.Signature)) {\r
+ if (CompareGuid (&gEdkiiWorkingBlockSignatureGuid, &mWorkingBlockHeader.Signature)) {\r
//\r
// The local work space header has been initialized.\r
//\r
);\r
\r
//\r
- // Here using gEfiSystemNvDataFvGuid as the signature.\r
+ // Here using gEdkiiWorkingBlockSignatureGuid as the signature.\r
//\r
CopyMem (\r
&mWorkingBlockHeader.Signature,\r
- &gEfiSystemNvDataFvGuid,\r
+ &gEdkiiWorkingBlockSignatureGuid,\r
sizeof (EFI_GUID)\r
);\r
- mWorkingBlockHeader.WriteQueueSize = (UINT64) (PcdGet32 (PcdFlashNvStorageFtwWorkingSize) - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER));\r
+ mWorkingBlockHeader.WriteQueueSize = PcdGet32 (PcdFlashNvStorageFtwWorkingSize) - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER);\r
\r
//\r
// Crc is calculated with all the fields except Crc and STATE, so leave them as FTW_ERASED_BYTE.\r
//\r
// Calculate the Crc of woking block header\r
//\r
- Status = gBS->CalculateCrc32 (\r
- &mWorkingBlockHeader,\r
- sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),\r
- &mWorkingBlockHeader.Crc\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+ mWorkingBlockHeader.Crc = FtwCalculateCrc32 (&mWorkingBlockHeader,\r
+ sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER));\r
\r
mWorkingBlockHeader.WorkingBlockValid = FTW_VALID_STATE;\r
mWorkingBlockHeader.WorkingBlockInvalid = FTW_INVALID_STATE;\r
return TRUE;\r
}\r
\r
- DEBUG ((EFI_D_ERROR, "Ftw: Work block header check error\n"));\r
+ DEBUG ((EFI_D_INFO, "Ftw: Work block header check mismatch\n"));\r
return FALSE;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Read work space data from work block or spare block.\r
+\r
+ @param FvBlock FVB Protocol interface to access the block.\r
+ @param BlockSize The size of the block.\r
+ @param Lba Lba of the block.\r
+ @param Offset The offset within the block.\r
+ @param Length The number of bytes to read from the block.\r
+ @param Buffer The data is read.\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
+ReadWorkSpaceData (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
+ IN UINTN BlockSize,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN Offset,\r
+ IN UINTN Length,\r
+ OUT UINT8 *Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 *Ptr;\r
+ UINTN MyLength;\r
+\r
+ //\r
+ // Calculate the real Offset and Lba to write.\r
+ //\r
+ while (Offset >= BlockSize) {\r
+ Offset -= BlockSize;\r
+ Lba++;\r
+ }\r
+\r
+ Ptr = Buffer;\r
+ while (Length > 0) {\r
+ if ((Offset + Length) > BlockSize) {\r
+ MyLength = BlockSize - Offset;\r
+ } else {\r
+ MyLength = Length;\r
+ }\r
+\r
+ Status = FvBlock->Read (\r
+ FvBlock,\r
+ Lba,\r
+ Offset,\r
+ &MyLength,\r
+ Ptr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_ABORTED;\r
+ }\r
+ Offset = 0;\r
+ Length -= MyLength;\r
+ Ptr += MyLength;\r
+ Lba++;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Write work space data to work block.\r
+\r
+ @param FvBlock FVB Protocol interface to access the block.\r
+ @param BlockSize The size of the block.\r
+ @param Lba Lba of the block.\r
+ @param Offset The offset within the block to place the data.\r
+ @param Length The number of bytes to write to the block.\r
+ @param Buffer The data to write.\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
+WriteWorkSpaceData (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
+ IN UINTN BlockSize,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN Offset,\r
+ IN UINTN Length,\r
+ IN UINT8 *Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 *Ptr;\r
+ UINTN MyLength;\r
+\r
+ //\r
+ // Calculate the real Offset and Lba to write.\r
+ //\r
+ while (Offset >= BlockSize) {\r
+ Offset -= BlockSize;\r
+ Lba++;\r
+ }\r
+\r
+ Ptr = Buffer;\r
+ while (Length > 0) {\r
+ if ((Offset + Length) > BlockSize) {\r
+ MyLength = BlockSize - Offset;\r
+ } else {\r
+ MyLength = Length;\r
+ }\r
+\r
+ Status = FvBlock->Write (\r
+ FvBlock,\r
+ Lba,\r
+ Offset,\r
+ &MyLength,\r
+ Ptr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_ABORTED;\r
+ }\r
+ Offset = 0;\r
+ Length -= MyLength;\r
+ Ptr += MyLength;\r
+ Lba++;\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Read from working block to refresh the work space in memory.\r
\r
)\r
{\r
EFI_STATUS Status;\r
- UINTN Length;\r
UINTN RemainingSpaceSize;\r
\r
//\r
//\r
// Read from working block\r
//\r
- Length = FtwDevice->FtwWorkSpaceSize;\r
- Status = FtwDevice->FtwFvBlock->Read (\r
- FtwDevice->FtwFvBlock,\r
- FtwDevice->FtwWorkSpaceLba,\r
- FtwDevice->FtwWorkSpaceBase,\r
- &Length,\r
- FtwDevice->FtwWorkSpace\r
- );\r
+ Status = ReadWorkSpaceData (\r
+ FtwDevice->FtwFvBlock,\r
+ FtwDevice->WorkBlockSize,\r
+ FtwDevice->FtwWorkSpaceLba,\r
+ FtwDevice->FtwWorkSpaceBase,\r
+ FtwDevice->FtwWorkSpaceSize,\r
+ FtwDevice->FtwWorkSpace\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_ABORTED;\r
}\r
//\r
// Read from working block again\r
//\r
- Length = FtwDevice->FtwWorkSpaceSize;\r
- Status = FtwDevice->FtwFvBlock->Read (\r
- FtwDevice->FtwFvBlock,\r
- FtwDevice->FtwWorkSpaceLba,\r
- FtwDevice->FtwWorkSpaceBase,\r
- &Length,\r
- FtwDevice->FtwWorkSpace\r
- );\r
+ Status = ReadWorkSpaceData (\r
+ FtwDevice->FtwFvBlock,\r
+ FtwDevice->WorkBlockSize,\r
+ FtwDevice->FtwWorkSpaceLba,\r
+ FtwDevice->FtwWorkSpaceBase,\r
+ FtwDevice->FtwWorkSpaceSize,\r
+ FtwDevice->FtwWorkSpace\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_ABORTED;\r
}\r
UINT8 *Ptr;\r
EFI_LBA WorkSpaceLbaOffset;\r
\r
- DEBUG ((EFI_D_ERROR, "Ftw: start to reclaim work space\n"));\r
+ DEBUG ((EFI_D_INFO, "Ftw: start to reclaim work space\n"));\r
\r
WorkSpaceLbaOffset = FtwDevice->FtwWorkSpaceLba - FtwDevice->FtwWorkBlockLba;\r
\r
//\r
// Read all original data from working block to a memory buffer\r
//\r
- TempBufferSize = FtwDevice->SpareAreaLength;\r
+ TempBufferSize = FtwDevice->NumberOfWorkBlock * FtwDevice->WorkBlockSize;\r
TempBuffer = AllocateZeroPool (TempBufferSize);\r
if (TempBuffer == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
Ptr = TempBuffer;\r
- for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) {\r
- Length = FtwDevice->BlockSize;\r
+ for (Index = 0; Index < FtwDevice->NumberOfWorkBlock; Index += 1) {\r
+ Length = FtwDevice->WorkBlockSize;\r
Status = FtwDevice->FtwFvBlock->Read (\r
FtwDevice->FtwFvBlock,\r
FtwDevice->FtwWorkBlockLba + Index,\r
// Clean up the workspace, remove all the completed records.\r
//\r
Ptr = TempBuffer +\r
- (UINTN) WorkSpaceLbaOffset * FtwDevice->BlockSize +\r
+ (UINTN) WorkSpaceLbaOffset * FtwDevice->WorkBlockSize +\r
FtwDevice->FtwWorkSpaceBase;\r
\r
//\r
CopyMem (\r
Ptr + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),\r
FtwDevice->FtwLastWriteHeader,\r
- WRITE_TOTAL_SIZE (Header->NumberOfWrites, Header->PrivateDataSize)\r
+ FTW_WRITE_TOTAL_SIZE (Header->NumberOfWrites, Header->PrivateDataSize)\r
);\r
}\r
}\r
// Set the WorkingBlockValid and WorkingBlockInvalid as INVALID\r
//\r
WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (TempBuffer +\r
- (UINTN) WorkSpaceLbaOffset * FtwDevice->BlockSize +\r
+ (UINTN) WorkSpaceLbaOffset * FtwDevice->WorkBlockSize +\r
FtwDevice->FtwWorkSpaceBase);\r
WorkingBlockHeader->WorkingBlockValid = FTW_INVALID_STATE;\r
WorkingBlockHeader->WorkingBlockInvalid = FTW_INVALID_STATE;\r
\r
Ptr = SpareBuffer;\r
for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) {\r
- Length = FtwDevice->BlockSize;\r
+ Length = FtwDevice->SpareBlockSize;\r
Status = FtwDevice->FtwBackupFvb->Read (\r
FtwDevice->FtwBackupFvb,\r
FtwDevice->FtwSpareLba + Index,\r
// Write the memory buffer to spare block\r
//\r
Status = FtwEraseSpareBlock (FtwDevice);\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (TempBuffer);\r
+ FreePool (SpareBuffer);\r
+ return EFI_ABORTED;\r
+ }\r
Ptr = TempBuffer;\r
- for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) {\r
- Length = FtwDevice->BlockSize;\r
+ for (Index = 0; TempBufferSize > 0; Index += 1) {\r
+ if (TempBufferSize > FtwDevice->SpareBlockSize) {\r
+ Length = FtwDevice->SpareBlockSize;\r
+ } else {\r
+ Length = TempBufferSize;\r
+ }\r
Status = FtwDevice->FtwBackupFvb->Write (\r
FtwDevice->FtwBackupFvb,\r
FtwDevice->FtwSpareLba + Index,\r
}\r
\r
Ptr += Length;\r
+ TempBufferSize -= Length;\r
}\r
//\r
// Free TempBuffer\r
//\r
Status = FtwUpdateFvState (\r
FtwDevice->FtwBackupFvb,\r
- FtwDevice->FtwSpareLba + WorkSpaceLbaOffset,\r
- FtwDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),\r
+ FtwDevice->SpareBlockSize,\r
+ FtwDevice->FtwSpareLba + FtwDevice->FtwWorkSpaceLbaInSpare,\r
+ FtwDevice->FtwWorkSpaceBaseInSpare + sizeof (EFI_GUID) + sizeof (UINT32),\r
WORKING_BLOCK_VALID\r
);\r
if (EFI_ERROR (Status)) {\r
//\r
Status = FtwUpdateFvState (\r
FtwDevice->FtwFvBlock,\r
+ FtwDevice->WorkBlockSize,\r
FtwDevice->FtwWorkSpaceLba,\r
FtwDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),\r
WORKING_BLOCK_INVALID\r
// Restore spare backup buffer into spare block , if no failure happened during FtwWrite.\r
//\r
Status = FtwEraseSpareBlock (FtwDevice);\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (SpareBuffer);\r
+ return EFI_ABORTED;\r
+ }\r
Ptr = SpareBuffer;\r
for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) {\r
- Length = FtwDevice->BlockSize;\r
+ Length = FtwDevice->SpareBlockSize;\r
Status = FtwDevice->FtwBackupFvb->Write (\r
FtwDevice->FtwBackupFvb,\r
FtwDevice->FtwSpareLba + Index,\r
\r
FreePool (SpareBuffer);\r
\r
- DEBUG ((EFI_D_ERROR, "Ftw: reclaim work space successfully\n"));\r
+ DEBUG ((EFI_D_INFO, "Ftw: reclaim work space successfully\n"));\r
\r
return EFI_SUCCESS;\r
}\r