Initial import.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -0,0 +1,951 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
|
||||
Module Name:
|
||||
|
||||
FtwLite.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is a simple fault tolerant write driver, based on PlatformFd library.
|
||||
And it only supports write BufferSize <= SpareAreaLength.
|
||||
|
||||
This boot service only protocol provides fault tolerant write capability for
|
||||
block devices. The protocol has internal non-volatile intermediate storage
|
||||
of the data and private information. It should be able to recover
|
||||
automatically from a critical fault, such as power failure.
|
||||
|
||||
Notes:
|
||||
|
||||
The implementation uses an FTW Lite (Fault Tolerant Write) Work Space.
|
||||
This work space is a memory copy of the work space on the Woring Block,
|
||||
the size of the work space is the FTW_WORK_SPACE_SIZE bytes.
|
||||
|
||||
--*/
|
||||
|
||||
#include <FtwLite.h>
|
||||
|
||||
//
|
||||
// In write function, we should check the target range to prevent the user
|
||||
// from writing Spare block and Working space directly.
|
||||
//
|
||||
//
|
||||
// Fault Tolerant Write Protocol API
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FtwLiteWrite (
|
||||
IN EFI_FTW_LITE_PROTOCOL *This,
|
||||
IN EFI_HANDLE FvbHandle,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN Offset,
|
||||
IN OUT UINTN *NumBytes,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Starts a target block update. This function will record data about write
|
||||
in fault tolerant storage and will complete the write in a recoverable
|
||||
manner, ensuring at all times that either the original contents or
|
||||
the modified contents are available.
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
FvbHandle - The handle of FVB protocol that provides services for
|
||||
reading, writing, and erasing the target block.
|
||||
Lba - The logical block address of the target block.
|
||||
Offset - The offset within the target block to place the data.
|
||||
NumBytes - The number of bytes to write to the target block.
|
||||
Buffer - The data to write.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
EFI_BAD_BUFFER_SIZE - The write would span a target block, which is not
|
||||
a valid action.
|
||||
EFI_ACCESS_DENIED - No writes have been allocated.
|
||||
EFI_NOT_FOUND - Cannot find FVB by handle.
|
||||
EFI_OUT_OF_RESOURCES - Cannot allocate memory.
|
||||
EFI_ABORTED - The function could not complete successfully.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice;
|
||||
EFI_FTW_LITE_RECORD *Record;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
|
||||
EFI_PHYSICAL_ADDRESS FvbPhysicalAddress;
|
||||
UINTN MyLength;
|
||||
UINTN MyOffset;
|
||||
UINTN MyBufferSize;
|
||||
UINT8 *MyBuffer;
|
||||
UINTN SpareBufferSize;
|
||||
UINT8 *SpareBuffer;
|
||||
UINTN Index;
|
||||
UINT8 *Ptr;
|
||||
EFI_DEV_PATH_PTR DevPtr;
|
||||
|
||||
//
|
||||
// Refresh work space and get last record
|
||||
//
|
||||
FtwLiteDevice = FTW_LITE_CONTEXT_FROM_THIS (This);
|
||||
Status = WorkSpaceRefresh (FtwLiteDevice);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
Record = FtwLiteDevice->FtwLastRecord;
|
||||
|
||||
//
|
||||
// Check the flags of last write record
|
||||
//
|
||||
if ((Record->WriteAllocated == FTW_VALID_STATE) || (Record->SpareCompleted == FTW_VALID_STATE)) {
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
//
|
||||
// IF former record has completed, THEN use next record
|
||||
//
|
||||
if (Record->WriteCompleted == FTW_VALID_STATE) {
|
||||
Record++;
|
||||
FtwLiteDevice->FtwLastRecord = Record;
|
||||
}
|
||||
|
||||
MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;
|
||||
|
||||
//
|
||||
// Check if the input data can fit within the target block
|
||||
//
|
||||
if ((Offset +*NumBytes) > FtwLiteDevice->SpareAreaLength) {
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
//
|
||||
// Check if there is enough free space for allocate a record
|
||||
//
|
||||
if ((MyOffset + WRITE_TOTAL_SIZE) > FtwLiteDevice->FtwWorkSpaceSize) {
|
||||
Status = FtwReclaimWorkSpace (FtwLiteDevice);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "FtwLite: Reclaim work space - %r", Status));
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Get the FVB protocol by handle
|
||||
//
|
||||
Status = FtwGetFvbByHandle (FvbHandle, &Fvb);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
//
|
||||
// Allocate a write record in workspace.
|
||||
// Update Header->WriteAllocated as VALID
|
||||
//
|
||||
Status = FtwUpdateFvState (
|
||||
FtwLiteDevice->FtwFvBlock,
|
||||
FtwLiteDevice->FtwWorkSpaceLba,
|
||||
FtwLiteDevice->FtwWorkSpaceBase + MyOffset,
|
||||
WRITE_ALLOCATED
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: Allocate record - %r\n", Status));
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
Record->WriteAllocated = FTW_VALID_STATE;
|
||||
|
||||
//
|
||||
// Prepare data of write record, filling DevPath with memory mapped address.
|
||||
//
|
||||
DevPtr.MemMap = (MEMMAP_DEVICE_PATH *) &Record->DevPath;
|
||||
DevPtr.MemMap->Header.Type = HARDWARE_DEVICE_PATH;
|
||||
DevPtr.MemMap->Header.SubType = HW_MEMMAP_DP;
|
||||
SetDevicePathNodeLength (&DevPtr.MemMap->Header, sizeof (MEMMAP_DEVICE_PATH));
|
||||
|
||||
Status = Fvb->GetPhysicalAddress (Fvb, &FvbPhysicalAddress);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: Get FVB physical address - %r\n", Status));
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
DevPtr.MemMap->MemoryType = EfiMemoryMappedIO;
|
||||
DevPtr.MemMap->StartingAddress = FvbPhysicalAddress;
|
||||
DevPtr.MemMap->EndingAddress = FvbPhysicalAddress +*NumBytes;
|
||||
//
|
||||
// ignored!
|
||||
//
|
||||
Record->Lba = Lba;
|
||||
Record->Offset = Offset;
|
||||
Record->NumBytes = *NumBytes;
|
||||
|
||||
//
|
||||
// Write the record to the work space.
|
||||
//
|
||||
MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;
|
||||
MyLength = FTW_LITE_RECORD_SIZE;
|
||||
|
||||
Status = FtwLiteDevice->FtwFvBlock->Write (
|
||||
FtwLiteDevice->FtwFvBlock,
|
||||
FtwLiteDevice->FtwWorkSpaceLba,
|
||||
FtwLiteDevice->FtwWorkSpaceBase + MyOffset,
|
||||
&MyLength,
|
||||
(UINT8 *) Record
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
//
|
||||
// Record has been written to working block, then write data.
|
||||
//
|
||||
//
|
||||
// Allocate a memory buffer
|
||||
//
|
||||
MyBufferSize = FtwLiteDevice->SpareAreaLength;
|
||||
MyBuffer = AllocatePool (MyBufferSize);
|
||||
if (MyBuffer == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
//
|
||||
// Starting at Lba, if the number of the rest blocks on Fvb is less
|
||||
// than NumberOfSpareBlock.
|
||||
//
|
||||
//
|
||||
// Read all original data from target block to memory buffer
|
||||
//
|
||||
if (IsInWorkingBlock (FtwLiteDevice, Fvb, Lba)) {
|
||||
//
|
||||
// If target block falls into working block, we must follow the process of
|
||||
// updating working block.
|
||||
//
|
||||
Ptr = MyBuffer;
|
||||
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
|
||||
MyLength = FtwLiteDevice->SizeOfSpareBlock;
|
||||
Status = FtwLiteDevice->FtwFvBlock->Read (
|
||||
FtwLiteDevice->FtwFvBlock,
|
||||
FtwLiteDevice->FtwWorkBlockLba + Index,
|
||||
0,
|
||||
&MyLength,
|
||||
Ptr
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (MyBuffer);
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
Ptr += MyLength;
|
||||
}
|
||||
//
|
||||
// Update Offset by adding the offset from the start LBA of working block to
|
||||
// the target LBA. The target block can not span working block!
|
||||
//
|
||||
Offset = (((UINTN) (Lba - FtwLiteDevice->FtwWorkBlockLba)) * FtwLiteDevice->SizeOfSpareBlock + Offset);
|
||||
ASSERT ((Offset +*NumBytes) <= FtwLiteDevice->SpareAreaLength);
|
||||
|
||||
} else {
|
||||
|
||||
Ptr = MyBuffer;
|
||||
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
|
||||
MyLength = FtwLiteDevice->SizeOfSpareBlock;
|
||||
Status = Fvb->Read (Fvb, Lba + Index, 0, &MyLength, Ptr);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (MyBuffer);
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
Ptr += MyLength;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Overwrite the updating range data with
|
||||
// the input buffer content
|
||||
//
|
||||
CopyMem (MyBuffer + Offset, Buffer, *NumBytes);
|
||||
|
||||
//
|
||||
// Try to keep the content of spare block
|
||||
// Save spare block into a spare backup memory buffer (Sparebuffer)
|
||||
//
|
||||
SpareBufferSize = FtwLiteDevice->SpareAreaLength;
|
||||
SpareBuffer = AllocatePool (SpareBufferSize);
|
||||
if (SpareBuffer == NULL) {
|
||||
gBS->FreePool (MyBuffer);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Ptr = SpareBuffer;
|
||||
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
|
||||
MyLength = FtwLiteDevice->SizeOfSpareBlock;
|
||||
Status = FtwLiteDevice->FtwBackupFvb->Read (
|
||||
FtwLiteDevice->FtwBackupFvb,
|
||||
FtwLiteDevice->FtwSpareLba + Index,
|
||||
0,
|
||||
&MyLength,
|
||||
Ptr
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (MyBuffer);
|
||||
gBS->FreePool (SpareBuffer);
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
Ptr += MyLength;
|
||||
}
|
||||
//
|
||||
// Write the memory buffer to spare block
|
||||
// Don't forget to erase Flash first.
|
||||
//
|
||||
Status = FtwEraseSpareBlock (FtwLiteDevice);
|
||||
Ptr = MyBuffer;
|
||||
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 (MyBuffer);
|
||||
gBS->FreePool (SpareBuffer);
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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_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;
|
||||
EFI_FLASH_MAP_ENTRY_DATA *FlashMapEntry;
|
||||
EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry;
|
||||
UINT32 LbaIndex;
|
||||
EFI_PEI_HOB_POINTERS GuidHob;
|
||||
|
||||
//
|
||||
// Allocate Private data of this driver,
|
||||
// INCLUDING THE FtwWorkSpace[FTW_WORK_SPACE_SIZE].
|
||||
//
|
||||
FtwLiteDevice = NULL;
|
||||
FtwLiteDevice = AllocatePool (sizeof (EFI_FTW_LITE_DEVICE) + FTW_WORK_SPACE_SIZE);
|
||||
if (FtwLiteDevice != NULL) {
|
||||
Status = EFI_SUCCESS;
|
||||
} else {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
ZeroMem (FtwLiteDevice, sizeof (EFI_FTW_LITE_DEVICE));
|
||||
FtwLiteDevice->Signature = FTW_LITE_DEVICE_SIGNATURE;
|
||||
|
||||
//
|
||||
// Initialize other parameters, and set WorkSpace as FTW_ERASED_BYTE.
|
||||
//
|
||||
FtwLiteDevice->FtwWorkSpace = (UINT8 *) (FtwLiteDevice + 1);
|
||||
FtwLiteDevice->FtwWorkSpaceSize = FTW_WORK_SPACE_SIZE;
|
||||
SetMem (
|
||||
FtwLiteDevice->FtwWorkSpace,
|
||||
FtwLiteDevice->FtwWorkSpaceSize,
|
||||
FTW_ERASED_BYTE
|
||||
);
|
||||
FtwLiteDevice->FtwWorkSpaceHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) FtwLiteDevice->FtwWorkSpace;
|
||||
|
||||
FtwLiteDevice->FtwLastRecord = NULL;
|
||||
|
||||
FtwLiteDevice->SpareAreaLength = 0;
|
||||
FtwLiteDevice->WorkSpaceLength = 0;
|
||||
|
||||
GuidHob.Raw = GetHobList ();
|
||||
while (NULL != (GuidHob.Raw = GetNextGuidHob (&gEfiFlashMapHobGuid, GuidHob.Raw))) {
|
||||
FlashMapEntry = (EFI_FLASH_MAP_ENTRY_DATA *) GET_GUID_HOB_DATA (GuidHob.Guid);
|
||||
//
|
||||
// Get the FTW work space Flash Map SUB area
|
||||
//
|
||||
if ((FlashMapEntry->AreaType == EFI_FLASH_AREA_FTW_STATE) && (FlashMapEntry->NumEntries == 1)) {
|
||||
FtwLiteDevice->WorkSpaceAddress = FlashMapEntry->Entries[0].Base;
|
||||
FtwLiteDevice->WorkSpaceLength = (UINTN) FlashMapEntry->Entries[0].Length;
|
||||
}
|
||||
//
|
||||
// Get the FTW backup SUB area
|
||||
//
|
||||
if ((FlashMapEntry->AreaType == EFI_FLASH_AREA_FTW_BACKUP) && (FlashMapEntry->NumEntries == 1)) {
|
||||
FtwLiteDevice->SpareAreaAddress = FlashMapEntry->Entries[0].Base;
|
||||
FtwLiteDevice->SpareAreaLength = (UINTN) FlashMapEntry->Entries[0].Length;
|
||||
}
|
||||
|
||||
GuidHob.Raw = GET_NEXT_HOB (GuidHob);
|
||||
}
|
||||
|
||||
ASSERT ((FtwLiteDevice->WorkSpaceLength != 0) && (FtwLiteDevice->SpareAreaLength != 0));
|
||||
|
||||
//
|
||||
// Locate FVB protocol
|
||||
//
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
NULL,
|
||||
&HandleCount,
|
||||
&HandleBuffer
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
ASSERT (HandleCount > 0);
|
||||
|
||||
FtwLiteDevice->FtwFvBlock = NULL;
|
||||
FtwLiteDevice->FtwBackupFvb = NULL;
|
||||
FtwLiteDevice->FtwWorkSpaceLba = (EFI_LBA) (-1);
|
||||
FtwLiteDevice->FtwSpareLba = (EFI_LBA) (-1);
|
||||
for (Index = 0; Index < HandleCount; Index += 1) {
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
(VOID **) &Fvb
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = Fvb->GetPhysicalAddress (Fvb, &BaseAddress);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) BaseAddress);
|
||||
|
||||
if ((FtwLiteDevice->WorkSpaceAddress >= BaseAddress) &&
|
||||
(FtwLiteDevice->WorkSpaceAddress <= (BaseAddress + FwVolHeader->FvLength))
|
||||
) {
|
||||
FtwLiteDevice->FtwFvBlock = Fvb;
|
||||
//
|
||||
// To get the LBA of work space
|
||||
//
|
||||
if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) {
|
||||
//
|
||||
// FV may have multiple types of BlockLength
|
||||
//
|
||||
FvbMapEntry = &FwVolHeader->FvBlockMap[0];
|
||||
while (!((FvbMapEntry->NumBlocks == 0) && (FvbMapEntry->BlockLength == 0))) {
|
||||
for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) {
|
||||
if (FtwLiteDevice->WorkSpaceAddress < (BaseAddress + FvbMapEntry->BlockLength * LbaIndex)) {
|
||||
FtwLiteDevice->FtwWorkSpaceLba = LbaIndex - 1;
|
||||
//
|
||||
// Get the Work space size and Base(Offset)
|
||||
//
|
||||
FtwLiteDevice->FtwWorkSpaceSize = FtwLiteDevice->WorkSpaceLength;
|
||||
FtwLiteDevice->FtwWorkSpaceBase = (UINTN) (FtwLiteDevice->WorkSpaceAddress - (BaseAddress + FvbMapEntry->BlockLength * (LbaIndex - 1)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
// end for
|
||||
//
|
||||
FvbMapEntry++;
|
||||
}
|
||||
//
|
||||
// end while
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
if ((FtwLiteDevice->SpareAreaAddress >= BaseAddress) &&
|
||||
(FtwLiteDevice->SpareAreaAddress <= (BaseAddress + FwVolHeader->FvLength))
|
||||
) {
|
||||
FtwLiteDevice->FtwBackupFvb = Fvb;
|
||||
//
|
||||
// To get the LBA of spare
|
||||
//
|
||||
if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) {
|
||||
//
|
||||
// FV may have multiple types of BlockLength
|
||||
//
|
||||
FvbMapEntry = &FwVolHeader->FvBlockMap[0];
|
||||
while (!((FvbMapEntry->NumBlocks == 0) && (FvbMapEntry->BlockLength == 0))) {
|
||||
for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) {
|
||||
if (FtwLiteDevice->SpareAreaAddress < (BaseAddress + FvbMapEntry->BlockLength * LbaIndex)) {
|
||||
//
|
||||
// Get the NumberOfSpareBlock and SizeOfSpareBlock
|
||||
//
|
||||
FtwLiteDevice->FtwSpareLba = LbaIndex - 1;
|
||||
FtwLiteDevice->SizeOfSpareBlock = FvbMapEntry->BlockLength;
|
||||
FtwLiteDevice->NumberOfSpareBlock = FtwLiteDevice->SpareAreaLength / FtwLiteDevice->SizeOfSpareBlock;
|
||||
//
|
||||
// Check the range of spare area to make sure that it's in FV range
|
||||
//
|
||||
ASSERT ((FtwLiteDevice->FtwSpareLba + FtwLiteDevice->NumberOfSpareBlock) <= FvbMapEntry->NumBlocks);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FvbMapEntry++;
|
||||
}
|
||||
//
|
||||
// end while
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Calculate the start LBA of working block. Working block is an area which
|
||||
// contains working space in its last block and has the same size as spare
|
||||
// block, unless there are not enough blocks before the block that contains
|
||||
// working space.
|
||||
//
|
||||
FtwLiteDevice->FtwWorkBlockLba = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->NumberOfSpareBlock + 1;
|
||||
if ((INT64) (FtwLiteDevice->FtwWorkBlockLba) < 0) {
|
||||
FtwLiteDevice->FtwWorkBlockLba = 0;
|
||||
}
|
||||
|
||||
if ((FtwLiteDevice->FtwFvBlock == NULL) ||
|
||||
(FtwLiteDevice->FtwBackupFvb == NULL) ||
|
||||
(FtwLiteDevice->FtwWorkSpaceLba == (EFI_LBA) (-1)) ||
|
||||
(FtwLiteDevice->FtwSpareLba == (EFI_LBA) (-1))
|
||||
) {
|
||||
DEBUG ((EFI_D_ERROR, "FtwLite: Working or spare FVB not ready\n"));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
//
|
||||
// Refresh workspace data from working block
|
||||
//
|
||||
Status = WorkSpaceRefresh (FtwLiteDevice);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// If the working block workspace is not valid, try the spare block
|
||||
//
|
||||
if (!IsValidWorkSpace (FtwLiteDevice->FtwWorkSpaceHeader)) {
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: Workspace invalid, read from backup\n"));
|
||||
//
|
||||
// Read from spare block
|
||||
//
|
||||
Length = FtwLiteDevice->FtwWorkSpaceSize;
|
||||
Status = FtwLiteDevice->FtwBackupFvb->Read (
|
||||
FtwLiteDevice->FtwBackupFvb,
|
||||
FtwLiteDevice->FtwSpareLba,
|
||||
FtwLiteDevice->FtwWorkSpaceBase,
|
||||
&Length,
|
||||
FtwLiteDevice->FtwWorkSpace
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// If spare block is valid, then replace working block content.
|
||||
//
|
||||
if (IsValidWorkSpace (FtwLiteDevice->FtwWorkSpaceHeader)) {
|
||||
Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice);
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: Restart working block in Init() - %r\n", Status));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
FtwAbort (FtwLiteDevice);
|
||||
//
|
||||
// Refresh work space.
|
||||
//
|
||||
Status = WorkSpaceRefresh (FtwLiteDevice);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
} else {
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: Both are invalid, init workspace\n"));
|
||||
//
|
||||
// If both are invalid, then initialize work space.
|
||||
//
|
||||
SetMem (
|
||||
FtwLiteDevice->FtwWorkSpace,
|
||||
FtwLiteDevice->FtwWorkSpaceSize,
|
||||
FTW_ERASED_BYTE
|
||||
);
|
||||
InitWorkSpaceHeader (FtwLiteDevice->FtwWorkSpaceHeader);
|
||||
//
|
||||
// Write to work space on the working block
|
||||
//
|
||||
Length = FtwLiteDevice->FtwWorkSpaceSize;
|
||||
Status = FtwLiteDevice->FtwFvBlock->Write (
|
||||
FtwLiteDevice->FtwFvBlock,
|
||||
FtwLiteDevice->FtwWorkSpaceLba,
|
||||
FtwLiteDevice->FtwWorkSpaceBase,
|
||||
&Length,
|
||||
FtwLiteDevice->FtwWorkSpace
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Hook the protocol API
|
||||
//
|
||||
FtwLiteDevice->FtwLiteInstance.Write = FtwLiteWrite;
|
||||
|
||||
//
|
||||
// Install protocol interface
|
||||
//
|
||||
Status = gBS->InstallProtocolInterface (
|
||||
&FtwLiteDevice->Handle,
|
||||
&gEfiFaultTolerantWriteLiteProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
&FtwLiteDevice->FtwLiteInstance
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
//
|
||||
// If (!SpareCompleted) THEN Abort to rollback.
|
||||
//
|
||||
if ((FtwLiteDevice->FtwLastRecord->WriteAllocated == FTW_VALID_STATE) &&
|
||||
(FtwLiteDevice->FtwLastRecord->SpareCompleted != FTW_VALID_STATE)
|
||||
) {
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: Init.. record not SpareCompleted, abort()\n"));
|
||||
FtwAbort (FtwLiteDevice);
|
||||
}
|
||||
//
|
||||
// if (SpareCompleted) THEN Restart to fault tolerant write.
|
||||
//
|
||||
if ((FtwLiteDevice->FtwLastRecord->SpareCompleted == FTW_VALID_STATE) &&
|
||||
(FtwLiteDevice->FtwLastRecord->WriteCompleted != FTW_VALID_STATE)
|
||||
) {
|
||||
|
||||
Status = FtwRestart (FtwLiteDevice);
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: Restart last write - %r\n", Status));
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
//
|
||||
// To check the workspace buffer behind last records is EMPTY or not.
|
||||
// If it's not EMPTY, FTW_LITE also need to call reclaim().
|
||||
//
|
||||
Record = FtwLiteDevice->FtwLastRecord;
|
||||
Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;
|
||||
if (FtwLiteDevice->FtwWorkSpace[Offset] != FTW_ERASED_BYTE) {
|
||||
Offset += WRITE_TOTAL_SIZE;
|
||||
}
|
||||
|
||||
if (!IsErasedFlashBuffer (
|
||||
FTW_ERASE_POLARITY,
|
||||
FtwLiteDevice->FtwWorkSpace + Offset,
|
||||
FtwLiteDevice->FtwWorkSpaceSize - Offset
|
||||
)) {
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: Workspace is dirty, call reclaim...\n"));
|
||||
Status = FtwReclaimWorkSpace (FtwLiteDevice);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: Workspace reclaim - %r\n", Status));
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
|
||||
Module Name:
|
||||
|
||||
FtwLite.dxs
|
||||
|
||||
Abstract:
|
||||
|
||||
Dependency expression source file.
|
||||
|
||||
--*/
|
||||
#include <AutoGen.h>
|
||||
#include <DxeDepex.h>
|
||||
|
||||
|
||||
DEPENDENCY_START
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID AND EFI_ALTERNATE_FV_BLOCK_GUID
|
||||
DEPENDENCY_END
|
@@ -0,0 +1,675 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
|
||||
Module Name:
|
||||
|
||||
FtwLite.h
|
||||
|
||||
Abstract:
|
||||
|
||||
This is a simple fault tolerant write driver, based on PlatformFd library.
|
||||
And it only supports write BufferSize <= SpareAreaLength.
|
||||
|
||||
This boot service only protocol provides fault tolerant write capability for
|
||||
block devices. The protocol has internal non-volatile intermediate storage
|
||||
of the data and private information. It should be able to recover
|
||||
automatically from a critical fault, such as power failure.
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _EFI_FAULT_TOLERANT_WRITE_LITE_H_
|
||||
#define _EFI_FAULT_TOLERANT_WRITE_LITE_H_
|
||||
|
||||
#include <Common/FlashMap.h>
|
||||
#include <Common/WorkingBlockHeader.h>
|
||||
|
||||
#define EFI_D_FTW_LITE EFI_D_ERROR
|
||||
#define EFI_D_FTW_INFO EFI_D_INFO
|
||||
|
||||
//
|
||||
// Flash erase polarity is 1
|
||||
//
|
||||
#define FTW_ERASE_POLARITY 1
|
||||
|
||||
#define FTW_VALID_STATE 0
|
||||
#define FTW_INVALID_STATE 1
|
||||
|
||||
#define FTW_ERASED_BYTE ((UINT8) (255))
|
||||
#define FTW_POLARITY_REVERT ((UINT8) (255))
|
||||
|
||||
typedef struct {
|
||||
UINT8 WriteAllocated : 1;
|
||||
UINT8 SpareCompleted : 1;
|
||||
UINT8 WriteCompleted : 1;
|
||||
UINT8 Reserved : 5;
|
||||
#define WRITE_ALLOCATED 0x1
|
||||
#define SPARE_COMPLETED 0x2
|
||||
#define WRITE_COMPLETED 0x4
|
||||
|
||||
EFI_DEV_PATH DevPath;
|
||||
EFI_LBA Lba;
|
||||
UINTN Offset;
|
||||
UINTN NumBytes;
|
||||
//
|
||||
// UINTN SpareAreaOffset;
|
||||
//
|
||||
} EFI_FTW_LITE_RECORD;
|
||||
|
||||
#define FTW_LITE_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('F', 'T', 'W', 'L')
|
||||
|
||||
//
|
||||
// MACRO for Block size.
|
||||
// Flash Erasing will do in block granularity.
|
||||
//
|
||||
#ifdef FV_BLOCK_SIZE
|
||||
#define FTW_BLOCK_SIZE FV_BLOCK_SIZE
|
||||
#else
|
||||
#define FV_BLOCK_SIZE 0x10000
|
||||
#define FTW_BLOCK_SIZE FV_BLOCK_SIZE
|
||||
#endif
|
||||
//
|
||||
// MACRO for FTW WORK SPACE Base & Size
|
||||
//
|
||||
#ifdef EFI_FTW_WORKING_OFFSET
|
||||
#define FTW_WORK_SPACE_BASE EFI_FTW_WORKING_OFFSET
|
||||
#else
|
||||
#define FTW_WORK_SPACE_BASE 0x00E000
|
||||
#endif
|
||||
|
||||
#ifdef EFI_FTW_WORKING_LENGTH
|
||||
#define FTW_WORK_SPACE_SIZE EFI_FTW_WORKING_LENGTH
|
||||
#else
|
||||
#define FTW_WORK_SPACE_SIZE 0x002000
|
||||
#endif
|
||||
//
|
||||
// MACRO for FTW header and record
|
||||
//
|
||||
#define FTW_WORKING_QUEUE_SIZE (FTW_WORK_SPACE_SIZE - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER))
|
||||
#define FTW_LITE_RECORD_SIZE (sizeof (EFI_FTW_LITE_RECORD))
|
||||
#define WRITE_TOTAL_SIZE FTW_LITE_RECORD_SIZE
|
||||
|
||||
//
|
||||
// EFI Fault tolerant protocol private data structure
|
||||
//
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_FTW_LITE_PROTOCOL FtwLiteInstance;
|
||||
EFI_PHYSICAL_ADDRESS WorkSpaceAddress;
|
||||
UINTN WorkSpaceLength;
|
||||
EFI_PHYSICAL_ADDRESS SpareAreaAddress;
|
||||
UINTN SpareAreaLength;
|
||||
UINTN NumberOfSpareBlock; // Number of the blocks in spare block
|
||||
UINTN SizeOfSpareBlock; // Block size in bytes of the blocks in spare block
|
||||
EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FtwWorkSpaceHeader;
|
||||
EFI_FTW_LITE_RECORD *FtwLastRecord;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FtwFvBlock; // FVB of working block
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FtwBackupFvb; // FVB of spare block
|
||||
EFI_LBA FtwSpareLba;
|
||||
EFI_LBA FtwWorkBlockLba; // Start LBA of working block
|
||||
EFI_LBA FtwWorkSpaceLba; // Start LBA of working space
|
||||
UINTN FtwWorkSpaceBase; // Offset from LBA start addr
|
||||
UINTN FtwWorkSpaceSize;
|
||||
UINT8 *FtwWorkSpace;
|
||||
//
|
||||
// Following a buffer of FtwWorkSpace[FTW_WORK_SPACE_SIZE],
|
||||
// Allocated with EFI_FTW_LITE_DEVICE.
|
||||
//
|
||||
} EFI_FTW_LITE_DEVICE;
|
||||
|
||||
#define FTW_LITE_CONTEXT_FROM_THIS(a) CR (a, EFI_FTW_LITE_DEVICE, FtwLiteInstance, FTW_LITE_DEVICE_SIGNATURE)
|
||||
|
||||
//
|
||||
// Driver entry point
|
||||
//
|
||||
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
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
//
|
||||
// Fault Tolerant Write Protocol API
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FtwLiteWrite (
|
||||
IN EFI_FTW_LITE_PROTOCOL *This,
|
||||
IN EFI_HANDLE FvbHandle,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN Offset,
|
||||
IN UINTN *NumBytes,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Starts a target block update. This function will record data about write
|
||||
in fault tolerant storage and will complete the write in a recoverable
|
||||
manner, ensuring at all times that either the original contents or
|
||||
the modified contents are available.
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
FvbHandle - The handle of FVB protocol that provides services for
|
||||
reading, writing, and erasing the target block.
|
||||
Lba - The logical block address of the target block.
|
||||
Offset - The offset within the target block to place the data.
|
||||
NumBytes - The number of bytes to write to the target block.
|
||||
Buffer - The data to write.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
EFI_BAD_BUFFER_SIZE - The write would span a target block, which is not
|
||||
a valid action.
|
||||
EFI_ACCESS_DENIED - No writes have been allocated.
|
||||
EFI_NOT_FOUND - Cannot find FVB by handle.
|
||||
EFI_OUT_OF_RESOURCES - Cannot allocate memory.
|
||||
EFI_ABORTED - The function could not complete successfully.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
//
|
||||
// Internal functions
|
||||
//
|
||||
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
|
||||
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
|
||||
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
|
||||
FtwEraseBlock (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,
|
||||
EFI_LBA Lba
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
To Erase one block. The size is FTW_BLOCK_SIZE
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - Calling context
|
||||
FvBlock - FVB Protocol interface
|
||||
Lba - Lba of the firmware block
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Block LBA is Erased successfully
|
||||
Others - Error occurs
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
FtwEraseSpareBlock (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Erase spare block.
|
||||
|
||||
Arguments:
|
||||
|
||||
FtwLiteDevice - Calling context
|
||||
|
||||
Returns:
|
||||
|
||||
Status code
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
FtwGetFvbByHandle (
|
||||
IN EFI_HANDLE FvBlockHandle,
|
||||
OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrive the proper FVB protocol interface by HANDLE.
|
||||
|
||||
Arguments:
|
||||
FvBlockHandle - The handle of FVB protocol that provides services for
|
||||
reading, writing, and erasing the target block.
|
||||
FvBlock - The interface of FVB protocol
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
EFI_ABORTED - The function could not complete successfully
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
GetFvbByAddress (
|
||||
IN EFI_PHYSICAL_ADDRESS Address,
|
||||
OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Get firmware block by address.
|
||||
|
||||
Arguments:
|
||||
|
||||
Address - Address specified the block
|
||||
FvBlock - The block caller wanted
|
||||
|
||||
Returns:
|
||||
|
||||
Status code
|
||||
|
||||
EFI_NOT_FOUND - Block not found
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
IsInWorkingBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,
|
||||
EFI_LBA Lba
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Is it in working block?
|
||||
|
||||
Arguments:
|
||||
|
||||
FtwLiteDevice - Calling context
|
||||
FvBlock - Fvb protocol instance
|
||||
Lba - The block specified
|
||||
|
||||
Returns:
|
||||
|
||||
In working block or not
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
IsBootBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,
|
||||
EFI_LBA Lba
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Check whether the block is a boot block.
|
||||
|
||||
Arguments:
|
||||
|
||||
FtwLiteDevice - Calling context
|
||||
FvBlock - Fvb protocol instance
|
||||
Lba - Lba value
|
||||
|
||||
Returns:
|
||||
|
||||
Is a boot block or not
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
FlushSpareBlockToTargetBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,
|
||||
EFI_LBA Lba
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Copy the content of spare block to a target block. Size is FTW_BLOCK_SIZE.
|
||||
Spare block is accessed by FTW backup FVB protocol interface. LBA is
|
||||
FtwLiteDevice->FtwSpareLba.
|
||||
Target block is accessed by FvBlock protocol interface. LBA is Lba.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - The private data of FTW_LITE driver
|
||||
FvBlock - FVB Protocol interface to access target block
|
||||
Lba - Lba of the target block
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Spare block content is copied to target block
|
||||
EFI_INVALID_PARAMETER - Input parameter error
|
||||
EFI_OUT_OF_RESOURCES - Allocate memory error
|
||||
EFI_ABORTED - The function could not complete successfully
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
FlushSpareBlockToWorkingBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Copy the content of spare block to working block. Size is FTW_BLOCK_SIZE.
|
||||
Spare block is accessed by FTW backup FVB protocol interface. LBA is
|
||||
FtwLiteDevice->FtwSpareLba.
|
||||
Working block is accessed by FTW working FVB protocol interface. LBA is
|
||||
FtwLiteDevice->FtwWorkBlockLba.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - The private data of FTW_LITE driver
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Spare block content is copied to target block
|
||||
EFI_OUT_OF_RESOURCES - Allocate memory error
|
||||
EFI_ABORTED - The function could not complete successfully
|
||||
|
||||
Notes:
|
||||
Since the working block header is important when FTW initializes, the
|
||||
state of the operation should be handled carefully. The Crc value is
|
||||
calculated without STATE element.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
FlushSpareBlockToBootBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.
|
||||
Spare block is accessed by FTW backup FVB protocol interface. LBA is
|
||||
FtwLiteDevice->FtwSpareLba.
|
||||
Boot block is accessed by BootFvb protocol interface. LBA is 0.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - The private data of FTW_LITE driver
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Spare block content is copied to boot block
|
||||
EFI_INVALID_PARAMETER - Input parameter error
|
||||
EFI_OUT_OF_RESOURCES - Allocate memory error
|
||||
EFI_ABORTED - The function could not complete successfully
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
FtwUpdateFvState (
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN Offset,
|
||||
IN UINT8 NewBit
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Update a bit of state on a block device. The location of the bit is
|
||||
calculated by the (Lba, Offset, bit). Here bit is determined by the
|
||||
the name of a certain bit.
|
||||
|
||||
Arguments:
|
||||
FvBlock - FVB Protocol interface to access SrcBlock and DestBlock
|
||||
Lba - Lba of a block
|
||||
Offset - Offset on the Lba
|
||||
NewBit - New value that will override the old value if it can be change
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - A state bit has been updated successfully
|
||||
Others - Access block device error.
|
||||
|
||||
Notes:
|
||||
Assume all bits of State are inside the same BYTE.
|
||||
|
||||
EFI_ABORTED - Read block fail
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
FtwGetLastRecord (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
OUT EFI_FTW_LITE_RECORD **FtwLastRecord
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Get the last Write record pointer.
|
||||
The last record is the record whose 'complete' state hasn't been set.
|
||||
After all, this header may be a EMPTY header entry for next Allocate.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - Private data of this driver
|
||||
FtwLastRecord - Pointer to retrieve the last write record
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Get the last write record successfully
|
||||
EFI_ABORTED - The FTW work space is damaged
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
IsErasedFlashBuffer (
|
||||
IN BOOLEAN Polarity,
|
||||
IN UINT8 *Buffer,
|
||||
IN UINTN BufferSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Check whether a flash buffer is erased.
|
||||
|
||||
Arguments:
|
||||
|
||||
Polarity - All 1 or all 0
|
||||
Buffer - Buffer to check
|
||||
BufferSize - Size of the buffer
|
||||
|
||||
Returns:
|
||||
|
||||
Erased or not.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
InitWorkSpaceHeader (
|
||||
IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Initialize a work space when there is no work space.
|
||||
|
||||
Arguments:
|
||||
WorkingHeader - Pointer of working block header
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
EFI_ABORTED - The function could not complete successfully.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
WorkSpaceRefresh (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Read from working block to refresh the work space in memory.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - Point to private data of FTW driver
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
EFI_ABORTED - The function could not complete successfully.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
IsValidWorkSpace (
|
||||
IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check to see if it is a valid work space.
|
||||
|
||||
Arguments:
|
||||
WorkingHeader - Pointer of working block header
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
EFI_ABORTED - The function could not complete successfully.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
CleanupWorkSpace (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
IN OUT UINT8 *BlockBuffer,
|
||||
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.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
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
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
-->
|
||||
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
|
||||
<MbdHeader>
|
||||
<BaseName>FtwLite</BaseName>
|
||||
<Guid>4C862FC6-0E54-4e36-8C8F-FF6F3167951F</Guid>
|
||||
<Version>0</Version>
|
||||
<Description>FIX ME!</Description>
|
||||
<Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
|
||||
<License>
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
</License>
|
||||
<Created>2006-03-22 14:11</Created>
|
||||
</MbdHeader>
|
||||
<Libraries>
|
||||
<Library>UefiBootServicesTableLib</Library>
|
||||
<Library>BaseLib</Library>
|
||||
<Library>UefiMemoryLib</Library>
|
||||
<Library>DxeHobLib</Library>
|
||||
<Library>UefiLib</Library>
|
||||
<Library>UefiDriverEntryPoint</Library>
|
||||
<Library>DxeReportStatusCodeLib</Library>
|
||||
<Library>BaseDebugLibReportStatusCode</Library>
|
||||
<Library>EdkDxePrintLib</Library>
|
||||
<Library>DxeMemoryAllocationLib</Library>
|
||||
</Libraries>
|
||||
<BuildOptions ToolChain="MSFT">
|
||||
<ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
|
||||
</BuildOptions>
|
||||
</ModuleBuildDescription>
|
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
-->
|
||||
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
|
||||
<MsaHeader>
|
||||
<BaseName>FtwLite</BaseName>
|
||||
<ModuleType>DXE_DRIVER</ModuleType>
|
||||
<ComponentType>BS_DRIVER</ComponentType>
|
||||
<Guid>4C862FC6-0E54-4e36-8C8F-FF6F3167951F</Guid>
|
||||
<Version>0</Version>
|
||||
<Abstract>Component description file for DiskIo module.</Abstract>
|
||||
<Description>FIX ME!</Description>
|
||||
<Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
|
||||
<License>
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
</License>
|
||||
<Specification>0</Specification>
|
||||
<Created>2006-03-22 14:11</Created>
|
||||
</MsaHeader>
|
||||
<LibraryClassDefinitions>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename>FtwLite.c</Filename>
|
||||
<Filename>FtwMisc.c</Filename>
|
||||
<Filename>FtwWorkSpace.c</Filename>
|
||||
<Filename>FtwLite.dxs</Filename>
|
||||
<Arch ArchType="IA32">
|
||||
<Filename>ia32\Ia32FtwMisc.c</Filename>
|
||||
</Arch>
|
||||
<Arch ArchType="X64">
|
||||
<Filename>x64\x64FtwMisc.c</Filename>
|
||||
</Arch>
|
||||
<Arch ArchType="IPF">
|
||||
<Filename>Ipf\IpfFtwMisc.c</Filename>
|
||||
</Arch>
|
||||
<Arch ArchType="EBC">
|
||||
<Filename>ia32\Ia32FtwMisc.c</Filename>
|
||||
</Arch>
|
||||
</SourceFiles>
|
||||
<Includes>
|
||||
<PackageName>MdePkg</PackageName>
|
||||
<PackageName>EdkModulePkg</PackageName>
|
||||
</Includes>
|
||||
<Protocols>
|
||||
<Protocol Usage="ALWAYS_PRODUCED">FaultTolerantWriteLite</Protocol>
|
||||
<Protocol Usage="SOMETIMES_CONSUMED">PciRootBridgeIo</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">FirmwareVolumeBlock</Protocol>
|
||||
</Protocols>
|
||||
<Hobs>
|
||||
<Hob Usage="ALWAYS_CONSUMED" HobType="GUID_EXTENSION">
|
||||
<Name>FlashMapHob</Name>
|
||||
<C_Name>gEfiFlashMapHobGuid</C_Name>
|
||||
<Guid>0xb091e7d2, 0x5a0, 0x4198, 0x94, 0xf0, 0x74, 0xb7, 0xb8, 0xc5, 0x54, 0x59</Guid>
|
||||
</Hob>
|
||||
</Hobs>
|
||||
<Guids>
|
||||
<GuidEntry Usage="ALWAYS_CONSUMED">
|
||||
<C_Name>FlashMapHob</C_Name>
|
||||
</GuidEntry>
|
||||
<GuidEntry Usage="ALWAYS_CONSUMED">
|
||||
<C_Name>SystemNvDataFv</C_Name>
|
||||
</GuidEntry>
|
||||
</Guids>
|
||||
<Externs>
|
||||
<Extern>
|
||||
<ModuleEntryPoint>InitializeFtwLite</ModuleEntryPoint>
|
||||
</Extern>
|
||||
</Externs>
|
||||
</ModuleSurfaceArea>
|
@@ -0,0 +1,530 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
FtwMisc.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Internal functions to support fault tolerant write.
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include <FtwLite.h>
|
||||
|
||||
BOOLEAN
|
||||
IsErasedFlashBuffer (
|
||||
IN BOOLEAN Polarity,
|
||||
IN UINT8 *Buffer,
|
||||
IN UINTN BufferSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Check whether a flash buffer is erased.
|
||||
|
||||
Arguments:
|
||||
|
||||
Polarity - All 1 or all 0
|
||||
Buffer - Buffer to check
|
||||
BufferSize - Size of the buffer
|
||||
|
||||
Returns:
|
||||
|
||||
Erased or not.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT8 ErasedValue;
|
||||
UINT8 *Ptr;
|
||||
|
||||
if (Polarity) {
|
||||
ErasedValue = 0xFF;
|
||||
} else {
|
||||
ErasedValue = 0;
|
||||
}
|
||||
|
||||
Ptr = Buffer;
|
||||
while (BufferSize--) {
|
||||
if (*Ptr++ != ErasedValue) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
FtwEraseBlock (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,
|
||||
EFI_LBA Lba
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
To Erase one block. The size is FTW_BLOCK_SIZE
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - Calling context
|
||||
FvBlock - FVB Protocol interface
|
||||
Lba - Lba of the firmware block
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Block LBA is Erased successfully
|
||||
Others - Error occurs
|
||||
|
||||
--*/
|
||||
{
|
||||
return FvBlock->EraseBlocks (
|
||||
FvBlock,
|
||||
Lba,
|
||||
FtwLiteDevice->NumberOfSpareBlock,
|
||||
EFI_LBA_LIST_TERMINATOR
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
FtwEraseSpareBlock (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Erase spare block.
|
||||
|
||||
Arguments:
|
||||
|
||||
FtwLiteDevice - Calling context
|
||||
|
||||
Returns:
|
||||
|
||||
Status code
|
||||
|
||||
--*/
|
||||
{
|
||||
return FtwLiteDevice->FtwBackupFvb->EraseBlocks (
|
||||
FtwLiteDevice->FtwBackupFvb,
|
||||
FtwLiteDevice->FtwSpareLba,
|
||||
FtwLiteDevice->NumberOfSpareBlock,
|
||||
EFI_LBA_LIST_TERMINATOR
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
FtwGetFvbByHandle (
|
||||
IN EFI_HANDLE FvBlockHandle,
|
||||
OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrive the proper FVB protocol interface by HANDLE.
|
||||
|
||||
Arguments:
|
||||
FvBlockHandle - The handle of FVB protocol that provides services for
|
||||
reading, writing, and erasing the target block.
|
||||
FvBlock - The interface of FVB protocol
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
EFI_ABORTED - The function could not complete successfully
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// To get the FVB protocol interface on the handle
|
||||
//
|
||||
return gBS->HandleProtocol (
|
||||
FvBlockHandle,
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
(VOID **) FvBlock
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
GetFvbByAddress (
|
||||
IN EFI_PHYSICAL_ADDRESS Address,
|
||||
OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Get firmware block by address.
|
||||
|
||||
Arguments:
|
||||
|
||||
Address - Address specified the block
|
||||
FvBlock - The block caller wanted
|
||||
|
||||
Returns:
|
||||
|
||||
Status code
|
||||
|
||||
EFI_NOT_FOUND - Block not found
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
UINTN HandleCount;
|
||||
UINTN Index;
|
||||
EFI_PHYSICAL_ADDRESS FvbBaseAddress;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
|
||||
*FvBlock = NULL;
|
||||
//
|
||||
// Locate all handles of Fvb protocol
|
||||
//
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
NULL,
|
||||
&HandleCount,
|
||||
&HandleBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
//
|
||||
// Search all FVB until find the right one
|
||||
//
|
||||
for (Index = 0; Index < HandleCount; Index += 1) {
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
(VOID **) &Fvb
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Compare the address and select the right one
|
||||
//
|
||||
Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);
|
||||
if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + (FwVolHeader->FvLength - 1)))) {
|
||||
*FvBlock = Fvb;
|
||||
Status = EFI_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gBS->FreePool (HandleBuffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
IsInWorkingBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,
|
||||
EFI_LBA Lba
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Is it in working block?
|
||||
|
||||
Arguments:
|
||||
|
||||
FtwLiteDevice - Calling context
|
||||
FvBlock - Fvb protocol instance
|
||||
Lba - The block specified
|
||||
|
||||
Returns:
|
||||
|
||||
In working block or not
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// If matching the following condition, the target block is in working block.
|
||||
// 1. Target block is on the FV of working block (Using the same FVB protocol instance).
|
||||
// 2. Lba falls into the range of working block.
|
||||
//
|
||||
return (BOOLEAN)
|
||||
(
|
||||
(FvBlock == FtwLiteDevice->FtwFvBlock) &&
|
||||
(Lba >= FtwLiteDevice->FtwWorkBlockLba) &&
|
||||
(Lba <= FtwLiteDevice->FtwWorkSpaceLba)
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
FlushSpareBlockToTargetBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,
|
||||
EFI_LBA Lba
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Copy the content of spare block to a target block. Size is FTW_BLOCK_SIZE.
|
||||
Spare block is accessed by FTW backup FVB protocol interface. LBA is
|
||||
FtwLiteDevice->FtwSpareLba.
|
||||
Target block is accessed by FvBlock protocol interface. LBA is Lba.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - The private data of FTW_LITE driver
|
||||
FvBlock - FVB Protocol interface to access target block
|
||||
Lba - Lba of the target block
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Spare block content is copied to target block
|
||||
EFI_INVALID_PARAMETER - Input parameter error
|
||||
EFI_OUT_OF_RESOURCES - Allocate memory error
|
||||
EFI_ABORTED - The function could not complete successfully
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Length;
|
||||
UINT8 *Buffer;
|
||||
UINTN Count;
|
||||
UINT8 *Ptr;
|
||||
UINTN Index;
|
||||
|
||||
if ((FtwLiteDevice == NULL) || (FvBlock == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
//
|
||||
// Allocate a memory buffer
|
||||
//
|
||||
Length = FtwLiteDevice->SpareAreaLength;
|
||||
Buffer = AllocatePool (Length);
|
||||
if (Buffer == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
//
|
||||
// Read all content of spare block to memory buffer
|
||||
//
|
||||
Ptr = Buffer;
|
||||
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
|
||||
Count = FtwLiteDevice->SizeOfSpareBlock;
|
||||
Status = FtwLiteDevice->FtwBackupFvb->Read (
|
||||
FtwLiteDevice->FtwBackupFvb,
|
||||
FtwLiteDevice->FtwSpareLba + Index,
|
||||
0,
|
||||
&Count,
|
||||
Ptr
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Ptr += Count;
|
||||
}
|
||||
//
|
||||
// Erase the target block
|
||||
//
|
||||
Status = FtwEraseBlock (FtwLiteDevice, FvBlock, Lba);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (Buffer);
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
//
|
||||
// Write memory buffer to block, using the FvbBlock protocol interface
|
||||
//
|
||||
Ptr = Buffer;
|
||||
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
|
||||
Count = FtwLiteDevice->SizeOfSpareBlock;
|
||||
Status = FvBlock->Write (FvBlock, Lba + Index, 0, &Count, Ptr);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Write block - %r\n", Status));
|
||||
gBS->FreePool (Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Ptr += Count;
|
||||
}
|
||||
|
||||
gBS->FreePool (Buffer);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
FlushSpareBlockToWorkingBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Copy the content of spare block to working block. Size is FTW_BLOCK_SIZE.
|
||||
Spare block is accessed by FTW backup FVB protocol interface. LBA is
|
||||
FtwLiteDevice->FtwSpareLba.
|
||||
Working block is accessed by FTW working FVB protocol interface. LBA is
|
||||
FtwLiteDevice->FtwWorkBlockLba.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - The private data of FTW_LITE driver
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Spare block content is copied to target block
|
||||
EFI_OUT_OF_RESOURCES - Allocate memory error
|
||||
EFI_ABORTED - The function could not complete successfully
|
||||
|
||||
Notes:
|
||||
Since the working block header is important when FTW initializes, the
|
||||
state of the operation should be handled carefully. The Crc value is
|
||||
calculated without STATE element.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Length;
|
||||
UINT8 *Buffer;
|
||||
EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader;
|
||||
EFI_LBA WorkSpaceLbaOffset;
|
||||
UINTN Count;
|
||||
UINT8 *Ptr;
|
||||
UINTN Index;
|
||||
|
||||
//
|
||||
// Allocate a memory buffer
|
||||
//
|
||||
Length = FtwLiteDevice->SpareAreaLength;
|
||||
Buffer = AllocatePool (Length);
|
||||
if (Buffer == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
//
|
||||
// To guarantee that the WorkingBlockValid is set on spare block
|
||||
//
|
||||
WorkSpaceLbaOffset = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba;
|
||||
FtwUpdateFvState (
|
||||
FtwLiteDevice->FtwBackupFvb,
|
||||
FtwLiteDevice->FtwSpareLba + WorkSpaceLbaOffset,
|
||||
FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),
|
||||
WORKING_BLOCK_VALID
|
||||
);
|
||||
//
|
||||
// Read from spare block to memory buffer
|
||||
//
|
||||
Ptr = Buffer;
|
||||
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
|
||||
Count = FtwLiteDevice->SizeOfSpareBlock;
|
||||
Status = FtwLiteDevice->FtwBackupFvb->Read (
|
||||
FtwLiteDevice->FtwBackupFvb,
|
||||
FtwLiteDevice->FtwSpareLba + Index,
|
||||
0,
|
||||
&Count,
|
||||
Ptr
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Ptr += Count;
|
||||
}
|
||||
//
|
||||
// Clear the CRC and STATE, copy data from spare to working block.
|
||||
//
|
||||
WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (Buffer + (UINTN) WorkSpaceLbaOffset * FtwLiteDevice->SizeOfSpareBlock + FtwLiteDevice->FtwWorkSpaceBase);
|
||||
InitWorkSpaceHeader (WorkingBlockHeader);
|
||||
WorkingBlockHeader->WorkingBlockValid = FTW_ERASE_POLARITY;
|
||||
WorkingBlockHeader->WorkingBlockInvalid = FTW_ERASE_POLARITY;
|
||||
|
||||
//
|
||||
// target block is working block, then
|
||||
// Set WorkingBlockInvalid in EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER
|
||||
// before erase the working block.
|
||||
//
|
||||
// Offset = EFI_FIELD_OFFSET(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER,
|
||||
// WorkingBlockInvalid);
|
||||
// To skip Signature and Crc: sizeof(EFI_GUID)+sizeof(UINT32).
|
||||
//
|
||||
Status = FtwUpdateFvState (
|
||||
FtwLiteDevice->FtwFvBlock,
|
||||
FtwLiteDevice->FtwWorkSpaceLba,
|
||||
FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),
|
||||
WORKING_BLOCK_INVALID
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (Buffer);
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
FtwLiteDevice->FtwWorkSpaceHeader->WorkingBlockInvalid = FTW_VALID_STATE;
|
||||
|
||||
//
|
||||
// Erase the working block
|
||||
//
|
||||
Status = FtwEraseBlock (
|
||||
FtwLiteDevice,
|
||||
FtwLiteDevice->FtwFvBlock,
|
||||
FtwLiteDevice->FtwWorkBlockLba
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (Buffer);
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
//
|
||||
// Write memory buffer to working block, using the FvbBlock protocol interface
|
||||
//
|
||||
Ptr = Buffer;
|
||||
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
|
||||
Count = FtwLiteDevice->SizeOfSpareBlock;
|
||||
Status = FtwLiteDevice->FtwFvBlock->Write (
|
||||
FtwLiteDevice->FtwFvBlock,
|
||||
FtwLiteDevice->FtwWorkBlockLba + Index,
|
||||
0,
|
||||
&Count,
|
||||
Ptr
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Write block - %r\n", Status));
|
||||
gBS->FreePool (Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Ptr += Count;
|
||||
}
|
||||
//
|
||||
// Since the memory buffer will not be used, free memory Buffer.
|
||||
//
|
||||
gBS->FreePool (Buffer);
|
||||
|
||||
//
|
||||
// Update the VALID of the working block
|
||||
//
|
||||
// Offset = EFI_FIELD_OFFSET(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER,
|
||||
// WorkingBlockValid);
|
||||
// Hardcode offset sizeof(EFI_GUID)+sizeof(UINT32), to skip Signature and Crc
|
||||
//
|
||||
Status = FtwUpdateFvState (
|
||||
FtwLiteDevice->FtwFvBlock,
|
||||
FtwLiteDevice->FtwWorkSpaceLba,
|
||||
FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),
|
||||
WORKING_BLOCK_VALID
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
FtwLiteDevice->FtwWorkSpaceHeader->WorkingBlockValid = FTW_VALID_STATE;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
@@ -0,0 +1,567 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
FtwWorkSpace.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include <FtwLite.h>
|
||||
|
||||
BOOLEAN
|
||||
IsValidWorkSpace (
|
||||
IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check to see if it is a valid work space.
|
||||
|
||||
Arguments:
|
||||
WorkingHeader - Pointer of working block header
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
EFI_ABORTED - The function could not complete successfully.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER WorkingBlockHeader;
|
||||
|
||||
ASSERT (WorkingHeader != NULL);
|
||||
if (WorkingHeader->WorkingBlockValid != FTW_VALID_STATE) {
|
||||
return FALSE;
|
||||
}
|
||||
//
|
||||
// Check signature with gEfiSystemNvDataFvGuid
|
||||
//
|
||||
if (!CompareGuid (&gEfiSystemNvDataFvGuid, &WorkingHeader->Signature)) {
|
||||
return FALSE;
|
||||
}
|
||||
//
|
||||
// Check the CRC of header
|
||||
//
|
||||
CopyMem (
|
||||
&WorkingBlockHeader,
|
||||
WorkingHeader,
|
||||
sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)
|
||||
);
|
||||
|
||||
//
|
||||
// Filter out the Crc and State fields
|
||||
//
|
||||
SetMem (
|
||||
&WorkingBlockHeader.Crc,
|
||||
sizeof (UINT32),
|
||||
FTW_ERASED_BYTE
|
||||
);
|
||||
WorkingBlockHeader.WorkingBlockValid = FTW_ERASE_POLARITY;
|
||||
WorkingBlockHeader.WorkingBlockInvalid = FTW_ERASE_POLARITY;
|
||||
|
||||
//
|
||||
// Calculate the Crc of woking block header
|
||||
//
|
||||
Status = gBS->CalculateCrc32 (
|
||||
(UINT8 *) &WorkingBlockHeader,
|
||||
sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
|
||||
&WorkingBlockHeader.Crc
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (WorkingBlockHeader.Crc != WorkingHeader->Crc) {
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: Work block header CRC check error\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
InitWorkSpaceHeader (
|
||||
IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Initialize a work space when there is no work space.
|
||||
|
||||
Arguments:
|
||||
WorkingHeader - Pointer of working block header
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
EFI_ABORTED - The function could not complete successfully.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
ASSERT (WorkingHeader != NULL);
|
||||
|
||||
//
|
||||
// Here using gEfiSystemNvDataFvGuid as the signature.
|
||||
//
|
||||
CopyMem (
|
||||
&WorkingHeader->Signature,
|
||||
&gEfiSystemNvDataFvGuid,
|
||||
sizeof (EFI_GUID)
|
||||
);
|
||||
WorkingHeader->WriteQueueSize = FTW_WORKING_QUEUE_SIZE;
|
||||
|
||||
//
|
||||
// Crc is calculated with all the fields except Crc and STATE
|
||||
//
|
||||
WorkingHeader->WorkingBlockValid = FTW_ERASE_POLARITY;
|
||||
WorkingHeader->WorkingBlockInvalid = FTW_ERASE_POLARITY;
|
||||
SetMem (&WorkingHeader->Crc, sizeof (UINT32), FTW_ERASED_BYTE);
|
||||
|
||||
//
|
||||
// Calculate the CRC value
|
||||
//
|
||||
Status = gBS->CalculateCrc32 (
|
||||
(UINT8 *) WorkingHeader,
|
||||
sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
|
||||
&WorkingHeader->Crc
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Restore the WorkingBlockValid flag to VALID state
|
||||
//
|
||||
WorkingHeader->WorkingBlockValid = FTW_VALID_STATE;
|
||||
WorkingHeader->WorkingBlockInvalid = FTW_INVALID_STATE;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
FtwUpdateFvState (
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN Offset,
|
||||
IN UINT8 NewBit
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Update a bit of state on a block device. The location of the bit is
|
||||
calculated by the (Lba, Offset, bit). Here bit is determined by the
|
||||
the name of a certain bit.
|
||||
|
||||
Arguments:
|
||||
FvBlock - FVB Protocol interface to access SrcBlock and DestBlock
|
||||
Lba - Lba of a block
|
||||
Offset - Offset on the Lba
|
||||
NewBit - New value that will override the old value if it can be change
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - A state bit has been updated successfully
|
||||
Others - Access block device error.
|
||||
|
||||
Notes:
|
||||
Assume all bits of State are inside the same BYTE.
|
||||
|
||||
EFI_ABORTED - Read block fail
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 State;
|
||||
UINTN Length;
|
||||
|
||||
//
|
||||
// Read state from device, assume State is only one byte.
|
||||
//
|
||||
Length = sizeof (UINT8);
|
||||
Status = FvBlock->Read (FvBlock, Lba, Offset, &Length, &State);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
State ^= FTW_POLARITY_REVERT;
|
||||
State |= NewBit;
|
||||
State ^= FTW_POLARITY_REVERT;
|
||||
|
||||
//
|
||||
// Write state back to device
|
||||
//
|
||||
Length = sizeof (UINT8);
|
||||
Status = FvBlock->Write (FvBlock, Lba, Offset, &Length, &State);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
FtwGetLastRecord (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
OUT EFI_FTW_LITE_RECORD **FtwLastRecord
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Get the last Write record pointer.
|
||||
The last record is the record whose 'complete' state hasn't been set.
|
||||
After all, this header may be a EMPTY header entry for next Allocate.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - Private data of this driver
|
||||
FtwLastRecord - Pointer to retrieve the last write record
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Get the last write record successfully
|
||||
EFI_ABORTED - The FTW work space is damaged
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_FTW_LITE_RECORD *Record;
|
||||
|
||||
Record = (EFI_FTW_LITE_RECORD *) (FtwLiteDevice->FtwWorkSpaceHeader + 1);
|
||||
while (Record->WriteCompleted == FTW_VALID_STATE) {
|
||||
//
|
||||
// If Offset exceed the FTW work space boudary, return error.
|
||||
//
|
||||
if ((UINTN) ((UINT8 *) Record - FtwLiteDevice->FtwWorkSpace) > FtwLiteDevice->FtwWorkSpaceSize) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
Record++;
|
||||
}
|
||||
//
|
||||
// Last write record is found
|
||||
//
|
||||
*FtwLastRecord = Record;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
WorkSpaceRefresh (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Read from working block to refresh the work space in memory.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - Point to private data of FTW driver
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
EFI_ABORTED - The function could not complete successfully.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Length;
|
||||
UINTN Offset;
|
||||
EFI_FTW_LITE_RECORD *Record;
|
||||
|
||||
//
|
||||
// Initialize WorkSpace as FTW_ERASED_BYTE
|
||||
//
|
||||
SetMem (
|
||||
FtwLiteDevice->FtwWorkSpace,
|
||||
FtwLiteDevice->FtwWorkSpaceSize,
|
||||
FTW_ERASED_BYTE
|
||||
);
|
||||
|
||||
//
|
||||
// Read from working block
|
||||
//
|
||||
Length = FtwLiteDevice->FtwWorkSpaceSize;
|
||||
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
|
||||
//
|
||||
SetMem (FtwSpaceBuffer, Length, FTW_ERASED_BYTE);
|
||||
|
||||
//
|
||||
// Copy EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER to buffer
|
||||
//
|
||||
CopyMem (
|
||||
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)) {
|
||||
CopyMem (
|
||||
(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,
|
||||
(VOID **) &TempBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
ZeroMem (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
|
||||
);
|
||||
|
||||
CopyMem (
|
||||
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 = AllocatePool (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;
|
||||
}
|
@@ -0,0 +1,399 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Ia32FtwMisc.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Ia32 platform related code to support FtwLite..
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include <FtwLite.h>
|
||||
|
||||
//
|
||||
// MACROs for boot block update
|
||||
//
|
||||
#define BOOT_BLOCK_BASE 0xFFFF0000
|
||||
|
||||
//
|
||||
// (LPC -- D31:F0)
|
||||
//
|
||||
#define LPC_BUS_NUMBER 0x00
|
||||
#define LPC_DEVICE_NUMBER 0x1F
|
||||
#define LPC_IF 0xF0
|
||||
//
|
||||
// Top swap
|
||||
//
|
||||
#define GEN_STATUS 0xD4
|
||||
#define TOP_SWAP_BIT (1 << 13)
|
||||
|
||||
STATIC
|
||||
UINT32
|
||||
ReadPciRegister (
|
||||
IN UINT32 Offset
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Read PCI register value.
|
||||
|
||||
Arguments:
|
||||
|
||||
Offset - Offset of the register
|
||||
|
||||
Returns:
|
||||
|
||||
The value.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 Value;
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
|
||||
|
||||
Value = 0;
|
||||
Status = gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID **) &PciRootBridgeIo);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "FtwLite: Locate PCI root bridge io protocol - %r", Status));
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status = PciRootBridgeIo->Pci.Read (
|
||||
PciRootBridgeIo,
|
||||
EfiPciWidthUint32,
|
||||
EFI_PCI_ADDRESS (LPC_BUS_NUMBER,
|
||||
LPC_DEVICE_NUMBER,
|
||||
LPC_IF,
|
||||
Offset),
|
||||
1,
|
||||
&Value
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GetSwapState (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
OUT BOOLEAN *SwapState
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Get swap state
|
||||
|
||||
Arguments:
|
||||
|
||||
FtwLiteDevice - Calling context
|
||||
SwapState - Swap state
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - State successfully got
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// Top swap status is 13 bit
|
||||
//
|
||||
*SwapState = (BOOLEAN) ((ReadPciRegister (GEN_STATUS) & TOP_SWAP_BIT) != 0);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
SetSwapState (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
IN BOOLEAN TopSwap
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Set swap state.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - Indicates a pointer to the calling context.
|
||||
TopSwap - New swap state
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
|
||||
Note:
|
||||
the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that
|
||||
software will not be able to clear the Top-Swap bit until the system is
|
||||
rebooted without GNT[A]# being pulled down.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 GenStatus;
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Top-Swap bit (bit 13, D31: F0, Offset D4h)
|
||||
//
|
||||
GenStatus = ReadPciRegister (GEN_STATUS);
|
||||
|
||||
//
|
||||
// Set 13 bit, according to input NewSwapState
|
||||
//
|
||||
if (TopSwap) {
|
||||
GenStatus |= TOP_SWAP_BIT;
|
||||
} else {
|
||||
GenStatus &= ~TOP_SWAP_BIT;
|
||||
}
|
||||
|
||||
Status = gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID **) &PciRootBridgeIo);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "FtwLite: Locate PCI root bridge io protocol - %r", Status));
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Write back the GenStatus register
|
||||
//
|
||||
Status = PciRootBridgeIo->Pci.Write (
|
||||
PciRootBridgeIo,
|
||||
EfiPciWidthUint32,
|
||||
EFI_PCI_ADDRESS (LPC_BUS_NUMBER,
|
||||
LPC_DEVICE_NUMBER,
|
||||
LPC_IF,
|
||||
GEN_STATUS),
|
||||
1,
|
||||
&GenStatus
|
||||
);
|
||||
|
||||
DEBUG_CODE (
|
||||
if (TopSwap) {
|
||||
DEBUG ((EFI_D_ERROR, "SAR: Set top swap\n"));
|
||||
} else {
|
||||
DEBUG ((EFI_D_ERROR, "SAR: Clear top swap\n"));
|
||||
}
|
||||
);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
IsBootBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,
|
||||
EFI_LBA Lba
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Check whether the block is a boot block.
|
||||
|
||||
Arguments:
|
||||
|
||||
FtwLiteDevice - Calling context
|
||||
FvBlock - Fvb protocol instance
|
||||
Lba - Lba value
|
||||
|
||||
Returns:
|
||||
|
||||
Is a boot block or not
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *BootFvb;
|
||||
|
||||
Status = GetFvbByAddress (BOOT_BLOCK_BASE, &BootFvb);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
//
|
||||
// Compare the Fvb
|
||||
//
|
||||
return (BOOLEAN) (FvBlock == BootFvb);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
FlushSpareBlockToBootBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.
|
||||
Spare block is accessed by FTW backup FVB protocol interface. LBA is
|
||||
FtwLiteDevice->FtwSpareLba.
|
||||
Boot block is accessed by BootFvb protocol interface. LBA is 0.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - The private data of FTW_LITE driver
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Spare block content is copied to boot block
|
||||
EFI_INVALID_PARAMETER - Input parameter error
|
||||
EFI_OUT_OF_RESOURCES - Allocate memory error
|
||||
EFI_ABORTED - The function could not complete successfully
|
||||
|
||||
Notes:
|
||||
FTW will do extra work on boot block update.
|
||||
FTW should depend on a protocol of EFI_ADDRESS_RANGE_SWAP_PROTOCOL,
|
||||
which is produced by a chipset driver.
|
||||
|
||||
FTW updating boot block steps:
|
||||
1. Erase top swap block (0xFFFE-0xFFFEFFFF) and write data to it ready
|
||||
2. Read data from top swap block to memory buffer
|
||||
3. SetSwapState(EFI_SWAPPED)
|
||||
4. Erasing boot block (0xFFFF-0xFFFFFFFF)
|
||||
5. Programming boot block until the boot block is ok.
|
||||
6. SetSwapState(UNSWAPPED)
|
||||
|
||||
Notes:
|
||||
1. Since the SwapState bit is saved in CMOS, FTW can restore and continue
|
||||
even in the scenario of power failure.
|
||||
2. FTW shall not allow to update boot block when battery state is error.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Length;
|
||||
UINT8 *Buffer;
|
||||
UINTN Count;
|
||||
UINT8 *Ptr;
|
||||
UINTN Index;
|
||||
BOOLEAN TopSwap;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *BootFvb;
|
||||
EFI_LBA BootLba;
|
||||
|
||||
//
|
||||
// Allocate a memory buffer
|
||||
//
|
||||
Length = FtwLiteDevice->SpareAreaLength;
|
||||
Buffer = AllocatePool (Length);
|
||||
if (Buffer == NULL) {
|
||||
}
|
||||
//
|
||||
// Get TopSwap bit state
|
||||
//
|
||||
Status = GetSwapState (FtwLiteDevice, &TopSwap);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "FtwLite: Get Top Swapped status - %r\n", Status));
|
||||
gBS->FreePool (Buffer);
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
if (TopSwap) {
|
||||
//
|
||||
// Get FVB of current boot block
|
||||
//
|
||||
Status = GetFvbByAddress (FtwLiteDevice->SpareAreaAddress + FTW_BLOCK_SIZE, &BootFvb);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (Buffer);
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Read data from current boot block
|
||||
//
|
||||
BootLba = 0;
|
||||
Ptr = Buffer;
|
||||
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
|
||||
Count = FtwLiteDevice->SizeOfSpareBlock;
|
||||
Status = BootFvb->Read (
|
||||
BootFvb,
|
||||
BootLba + Index,
|
||||
0,
|
||||
&Count,
|
||||
Ptr
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Ptr += Count;
|
||||
}
|
||||
|
||||
} else {
|
||||
//
|
||||
// Read data from spare block
|
||||
//
|
||||
Ptr = Buffer;
|
||||
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
|
||||
Count = FtwLiteDevice->SizeOfSpareBlock;
|
||||
Status = FtwLiteDevice->FtwBackupFvb->Read (
|
||||
FtwLiteDevice->FtwBackupFvb,
|
||||
FtwLiteDevice->FtwSpareLba + Index,
|
||||
0,
|
||||
&Count,
|
||||
Ptr
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Ptr += Count;
|
||||
}
|
||||
//
|
||||
// Set TopSwap bit
|
||||
//
|
||||
Status = SetSwapState (FtwLiteDevice, TRUE);
|
||||
DEBUG ((EFI_D_ERROR, "FtwLite: Set Swap State - %r\n", Status));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
//
|
||||
// Erase boot block. After setting TopSwap bit, it's spare block now!
|
||||
//
|
||||
Status = FtwEraseSpareBlock (FtwLiteDevice);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (Buffer);
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
//
|
||||
// Write memory buffer to currenet spare block
|
||||
//
|
||||
Ptr = Buffer;
|
||||
for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
|
||||
Count = FtwLiteDevice->SizeOfSpareBlock;
|
||||
Status = FtwLiteDevice->FtwBackupFvb->Write (
|
||||
FtwLiteDevice->FtwBackupFvb,
|
||||
FtwLiteDevice->FtwSpareLba + Index,
|
||||
0,
|
||||
&Count,
|
||||
Ptr
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Write boot block - %r\n", Status));
|
||||
gBS->FreePool (Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Ptr += Count;
|
||||
}
|
||||
|
||||
gBS->FreePool (Buffer);
|
||||
|
||||
//
|
||||
// Clear TopSwap bit
|
||||
//
|
||||
Status = SetSwapState (FtwLiteDevice, FALSE);
|
||||
DEBUG ((EFI_D_ERROR, "FtwLite: Clear Swap State - %r\n", Status));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
@@ -0,0 +1,143 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
IpfFtwMisc.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Ipf platform related code to support FtwLite..
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include <FtwLite.h>
|
||||
|
||||
//
|
||||
// MACROs for boot block update
|
||||
//
|
||||
#define BOOT_BLOCK_BASE
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GetSwapState (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
OUT BOOLEAN *SwapState
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Get swap state
|
||||
|
||||
Arguments:
|
||||
|
||||
FtwLiteDevice - Calling context
|
||||
SwapState - Swap state
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - State successfully got
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
SetSwapState (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
IN BOOLEAN TopSwap
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Set swap state.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - Indicates a pointer to the calling context.
|
||||
TopSwap - New swap state
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
|
||||
Note:
|
||||
the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that
|
||||
software will not be able to clear the Top-Swap bit until the system is
|
||||
rebooted without GNT[A]# being pulled down.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
IsBootBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,
|
||||
EFI_LBA Lba
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Check whether the block is a boot block.
|
||||
|
||||
Arguments:
|
||||
|
||||
FtwLiteDevice - Calling context
|
||||
FvBlock - Fvb protocol instance
|
||||
Lba - Lba value
|
||||
|
||||
Returns:
|
||||
|
||||
Is a boot block or not
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// IPF doesn't support safe bootblock update
|
||||
// so treat bootblock as normal block
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
FlushSpareBlockToBootBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.
|
||||
Spare block is accessed by FTW backup FVB protocol interface. LBA is
|
||||
FtwLiteDevice->FtwSpareLba.
|
||||
Boot block is accessed by BootFvb protocol interface. LBA is 0.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - The private data of FTW_LITE driver
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Spare block content is copied to boot block
|
||||
EFI_INVALID_PARAMETER - Input parameter error
|
||||
EFI_OUT_OF_RESOURCES - Allocate memory error
|
||||
EFI_ABORTED - The function could not complete successfully
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
|
||||
<project basedir="." default="FtwLite"><!--Apply external ANT tasks-->
|
||||
<taskdef resource="GenBuild.tasks"/>
|
||||
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
|
||||
<property environment="env"/>
|
||||
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
|
||||
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
|
||||
<property name="MODULE_RELATIVE_PATH" value="Universal\FirmwareVolume\FaultTolerantWriteLite\Dxe"/>
|
||||
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
|
||||
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
|
||||
<target name="FtwLite">
|
||||
<GenBuild baseName="FtwLite" mbdFilename="${MODULE_DIR}\FtwLite.mbd" msaFilename="${MODULE_DIR}\FtwLite.msa"/>
|
||||
</target>
|
||||
<target depends="FtwLite_clean" name="clean"/>
|
||||
<target depends="FtwLite_cleanall" name="cleanall"/>
|
||||
<target name="FtwLite_clean">
|
||||
<OutputDirSetup baseName="FtwLite" mbdFilename="${MODULE_DIR}\FtwLite.mbd" msaFilename="${MODULE_DIR}\FtwLite.msa"/>
|
||||
<if>
|
||||
<available file="${DEST_DIR_OUTPUT}\FtwLite_build.xml"/>
|
||||
<then>
|
||||
<ant antfile="${DEST_DIR_OUTPUT}\FtwLite_build.xml" target="clean"/>
|
||||
</then>
|
||||
</if>
|
||||
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
|
||||
</target>
|
||||
<target name="FtwLite_cleanall">
|
||||
<OutputDirSetup baseName="FtwLite" mbdFilename="${MODULE_DIR}\FtwLite.mbd" msaFilename="${MODULE_DIR}\FtwLite.msa"/>
|
||||
<if>
|
||||
<available file="${DEST_DIR_OUTPUT}\FtwLite_build.xml"/>
|
||||
<then>
|
||||
<ant antfile="${DEST_DIR_OUTPUT}\FtwLite_build.xml" target="cleanall"/>
|
||||
</then>
|
||||
</if>
|
||||
<delete dir="${DEST_DIR_OUTPUT}"/>
|
||||
<delete dir="${DEST_DIR_DEBUG}"/>
|
||||
<delete>
|
||||
<fileset dir="${BIN_DIR}" includes="**FtwLite*"/>
|
||||
</delete>
|
||||
</target>
|
||||
</project>
|
@@ -0,0 +1,140 @@
|
||||
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
x64FtwMisc.c
|
||||
|
||||
Abstract:
|
||||
|
||||
X64 platform related code to support FtwLite..
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include <FtwLite.h>
|
||||
|
||||
//
|
||||
// MACROs for boot block update
|
||||
//
|
||||
#define BOOT_BLOCK_BASE
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GetSwapState (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
OUT BOOLEAN *SwapState
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Get swap state
|
||||
|
||||
Arguments:
|
||||
|
||||
FtwLiteDevice - Calling context
|
||||
SwapState - Swap state
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - State successfully got
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
SetSwapState (
|
||||
IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
IN BOOLEAN TopSwap
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Set swap state.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - Indicates a pointer to the calling context.
|
||||
TopSwap - New swap state
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The function completed successfully
|
||||
|
||||
Note:
|
||||
the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that
|
||||
software will not be able to clear the Top-Swap bit until the system is
|
||||
rebooted without GNT[A]# being pulled down.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
IsBootBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice,
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,
|
||||
EFI_LBA Lba
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Check whether the block is a boot block.
|
||||
|
||||
Arguments:
|
||||
|
||||
FtwLiteDevice - Calling context
|
||||
FvBlock - Fvb protocol instance
|
||||
Lba - Lba value
|
||||
|
||||
Returns:
|
||||
|
||||
Is a boot block or not
|
||||
|
||||
--*/
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
FlushSpareBlockToBootBlock (
|
||||
EFI_FTW_LITE_DEVICE *FtwLiteDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.
|
||||
Spare block is accessed by FTW backup FVB protocol interface. LBA is
|
||||
FtwLiteDevice->FtwSpareLba.
|
||||
Boot block is accessed by BootFvb protocol interface. LBA is 0.
|
||||
|
||||
Arguments:
|
||||
FtwLiteDevice - The private data of FTW_LITE driver
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Spare block content is copied to boot block
|
||||
EFI_INVALID_PARAMETER - Input parameter error
|
||||
EFI_OUT_OF_RESOURCES - Allocate memory error
|
||||
EFI_ABORTED - The function could not complete successfully
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
@@ -0,0 +1,234 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Crc32SectionExtract.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Implements GUIDed section extraction protocol interface with
|
||||
a specific GUID: CRC32.
|
||||
|
||||
Please refer to the Tiano File Image Format Specification,
|
||||
FV spec 0.3.6
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include <GuidedSection.h>
|
||||
#include <Crc32SectionExtract.h>
|
||||
|
||||
EFI_STATUS
|
||||
InitializeCrc32GuidedSectionExtractionProtocol (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
InitializeCrc32GuidedSectionExtractionProtocol (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Entry point of the CRC32 GUIDed section extraction protocol.
|
||||
Creates and initializes an instance of the GUIDed section
|
||||
extraction protocol with CRC32 GUID.
|
||||
|
||||
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: Driver initialized successfully
|
||||
EFI_LOAD_ERROR: Failed to Initialize or has been loaded
|
||||
EFI_OUT_OF_RESOURCES: Could not allocate needed resources
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *Crc32GuidedSep;
|
||||
EFI_HANDLE Handle;
|
||||
|
||||
//
|
||||
// Call all constructors per produced protocols
|
||||
//
|
||||
Status = GuidedSectionExtractionProtocolConstructor (
|
||||
&Crc32GuidedSep,
|
||||
(EFI_EXTRACT_GUIDED_SECTION) Crc32ExtractSection
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Crc32GuidedSep != NULL) {
|
||||
gBS->FreePool (Crc32GuidedSep);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Pass in a NULL to install to a new handle
|
||||
//
|
||||
Handle = NULL;
|
||||
Status = gBS->InstallProtocolInterface (
|
||||
&Handle,
|
||||
&gEfiCrc32GuidedSectionExtractionProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
Crc32GuidedSep
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (Crc32GuidedSep);
|
||||
return EFI_LOAD_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT32
|
||||
GetSectionLength (
|
||||
IN EFI_COMMON_SECTION_HEADER *CommonHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Get a length of section.
|
||||
|
||||
Parameters:
|
||||
CommonHeader - Pointer to the common section header.
|
||||
|
||||
Return Value:
|
||||
The length of the section, including the section header.
|
||||
|
||||
--*/
|
||||
// TODO: function comment is missing 'Arguments:'
|
||||
// TODO: function comment is missing 'Returns:'
|
||||
// TODO: CommonHeader - add argument and description to function comment
|
||||
{
|
||||
UINT32 Size;
|
||||
|
||||
Size = *(UINT32 *) CommonHeader->Size & 0x00FFFFFF;
|
||||
|
||||
return Size;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
Crc32ExtractSection (
|
||||
IN EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This,
|
||||
IN VOID *InputSection,
|
||||
OUT VOID **OutputBuffer,
|
||||
OUT UINTN *OutputSize,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This function reads and extracts contents of a section from an
|
||||
encapsulating section.
|
||||
|
||||
Parameters:
|
||||
This - Indicates the calling context.
|
||||
InputSection - Buffer containing the input GUIDed section
|
||||
to be processed.
|
||||
OutputBuffer - *OutputBuffer is allocated from boot services
|
||||
pool memory and containing the new section
|
||||
stream. The caller is responsible for freeing
|
||||
this buffer.
|
||||
AuthenticationStatus - Pointer to a caller allocated UINT32 that
|
||||
indicates the authentication status of the
|
||||
output buffer
|
||||
|
||||
Return Value:
|
||||
EFI_SUCCESS
|
||||
EFI_OUT_OF_RESOURCES
|
||||
EFI_INVALID_PARAMETER
|
||||
EFI_NOT_AVAILABLE_YET
|
||||
|
||||
--*/
|
||||
// TODO: function comment is missing 'Arguments:'
|
||||
// TODO: function comment is missing 'Returns:'
|
||||
// TODO: This - add argument and description to function comment
|
||||
// TODO: InputSection - add argument and description to function comment
|
||||
// TODO: OutputBuffer - add argument and description to function comment
|
||||
// TODO: OutputSize - add argument and description to function comment
|
||||
// TODO: AuthenticationStatus - add argument and description to function comment
|
||||
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
||||
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
||||
// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||
// TODO: EFI_SUCCESS - add return value to function comment
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
CRC32_SECTION_HEADER *Crc32SectionHeader;
|
||||
EFI_GUID_DEFINED_SECTION *GuidedSectionHeader;
|
||||
UINT8 *Image;
|
||||
UINT32 Crc32Checksum;
|
||||
VOID *DummyInterface;
|
||||
|
||||
if (OutputBuffer == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*OutputBuffer = NULL;
|
||||
|
||||
//
|
||||
// Points to the section header
|
||||
//
|
||||
Crc32SectionHeader = (CRC32_SECTION_HEADER *) InputSection;
|
||||
GuidedSectionHeader = (EFI_GUID_DEFINED_SECTION *) InputSection;
|
||||
|
||||
//
|
||||
// Check if the GUID is a CRC32 section GUID
|
||||
//
|
||||
if (!CompareGuid (
|
||||
&(GuidedSectionHeader->SectionDefinitionGuid),
|
||||
&gEfiCrc32GuidedSectionExtractionProtocolGuid
|
||||
)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Image = (UINT8 *) InputSection + (UINT32) (GuidedSectionHeader->DataOffset);
|
||||
*OutputSize = GetSectionLength ((EFI_COMMON_SECTION_HEADER *) InputSection) - (UINT32) GuidedSectionHeader->DataOffset;
|
||||
|
||||
Status = gBS->AllocatePool (EfiBootServicesData, *OutputSize, OutputBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
//
|
||||
// Implictly CRC32 GUIDed section should have STATUS_VALID bit set
|
||||
//
|
||||
ASSERT (GuidedSectionHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID);
|
||||
*AuthenticationStatus = EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED | EFI_AGGREGATE_AUTH_STATUS_IMAGE_SIGNED;
|
||||
|
||||
//
|
||||
// Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID.
|
||||
//
|
||||
Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
*AuthenticationStatus |= EFI_LOCAL_AUTH_STATUS_PLATFORM_OVERRIDE | EFI_AGGREGATE_AUTH_STATUS_PLATFORM_OVERRIDE;
|
||||
} else {
|
||||
//
|
||||
// Calculate CRC32 Checksum of Image
|
||||
//
|
||||
gBS->CalculateCrc32 (Image, *OutputSize, &Crc32Checksum);
|
||||
if (Crc32Checksum != Crc32SectionHeader->CRC32Checksum) {
|
||||
*AuthenticationStatus |= EFI_LOCAL_AUTH_STATUS_TEST_FAILED | EFI_AGGREGATE_AUTH_STATUS_TEST_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
CopyMem (*OutputBuffer, Image, *OutputSize);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Crc32SectionExtraction.dxs
|
||||
|
||||
Abstract:
|
||||
|
||||
Dependency expression file.
|
||||
|
||||
--*/
|
||||
|
||||
#include <AutoGen.h>
|
||||
#include "DxeDepex.h"
|
||||
|
||||
DEPENDENCY_START
|
||||
EFI_RUNTIME_ARCH_PROTOCOL_GUID
|
||||
DEPENDENCY_END
|
||||
|
@@ -0,0 +1,65 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Crc32SectionExtract.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Header file for Crc32SectionExtract.c
|
||||
Please refer to Tiano File Image Format specification
|
||||
FV spec 0.3.6
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _CRC32_GUIDED_SECTION_EXTRACTION_H
|
||||
#define _CRC32_GUIDED_SECTION_EXTRACTION_H
|
||||
|
||||
typedef struct {
|
||||
EFI_GUID_DEFINED_SECTION GuidedSectionHeader;
|
||||
UINT32 CRC32Checksum;
|
||||
} CRC32_SECTION_HEADER;
|
||||
|
||||
//
|
||||
// Function prototype declarations
|
||||
//
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
Crc32ExtractSection (
|
||||
IN EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This,
|
||||
IN VOID *InputSection,
|
||||
OUT VOID **OutputBuffer,
|
||||
OUT UINTN *OutputSize,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
This - TODO: add argument description
|
||||
InputSection - TODO: add argument description
|
||||
OutputBuffer - TODO: add argument description
|
||||
OutputSize - TODO: add argument description
|
||||
AuthenticationStatus - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
-->
|
||||
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
|
||||
<MbdHeader>
|
||||
<BaseName>Crc32SectionExtract</BaseName>
|
||||
<Guid>51C9F40C-5243-4473-B265-B3C8FFAFF9FA</Guid>
|
||||
<Version>0</Version>
|
||||
<Description>FIX ME!</Description>
|
||||
<Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
|
||||
<License>
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
</License>
|
||||
<Created>2006-03-12 17:09</Created>
|
||||
<Modified>2006-03-19 15:19</Modified>
|
||||
</MbdHeader>
|
||||
<Libraries>
|
||||
<Library>UefiBootServicesTableLib</Library>
|
||||
<Library>UefiMemoryLib</Library>
|
||||
<Library>UefiLib</Library>
|
||||
<Library>UefiDriverEntryPoint</Library>
|
||||
<Library>DxeReportStatusCodeLib</Library>
|
||||
<Library>BaseDebugLibReportStatusCode</Library>
|
||||
<Library>EdkDxePrintLib</Library>
|
||||
<Library>BaseLib</Library>
|
||||
</Libraries>
|
||||
</ModuleBuildDescription>
|
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
-->
|
||||
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
|
||||
<MsaHeader>
|
||||
<BaseName>Crc32SectionExtract</BaseName>
|
||||
<ModuleType>DXE_DRIVER</ModuleType>
|
||||
<ComponentType>BS_DRIVER</ComponentType>
|
||||
<Guid>51C9F40C-5243-4473-B265-B3C8FFAFF9FA</Guid>
|
||||
<Version>0</Version>
|
||||
<Abstract>Component description file for DiskIo module.</Abstract>
|
||||
<Description>FIX ME!</Description>
|
||||
<Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
|
||||
<License>
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
</License>
|
||||
<Specification>0</Specification>
|
||||
<Created>2006-03-12 17:09</Created>
|
||||
<Updated>2006-03-19 15:19</Updated>
|
||||
</MsaHeader>
|
||||
<LibraryClassDefinitions>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename>Crc32SectionExtract.c</Filename>
|
||||
<Filename>Crc32SectionExtract.h</Filename>
|
||||
<Filename>GuidedSection.c</Filename>
|
||||
<Filename>GuidedSection.h</Filename>
|
||||
</SourceFiles>
|
||||
<Includes>
|
||||
<PackageName>MdePkg</PackageName>
|
||||
<PackageName>EdkModulePkg</PackageName>
|
||||
</Includes>
|
||||
<Protocols>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">SecurityPolicy</Protocol>
|
||||
<Protocol Usage="ALWAYS_PRODUCED">Crc32GuidedSectionExtraction</Protocol>
|
||||
</Protocols>
|
||||
<Externs>
|
||||
<Extern>
|
||||
<ModuleEntryPoint>InitializeCrc32GuidedSectionExtractionProtocol</ModuleEntryPoint>
|
||||
</Extern>
|
||||
</Externs>
|
||||
</ModuleSurfaceArea>
|
@@ -0,0 +1,75 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
GuidedSection.c
|
||||
|
||||
Abstract:
|
||||
|
||||
GUIDed section extraction protocol implementation.
|
||||
This contains the common constructor of GUIDed section
|
||||
extraction protocol. GUID specific implementation of each
|
||||
GUIDed section extraction protocol can be found in other
|
||||
files under the same directory.
|
||||
|
||||
Please refer to the Tiano File Image Format Specification,
|
||||
FV spec 0.3.6
|
||||
|
||||
Acronyms used Meaning
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "Common/FirmwareFileSystem.h"
|
||||
|
||||
EFI_STATUS
|
||||
GuidedSectionExtractionProtocolConstructor (
|
||||
OUT EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL **GuidedSep,
|
||||
IN EFI_EXTRACT_GUIDED_SECTION ExtractSection
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Constructor for the GUIDed section extraction protocol. Initializes
|
||||
instance data.
|
||||
|
||||
Arguments:
|
||||
|
||||
This Instance to construct
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS: Instance initialized.
|
||||
|
||||
--*/
|
||||
// TODO: GuidedSep - add argument and description to function comment
|
||||
// TODO: ExtractSection - add argument and description to function comment
|
||||
// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
*GuidedSep = NULL;
|
||||
Status = gBS->AllocatePool (
|
||||
EfiBootServicesData,
|
||||
sizeof (EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL),
|
||||
(VOID **) GuidedSep
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
(*GuidedSep)->ExtractSection = ExtractSection;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
GuidedSection.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Header file for GuidedSection.c
|
||||
Please refer to Tiano File Image Format specification
|
||||
FV spec 0.3.6
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _GUIDED_SECTION_EXTRACTION_H
|
||||
#define _GUIDED_SECTION_EXTRACTION_H
|
||||
|
||||
//
|
||||
// Function prototype declarations
|
||||
//
|
||||
EFI_STATUS
|
||||
GuidedSectionExtractionProtocolConstructor (
|
||||
OUT EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL **GuidedSep,
|
||||
IN EFI_EXTRACT_GUIDED_SECTION ExtractSection
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
GuidedSep - TODO: add argument description
|
||||
ExtractSection - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
|
||||
<project basedir="." default="Crc32SectionExtract"><!--Apply external ANT tasks-->
|
||||
<taskdef resource="GenBuild.tasks"/>
|
||||
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
|
||||
<property environment="env"/>
|
||||
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
|
||||
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
|
||||
<property name="MODULE_RELATIVE_PATH" value="Universal\FirmwareVolume\GuidedSectionExtraction\Crc32SectionExtract\Dxe"/>
|
||||
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
|
||||
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
|
||||
<target name="Crc32SectionExtract">
|
||||
<GenBuild baseName="Crc32SectionExtract" mbdFilename="${MODULE_DIR}\Crc32SectionExtract.mbd" msaFilename="${MODULE_DIR}\Crc32SectionExtract.msa"/>
|
||||
</target>
|
||||
<target depends="Crc32SectionExtract_clean" name="clean"/>
|
||||
<target depends="Crc32SectionExtract_cleanall" name="cleanall"/>
|
||||
<target name="Crc32SectionExtract_clean">
|
||||
<OutputDirSetup baseName="Crc32SectionExtract" mbdFilename="${MODULE_DIR}\Crc32SectionExtract.mbd" msaFilename="${MODULE_DIR}\Crc32SectionExtract.msa"/>
|
||||
<if>
|
||||
<available file="${DEST_DIR_OUTPUT}\Crc32SectionExtract_build.xml"/>
|
||||
<then>
|
||||
<ant antfile="${DEST_DIR_OUTPUT}\Crc32SectionExtract_build.xml" target="clean"/>
|
||||
</then>
|
||||
</if>
|
||||
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
|
||||
</target>
|
||||
<target name="Crc32SectionExtract_cleanall">
|
||||
<OutputDirSetup baseName="Crc32SectionExtract" mbdFilename="${MODULE_DIR}\Crc32SectionExtract.mbd" msaFilename="${MODULE_DIR}\Crc32SectionExtract.msa"/>
|
||||
<if>
|
||||
<available file="${DEST_DIR_OUTPUT}\Crc32SectionExtract_build.xml"/>
|
||||
<then>
|
||||
<ant antfile="${DEST_DIR_OUTPUT}\Crc32SectionExtract_build.xml" target="cleanall"/>
|
||||
</then>
|
||||
</if>
|
||||
<delete dir="${DEST_DIR_OUTPUT}"/>
|
||||
<delete dir="${DEST_DIR_DEBUG}"/>
|
||||
<delete>
|
||||
<fileset dir="${BIN_DIR}" includes="**Crc32SectionExtract*"/>
|
||||
</delete>
|
||||
</target>
|
||||
</project>
|
Reference in New Issue
Block a user