ftwworkspace.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 567 行 · 第 1/2 页
C
567 行
Status = FtwLiteDevice->FtwFvBlock->Read (
FtwLiteDevice->FtwFvBlock,
FtwLiteDevice->FtwWorkSpaceLba,
FtwLiteDevice->FtwWorkSpaceBase,
&Length,
FtwLiteDevice->FtwWorkSpace
);
if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
//
// Refresh the FtwLastRecord
//
Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);
Record = FtwLiteDevice->FtwLastRecord;
Offset = (UINTN) (UINT8 *) Record - (UINTN) FtwLiteDevice->FtwWorkSpace;
//
// IF work space has error or Record is out of the workspace limit, THEN
// call reclaim.
//
if (EFI_ERROR (Status) || (Offset + WRITE_TOTAL_SIZE >= FtwLiteDevice->FtwWorkSpaceSize)) {
//
// reclaim work space in working block.
//
Status = FtwReclaimWorkSpace (FtwLiteDevice);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_FTW_LITE, "FtwLite: Reclaim workspace - %r\n", Status));
return EFI_ABORTED;
}
}
return EFI_SUCCESS;
}
EFI_STATUS
CleanupWorkSpace (
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
IN OUT UINT8 *FtwSpaceBuffer,
IN UINTN BufferSize
)
/*++
Routine Description:
Reclaim the work space. Get rid of all the completed write records
and write records in the Fault Tolerant work space.
Arguments:
FtwLiteDevice - Point to private data of FTW driver
FtwSpaceBuffer - Buffer to contain the reclaimed clean data
BufferSize - Size of the FtwSpaceBuffer
Returns:
EFI_SUCCESS - The function completed successfully
EFI_BUFFER_TOO_SMALL - The FtwSpaceBuffer is too small
EFI_ABORTED - The function could not complete successfully.
--*/
{
UINTN Length;
EFI_FTW_LITE_RECORD *Record;
//
// To check if the buffer is large enough
//
Length = FtwLiteDevice->FtwWorkSpaceSize;
if (BufferSize < Length) {
return EFI_BUFFER_TOO_SMALL;
}
//
// Clear the content of buffer that will save the new work space data
//
EfiSetMem (FtwSpaceBuffer, Length, FTW_ERASED_BYTE);
//
// Copy EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER to buffer
//
EfiCopyMem (
FtwSpaceBuffer,
FtwLiteDevice->FtwWorkSpaceHeader,
sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)
);
//
// Get the last record
//
Record = FtwLiteDevice->FtwLastRecord;
if ((Record != NULL) && (Record->WriteAllocated == FTW_VALID_STATE) && (Record->WriteCompleted != FTW_VALID_STATE)) {
EfiCopyMem (
(UINT8 *) FtwSpaceBuffer + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
Record,
WRITE_TOTAL_SIZE
);
}
return EFI_SUCCESS;
}
EFI_STATUS
FtwReclaimWorkSpace (
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice
)
/*++
Routine Description:
Reclaim the work space on the working block.
Arguments:
FtwLiteDevice - Point to private data of FTW driver
Returns:
EFI_SUCCESS - The function completed successfully
EFI_OUT_OF_RESOURCES - Allocate memory error
EFI_ABORTED - The function could not complete successfully
--*/
{
EFI_STATUS Status;
UINT8 *TempBuffer;
UINTN TempBufferSize;
UINT8 *Ptr;
UINTN Length;
UINTN Index;
UINTN SpareBufferSize;
UINT8 *SpareBuffer;
EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader;
DEBUG ((EFI_D_FTW_LITE, "FtwLite: start to reclaim work space\n"));
//
// Read all original data from working block to a memory buffer
//
TempBufferSize = FtwLiteDevice->SpareAreaLength;
Status = gBS->AllocatePool (
EfiBootServicesData,
TempBufferSize,
&TempBuffer
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
EfiZeroMem (TempBuffer, TempBufferSize);
Ptr = TempBuffer;
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
Length = FtwLiteDevice->SizeOfSpareBlock;
Status = FtwLiteDevice->FtwFvBlock->Read (
FtwLiteDevice->FtwFvBlock,
FtwLiteDevice->FtwWorkBlockLba + Index,
0,
&Length,
Ptr
);
if (EFI_ERROR (Status)) {
gBS->FreePool (TempBuffer);
return EFI_ABORTED;
}
Ptr += Length;
}
//
// Clean up the workspace, remove all the completed records.
//
Ptr = TempBuffer +
((UINTN) (FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba)) *
FtwLiteDevice->SizeOfSpareBlock +
FtwLiteDevice->FtwWorkSpaceBase;
Status = CleanupWorkSpace (
FtwLiteDevice,
Ptr,
FtwLiteDevice->FtwWorkSpaceSize
);
EfiCopyMem (
FtwLiteDevice->FtwWorkSpace,
Ptr,
FtwLiteDevice->FtwWorkSpaceSize
);
Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);
//
// Set the WorkingBlockValid and WorkingBlockInvalid as INVALID
//
WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) Ptr;
WorkingBlockHeader->WorkingBlockValid = FTW_INVALID_STATE;
WorkingBlockHeader->WorkingBlockInvalid = FTW_INVALID_STATE;
//
// Try to keep the content of spare block
// Save spare block into a spare backup memory buffer (Sparebuffer)
//
SpareBufferSize = FtwLiteDevice->SpareAreaLength;
SpareBuffer = EfiLibAllocatePool (SpareBufferSize);
if (SpareBuffer == NULL) {
gBS->FreePool (TempBuffer);
return EFI_OUT_OF_RESOURCES;
}
Ptr = SpareBuffer;
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
Length = FtwLiteDevice->SizeOfSpareBlock;
Status = FtwLiteDevice->FtwBackupFvb->Read (
FtwLiteDevice->FtwBackupFvb,
FtwLiteDevice->FtwSpareLba + Index,
0,
&Length,
Ptr
);
if (EFI_ERROR (Status)) {
gBS->FreePool (TempBuffer);
gBS->FreePool (SpareBuffer);
return EFI_ABORTED;
}
Ptr += Length;
}
//
// Write the memory buffer to spare block
//
Status = FtwEraseSpareBlock (FtwLiteDevice);
Ptr = TempBuffer;
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
Length = FtwLiteDevice->SizeOfSpareBlock;
Status = FtwLiteDevice->FtwBackupFvb->Write (
FtwLiteDevice->FtwBackupFvb,
FtwLiteDevice->FtwSpareLba + Index,
0,
&Length,
Ptr
);
if (EFI_ERROR (Status)) {
gBS->FreePool (TempBuffer);
gBS->FreePool (SpareBuffer);
return EFI_ABORTED;
}
Ptr += Length;
}
//
// Free TempBuffer
//
gBS->FreePool (TempBuffer);
//
// Write the spare block to working block
//
Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice);
if (EFI_ERROR (Status)) {
gBS->FreePool (SpareBuffer);
return Status;
}
//
// 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) {
Length = FtwLiteDevice->SizeOfSpareBlock;
Status = FtwLiteDevice->FtwBackupFvb->Write (
FtwLiteDevice->FtwBackupFvb,
FtwLiteDevice->FtwSpareLba + Index,
0,
&Length,
Ptr
);
if (EFI_ERROR (Status)) {
gBS->FreePool (SpareBuffer);
return EFI_ABORTED;
}
Ptr += Length;
}
gBS->FreePool (SpareBuffer);
DEBUG ((EFI_D_FTW_LITE, "FtwLite: reclaim work space success\n"));
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?