From 88a5561c66bccd27c0fe4c3d7d0b3c235b2ae531 Mon Sep 17 00:00:00 2001 From: lgao4 Date: Wed, 4 Mar 2009 01:27:50 +0000 Subject: [PATCH] Update Variable driver to depend on full version FaultTolerantWrite protocol, and remove the lite version FaultTolerantWrite Dxe Driver. New full version FaultTolerantWriteDxe driver is added in MdeModulePkg. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7788 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Include/Protocol/FaultTolerantWriteLite.h | 73 -- MdeModulePkg/MdeModulePkg.dec | 5 - .../FaultTolerantWriteDxe/FtwLite.c | 922 ------------------ .../FaultTolerantWriteDxe/FtwLite.h | 497 ---------- .../FaultTolerantWriteDxe/FtwLite.inf | 64 -- .../FaultTolerantWriteDxe/FtwMisc.c | 505 ---------- .../FaultTolerantWriteDxe/FtwWorkSpace.c | 504 ---------- .../Universal/Variable/RuntimeDxe/Reclaim.c | 29 +- .../Universal/Variable/RuntimeDxe/Variable.h | 2 +- .../RuntimeDxe/VariableRuntimeDxe.inf | 4 +- 10 files changed, 18 insertions(+), 2587 deletions(-) delete mode 100644 MdeModulePkg/Include/Protocol/FaultTolerantWriteLite.h delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.c delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.h delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.inf delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwMisc.c delete mode 100644 MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwWorkSpace.c diff --git a/MdeModulePkg/Include/Protocol/FaultTolerantWriteLite.h b/MdeModulePkg/Include/Protocol/FaultTolerantWriteLite.h deleted file mode 100644 index d28845da95..0000000000 --- a/MdeModulePkg/Include/Protocol/FaultTolerantWriteLite.h +++ /dev/null @@ -1,73 +0,0 @@ -/** @file - Fault tolerant write lite protocol defines only one interface to write - the buffer to the fault tolerant storage. - -Copyright (c) 2006 - 2008, 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. - -**/ - -#ifndef __FW_FAULT_TOLERANT_WRITE_LITE_PROTOCOL_H__ -#define __FW_FAULT_TOLERANT_WRITE_LITE_PROTOCOL_H__ - -#define EFI_FTW_LITE_PROTOCOL_GUID \ -{ 0x3f557189, 0x8dae, 0x45ae, {0xa0, 0xb3, 0x2b, 0x99, 0xca, 0x7a, 0xa7, 0xa0 } } - -// -// Forward reference for pure ANSI compatability -// -typedef struct _EFI_FTW_LITE_PROTOCOL EFI_FTW_LITE_PROTOCOL; - -// -// Protocol API definitions -// -/** - Starts a target block update. This records information about the write - in fault tolerant storage will complete the write in a recoverable - manner, ensuring at all times that either the original contents or - the modified contents are available. - - @param This The pointer to this protocol instance. - @param FvbHandle The handle of FVB protocol that provides services - for reading, writing, and erasing the target block. - @param Lba The logical block address of the target block. - @param Offset The offset within the target block to place the data. - @param NumBytes The number of bytes to write to the target block. - @param Buffer The data to write. - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully. - @retval EFI_BAD_BUFFER_SIZE The input data can't fit within the FTW range. - The write buffer is too large to be supported. - @retval EFI_ACCESS_DENIED No writes have been allocated. - @retval EFI_OUT_OF_RESOURCES Cannot allocate enough memory resource. - @retval EFI_NOT_FOUND Cannot find FVB protocol by handle. - -**/ -typedef -EFI_STATUS -(EFIAPI * EFI_FTW_LITE_WRITE)( - IN EFI_FTW_LITE_PROTOCOL *This, - IN EFI_HANDLE FvbHandle, - IN EFI_LBA Lba, - IN UINTN Offset, - IN UINTN *NumBytes, - IN VOID *Buffer - ); - -// -// Protocol declaration -// -struct _EFI_FTW_LITE_PROTOCOL { - EFI_FTW_LITE_WRITE Write; -}; - -extern EFI_GUID gEfiFaultTolerantWriteLiteProtocolGuid; - -#endif diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index c8ecd0e356..882cdd3e95 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -173,11 +173,6 @@ ## This protocol defines the generic memory test interfaces in Dxe phase. ## Include/Protocol/GenericMemoryTest.h gEfiGenericMemTestProtocolGuid = { 0x309DE7F1, 0x7F5E, 0x4ACE, { 0xB4, 0x9C, 0x53, 0x1B, 0xE5, 0xAA, 0x95, 0xEF }} - - ## Fault tolerant write lite protocol defines only one interface to write - # the buffer to the fault tolerant storage. - ## Include/Protocol/FaultTolerantWriteLite.h - gEfiFaultTolerantWriteLiteProtocolGuid = { 0x3F557189, 0x8DAE, 0x45AE, { 0xA0, 0xB3, 0x2B, 0x99, 0xCA, 0x7A, 0xA7, 0xA0 }} ## This protocol provides the interfaces to Get/Set the current video mode for GOP/UGA screen ## Include/Protocol/ConsoleControl.h diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.c deleted file mode 100644 index 5e3b7af3f0..0000000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.c +++ /dev/null @@ -1,922 +0,0 @@ -/** @file - - This is a simple fault tolerant write driver. - - This boot service protocol only 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. - - The implementation uses an FTW Lite (Fault Tolerant Write) Work Space. - This work space is a memory copy of the work space on the Working Block, - the size of the work space is the FTW_WORK_SPACE_SIZE bytes. - - The work space stores each write record as EFI_FTW_LITE_RECORD structure. - The spare block stores the write buffer before write to the target block. - - The write record has three states to specify the different phase of write operation. - 1) WRITE_ALLOCATED is that the record is allocated in write space. - The information of write operation is stored in write record structure. - 2) SPARE_COMPLETED is that the data from write buffer is writed into the spare block as the backup. - 3) WRITE_COMPLETED is that the data is copied from the spare block to the target block. - - This driver operates the data as the whole size of spare block. - It first read the SpareAreaLength data from the target block into the spare memory buffer. - Then copy the write buffer data into the spare memory buffer. - Then write the spare memory buffer into the spare block. - Final copy the data from the spare block to the target block. - - To make this drive work well, the following conditions must be satisfied: - 1. The write NumBytes data must be fit within Spare area. - Offset + NumBytes <= SpareAreaLength - 2. The whole flash range has the same block size. - 3. Working block is an area which contains working space in its last block and has the same size as spare block. - 4. Working Block area must be in the single one Firmware Volume Block range which FVB protocol is produced on. - 5. Spare area must be in the single one Firmware Volume Block range which FVB protocol is produced on. - 6. Any write data area (SpareAreaLength Area) which the data will be written into must be - in the single one Firmware Volume Block range which FVB protocol is produced on. - 7. If write data area (such as Variable range) is enlarged, the spare area range must be enlarged. - The spare area must be enough large to store the write data before write them into the target range. - If one of them is not satisfied, FtwLiteWrite may fail. - Usually, Spare area only takes one block. That's SpareAreaLength = BlockSize, NumberOfSpareBlock = 1. - -Copyright (c) 2006 - 2009, 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. - -**/ - -#include "FtwLite.h" - -/** - 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. - - @param This The pointer to this protocol instance. - @param FvbHandle The handle of FVB protocol that provides services for - reading, writing, and erasing the target block. - @param Lba The logical block address of the target block. - @param Offset The offset within the target block to place the data. - @param NumBytes The number of bytes to write to the target block. - @param Buffer The data to write. - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully. - @retval EFI_BAD_BUFFER_SIZE The input data can't fit within the spare block. - Offset + *NumBytes > SpareAreaLength. - @retval EFI_ACCESS_DENIED No writes have been allocated. - @retval EFI_OUT_OF_RESOURCES Cannot allocate enough memory resource. - @retval EFI_NOT_FOUND Cannot find FVB protocol by handle. - -**/ -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 - ) -{ - 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) { - *NumBytes = FtwLiteDevice->SpareAreaLength - Offset; - return EFI_BAD_BUFFER_SIZE; - } - // - // Check if there is enough free space for allocate a record - // - if ((MyOffset + FTW_LITE_RECORD_SIZE) > FtwLiteDevice->FtwWorkSpaceSize) { - Status = FtwReclaimWorkSpace (FtwLiteDevice, TRUE); - 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_ERROR, "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_ERROR, "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->BlockSize; - Status = FtwLiteDevice->FtwFvBlock->Read ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkBlockLba + Index, - 0, - &MyLength, - Ptr - ); - if (EFI_ERROR (Status)) { - 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->BlockSize + Offset); - ASSERT ((Offset +*NumBytes) <= FtwLiteDevice->SpareAreaLength); - - } else { - - Ptr = MyBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - MyLength = FtwLiteDevice->BlockSize; - Status = Fvb->Read (Fvb, Lba + Index, 0, &MyLength, Ptr); - if (EFI_ERROR (Status)) { - 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) { - FreePool (MyBuffer); - return EFI_OUT_OF_RESOURCES; - } - - Ptr = SpareBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - MyLength = FtwLiteDevice->BlockSize; - Status = FtwLiteDevice->FtwBackupFvb->Read ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &MyLength, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (MyBuffer); - 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->BlockSize; - Status = FtwLiteDevice->FtwBackupFvb->Write ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &MyLength, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (MyBuffer); - FreePool (SpareBuffer); - return EFI_ABORTED; - } - - Ptr += MyLength; - } - // - // Free MyBuffer - // - FreePool (MyBuffer); - - // - // Set the SpareComplete in the FTW record, - // - MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace; - Status = FtwUpdateFvState ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkSpaceLba, - FtwLiteDevice->FtwWorkSpaceBase + MyOffset, - SPARE_COMPLETED - ); - if (EFI_ERROR (Status)) { - 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)) { - 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->BlockSize; - Status = FtwLiteDevice->FtwBackupFvb->Write ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &MyLength, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (SpareBuffer); - return EFI_ABORTED; - } - - Ptr += MyLength; - } - // - // All success. - // - FreePool (SpareBuffer); - - DEBUG ( - (EFI_D_ERROR, - "FtwLite: Write() success, (Lba:Offset)=(%lx:0x%x), NumBytes: 0x%x\n", - Lba, - Offset, - *NumBytes) - ); - - return EFI_SUCCESS; -} - - -/** - Write a record with fault tolerant manner. - Since the content has already backuped in spare block, the write is - guaranteed to be completed with fault tolerant manner. - - - @param FtwLiteDevice The private data of FTW_LITE driver - @param Fvb The FVB protocol that provides services for - reading, writing, and erasing the target block. - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully - -**/ -EFI_STATUS -FtwWriteRecord ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb - ) -{ - 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 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 { - // - // Update blocks other than working 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; -} - - -/** - Restarts a previously interrupted write. The caller must provide the - block protocol needed to complete the interrupted write. - - - @param 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. - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ACCESS_DENIED No pending writes exist - @retval EFI_NOT_FOUND FVB protocol not found by the handle - @retval EFI_ABORTED The function could not complete successfully - -**/ -EFI_STATUS -FtwRestart ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -{ - 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_ERROR, "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_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; -} - - -/** - Aborts all previous allocated writes. - - - @param FtwLiteDevice The private data of FTW_LITE driver - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully. - @retval EFI_NOT_FOUND No allocated writes exist. - -**/ -EFI_STATUS -FtwAbort ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -{ - 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_INFO, "FtwLite: Abort() success \n")); - return EFI_SUCCESS; -} - -/** - This function is the entry point of the Fault Tolerant Write driver. - - @param ImageHandle A handle for the image that is initializing this driver - @param SystemTable A pointer to the EFI system table - - @retval EFI_SUCCESS FTW has finished the initialization - @retval EFI_ABORTED FTW initialization error - -**/ -EFI_STATUS -EFIAPI -InitializeFtwLite ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - 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; - EFI_STATUS Status; - UINTN Offset; - UINTN Length; - EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry; - UINT32 LbaIndex; - // - // Allocate Private data of this driver, including the FtwWorkSpace[FTW_WORK_SPACE_SIZE]. - // - FtwLiteDevice = NULL; - FtwLiteDevice = AllocatePool (sizeof (EFI_FTW_LITE_DEVICE) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize)); - ASSERT (FtwLiteDevice != NULL); - - 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->FtwWorkSpaceHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) FtwLiteDevice->FtwWorkSpace; - FtwLiteDevice->FtwLastRecord = NULL; - - FtwLiteDevice->WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwWorkingBase); - FtwLiteDevice->WorkSpaceLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwWorkingSize); - - FtwLiteDevice->SpareAreaAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwSpareBase); - FtwLiteDevice->SpareAreaLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwSpareSize); - - 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 + FtwLiteDevice->WorkSpaceLength) <= (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->BlockMap[0]; - while (!((FvbMapEntry->NumBlocks == 0) && (FvbMapEntry->Length == 0))) { - for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) { - if ((FtwLiteDevice->WorkSpaceAddress >= (BaseAddress + FvbMapEntry->Length * (LbaIndex - 1))) - && (FtwLiteDevice->WorkSpaceAddress < (BaseAddress + FvbMapEntry->Length * LbaIndex))) { - FtwLiteDevice->FtwWorkSpaceLba = LbaIndex - 1; - // - // Get the Work space size and Base(Offset) - // - FtwLiteDevice->FtwWorkSpaceSize = FtwLiteDevice->WorkSpaceLength; - FtwLiteDevice->FtwWorkSpaceBase = (UINTN) (FtwLiteDevice->WorkSpaceAddress - (BaseAddress + FvbMapEntry->Length * (LbaIndex - 1))); - break; - } - } - // - // end for - // - if (LbaIndex <= FvbMapEntry->NumBlocks) { - // - // Work space range is found. - // - break; - } - FvbMapEntry++; - } - // - // end while - // - } - } - - if ((FtwLiteDevice->SpareAreaAddress >= BaseAddress) && - ((FtwLiteDevice->SpareAreaAddress + FtwLiteDevice->SpareAreaLength) <= (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->BlockMap[0]; - while (!((FvbMapEntry->NumBlocks == 0) && (FvbMapEntry->Length == 0))) { - for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) { - if ((FtwLiteDevice->SpareAreaAddress >= (BaseAddress + FvbMapEntry->Length * (LbaIndex - 1))) - && (FtwLiteDevice->SpareAreaAddress < (BaseAddress + FvbMapEntry->Length * LbaIndex))) { - // - // Get the NumberOfSpareBlock and BlockSize - // - FtwLiteDevice->FtwSpareLba = LbaIndex - 1; - FtwLiteDevice->BlockSize = FvbMapEntry->Length; - FtwLiteDevice->NumberOfSpareBlock = FtwLiteDevice->SpareAreaLength / FtwLiteDevice->BlockSize; - // - // Check the range of spare area to make sure that it's in FV range - // To do delete - // - ASSERT ((FtwLiteDevice->FtwSpareLba + FtwLiteDevice->NumberOfSpareBlock) <= FvbMapEntry->NumBlocks); - break; - } - } - if (LbaIndex <= FvbMapEntry->NumBlocks) { - // - // Spare FV range is found. - // - 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) { - DEBUG ((EFI_D_ERROR, "FtwLite: The spare block range is too large than the working block range!\n")); - FreePool (FtwLiteDevice); - return EFI_ABORTED; - } - - 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")); - FreePool (FtwLiteDevice); - return EFI_ABORTED; - } - - // - // 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_ERROR, "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_ERROR, "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)) { - FreePool (FtwLiteDevice); - return EFI_ABORTED; - } - } else { - DEBUG ((EFI_D_ERROR, "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); - // - // Initialize the work space - // - Status = FtwReclaimWorkSpace (FtwLiteDevice, FALSE); - - if (EFI_ERROR (Status)) { - FreePool (FtwLiteDevice); - 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)) { - FreePool (FtwLiteDevice); - 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_ERROR, "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_ERROR, "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 += FTW_LITE_RECORD_SIZE; - } - - if (!IsErasedFlashBuffer ( - FTW_ERASE_POLARITY, - FtwLiteDevice->FtwWorkSpace + Offset, - FtwLiteDevice->FtwWorkSpaceSize - Offset - )) { - DEBUG ((EFI_D_ERROR, "FtwLite: Workspace is dirty, call reclaim...\n")); - Status = FtwReclaimWorkSpace (FtwLiteDevice, TRUE); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FtwLite: Workspace reclaim - %r\n", Status)); - FreePool (FtwLiteDevice); - return EFI_ABORTED; - } - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.h b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.h deleted file mode 100644 index c33e1798b2..0000000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.h +++ /dev/null @@ -1,497 +0,0 @@ -/** @file - - The internal header file includes the common header files, defines - internal structure and functions used by FtwLite module. - -Copyright (c) 2006 - 2008, 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. - -**/ - -#ifndef _EFI_FAULT_TOLERANT_WRITE_LITE_H_ -#define _EFI_FAULT_TOLERANT_WRITE_LITE_H_ - - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -// -// 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 SIGNATURE_32 ('F', 'T', 'W', 'L') - -// -// MACRO for FTW header and record -// -#define FTW_LITE_RECORD_SIZE (sizeof (EFI_FTW_LITE_RECORD)) - -// -// EFI Fault tolerant protocol private data structure -// -typedef struct { - UINTN Signature; - EFI_HANDLE Handle; - EFI_FTW_LITE_PROTOCOL FtwLiteInstance; - EFI_PHYSICAL_ADDRESS WorkSpaceAddress; // Base address of working space range in flash. - UINTN WorkSpaceLength; // Size of working space range in flash. - EFI_PHYSICAL_ADDRESS SpareAreaAddress; // Base address of spare range in flash. - UINTN SpareAreaLength; // Size of spare range in flash. - UINTN NumberOfSpareBlock; // Number of the blocks in spare block. - UINTN BlockSize; // Block size in bytes of the blocks in flash - EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FtwWorkSpaceHeader;// Pointer to Working Space Header in memory buffer - EFI_FTW_LITE_RECORD *FtwLastRecord; // Pointer to last record in memory buffer - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FtwFvBlock; // FVB of working block - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FtwBackupFvb; // FVB of spare block - EFI_LBA FtwSpareLba; // Start LBA of spare block - EFI_LBA FtwWorkBlockLba; // Start LBA of working block that contains working space in its last block. - EFI_LBA FtwWorkSpaceLba; // Start LBA of working space - UINTN FtwWorkSpaceBase; // Offset into the FtwWorkSpaceLba block. - UINTN FtwWorkSpaceSize; // Size of working space range that stores write record. - UINT8 *FtwWorkSpace; // Point to Work Space in memory buffer - // - // 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 -// -/** - This function is the entry point of the Fault Tolerant Write driver. - - - @param ImageHandle A handle for the image that is initializing - this driver - @param SystemTable A pointer to the EFI system table - - @retval EFI_SUCCESS FTW has finished the initialization - @retval EFI_ABORTED FTW initialization error - -**/ -EFI_STATUS -EFIAPI -InitializeFtwLite ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ); - -// -// Fault Tolerant Write Protocol API -// -/** - 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. - - - @param This Calling context - @param FvbHandle The handle of FVB protocol that provides services for - reading, writing, and erasing the target block. - @param Lba The logical block address of the target block. - @param Offset The offset within the target block to place the data. - @param NumBytes The number of bytes to write to the target block. - @param Buffer The data to write. - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_BAD_BUFFER_SIZE The write would span a target block, which is not - a valid action. - @retval EFI_ACCESS_DENIED No writes have been allocated. - @retval EFI_NOT_FOUND Cannot find FVB by handle. - @retval EFI_OUT_OF_RESOURCES Cannot allocate memory. - @retval EFI_ABORTED The function could not complete successfully. - -**/ -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 - ); - -// -// Internal functions -// -/** - Restarts a previously interrupted write. The caller must provide the - block protocol needed to complete the interrupted write. - - - @param 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. - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ACCESS_DENIED No pending writes exist - @retval EFI_NOT_FOUND FVB protocol not found by the handle - @retval EFI_ABORTED The function could not complete successfully - -**/ -EFI_STATUS -FtwRestart ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ); - -/** - Aborts all previous allocated writes. - - - @param FtwLiteDevice The private data of FTW_LITE driver - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully. - @retval EFI_NOT_FOUND No allocated writes exist. - -**/ -EFI_STATUS -FtwAbort ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ); - - -/** - 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. - - - @param FtwLiteDevice The private data of FTW_LITE driver - @param Fvb The FVB protocol that provides services for - reading, writing, and erasing the target block. - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully - -**/ -EFI_STATUS -FtwWriteRecord ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb - ); - -/** - To erase the block with the spare block size. - - - @param FtwLiteDevice Calling context - @param FvBlock FVB Protocol interface - @param Lba Lba of the firmware block - - @retval EFI_SUCCESS Block LBA is Erased successfully - @retval Others Error occurs - -**/ -EFI_STATUS -FtwEraseBlock ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ); - -/** - - Erase spare block. - - - @param FtwLiteDevice Calling context - - @retval EFI_SUCCESS The erase request was successfully - completed. - - @retval EFI_ACCESS_DENIED The firmware volume is in the - WriteDisabled state. - @retval EFI_DEVICE_ERROR The block device is not functioning - correctly and could not be written. - The firmware device may have been - partially erased. - @retval EFI_INVALID_PARAMETER One or more of the LBAs listed - in the variable argument list do - not exist in the firmware volume. - -**/ -EFI_STATUS -FtwEraseSpareBlock ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ); - -/** - Retrive the proper FVB protocol interface by HANDLE. - - - @param FvBlockHandle The handle of FVB protocol that provides services for - reading, writing, and erasing the target block. - @param FvBlock The interface of FVB protocol - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully - -**/ -EFI_STATUS -FtwGetFvbByHandle ( - IN EFI_HANDLE FvBlockHandle, - OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock - ); - -/** - - Get firmware block by address. - - - @param Address Address specified the block - @param FvBlock The block caller wanted - - @retval EFI_SUCCESS The protocol instance if found. - @retval EFI_NOT_FOUND Block not found - -**/ -EFI_STATUS -GetFvbByAddress ( - IN EFI_PHYSICAL_ADDRESS Address, - OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock - ); - -/** - - Is it in working block? - - - @param FtwLiteDevice Calling context - @param FvBlock Fvb protocol instance - @param Lba The block specified - - @return A BOOLEAN value indicating in working block or not. - -**/ -BOOLEAN -IsInWorkingBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ); - -/** - 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. - - - @param FtwLiteDevice The private data of FTW_LITE driver - @param FvBlock FVB Protocol interface to access target block - @param Lba Lba of the target block - - @retval EFI_SUCCESS Spare block content is copied to target block - @retval EFI_INVALID_PARAMETER Input parameter error - @retval EFI_OUT_OF_RESOURCES Allocate memory error - @retval EFI_ABORTED The function could not complete successfully - -**/ -EFI_STATUS -FlushSpareBlockToTargetBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ); - -/** - 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. - - - @param FtwLiteDevice The private data of FTW_LITE driver - - @retval EFI_SUCCESS Spare block content is copied to target block - @retval EFI_OUT_OF_RESOURCES Allocate memory error - @retval 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 -FlushSpareBlockToWorkingBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice - ); - -/** - 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. - - - @param FvBlock FVB Protocol interface to access SrcBlock and DestBlock - @param Lba Lba of a block - @param Offset Offset on the Lba - @param NewBit New value that will override the old value if it can be change - - @retval EFI_SUCCESS A state bit has been updated successfully - @retval Others Access block device error. - Notes: - Assume all bits of State are inside the same BYTE. - @retval EFI_ABORTED Read block fail - -**/ -EFI_STATUS -FtwUpdateFvState ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - IN EFI_LBA Lba, - IN UINTN Offset, - IN UINT8 NewBit - ); - -/** - 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. - - - @param FtwLiteDevice Private data of this driver - @param FtwLastRecord Pointer to retrieve the last write record - - @retval EFI_SUCCESS Get the last write record successfully - @retval EFI_ABORTED The FTW work space is damaged - -**/ -EFI_STATUS -FtwGetLastRecord ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - OUT EFI_FTW_LITE_RECORD **FtwLastRecord - ); - -/** - - Check whether a flash buffer is erased. - - - @param Polarity All 1 or all 0 - @param Buffer Buffer to check - @param BufferSize Size of the buffer - - @return A BOOLEAN value indicating erased or not. - -**/ -BOOLEAN -IsErasedFlashBuffer ( - IN BOOLEAN Polarity, - IN UINT8 *Buffer, - IN UINTN BufferSize - ); - -/** - Initialize a work space when there is no work space. - - - @param WorkingHeader Pointer of working block header - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully. - -**/ -EFI_STATUS -InitWorkSpaceHeader ( - IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader - ); - -/** - Read from working block to refresh the work space in memory. - - - @param FtwLiteDevice Point to private data of FTW driver - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully. - -**/ -EFI_STATUS -WorkSpaceRefresh ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ); - -/** - Check to see if it is a valid work space. - - - @param WorkingHeader Pointer of working block header - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully. - -**/ -BOOLEAN -IsValidWorkSpace ( - IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader - ); - -/** - Reclaim the work space on the working block. - - - @param FtwLiteDevice Point to private data of FTW driver - @param PreserveRecord Whether to preserve the working record is needed - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_OUT_OF_RESOURCES Allocate memory error - @retval EFI_ABORTED The function could not complete successfully - -**/ -EFI_STATUS -FtwReclaimWorkSpace ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - IN BOOLEAN PreserveRecord - ); - -#endif diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.inf b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.inf deleted file mode 100644 index 32dbadbc0f..0000000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwLite.inf +++ /dev/null @@ -1,64 +0,0 @@ -#/** @file -# This driver provides lite version of fault tolerant capability for writing operation on flash devices. -# Its implementation depends on the full functionality FVB protocol that support read, write/erase flash access. -# -# Copyright (c) 2006 - 2009, 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. -# -#**/ - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = FtwLite - FILE_GUID = 4C862FC6-0E54-4e36-8C8F-FF6F3167951F - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = InitializeFtwLite - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources.common] - FtwWorkSpace.c - FtwMisc.c - FtwLite.c - FtwLite.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - UefiBootServicesTableLib - MemoryAllocationLib - BaseMemoryLib - UefiDriverEntryPoint - DebugLib - PcdLib - DevicePathLib - -[Guids] - gEfiSystemNvDataFvGuid ## CONSUMED ## FV Signature of Working Space Header - -[Protocols] - gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMED - gEfiFaultTolerantWriteLiteProtocolGuid ## PRODUCED - -[Pcd.common] - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase - -[Depex] - gEfiFirmwareVolumeBlockProtocolGuid AND gEfiAlternateFvBlockGuid ## gEfiAlternateFvBlockGuid specifies FVB protocol with read, write/erase flash access. - \ No newline at end of file diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwMisc.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwMisc.c deleted file mode 100644 index 1283215864..0000000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwMisc.c +++ /dev/null @@ -1,505 +0,0 @@ -/** @file - - Internal generic functions to operate flash block. - -Copyright (c) 2006 - 2008, 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. - -**/ - -#include "FtwLite.h" - -/** - - Check whether a flash buffer is erased. - - - @param Polarity All 1 or all 0 - @param Buffer Buffer to check - @param BufferSize Size of the buffer - - @return A BOOLEAN value indicating erased or not. - -**/ -BOOLEAN -IsErasedFlashBuffer ( - IN BOOLEAN Polarity, - IN UINT8 *Buffer, - IN UINTN BufferSize - ) -{ - UINT8 ErasedValue; - UINT8 *Ptr; - - if (Polarity) { - ErasedValue = 0xFF; - } else { - ErasedValue = 0; - } - - Ptr = Buffer; - while ((BufferSize--) != 0) { - if (*Ptr++ != ErasedValue) { - return FALSE; - } - } - - return TRUE; -} - -/** - To erase the block with the spare block size. - - - @param FtwLiteDevice Calling context - @param FvBlock FVB Protocol interface - @param Lba Lba of the firmware block - - @retval EFI_SUCCESS Block LBA is Erased successfully - @retval Others Error occurs - -**/ -EFI_STATUS -FtwEraseBlock ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -{ - return FvBlock->EraseBlocks ( - FvBlock, - Lba, - FtwLiteDevice->NumberOfSpareBlock, - EFI_LBA_LIST_TERMINATOR - ); -} - -/** - - Erase spare block. - - - @param FtwLiteDevice Calling context - - @retval EFI_SUCCESS The erase request was successfully - completed. - - @retval EFI_ACCESS_DENIED The firmware volume is in the - WriteDisabled state. - @retval EFI_DEVICE_ERROR The block device is not functioning - correctly and could not be written. - The firmware device may have been - partially erased. - @retval EFI_INVALID_PARAMETER One or more of the LBAs listed - in the variable argument list do - not exist in the firmware volume. - - -**/ -EFI_STATUS -FtwEraseSpareBlock ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -{ - return FtwLiteDevice->FtwBackupFvb->EraseBlocks ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba, - FtwLiteDevice->NumberOfSpareBlock, - EFI_LBA_LIST_TERMINATOR - ); -} - -/** - Retrive the proper FVB protocol interface by HANDLE. - - - @param FvBlockHandle The handle of FVB protocol that provides services for - reading, writing, and erasing the target block. - @param FvBlock The interface of FVB protocol - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully - -**/ -EFI_STATUS -FtwGetFvbByHandle ( - IN EFI_HANDLE FvBlockHandle, - OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock - ) -{ - // - // To get the FVB protocol interface on the handle - // - return gBS->HandleProtocol ( - FvBlockHandle, - &gEfiFirmwareVolumeBlockProtocolGuid, - (VOID **) FvBlock - ); -} - -/** - - Get firmware block by address. - - - @param Address Address specified the block - @param FvBlock The block caller wanted - - @retval EFI_SUCCESS The protocol instance if found. - @retval EFI_NOT_FOUND Block not found - -**/ -EFI_STATUS -GetFvbByAddress ( - IN EFI_PHYSICAL_ADDRESS Address, - OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock - ) -{ - 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; - } - } - - FreePool (HandleBuffer); - return Status; -} - -/** - - Is it in working block? - - - @param FtwLiteDevice Calling context - @param FvBlock Fvb protocol instance - @param Lba The block specified - - @return A BOOLEAN value indicating in working block or not. - -**/ -BOOLEAN -IsInWorkingBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -{ - // - // 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) - ); -} - -/** - 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. - - - @param FtwLiteDevice The private data of FTW_LITE driver - @param FvBlock FVB Protocol interface to access target block - @param Lba Lba of the target block - - @retval EFI_SUCCESS Spare block content is copied to target block - @retval EFI_INVALID_PARAMETER Input parameter error - @retval EFI_OUT_OF_RESOURCES Allocate memory error - @retval EFI_ABORTED The function could not complete successfully - -**/ -EFI_STATUS -FlushSpareBlockToTargetBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice, - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - EFI_LBA Lba - ) -{ - 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->BlockSize; - Status = FtwLiteDevice->FtwBackupFvb->Read ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &Count, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (Buffer); - return Status; - } - - Ptr += Count; - } - // - // Erase the target block - // - Status = FtwEraseBlock (FtwLiteDevice, FvBlock, Lba); - if (EFI_ERROR (Status)) { - 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->BlockSize; - Status = FvBlock->Write (FvBlock, Lba + Index, 0, &Count, Ptr); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FtwLite: FVB Write block - %r\n", Status)); - FreePool (Buffer); - return Status; - } - - Ptr += Count; - } - - FreePool (Buffer); - - return Status; -} - -/** - 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. - - - @param FtwLiteDevice The private data of FTW_LITE driver - - @retval EFI_SUCCESS Spare block content is copied to target block - @retval EFI_OUT_OF_RESOURCES Allocate memory error - @retval 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 -FlushSpareBlockToWorkingBlock ( - EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -{ - 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 - // - // Offset = OFFSET_OF(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER, - // WorkingBlockValid); - // To skip Signature and Crc: sizeof(EFI_GUID)+sizeof(UINT32). - // - 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->BlockSize; - Status = FtwLiteDevice->FtwBackupFvb->Read ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &Count, - Ptr - ); - if (EFI_ERROR (Status)) { - 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->BlockSize + 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 = OFFSET_OF(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)) { - 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)) { - 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->BlockSize; - Status = FtwLiteDevice->FtwFvBlock->Write ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkBlockLba + Index, - 0, - &Count, - Ptr - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FtwLite: FVB Write block - %r\n", Status)); - FreePool (Buffer); - return Status; - } - - Ptr += Count; - } - // - // Since the memory buffer will not be used, free memory Buffer. - // - FreePool (Buffer); - - // - // Update the VALID of the working block - // - // Offset = OFFSET_OF(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; -} diff --git a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwWorkSpace.c b/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwWorkSpace.c deleted file mode 100644 index 1dae0d6b56..0000000000 --- a/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteDxe/FtwWorkSpace.c +++ /dev/null @@ -1,504 +0,0 @@ -/** @file - - Internal functions to operate Working Block Space. - -Copyright (c) 2006 - 2008, 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. - -**/ - - -#include "FtwLite.h" - -/** - Check to see if it is a valid work space. - - - @param WorkingHeader Pointer of working block header - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully. - -**/ -BOOLEAN -IsValidWorkSpace ( - IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader - ) -{ - EFI_STATUS Status; - EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER WorkingBlockHeader; - - ASSERT (WorkingHeader != NULL); - if (WorkingHeader->WorkingBlockValid != FTW_VALID_STATE) { - DEBUG ((EFI_D_ERROR, "FtwLite: Work block header valid bit check error\n")); - return FALSE; - } - // - // Check signature with gEfiSystemNvDataFvGuid - // - if (!CompareGuid (&gEfiSystemNvDataFvGuid, &WorkingHeader->Signature)) { - DEBUG ((EFI_D_ERROR, "FtwLite: Work block header signature check error\n")); - 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_ERROR, "FtwLite: Work block header CRC check error\n")); - return FALSE; - } - - return TRUE; -} - -/** - Initialize a work space when there is no work space. - - - @param WorkingHeader Pointer of working block header - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully. - -**/ -EFI_STATUS -InitWorkSpaceHeader ( - IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader - ) -{ - EFI_STATUS Status; - - ASSERT (WorkingHeader != NULL); - - // - // Here using gEfiSystemNvDataFvGuid as the signature. - // - CopyMem ( - &WorkingHeader->Signature, - &gEfiSystemNvDataFvGuid, - sizeof (EFI_GUID) - ); - WorkingHeader->WriteQueueSize = (UINT64) (PcdGet32 (PcdFlashNvStorageFtwWorkingSize) - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)); - - // - // 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; -} - -/** - 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. - - - @param FvBlock FVB Protocol interface to access SrcBlock and DestBlock - @param Lba Lba of a block - @param Offset Offset on the Lba - @param NewBit New value that will override the old value if it can be change - - @retval EFI_SUCCESS A state bit has been updated successfully - @retval Others Access block device error. - Notes: - Assume all bits of State are inside the same BYTE. - @retval EFI_ABORTED Read block fail - -**/ -EFI_STATUS -FtwUpdateFvState ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock, - IN EFI_LBA Lba, - IN UINTN Offset, - IN UINT8 NewBit - ) -{ - 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 = (UINT8) (State | NewBit); - State ^= FTW_POLARITY_REVERT; - - // - // Write state back to device - // - Length = sizeof (UINT8); - Status = FvBlock->Write (FvBlock, Lba, Offset, &Length, &State); - - return Status; -} - -/** - 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. - - - @param FtwLiteDevice Private data of this driver - @param FtwLastRecord Pointer to retrieve the last write record - - @retval EFI_SUCCESS Get the last write record successfully - @retval EFI_ABORTED The FTW work space is damaged - -**/ -EFI_STATUS -FtwGetLastRecord ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - OUT EFI_FTW_LITE_RECORD **FtwLastRecord - ) -{ - EFI_FTW_LITE_RECORD *Record; - - *FtwLastRecord = NULL; - 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; -} - -/** - Read from working block to refresh the work space in memory. - - - @param FtwLiteDevice Point to private data of FTW driver - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_ABORTED The function could not complete successfully. - -**/ -EFI_STATUS -WorkSpaceRefresh ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice - ) -{ - 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 + FTW_LITE_RECORD_SIZE >= FtwLiteDevice->FtwWorkSpaceSize)) { - // - // reclaim work space in working block. - // - Status = FtwReclaimWorkSpace (FtwLiteDevice, TRUE); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FtwLite: Reclaim workspace - %r\n", Status)); - return EFI_ABORTED; - } - } - - return EFI_SUCCESS; -} - -/** - Reclaim the work space on the working block. - - - @param FtwLiteDevice Point to private data of FTW driver - @param PreserveRecord Whether get the last record or not - - @retval EFI_SUCCESS The function completed successfully - @retval EFI_OUT_OF_RESOURCES Allocate memory error - @retval EFI_ABORTED The function could not complete successfully - -**/ -EFI_STATUS -FtwReclaimWorkSpace ( - IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, - IN BOOLEAN PreserveRecord - ) -{ - EFI_STATUS Status; - UINT8 *TempBuffer; - UINTN TempBufferSize; - UINT8 *Ptr; - UINTN Length; - UINTN Index; - UINTN SpareBufferSize; - UINT8 *SpareBuffer; - EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader; - EFI_FTW_LITE_RECORD *Record; - - DEBUG ((EFI_D_ERROR, "FtwLite: start to reclaim work space\n")); - - // - // Read all original data from working block to a memory buffer - // - TempBufferSize = FtwLiteDevice->SpareAreaLength; - TempBuffer = AllocateZeroPool (TempBufferSize); - if (TempBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Ptr = TempBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Length = FtwLiteDevice->BlockSize; - Status = FtwLiteDevice->FtwFvBlock->Read ( - FtwLiteDevice->FtwFvBlock, - FtwLiteDevice->FtwWorkBlockLba + Index, - 0, - &Length, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (TempBuffer); - return EFI_ABORTED; - } - - Ptr += Length; - } - // - // Clean up the workspace, remove all the completed records. - // - Ptr = TempBuffer + - ((UINTN) (FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba)) * - FtwLiteDevice->BlockSize + FtwLiteDevice->FtwWorkSpaceBase; - - // - // Clear the content of buffer that will save the new work space data - // - SetMem (Ptr, FtwLiteDevice->FtwWorkSpaceSize, FTW_ERASED_BYTE); - - // - // Copy EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER to buffer - // - CopyMem ( - Ptr, - FtwLiteDevice->FtwWorkSpaceHeader, - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER) - ); - if (PreserveRecord) { - // - // Get the last record - // - Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord); - Record = FtwLiteDevice->FtwLastRecord; - if (!EFI_ERROR (Status) && - Record != NULL && - Record->WriteAllocated == FTW_VALID_STATE && - Record->WriteCompleted != FTW_VALID_STATE) { - CopyMem ( - (UINT8 *) Ptr + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), - Record, - FTW_LITE_RECORD_SIZE - ); - } - } - - 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) { - FreePool (TempBuffer); - return EFI_OUT_OF_RESOURCES; - } - - Ptr = SpareBuffer; - for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { - Length = FtwLiteDevice->BlockSize; - Status = FtwLiteDevice->FtwBackupFvb->Read ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &Length, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (TempBuffer); - 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->BlockSize; - Status = FtwLiteDevice->FtwBackupFvb->Write ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &Length, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (TempBuffer); - FreePool (SpareBuffer); - return EFI_ABORTED; - } - - Ptr += Length; - } - // - // Free TempBuffer - // - FreePool (TempBuffer); - - // - // Write the spare block to working block - // - Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice); - if (EFI_ERROR (Status)) { - 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->BlockSize; - Status = FtwLiteDevice->FtwBackupFvb->Write ( - FtwLiteDevice->FtwBackupFvb, - FtwLiteDevice->FtwSpareLba + Index, - 0, - &Length, - Ptr - ); - if (EFI_ERROR (Status)) { - FreePool (SpareBuffer); - return EFI_ABORTED; - } - - Ptr += Length; - } - - FreePool (SpareBuffer); - - DEBUG ((EFI_D_ERROR, "FtwLite: reclaim work space success\n")); - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c index e3189c4960..9c351a3547 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c @@ -201,21 +201,21 @@ FtwVariableSpace ( IN UINTN BufferSize ) { - EFI_STATUS Status; - EFI_HANDLE FvbHandle; - EFI_FTW_LITE_PROTOCOL *FtwLiteProtocol; - EFI_LBA VarLba; - UINTN VarOffset; - UINT8 *FtwBuffer; - UINTN FtwBufferSize; + EFI_STATUS Status; + EFI_HANDLE FvbHandle; + EFI_LBA VarLba; + UINTN VarOffset; + UINT8 *FtwBuffer; + UINTN FtwBufferSize; + EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol; // // Locate fault tolerant write protocol // Status = gBS->LocateProtocol ( - &gEfiFaultTolerantWriteLiteProtocolGuid, + &gEfiFaultTolerantWriteProtocolGuid, NULL, - (VOID **) &FtwLiteProtocol + (VOID **) &FtwProtocol ); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; @@ -249,13 +249,14 @@ FtwVariableSpace ( // // FTW write record // - Status = FtwLiteProtocol->Write ( - FtwLiteProtocol, - FvbHandle, + Status = FtwProtocol->Write ( + FtwProtocol, VarLba, // LBA VarOffset, // Offset - &FtwBufferSize, // NumBytes - FtwBuffer + FtwBufferSize, // NumBytes + NULL, // PrivateData NULL + FvbHandle, // Fvb Handle + FtwBuffer // write buffer ); FreePool (FtwBuffer); diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h index 4e861dccbc..6ae0ea91ec 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h @@ -19,7 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include -#include +#include #include #include #include diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf index 44063224a7..ffd78aa8bc 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf @@ -55,9 +55,9 @@ [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES - gEfiFaultTolerantWriteLiteProtocolGuid ## SOMETIMES_CONSUMES gEfiVariableWriteArchProtocolGuid ## ALWAYS_PRODUCES gEfiVariableArchProtocolGuid ## ALWAYS_PRODUCES + gEfiFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES [Guids] gEfiVariableGuid ## PRODUCES ## Configuration Table Guid @@ -75,7 +75,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.) [Depex] - gEfiFirmwareVolumeBlockProtocolGuid AND gEfiFaultTolerantWriteLiteProtocolGuid + gEfiFirmwareVolumeBlockProtocolGuid AND gEfiFaultTolerantWriteProtocolGuid # [Event] # ## -- 2.39.2