34 for (Index = 0; Index < BufferSize; Index += 1) {
35 if (*Ptr++ != FTW_ERASED_BYTE) {
65 return FvBlock->EraseBlocks (
95 return FtwDevice->FtwBackupFvb->EraseBlocks (
96 FtwDevice->FtwBackupFvb,
97 FtwDevice->FtwSpareLba,
98 FtwDevice->NumberOfSpareBlock,
128 (FvBlock == FtwDevice->FtwFvBlock) &&
129 (Lba >= FtwDevice->FtwWorkBlockLba) &&
130 (Lba <= FtwDevice->FtwWorkSpaceLba)
160 UINTN NumberOfBlocks;
169 if (EFI_ERROR (Status)) {
176 for (Index = 0; Index < HandleCount; Index += 1) {
178 if (EFI_ERROR (Status)) {
185 Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);
186 if (EFI_ERROR (Status)) {
193 Status = Fvb->GetBlockSize (Fvb, 0, &BlockSize, &NumberOfBlocks);
194 if (EFI_ERROR (Status)) {
198 if ((Address >= FvbBaseAddress) && (Address < (FvbBaseAddress + BlockSize * NumberOfBlocks))) {
200 FvbHandle = HandleBuffer[Index];
230 UINTN BackupBlockSize;
240 if (EFI_ERROR (Status)) {
247 Status = SarProtocol->GetRangeLocation (
254 if (EFI_ERROR (Status)) {
258 Status = SarProtocol->GetSwapState (SarProtocol, &IsSwapped);
259 if (EFI_ERROR (Status)) {
272 if (FvbHandle ==
NULL) {
279 return (BOOLEAN)(FvBlock == BootFvb);
325 return EFI_UNSUPPORTED;
332 if (EFI_ERROR (Status)) {
339 Length = FtwDevice->SpareAreaLength;
341 if (Buffer ==
NULL) {
342 return EFI_OUT_OF_RESOURCES;
348 Status = SarProtocol->GetSwapState (SarProtocol, &TopSwap);
349 if (EFI_ERROR (Status)) {
350 DEBUG ((DEBUG_ERROR,
"Ftw: Get Top Swapped status - %r\n", Status));
359 if (
GetFvbByAddress (FtwDevice->SpareAreaAddress + FtwDevice->SpareAreaLength, &BootFvb) ==
NULL) {
369 for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) {
370 Count = FtwDevice->SpareBlockSize;
371 Status = BootFvb->Read (
378 if (EFI_ERROR (Status)) {
390 for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) {
391 Count = FtwDevice->SpareBlockSize;
392 Status = FtwDevice->FtwBackupFvb->Read (
393 FtwDevice->FtwBackupFvb,
394 FtwDevice->FtwSpareLba + Index,
399 if (EFI_ERROR (Status)) {
410 Status = SarProtocol->SetSwapState (SarProtocol,
TRUE);
411 if (EFI_ERROR (Status)) {
422 if (EFI_ERROR (Status)) {
431 for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) {
432 Count = FtwDevice->SpareBlockSize;
433 Status = FtwDevice->FtwBackupFvb->Write (
434 FtwDevice->FtwBackupFvb,
435 FtwDevice->FtwSpareLba + Index,
440 if (EFI_ERROR (Status)) {
441 DEBUG ((DEBUG_ERROR,
"Ftw: FVB Write boot block - %r\n", Status));
454 Status = SarProtocol->SetSwapState (SarProtocol,
FALSE);
493 if ((FtwDevice ==
NULL) || (FvBlock ==
NULL)) {
494 return EFI_INVALID_PARAMETER;
500 Length = FtwDevice->SpareAreaLength;
502 if (Buffer ==
NULL) {
503 return EFI_OUT_OF_RESOURCES;
510 for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) {
511 Count = FtwDevice->SpareBlockSize;
512 Status = FtwDevice->FtwBackupFvb->Read (
513 FtwDevice->FtwBackupFvb,
514 FtwDevice->FtwSpareLba + Index,
519 if (EFI_ERROR (Status)) {
530 Status =
FtwEraseBlock (FtwDevice, FvBlock, Lba, NumberOfBlocks);
531 if (EFI_ERROR (Status)) {
540 for (Index = 0; Index < NumberOfBlocks; Index += 1) {
542 Status = FvBlock->Write (FvBlock, Lba + Index, 0, &Count, Ptr);
543 if (EFI_ERROR (Status)) {
544 DEBUG ((DEBUG_ERROR,
"Ftw: FVB Write block - %r\n", Status));
591 Length = FtwDevice->SpareAreaLength;
593 if (Buffer ==
NULL) {
594 return EFI_OUT_OF_RESOURCES;
605 FtwDevice->FtwBackupFvb,
606 FtwDevice->SpareBlockSize,
607 FtwDevice->FtwSpareLba + FtwDevice->FtwWorkSpaceLbaInSpare,
608 FtwDevice->FtwWorkSpaceBaseInSpare + sizeof (
EFI_GUID) +
sizeof (UINT32),
615 for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) {
616 Count = FtwDevice->SpareBlockSize;
617 Status = FtwDevice->FtwBackupFvb->Read (
618 FtwDevice->FtwBackupFvb,
619 FtwDevice->FtwSpareLba + Index,
624 if (EFI_ERROR (Status)) {
638 WorkingBlockHeader->WorkingBlockInvalid = FTW_ERASE_POLARITY;
651 FtwDevice->FtwFvBlock,
652 FtwDevice->WorkBlockSize,
653 FtwDevice->FtwWorkSpaceLba,
654 FtwDevice->FtwWorkSpaceBase + sizeof (
EFI_GUID) +
sizeof (UINT32),
655 WORKING_BLOCK_INVALID
657 if (EFI_ERROR (Status)) {
662 FtwDevice->FtwWorkSpaceHeader->WorkingBlockInvalid = FTW_VALID_STATE;
667 Status =
FtwEraseBlock (FtwDevice, FtwDevice->FtwFvBlock, FtwDevice->FtwWorkBlockLba, FtwDevice->NumberOfWorkBlock);
668 if (EFI_ERROR (Status)) {
677 for (Index = 0; Index < FtwDevice->NumberOfWorkBlock; Index += 1) {
678 Count = FtwDevice->WorkBlockSize;
679 Status = FtwDevice->FtwFvBlock->Write (
680 FtwDevice->FtwFvBlock,
681 FtwDevice->FtwWorkBlockLba + Index,
686 if (EFI_ERROR (Status)) {
687 DEBUG ((DEBUG_ERROR,
"Ftw: FVB Write block - %r\n", Status));
707 FtwDevice->FtwFvBlock,
708 FtwDevice->WorkBlockSize,
709 FtwDevice->FtwWorkSpaceLba,
710 FtwDevice->FtwWorkSpaceBase + sizeof (
EFI_GUID) +
sizeof (UINT32),
713 if (EFI_ERROR (Status)) {
717 FtwDevice->FtwWorkSpaceHeader->WorkingBlockInvalid = FTW_INVALID_STATE;
758 while (Offset >= BlockSize) {
766 Length =
sizeof (UINT8);
767 Status = FvBlock->Read (FvBlock, Lba, Offset, &Length, &State);
768 if (EFI_ERROR (Status)) {
772 State ^= FTW_POLARITY_REVERT;
773 State = (UINT8)(State | NewBit);
774 State ^= FTW_POLARITY_REVERT;
779 Length =
sizeof (UINT8);
780 Status = FvBlock->Write (FvBlock, Lba, Offset, &Length, &State);
809 *FtwWriteHeader =
NULL;
813 if (!
CompareGuid (&FtwWorkSpaceHeader->Signature, &gEdkiiWorkingBlockSignatureGuid)) {
814 *FtwWriteHeader = FtwHeader;
818 while (FtwHeader->Complete == FTW_VALID_STATE) {
819 Offset += FTW_WRITE_TOTAL_SIZE (FtwHeader->NumberOfWrites, FtwHeader->PrivateDataSize);
825 *FtwWriteHeader = FtwHeader;
835 *FtwWriteHeader = FtwHeader;
868 for (Index = 0; Index < FtwWriteHeader->NumberOfWrites; Index += 1) {
869 if (FtwRecord->DestinationComplete != FTW_VALID_STATE) {
879 if (FtwWriteHeader->PrivateDataSize != 0) {
890 if (Index == FtwWriteHeader->NumberOfWrites) {
917 Head = (UINT8 *)FtwHeader;
918 Ptr = (UINT8 *)FtwRecord;
921 return (BOOLEAN)(Head == Ptr);
945 Head = (UINT8 *)FtwHeader;
946 Ptr = (UINT8 *)FtwRecord;
948 Head += FTW_WRITE_TOTAL_SIZE (FtwHeader->NumberOfWrites - 1, FtwHeader->PrivateDataSize);
949 return (BOOLEAN)(Head == Ptr);
972 return EFI_ACCESS_DENIED;
975 Ptr = (UINT8 *)(*FtwRecord);
976 Ptr -= FTW_RECORD_SIZE (FtwHeader->PrivateDataSize);
999 UINTN FtwWorkingSize;
1016 if (FtwDevice ==
NULL) {
1017 return EFI_OUT_OF_RESOURCES;
1020 FtwDevice->WorkSpaceAddress = WorkSpaceAddress;
1021 FtwDevice->WorkSpaceLength = FtwWorkingSize;
1033 if ((FtwDevice->WorkSpaceLength == 0) || (FtwDevice->SpareAreaLength == 0)) {
1034 DEBUG ((DEBUG_ERROR,
"Ftw: Workspace or Spare block does not exist!\n"));
1036 return EFI_INVALID_PARAMETER;
1039 FtwDevice->Signature = FTW_DEVICE_SIGNATURE;
1040 FtwDevice->FtwFvBlock =
NULL;
1041 FtwDevice->FtwBackupFvb =
NULL;
1042 FtwDevice->FtwWorkSpaceLba = (
EFI_LBA)(-1);
1043 FtwDevice->FtwSpareLba = (
EFI_LBA)(-1);
1045 *FtwData = FtwDevice;
1073 UINTN NumberOfBlocks;
1075 HandleBuffer =
NULL;
1081 if (EFI_ERROR (Status)) {
1082 return EFI_NOT_FOUND;
1089 for (Index = 0; Index < HandleCount; Index += 1) {
1091 if (EFI_ERROR (Status)) {
1092 Status = EFI_NOT_FOUND;
1099 Status = Fvb->GetAttributes (Fvb, &Attributes);
1100 if (EFI_ERROR (Status) || ((Attributes & EFI_FVB2_WRITE_STATUS) == 0)) {
1107 Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);
1108 if (EFI_ERROR (Status)) {
1115 Status = Fvb->GetBlockSize (Fvb, 0, &BlockSize, &NumberOfBlocks);
1116 if (EFI_ERROR (Status)) {
1120 if ((FtwDevice->FtwFvBlock ==
NULL) && (FtwDevice->WorkSpaceAddress >= FvbBaseAddress) &&
1121 ((FtwDevice->WorkSpaceAddress + FtwDevice->WorkSpaceLength) <= (FvbBaseAddress + BlockSize * NumberOfBlocks)))
1123 FtwDevice->FtwFvBlock = Fvb;
1127 for (LbaIndex = 1; LbaIndex <= NumberOfBlocks; LbaIndex += 1) {
1128 if ( (FtwDevice->WorkSpaceAddress >= (FvbBaseAddress + BlockSize * (LbaIndex - 1)))
1129 && (FtwDevice->WorkSpaceAddress < (FvbBaseAddress + BlockSize * LbaIndex)))
1131 FtwDevice->FtwWorkSpaceLba = LbaIndex - 1;
1135 FtwDevice->FtwWorkSpaceSize = FtwDevice->WorkSpaceLength;
1136 FtwDevice->WorkBlockSize = BlockSize;
1137 FtwDevice->FtwWorkSpaceBase = (
UINTN)(FtwDevice->WorkSpaceAddress - (FvbBaseAddress + FtwDevice->WorkBlockSize * (LbaIndex - 1)));
1138 FtwDevice->NumberOfWorkSpaceBlock = FTW_BLOCKS (FtwDevice->FtwWorkSpaceBase + FtwDevice->FtwWorkSpaceSize, FtwDevice->WorkBlockSize);
1139 if (FtwDevice->FtwWorkSpaceSize >= FtwDevice->WorkBlockSize) {
1143 if (((FtwDevice->WorkSpaceAddress & (FtwDevice->WorkBlockSize - 1)) != 0) ||
1144 ((FtwDevice->WorkSpaceLength & (FtwDevice->WorkBlockSize - 1)) != 0))
1146 DEBUG ((DEBUG_ERROR,
"Ftw: Work space address or length is not block size aligned when work space size is larger than one block size\n"));
1151 }
else if ((FtwDevice->FtwWorkSpaceBase + FtwDevice->FtwWorkSpaceSize) > FtwDevice->WorkBlockSize) {
1152 DEBUG ((DEBUG_ERROR,
"Ftw: The work space range should not span blocks when work space size is less than one block size\n"));
1163 if ((FtwDevice->FtwBackupFvb ==
NULL) && (FtwDevice->SpareAreaAddress >= FvbBaseAddress) &&
1164 ((FtwDevice->SpareAreaAddress + FtwDevice->SpareAreaLength) <= (FvbBaseAddress + BlockSize * NumberOfBlocks)))
1166 FtwDevice->FtwBackupFvb = Fvb;
1170 for (LbaIndex = 1; LbaIndex <= NumberOfBlocks; LbaIndex += 1) {
1171 if ( (FtwDevice->SpareAreaAddress >= (FvbBaseAddress + BlockSize * (LbaIndex - 1)))
1172 && (FtwDevice->SpareAreaAddress < (FvbBaseAddress + BlockSize * LbaIndex)))
1177 FtwDevice->FtwSpareLba = LbaIndex - 1;
1178 FtwDevice->SpareBlockSize = BlockSize;
1179 FtwDevice->NumberOfSpareBlock = FtwDevice->SpareAreaLength / FtwDevice->SpareBlockSize;
1183 if ((FtwDevice->FtwSpareLba + FtwDevice->NumberOfSpareBlock) > NumberOfBlocks) {
1184 DEBUG ((DEBUG_ERROR,
"Ftw: Spare area is out of FV range\n"));
1193 if (((FtwDevice->SpareAreaAddress & (FtwDevice->SpareBlockSize - 1)) != 0) ||
1194 ((FtwDevice->SpareAreaLength & (FtwDevice->SpareBlockSize - 1)) != 0))
1196 DEBUG ((DEBUG_ERROR,
"Ftw: Spare area address or length is not block size aligned\n"));
1201 REPORT_STATUS_CODE ((EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED), (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ABORTED));
1214 if ((FtwDevice->FtwBackupFvb ==
NULL) || (FtwDevice->FtwFvBlock ==
NULL) ||
1215 (FtwDevice->FtwWorkSpaceLba == (
EFI_LBA)(-1)) || (FtwDevice->FtwSpareLba == (
EFI_LBA)(-1)))
1220 DEBUG ((DEBUG_INFO,
"Ftw: FtwWorkSpaceLba - 0x%lx, WorkBlockSize - 0x%x, FtwWorkSpaceBase - 0x%x\n", FtwDevice->FtwWorkSpaceLba, FtwDevice->WorkBlockSize, FtwDevice->FtwWorkSpaceBase));
1221 DEBUG ((DEBUG_INFO,
"Ftw: FtwSpareLba - 0x%lx, SpareBlockSize - 0x%x\n", FtwDevice->FtwSpareLba, FtwDevice->SpareBlockSize));
1251 if (EFI_ERROR (Status)) {
1252 return EFI_NOT_FOUND;
1258 if (FtwDevice->FtwWorkSpaceSize >= FtwDevice->WorkBlockSize) {
1262 FtwDevice->NumberOfWorkBlock = FtwDevice->NumberOfWorkSpaceBlock;
1270 FtwDevice->NumberOfWorkBlock = (
UINTN)(FtwDevice->FtwWorkSpaceLba + FtwDevice->NumberOfWorkSpaceBlock);
1271 while (FtwDevice->NumberOfWorkBlock * FtwDevice->WorkBlockSize > FtwDevice->SpareAreaLength) {
1272 FtwDevice->NumberOfWorkBlock--;
1276 FtwDevice->FtwWorkBlockLba = FtwDevice->FtwWorkSpaceLba + FtwDevice->NumberOfWorkSpaceBlock - FtwDevice->NumberOfWorkBlock;
1277 DEBUG ((DEBUG_INFO,
"Ftw: NumberOfWorkBlock - 0x%x, FtwWorkBlockLba - 0x%lx\n", FtwDevice->NumberOfWorkBlock, FtwDevice->FtwWorkBlockLba));
1283 WorkSpaceLbaOffset = FtwDevice->FtwWorkSpaceLba - FtwDevice->FtwWorkBlockLba;
1284 FtwDevice->FtwWorkSpaceLbaInSpare = (
EFI_LBA)(((
UINTN)WorkSpaceLbaOffset * FtwDevice->WorkBlockSize + FtwDevice->FtwWorkSpaceBase) / FtwDevice->SpareBlockSize);
1285 FtwDevice->FtwWorkSpaceBaseInSpare = ((
UINTN)WorkSpaceLbaOffset * FtwDevice->WorkBlockSize + FtwDevice->FtwWorkSpaceBase) % FtwDevice->SpareBlockSize;
1286 DEBUG ((DEBUG_INFO,
"Ftw: WorkSpaceLbaInSpare - 0x%lx, WorkSpaceBaseInSpare - 0x%x\n", FtwDevice->FtwWorkSpaceLbaInSpare, FtwDevice->FtwWorkSpaceBaseInSpare));
1291 FtwDevice->FtwWorkSpace = (UINT8 *)(FtwDevice + 1);
1294 FtwDevice->FtwLastWriteHeader =
NULL;
1295 FtwDevice->FtwLastWriteRecord =
NULL;
1312 FtwDevice->FtwBackupFvb,
1313 FtwDevice->SpareBlockSize,
1314 FtwDevice->FtwSpareLba + FtwDevice->FtwWorkSpaceLbaInSpare,
1315 FtwDevice->FtwWorkSpaceBaseInSpare,
1316 FtwDevice->FtwWorkSpaceSize,
1317 FtwDevice->FtwWorkSpace
1328 "Ftw: Restart working block update in %a() - %r\n",
1332 FtwAbort (&FtwDevice->FtwInstance);
1341 "Ftw: Both working and spare blocks are invalid, init workspace\n"
1347 FtwDevice->FtwWorkSpace,
1348 FtwDevice->FtwWorkSpaceSize,
1364 if ((FtwDevice->FtwLastWriteHeader->HeaderAllocated == FTW_VALID_STATE) &&
1365 (FtwDevice->FtwLastWriteRecord->SpareComplete != FTW_VALID_STATE) &&
1369 DEBUG ((DEBUG_ERROR,
"Ftw: Init.. find first record not SpareCompleted, abort()\n"));
1370 FtwAbort (&FtwDevice->FtwInstance);
1377 if ((FtwDevice->FtwLastWriteHeader->Complete != FTW_VALID_STATE) &&
1378 (FtwDevice->FtwLastWriteRecord->DestinationComplete == FTW_VALID_STATE) &&
1382 DEBUG ((DEBUG_ERROR,
"Ftw: Init.. find last record completed but header not, abort()\n"));
1383 FtwAbort (&FtwDevice->FtwInstance);
1390 FtwHeader = FtwDevice->FtwLastWriteHeader;
1391 Offset = (UINT8 *)FtwHeader - FtwDevice->FtwWorkSpace;
1392 if (FtwDevice->FtwWorkSpace[Offset] != FTW_ERASED_BYTE) {
1393 Offset += FTW_WRITE_TOTAL_SIZE (FtwHeader->NumberOfWrites, FtwHeader->PrivateDataSize);
1396 if (!
IsErasedFlashBuffer (FtwDevice->FtwWorkSpace + Offset, FtwDevice->FtwWorkSpaceSize - Offset)) {
1404 if ((FtwDevice->FtwLastWriteHeader->Complete != FTW_VALID_STATE) &&
1405 (FtwDevice->FtwLastWriteRecord->SpareComplete == FTW_VALID_STATE)
1408 if (FtwDevice->FtwLastWriteRecord->BootBlockUpdate == FTW_VALID_STATE) {
1410 DEBUG ((DEBUG_ERROR,
"Ftw: Restart boot block update - %r\n", Status));
1412 FtwAbort (&FtwDevice->FtwInstance);
1419 if (FvbHandle !=
NULL) {
1420 Status =
FtwRestart (&FtwDevice->FtwInstance, FvbHandle);
1421 DEBUG ((DEBUG_ERROR,
"Ftw: Restart last write - %r\n", Status));
1425 FtwAbort (&FtwDevice->FtwInstance);
1434 FtwDevice->FtwInstance.Write =
FtwWrite;
1436 FtwDevice->FtwInstance.Abort =
FtwAbort;
VOID EFIAPI CpuDeadLoop(VOID)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS FtwWriteRecord(IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This, IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb, IN UINTN BlockSize)
EFI_STATUS EFIAPI FtwGetMaxBlockSize(IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This, OUT UINTN *BlockSize)
EFI_STATUS EFIAPI FtwRestart(IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This, IN EFI_HANDLE FvBlockHandle)
EFI_STATUS EFIAPI FtwAllocate(IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This, IN EFI_GUID *CallerId, IN UINTN PrivateDataSize, IN UINTN NumberOfWrites)
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 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 EFIAPI FtwAbort(IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This)
#define EFI_LBA_LIST_TERMINATOR
EFI_STATUS FtwEraseSpareBlock(IN EFI_FTW_DEVICE *FtwDevice)
EFI_STATUS FtwGetLastWriteRecord(IN EFI_FAULT_TOLERANT_WRITE_HEADER *FtwWriteHeader, OUT EFI_FAULT_TOLERANT_WRITE_RECORD **FtwWriteRecord)
EFI_HANDLE GetFvbByAddress(IN EFI_PHYSICAL_ADDRESS Address, OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock)
EFI_STATUS FlushSpareBlockToTargetBlock(EFI_FTW_DEVICE *FtwDevice, EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, EFI_LBA Lba, UINTN BlockSize, UINTN NumberOfBlocks)
EFI_STATUS FlushSpareBlockToWorkingBlock(EFI_FTW_DEVICE *FtwDevice)
BOOLEAN IsBootBlock(EFI_FTW_DEVICE *FtwDevice, EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock)
EFI_STATUS InitFtwDevice(OUT EFI_FTW_DEVICE **FtwData)
EFI_STATUS FlushSpareBlockToBootBlock(EFI_FTW_DEVICE *FtwDevice)
BOOLEAN IsWorkingBlock(EFI_FTW_DEVICE *FtwDevice, EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, EFI_LBA Lba)
BOOLEAN IsErasedFlashBuffer(IN UINT8 *Buffer, IN UINTN BufferSize)
EFI_STATUS FtwEraseBlock(IN EFI_FTW_DEVICE *FtwDevice, EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, EFI_LBA Lba, UINTN NumberOfBlocks)
BOOLEAN IsLastRecordOfWrites(IN EFI_FAULT_TOLERANT_WRITE_HEADER *FtwHeader, IN EFI_FAULT_TOLERANT_WRITE_RECORD *FtwRecord)
EFI_STATUS FtwGetLastWriteHeader(IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FtwWorkSpaceHeader, IN UINTN FtwWorkSpaceSize, OUT EFI_FAULT_TOLERANT_WRITE_HEADER **FtwWriteHeader)
EFI_STATUS InitFtwProtocol(IN OUT EFI_FTW_DEVICE *FtwDevice)
BOOLEAN IsFirstRecordOfWrites(IN EFI_FAULT_TOLERANT_WRITE_HEADER *FtwHeader, IN EFI_FAULT_TOLERANT_WRITE_RECORD *FtwRecord)
EFI_STATUS FindFvbForFtw(IN OUT EFI_FTW_DEVICE *FtwDevice)
EFI_STATUS GetPreviousRecordOfWrites(IN EFI_FAULT_TOLERANT_WRITE_HEADER *FtwHeader, IN OUT EFI_FAULT_TOLERANT_WRITE_RECORD **FtwRecord)
EFI_STATUS FtwUpdateFvState(IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, IN UINTN BlockSize, IN EFI_LBA Lba, IN UINTN Offset, IN UINT8 NewBit)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define REPORT_STATUS_CODE(Type, Value)
#define FeaturePcdGet(TokenName)
UINT32 EFI_FVB_ATTRIBUTES_2
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFIAPI SafeUint64ToUintn(IN UINT64 Operand, OUT UINTN *Result)
UINT64 EFI_PHYSICAL_ADDRESS
BOOLEAN IsValidWorkSpace(IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader)
EFI_STATUS InitWorkSpaceHeader(IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader)
EFI_STATUS FtwGetSarProtocol(OUT VOID **SarProtocol)
EFI_STATUS FtwReclaimWorkSpace(IN EFI_FTW_DEVICE *FtwDevice, IN BOOLEAN PreserveRecord)
EFI_STATUS WorkSpaceRefresh(IN EFI_FTW_DEVICE *FtwDevice)
VOID InitializeLocalWorkSpaceHeader(IN UINTN WorkSpaceLength)
EFI_STATUS GetFvbCountAndBuffer(OUT UINTN *NumberHandles, OUT EFI_HANDLE **Buffer)
EFI_STATUS FtwGetFvbByHandle(IN EFI_HANDLE FvBlockHandle, OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock)
EFI_STATUS ReadWorkSpaceData(IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, IN UINTN BlockSize, IN EFI_LBA Lba, IN UINTN Offset, IN UINTN Length, OUT UINT8 *Buffer)
EFI_STATUS EFIAPI GetVariableFlashFtwWorkingInfo(OUT EFI_PHYSICAL_ADDRESS *BaseAddress, OUT UINT64 *Length)
EFI_STATUS EFIAPI GetVariableFlashFtwSpareInfo(OUT EFI_PHYSICAL_ADDRESS *BaseAddress, OUT UINT64 *Length)