23 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
24 &gEdkiiFaultTolerantWriteGuid,
52 *FtwWriteHeader =
NULL;
56 while (FtwHeader->Complete == FTW_VALID_STATE) {
57 Offset += FTW_WRITE_TOTAL_SIZE (FtwHeader->NumberOfWrites, FtwHeader->PrivateDataSize);
61 if (Offset >= FtwWorkSpaceSize) {
62 *FtwWriteHeader = FtwHeader;
72 *FtwWriteHeader = FtwHeader;
105 for (Index = 0; Index < FtwWriteHeader->NumberOfWrites; Index += 1) {
106 if (FtwRecord->DestinationComplete != FTW_VALID_STATE) {
116 if (FtwWriteHeader->PrivateDataSize != 0) {
127 if (Index == FtwWriteHeader->NumberOfWrites) {
154 if (WorkingHeader ==
NULL) {
158 if ((WorkingHeader->WorkingBlockValid != FTW_VALID_STATE) || (WorkingHeader->WorkingBlockInvalid == FTW_VALID_STATE)) {
159 DEBUG ((DEBUG_ERROR,
"FtwPei: Work block header valid bit check error\n"));
164 DEBUG ((DEBUG_ERROR,
"FtwPei: Work block header WriteQueueSize check error\n"));
171 if (!
CompareGuid (&gEdkiiWorkingBlockSignatureGuid, &WorkingHeader->Signature)) {
172 DEBUG ((DEBUG_ERROR,
"FtwPei: Work block header signature check error, it should be gEdkiiWorkingBlockSignatureGuid\n"));
176 if (!
CompareGuid (&gEfiSystemNvDataFvGuid, &WorkingHeader->Signature)) {
179 Data = *(UINT8 *)(WorkingHeader + 1);
181 DEBUG ((DEBUG_ERROR,
"FtwPei: Old format FTW structure can't be handled\n"));
213 UINTN WorkSpaceLength;
215 UINTN SpareAreaLength;
220 FtwWorkingBlockHeader =
NULL;
221 FtwLastWriteHeader =
NULL;
222 FtwLastWriteRecord =
NULL;
224 SpareAreaAddress = 0;
226 WorkSpaceAddress = 0;
246 ASSERT ((WorkSpaceAddress != 0) && (SpareAreaAddress != 0));
251 FtwWorkingBlockHeader,
255 if (!EFI_ERROR (Status)) {
262 if (!EFI_ERROR (Status)) {
263 ASSERT (FtwLastWriteRecord !=
NULL);
264 if ((FtwLastWriteRecord->SpareComplete == FTW_VALID_STATE) && (FtwLastWriteRecord->DestinationComplete != FTW_VALID_STATE)) {
273 FtwLastWrite.
Length = SpareAreaLength;
276 "FtwPei last write data: TargetAddress - 0x%x SpareAddress - 0x%x Length - 0x%x\n",
285 FtwWorkingBlockHeader =
NULL;
289 WorkSpaceInSpareArea = SpareAreaAddress + SpareAreaLength - WorkSpaceLength;
290 while (WorkSpaceInSpareArea >= SpareAreaAddress) {
295 DEBUG ((DEBUG_INFO,
"FtwPei: workspace in spare block is at 0x%x.\n", (
UINTN)WorkSpaceInSpareArea));
300 WorkSpaceInSpareArea = WorkSpaceInSpareArea -
sizeof (
EFI_GUID);
303 if ((FtwWorkingBlockHeader !=
NULL) &&
IsValidWorkSpace (FtwWorkingBlockHeader, WorkSpaceLength)) {
307 FtwLastWrite.
TargetAddress = WorkSpaceAddress - (WorkSpaceInSpareArea - SpareAreaAddress);
309 FtwLastWrite.
Length = SpareAreaLength;
312 "FtwPei last write data: TargetAddress - 0x%x SpareAddress - 0x%x Length - 0x%x\n",
322 DEBUG ((DEBUG_ERROR,
"FtwPei: Both working and spare block are invalid.\n"));
VOID *EFIAPI BuildGuidDataHob(IN CONST EFI_GUID *Guid, IN VOID *Data, IN UINTN DataLength)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
EFI_STATUS FtwWriteRecord(IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This, IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb, IN UINTN BlockSize)
EFI_STATUS FtwGetLastWriteRecord(IN EFI_FAULT_TOLERANT_WRITE_HEADER *FtwWriteHeader, OUT EFI_FAULT_TOLERANT_WRITE_RECORD **FtwWriteRecord)
BOOLEAN IsValidWorkSpace(IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader, IN UINTN WorkingLength)
EFI_STATUS EFIAPI PeimFaultTolerantWriteInitialize(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
EFI_STATUS FtwGetLastWriteHeader(IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FtwWorkSpaceHeader, IN UINTN FtwWorkSpaceSize, OUT EFI_FAULT_TOLERANT_WRITE_HEADER **FtwWriteHeader)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
VOID * EFI_PEI_FILE_HANDLE
RETURN_STATUS EFIAPI SafeUint64ToUintn(IN UINT64 Operand, OUT UINTN *Result)
UINT64 EFI_PHYSICAL_ADDRESS
EFI_STATUS EFIAPI GetVariableFlashFtwWorkingInfo(OUT EFI_PHYSICAL_ADDRESS *BaseAddress, OUT UINT64 *Length)
EFI_STATUS EFIAPI GetVariableFlashFtwSpareInfo(OUT EFI_PHYSICAL_ADDRESS *BaseAddress, OUT UINT64 *Length)
EFI_PHYSICAL_ADDRESS SpareAddress
EFI_PHYSICAL_ADDRESS TargetAddress