ftwlite.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 971 行 · 第 1/3 页
C
971 行
}
Ptr += MyLength;
}
//
// Free MyBuffer
//
gBS->FreePool (MyBuffer);
//
// Set the SpareCompleteD in the FTW record,
//
MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;
Status = FtwUpdateFvState (
FtwLiteDevice->FtwFvBlock,
FtwLiteDevice->FtwWorkSpaceLba,
FtwLiteDevice->FtwWorkSpaceBase + MyOffset,
SPARE_COMPLETED
);
if (EFI_ERROR (Status)) {
gBS->FreePool (SpareBuffer);
return EFI_ABORTED;
}
Record->SpareCompleted = FTW_VALID_STATE;
//
// Since the content has already backuped in spare block, the write is
// guaranteed to be completed with fault tolerant manner.
//
Status = FtwWriteRecord (FtwLiteDevice, Fvb);
if (EFI_ERROR (Status)) {
gBS->FreePool (SpareBuffer);
return EFI_ABORTED;
}
Record++;
FtwLiteDevice->FtwLastRecord = Record;
//
// Restore spare backup buffer into spare block , if no failure happened during FtwWrite.
//
Status = FtwEraseSpareBlock (FtwLiteDevice);
Ptr = SpareBuffer;
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
MyLength = FtwLiteDevice->SizeOfSpareBlock;
Status = FtwLiteDevice->FtwBackupFvb->Write (
FtwLiteDevice->FtwBackupFvb,
FtwLiteDevice->FtwSpareLba + Index,
0,
&MyLength,
Ptr
);
if (EFI_ERROR (Status)) {
gBS->FreePool (SpareBuffer);
return EFI_ABORTED;
}
Ptr += MyLength;
}
//
// All success.
//
gBS->FreePool (SpareBuffer);
DEBUG (
(EFI_D_FTW_LITE,
"FtwLite: Write() success, (Lba:Offset)=(%lx:0x%x), NumBytes: 0x%x\n",
Lba,
Offset,
*NumBytes)
);
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
FtwWriteRecord (
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb
)
/*++
Routine Description:
Write a record with fault tolerant mannaer.
Since the content has already backuped in spare block, the write is
guaranteed to be completed with fault tolerant manner.
Arguments:
FtwLiteDevice - The private data of FTW_LITE driver
Fvb - The FVB protocol that provides services for
reading, writing, and erasing the target block.
Returns:
EFI_SUCCESS - The function completed successfully
EFI_ABORTED - The function could not complete successfully
--*/
{
EFI_STATUS Status;
EFI_FTW_LITE_RECORD *Record;
EFI_LBA WorkSpaceLbaOffset;
UINTN Offset;
//
// Spare Complete but Destination not complete,
// Recover the targt block with the spare block.
//
Record = FtwLiteDevice->FtwLastRecord;
//
// IF target block is working block, THEN Flush Spare Block To Working Block;
// ELSE IF target block is boot block, THEN Flush Spare Block To boot Block;
// ELSE flush spare block to normal target block.ENDIF
//
if (IsInWorkingBlock (FtwLiteDevice, Fvb, Record->Lba)) {
//
// If target block is working block, Attention:
// it's required to set SPARE_COMPLETED to spare block.
//
WorkSpaceLbaOffset = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba;
Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;
Status = FtwUpdateFvState (
FtwLiteDevice->FtwBackupFvb,
FtwLiteDevice->FtwSpareLba + WorkSpaceLbaOffset,
FtwLiteDevice->FtwWorkSpaceBase + Offset,
SPARE_COMPLETED
);
ASSERT_EFI_ERROR (Status);
Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice);
} else if (IsBootBlock (FtwLiteDevice, Fvb, Record->Lba)) {
//
// Update boot block
//
Status = FlushSpareBlockToBootBlock (FtwLiteDevice);
} else {
//
// Update blocks other than working block or boot block
//
Status = FlushSpareBlockToTargetBlock (FtwLiteDevice, Fvb, Record->Lba);
}
ASSERT_EFI_ERROR (Status);
//
// Set WriteCompleted flag in record
//
Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;
Status = FtwUpdateFvState (
FtwLiteDevice->FtwFvBlock,
FtwLiteDevice->FtwWorkSpaceLba,
FtwLiteDevice->FtwWorkSpaceBase + Offset,
WRITE_COMPLETED
);
ASSERT_EFI_ERROR (Status);
Record->WriteCompleted = FTW_VALID_STATE;
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
FtwRestart (
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice
)
/*++
Routine Description:
Restarts a previously interrupted write. The caller must provide the
block protocol needed to complete the interrupted write.
Arguments:
FtwLiteDevice - The private data of FTW_LITE driver
FvbHandle - The handle of FVB protocol that provides services for
reading, writing, and erasing the target block.
Returns:
EFI_SUCCESS - The function completed successfully
EFI_ACCESS_DENIED - No pending writes exist
EFI_NOT_FOUND - FVB protocol not found by the handle
EFI_ABORTED - The function could not complete successfully
--*/
{
EFI_STATUS Status;
EFI_FTW_LITE_RECORD *Record;
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
EFI_DEV_PATH_PTR DevPathPtr;
//
// Spare Completed but Destination not complete,
// Recover the targt block with the spare block.
//
Record = FtwLiteDevice->FtwLastRecord;
//
// Only support memory mapped FVB device path by now.
//
DevPathPtr.MemMap = (MEMMAP_DEVICE_PATH *) &Record->DevPath;
if (!((DevPathPtr.MemMap->Header.Type == HARDWARE_DEVICE_PATH) && (DevPathPtr.MemMap->Header.SubType == HW_MEMMAP_DP))
) {
DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Device Path is not memory mapped\n"));
return EFI_ABORTED;
}
Status = GetFvbByAddress (DevPathPtr.MemMap->StartingAddress, &Fvb);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
//
// Since the content has already backuped in spare block, the write is
// guaranteed to be completed with fault tolerant manner.
//
Status = FtwWriteRecord (FtwLiteDevice, Fvb);
DEBUG ((EFI_D_FTW_INFO, "FtwLite: Restart() - %r\n", Status));
Record++;
FtwLiteDevice->FtwLastRecord = Record;
//
// Erase Spare block
// This is restart, no need to keep spareblock content.
//
FtwEraseSpareBlock (FtwLiteDevice);
return Status;
}
STATIC
EFI_STATUS
FtwAbort (
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice
)
/*++
Routine Description:
Aborts all previous allocated writes.
Arguments:
FtwLiteDevice - The private data of FTW_LITE driver
Returns:
EFI_SUCCESS - The function completed successfully
EFI_ABORTED - The function could not complete successfully.
EFI_NOT_FOUND - No allocated writes exist.
--*/
{
EFI_STATUS Status;
UINTN Offset;
if (FtwLiteDevice->FtwLastRecord->WriteCompleted == FTW_VALID_STATE) {
return EFI_NOT_FOUND;
}
//
// Update the complete state of the header as VALID and abort.
//
Offset = (UINT8 *) FtwLiteDevice->FtwLastRecord - FtwLiteDevice->FtwWorkSpace;
Status = FtwUpdateFvState (
FtwLiteDevice->FtwFvBlock,
FtwLiteDevice->FtwWorkSpaceLba,
FtwLiteDevice->FtwWorkSpaceBase + Offset,
WRITE_COMPLETED
);
if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
FtwLiteDevice->FtwLastRecord->WriteCompleted = FTW_VALID_STATE;
Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);
//
// Erase the spare block
//
Status = FtwEraseSpareBlock (FtwLiteDevice);
DEBUG ((EFI_D_FTW_INFO, "FtwLite: Abort() success \n"));
return EFI_SUCCESS;
}
EFI_DRIVER_ENTRY_POINT (InitializeFtwLite)
EFI_STATUS
EFIAPI
InitializeFtwLite (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
This function is the entry point of the Fault Tolerant Write driver.
Arguments:
ImageHandle - EFI_HANDLE: A handle for the image that is initializing
this driver
SystemTable - EFI_SYSTEM_TABLE: A pointer to the EFI system table
Returns:
EFI_SUCCESS - FTW has finished the initialization
EFI_ABORTED - FTW initialization error
--*/
{
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
UINTN Index;
EFI_HANDLE *HandleBuffer;
UINTN HandleCount;
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
EFI_PHYSICAL_ADDRESS BaseAddress;
EFI_FTW_LITE_DEVICE *FtwLiteDevice;
EFI_FTW_LITE_RECORD *Record;
UINTN Length;
EFI_STATUS Status;
UINTN Offset;
VOID *HobList;
VOID *Buffer;
EFI_FLASH_MAP_ENTRY_DATA *FlashMapEntry;
EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry;
UINT32 LbaIndex;
EFI_LBA WorkSpaceLbaOffset;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?