+++ /dev/null
-/** @file\r
- Fault tolerant write lite protocol defines only one interface to write \r
- the buffer to the fault tolerant storage.\r
-\r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef __FW_FAULT_TOLERANT_WRITE_LITE_PROTOCOL_H__\r
-#define __FW_FAULT_TOLERANT_WRITE_LITE_PROTOCOL_H__\r
-\r
-#define EFI_FTW_LITE_PROTOCOL_GUID \\r
-{ 0x3f557189, 0x8dae, 0x45ae, {0xa0, 0xb3, 0x2b, 0x99, 0xca, 0x7a, 0xa7, 0xa0 } }\r
-\r
-//\r
-// Forward reference for pure ANSI compatability\r
-//\r
-typedef struct _EFI_FTW_LITE_PROTOCOL EFI_FTW_LITE_PROTOCOL;\r
-\r
-//\r
-// Protocol API definitions\r
-//\r
-/**\r
- Starts a target block update. This records information about the write\r
- in fault tolerant storage will complete the write in a recoverable\r
- manner, ensuring at all times that either the original contents or\r
- the modified contents are available.\r
-\r
- @param This The pointer to this protocol instance. \r
- @param FvbHandle The handle of FVB protocol that provides services \r
- for reading, writing, and erasing the target block. \r
- @param Lba The logical block address of the target block. \r
- @param Offset The offset within the target block to place the data. \r
- @param NumBytes The number of bytes to write to the target block. \r
- @param Buffer The data to write. \r
-\r
- @retval EFI_SUCCESS The function completed successfully \r
- @retval EFI_ABORTED The function could not complete successfully. \r
- @retval EFI_BAD_BUFFER_SIZE The input data can't fit within the FTW range. \r
- The write buffer is too large to be supported.\r
- @retval EFI_ACCESS_DENIED No writes have been allocated. \r
- @retval EFI_OUT_OF_RESOURCES Cannot allocate enough memory resource.\r
- @retval EFI_NOT_FOUND Cannot find FVB protocol by handle.\r
- \r
-**/\r
-typedef\r
-EFI_STATUS\r
-(EFIAPI * EFI_FTW_LITE_WRITE)(\r
- IN EFI_FTW_LITE_PROTOCOL *This,\r
- IN EFI_HANDLE FvbHandle,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN UINTN *NumBytes,\r
- IN VOID *Buffer\r
- );\r
-\r
-//\r
-// Protocol declaration\r
-//\r
-struct _EFI_FTW_LITE_PROTOCOL {\r
- EFI_FTW_LITE_WRITE Write;\r
-};\r
-\r
-extern EFI_GUID gEfiFaultTolerantWriteLiteProtocolGuid;\r
-\r
-#endif\r
## This protocol defines the generic memory test interfaces in Dxe phase.\r
## Include/Protocol/GenericMemoryTest.h\r
gEfiGenericMemTestProtocolGuid = { 0x309DE7F1, 0x7F5E, 0x4ACE, { 0xB4, 0x9C, 0x53, 0x1B, 0xE5, 0xAA, 0x95, 0xEF }}\r
-\r
- ## Fault tolerant write lite protocol defines only one interface to write \r
- # the buffer to the fault tolerant storage.\r
- ## Include/Protocol/FaultTolerantWriteLite.h\r
- gEfiFaultTolerantWriteLiteProtocolGuid = { 0x3F557189, 0x8DAE, 0x45AE, { 0xA0, 0xB3, 0x2B, 0x99, 0xCA, 0x7A, 0xA7, 0xA0 }}\r
\r
## This protocol provides the interfaces to Get/Set the current video mode for GOP/UGA screen\r
## Include/Protocol/ConsoleControl.h\r
+++ /dev/null
-/** @file\r
-\r
- This is a simple fault tolerant write driver.\r
-\r
- This boot service protocol only provides fault tolerant write capability for \r
- block devices. The protocol has internal non-volatile intermediate storage \r
- of the data and private information. It should be able to recover \r
- automatically from a critical fault, such as power failure. \r
-\r
- The implementation uses an FTW Lite (Fault Tolerant Write) Work Space. \r
- This work space is a memory copy of the work space on the Working Block,\r
- the size of the work space is the FTW_WORK_SPACE_SIZE bytes.\r
- \r
- The work space stores each write record as EFI_FTW_LITE_RECORD structure.\r
- The spare block stores the write buffer before write to the target block.\r
- \r
- The write record has three states to specify the different phase of write operation.\r
- 1) WRITE_ALLOCATED is that the record is allocated in write space.\r
- The information of write operation is stored in write record structure.\r
- 2) SPARE_COMPLETED is that the data from write buffer is writed into the spare block as the backup.\r
- 3) WRITE_COMPLETED is that the data is copied from the spare block to the target block.\r
-\r
- This driver operates the data as the whole size of spare block.\r
- It first read the SpareAreaLength data from the target block into the spare memory buffer.\r
- Then copy the write buffer data into the spare memory buffer.\r
- Then write the spare memory buffer into the spare block.\r
- Final copy the data from the spare block to the target block.\r
-\r
- To make this drive work well, the following conditions must be satisfied:\r
- 1. The write NumBytes data must be fit within Spare area. \r
- Offset + NumBytes <= SpareAreaLength\r
- 2. The whole flash range has the same block size.\r
- 3. Working block is an area which contains working space in its last block and has the same size as spare block.\r
- 4. Working Block area must be in the single one Firmware Volume Block range which FVB protocol is produced on. \r
- 5. Spare area must be in the single one Firmware Volume Block range which FVB protocol is produced on.\r
- 6. Any write data area (SpareAreaLength Area) which the data will be written into must be \r
- in the single one Firmware Volume Block range which FVB protocol is produced on.\r
- 7. If write data area (such as Variable range) is enlarged, the spare area range must be enlarged.\r
- The spare area must be enough large to store the write data before write them into the target range.\r
- If one of them is not satisfied, FtwLiteWrite may fail.\r
- Usually, Spare area only takes one block. That's SpareAreaLength = BlockSize, NumberOfSpareBlock = 1.\r
-\r
-Copyright (c) 2006 - 2009, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-#include "FtwLite.h"\r
-\r
-/**\r
- Starts a target block update. This function will record data about write\r
- in fault tolerant storage and will complete the write in a recoverable\r
- manner, ensuring at all times that either the original contents or\r
- the modified contents are available.\r
-\r
- @param This The pointer to this protocol instance. \r
- @param FvbHandle The handle of FVB protocol that provides services for\r
- reading, writing, and erasing the target block.\r
- @param Lba The logical block address of the target block.\r
- @param Offset The offset within the target block to place the data.\r
- @param NumBytes The number of bytes to write to the target block.\r
- @param Buffer The data to write.\r
-\r
- @retval EFI_SUCCESS The function completed successfully \r
- @retval EFI_ABORTED The function could not complete successfully. \r
- @retval EFI_BAD_BUFFER_SIZE The input data can't fit within the spare block. \r
- Offset + *NumBytes > SpareAreaLength.\r
- @retval EFI_ACCESS_DENIED No writes have been allocated. \r
- @retval EFI_OUT_OF_RESOURCES Cannot allocate enough memory resource.\r
- @retval EFI_NOT_FOUND Cannot find FVB protocol by handle.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FtwLiteWrite (\r
- IN EFI_FTW_LITE_PROTOCOL *This,\r
- IN EFI_HANDLE FvbHandle,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN OUT UINTN *NumBytes,\r
- IN VOID *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_FTW_LITE_DEVICE *FtwLiteDevice;\r
- EFI_FTW_LITE_RECORD *Record;\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;\r
- EFI_PHYSICAL_ADDRESS FvbPhysicalAddress;\r
- UINTN MyLength;\r
- UINTN MyOffset;\r
- UINTN MyBufferSize;\r
- UINT8 *MyBuffer;\r
- UINTN SpareBufferSize;\r
- UINT8 *SpareBuffer;\r
- UINTN Index;\r
- UINT8 *Ptr;\r
- EFI_DEV_PATH_PTR DevPtr;\r
- //\r
- // Refresh work space and get last record\r
- //\r
- FtwLiteDevice = FTW_LITE_CONTEXT_FROM_THIS (This);\r
- Status = WorkSpaceRefresh (FtwLiteDevice);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- Record = FtwLiteDevice->FtwLastRecord;\r
-\r
- //\r
- // Check the flags of last write record\r
- //\r
- if ((Record->WriteAllocated == FTW_VALID_STATE) || (Record->SpareCompleted == FTW_VALID_STATE)) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- //\r
- // IF former record has completed, THEN use next record\r
- //\r
- if (Record->WriteCompleted == FTW_VALID_STATE) {\r
- Record++;\r
- FtwLiteDevice->FtwLastRecord = Record;\r
- }\r
-\r
- MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;\r
-\r
- //\r
- // Check if the input data can fit within the target block\r
- //\r
- if ((Offset +*NumBytes) > FtwLiteDevice->SpareAreaLength) {\r
- *NumBytes = FtwLiteDevice->SpareAreaLength - Offset;\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
- //\r
- // Check if there is enough free space for allocate a record\r
- //\r
- if ((MyOffset + FTW_LITE_RECORD_SIZE) > FtwLiteDevice->FtwWorkSpaceSize) {\r
- Status = FtwReclaimWorkSpace (FtwLiteDevice, TRUE);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Reclaim work space - %r", Status));\r
- return EFI_ABORTED;\r
- }\r
- }\r
- //\r
- // Get the FVB protocol by handle\r
- //\r
- Status = FtwGetFvbByHandle (FvbHandle, &Fvb);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
- //\r
- // Allocate a write record in workspace.\r
- // Update Header->WriteAllocated as VALID\r
- //\r
- Status = FtwUpdateFvState (\r
- FtwLiteDevice->FtwFvBlock,\r
- FtwLiteDevice->FtwWorkSpaceLba,\r
- FtwLiteDevice->FtwWorkSpaceBase + MyOffset,\r
- WRITE_ALLOCATED\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Allocate record - %r\n", Status));\r
- return EFI_ABORTED;\r
- }\r
-\r
- Record->WriteAllocated = FTW_VALID_STATE;\r
-\r
- //\r
- // Prepare data of write record, filling DevPath with memory mapped address.\r
- //\r
- DevPtr.MemMap = (MEMMAP_DEVICE_PATH *) &Record->DevPath;\r
- DevPtr.MemMap->Header.Type = HARDWARE_DEVICE_PATH;\r
- DevPtr.MemMap->Header.SubType = HW_MEMMAP_DP;\r
- SetDevicePathNodeLength (&DevPtr.MemMap->Header, sizeof (MEMMAP_DEVICE_PATH));\r
-\r
- Status = Fvb->GetPhysicalAddress (Fvb, &FvbPhysicalAddress);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Get FVB physical address - %r\n", Status));\r
- return EFI_ABORTED;\r
- }\r
-\r
- DevPtr.MemMap->MemoryType = EfiMemoryMappedIO;\r
- DevPtr.MemMap->StartingAddress = FvbPhysicalAddress;\r
- DevPtr.MemMap->EndingAddress = FvbPhysicalAddress +*NumBytes;\r
- //\r
- // ignored!\r
- //\r
- Record->Lba = Lba;\r
- Record->Offset = Offset;\r
- Record->NumBytes = *NumBytes;\r
-\r
- //\r
- // Write the record to the work space.\r
- //\r
- MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;\r
- MyLength = FTW_LITE_RECORD_SIZE;\r
-\r
- Status = FtwLiteDevice->FtwFvBlock->Write (\r
- FtwLiteDevice->FtwFvBlock,\r
- FtwLiteDevice->FtwWorkSpaceLba,\r
- FtwLiteDevice->FtwWorkSpaceBase + MyOffset,\r
- &MyLength,\r
- (UINT8 *) Record\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Record has been written to working block, then write data.\r
- //\r
- //\r
- // Allocate a memory buffer\r
- //\r
- MyBufferSize = FtwLiteDevice->SpareAreaLength;\r
- MyBuffer = AllocatePool (MyBufferSize);\r
- if (MyBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Starting at Lba, if the number of the rest blocks on Fvb is less\r
- // than NumberOfSpareBlock.\r
- //\r
- //\r
- // Read all original data from target block to memory buffer\r
- //\r
- if (IsInWorkingBlock (FtwLiteDevice, Fvb, Lba)) {\r
- //\r
- // If target block falls into working block, we must follow the process of\r
- // updating working block.\r
- //\r
- Ptr = MyBuffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- MyLength = FtwLiteDevice->BlockSize;\r
- Status = FtwLiteDevice->FtwFvBlock->Read (\r
- FtwLiteDevice->FtwFvBlock,\r
- FtwLiteDevice->FtwWorkBlockLba + Index,\r
- 0,\r
- &MyLength,\r
- Ptr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (MyBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Ptr += MyLength;\r
- }\r
- //\r
- // Update Offset by adding the offset from the start LBA of working block to\r
- // the target LBA. The target block can not span working block!\r
- //\r
- Offset = (((UINTN) (Lba - FtwLiteDevice->FtwWorkBlockLba)) * FtwLiteDevice->BlockSize + Offset);\r
- ASSERT ((Offset +*NumBytes) <= FtwLiteDevice->SpareAreaLength);\r
-\r
- } else {\r
-\r
- Ptr = MyBuffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- MyLength = FtwLiteDevice->BlockSize;\r
- Status = Fvb->Read (Fvb, Lba + Index, 0, &MyLength, Ptr);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (MyBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Ptr += MyLength;\r
- }\r
- }\r
- //\r
- // Overwrite the updating range data with\r
- // the input buffer content\r
- //\r
- CopyMem (MyBuffer + Offset, Buffer, *NumBytes);\r
-\r
- //\r
- // Try to keep the content of spare block\r
- // Save spare block into a spare backup memory buffer (Sparebuffer)\r
- //\r
- SpareBufferSize = FtwLiteDevice->SpareAreaLength;\r
- SpareBuffer = AllocatePool (SpareBufferSize);\r
- if (SpareBuffer == NULL) {\r
- FreePool (MyBuffer);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Ptr = SpareBuffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- MyLength = FtwLiteDevice->BlockSize;\r
- Status = FtwLiteDevice->FtwBackupFvb->Read (\r
- FtwLiteDevice->FtwBackupFvb,\r
- FtwLiteDevice->FtwSpareLba + Index,\r
- 0,\r
- &MyLength,\r
- Ptr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (MyBuffer);\r
- FreePool (SpareBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Ptr += MyLength;\r
- }\r
- //\r
- // Write the memory buffer to spare block\r
- // Don't forget to erase Flash first.\r
- //\r
- Status = FtwEraseSpareBlock (FtwLiteDevice);\r
- Ptr = MyBuffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- MyLength = FtwLiteDevice->BlockSize;\r
- Status = FtwLiteDevice->FtwBackupFvb->Write (\r
- FtwLiteDevice->FtwBackupFvb,\r
- FtwLiteDevice->FtwSpareLba + Index,\r
- 0,\r
- &MyLength,\r
- Ptr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (MyBuffer);\r
- FreePool (SpareBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Ptr += MyLength;\r
- }\r
- //\r
- // Free MyBuffer\r
- //\r
- FreePool (MyBuffer);\r
-\r
- //\r
- // Set the SpareComplete in the FTW record,\r
- //\r
- MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;\r
- Status = FtwUpdateFvState (\r
- FtwLiteDevice->FtwFvBlock,\r
- FtwLiteDevice->FtwWorkSpaceLba,\r
- FtwLiteDevice->FtwWorkSpaceBase + MyOffset,\r
- SPARE_COMPLETED\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (SpareBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Record->SpareCompleted = FTW_VALID_STATE;\r
-\r
- //\r
- // Since the content has already backuped in spare block, the write is\r
- // guaranteed to be completed with fault tolerant manner.\r
- //\r
- Status = FtwWriteRecord (FtwLiteDevice, Fvb);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (SpareBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Record++;\r
- FtwLiteDevice->FtwLastRecord = Record;\r
-\r
- //\r
- // Restore spare backup buffer into spare block , if no failure happened during FtwWrite.\r
- //\r
- Status = FtwEraseSpareBlock (FtwLiteDevice);\r
- Ptr = SpareBuffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- MyLength = FtwLiteDevice->BlockSize;\r
- Status = FtwLiteDevice->FtwBackupFvb->Write (\r
- FtwLiteDevice->FtwBackupFvb,\r
- FtwLiteDevice->FtwSpareLba + Index,\r
- 0,\r
- &MyLength,\r
- Ptr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (SpareBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Ptr += MyLength;\r
- }\r
- //\r
- // All success.\r
- //\r
- FreePool (SpareBuffer);\r
-\r
- DEBUG (\r
- (EFI_D_ERROR,\r
- "FtwLite: Write() success, (Lba:Offset)=(%lx:0x%x), NumBytes: 0x%x\n",\r
- Lba,\r
- Offset,\r
- *NumBytes)\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Write a record with fault tolerant manner.\r
- Since the content has already backuped in spare block, the write is\r
- guaranteed to be completed with fault tolerant manner.\r
-\r
-\r
- @param FtwLiteDevice The private data of FTW_LITE driver\r
- @param Fvb The FVB protocol that provides services for\r
- reading, writing, and erasing the target block.\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ABORTED The function could not complete successfully\r
-\r
-**/\r
-EFI_STATUS\r
-FtwWriteRecord (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_FTW_LITE_RECORD *Record;\r
- EFI_LBA WorkSpaceLbaOffset; \r
- UINTN Offset;\r
-\r
- //\r
- // Spare Complete but Destination not complete,\r
- // Recover the targt block with the spare block.\r
- //\r
- Record = FtwLiteDevice->FtwLastRecord;\r
-\r
- //\r
- // IF target block is working block, THEN Flush Spare Block To Working Block;\r
- // ELSE flush spare block to normal target block.ENDIF\r
- //\r
- if (IsInWorkingBlock (FtwLiteDevice, Fvb, Record->Lba)) {\r
- //\r
- // If target block is working block, Attention:\r
- // it's required to set SPARE_COMPLETED to spare block.\r
- //\r
- WorkSpaceLbaOffset = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba;\r
- Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;\r
- Status = FtwUpdateFvState (\r
- FtwLiteDevice->FtwBackupFvb,\r
- FtwLiteDevice->FtwSpareLba + WorkSpaceLbaOffset,\r
- FtwLiteDevice->FtwWorkSpaceBase + Offset,\r
- SPARE_COMPLETED\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice);\r
- } else {\r
- //\r
- // Update blocks other than working block\r
- //\r
- Status = FlushSpareBlockToTargetBlock (FtwLiteDevice, Fvb, Record->Lba);\r
- }\r
-\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Set WriteCompleted flag in record\r
- //\r
- Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;\r
- Status = FtwUpdateFvState (\r
- FtwLiteDevice->FtwFvBlock,\r
- FtwLiteDevice->FtwWorkSpaceLba,\r
- FtwLiteDevice->FtwWorkSpaceBase + Offset,\r
- WRITE_COMPLETED\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Record->WriteCompleted = FTW_VALID_STATE;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Restarts a previously interrupted write. The caller must provide the\r
- block protocol needed to complete the interrupted write.\r
-\r
-\r
- @param FtwLiteDevice The private data of FTW_LITE driver\r
- FvbHandle - The handle of FVB protocol that provides services for\r
- reading, writing, and erasing the target block.\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ACCESS_DENIED No pending writes exist\r
- @retval EFI_NOT_FOUND FVB protocol not found by the handle\r
- @retval EFI_ABORTED The function could not complete successfully\r
-\r
-**/\r
-EFI_STATUS\r
-FtwRestart (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_FTW_LITE_RECORD *Record;\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;\r
- EFI_DEV_PATH_PTR DevPathPtr;\r
-\r
- //\r
- // Spare Completed but Destination not complete,\r
- // Recover the targt block with the spare block.\r
- //\r
- Record = FtwLiteDevice->FtwLastRecord;\r
-\r
- //\r
- // Only support memory mapped FVB device path by now.\r
- //\r
- DevPathPtr.MemMap = (MEMMAP_DEVICE_PATH *) &Record->DevPath;\r
- if (!((DevPathPtr.MemMap->Header.Type == HARDWARE_DEVICE_PATH) && (DevPathPtr.MemMap->Header.SubType == HW_MEMMAP_DP))\r
- ) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: FVB Device Path is not memory mapped\n"));\r
- return EFI_ABORTED;\r
- }\r
-\r
- Status = GetFvbByAddress (DevPathPtr.MemMap->StartingAddress, &Fvb);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
- //\r
- // Since the content has already backuped in spare block, the write is\r
- // guaranteed to be completed with fault tolerant manner.\r
- //\r
- Status = FtwWriteRecord (FtwLiteDevice, Fvb);\r
- DEBUG ((EFI_D_INFO, "FtwLite: Restart() - %r\n", Status));\r
-\r
- Record++;\r
- FtwLiteDevice->FtwLastRecord = Record;\r
-\r
- //\r
- // Erase Spare block\r
- // This is restart, no need to keep spareblock content.\r
- //\r
- FtwEraseSpareBlock (FtwLiteDevice);\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Aborts all previous allocated writes.\r
-\r
-\r
- @param FtwLiteDevice The private data of FTW_LITE driver\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ABORTED The function could not complete successfully.\r
- @retval EFI_NOT_FOUND No allocated writes exist.\r
-\r
-**/\r
-EFI_STATUS\r
-FtwAbort (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Offset;\r
-\r
- if (FtwLiteDevice->FtwLastRecord->WriteCompleted == FTW_VALID_STATE) {\r
- return EFI_NOT_FOUND;\r
- }\r
- //\r
- // Update the complete state of the header as VALID and abort.\r
- //\r
- Offset = (UINT8 *) FtwLiteDevice->FtwLastRecord - FtwLiteDevice->FtwWorkSpace;\r
- Status = FtwUpdateFvState (\r
- FtwLiteDevice->FtwFvBlock,\r
- FtwLiteDevice->FtwWorkSpaceLba,\r
- FtwLiteDevice->FtwWorkSpaceBase + Offset,\r
- WRITE_COMPLETED\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- FtwLiteDevice->FtwLastRecord->WriteCompleted = FTW_VALID_STATE;\r
-\r
- Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);\r
-\r
- //\r
- // Erase the spare block\r
- //\r
- Status = FtwEraseSpareBlock (FtwLiteDevice);\r
-\r
- DEBUG ((EFI_D_INFO, "FtwLite: Abort() success \n"));\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is the entry point of the Fault Tolerant Write driver.\r
-\r
- @param ImageHandle A handle for the image that is initializing this driver\r
- @param SystemTable A pointer to the EFI system table\r
-\r
- @retval EFI_SUCCESS FTW has finished the initialization\r
- @retval EFI_ABORTED FTW initialization error\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeFtwLite (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;\r
- UINTN Index;\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN HandleCount;\r
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
- EFI_PHYSICAL_ADDRESS BaseAddress;\r
- EFI_FTW_LITE_DEVICE *FtwLiteDevice;\r
- EFI_FTW_LITE_RECORD *Record;\r
- EFI_STATUS Status;\r
- UINTN Offset;\r
- UINTN Length;\r
- EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry;\r
- UINT32 LbaIndex;\r
- //\r
- // Allocate Private data of this driver, including the FtwWorkSpace[FTW_WORK_SPACE_SIZE].\r
- //\r
- FtwLiteDevice = NULL;\r
- FtwLiteDevice = AllocatePool (sizeof (EFI_FTW_LITE_DEVICE) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize));\r
- ASSERT (FtwLiteDevice != NULL);\r
-\r
- ZeroMem (FtwLiteDevice, sizeof (EFI_FTW_LITE_DEVICE));\r
- FtwLiteDevice->Signature = FTW_LITE_DEVICE_SIGNATURE;\r
-\r
- //\r
- // Initialize other parameters, and set WorkSpace as FTW_ERASED_BYTE.\r
- //\r
- FtwLiteDevice->FtwWorkSpace = (UINT8 *) (FtwLiteDevice + 1);\r
- FtwLiteDevice->FtwWorkSpaceHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) FtwLiteDevice->FtwWorkSpace;\r
- FtwLiteDevice->FtwLastRecord = NULL;\r
-\r
- FtwLiteDevice->WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwWorkingBase);\r
- FtwLiteDevice->WorkSpaceLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwWorkingSize);\r
-\r
- FtwLiteDevice->SpareAreaAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwSpareBase);\r
- FtwLiteDevice->SpareAreaLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwSpareSize);\r
-\r
- ASSERT ((FtwLiteDevice->WorkSpaceLength != 0) && (FtwLiteDevice->SpareAreaLength != 0));\r
-\r
- //\r
- // Locate FVB protocol\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- ASSERT (HandleCount > 0);\r
-\r
- FtwLiteDevice->FtwFvBlock = NULL;\r
- FtwLiteDevice->FtwBackupFvb = NULL;\r
- FtwLiteDevice->FtwWorkSpaceLba = (EFI_LBA) (-1);\r
- FtwLiteDevice->FtwSpareLba = (EFI_LBA) (-1);\r
- for (Index = 0; Index < HandleCount; Index += 1) {\r
- Status = gBS->HandleProtocol (\r
- HandleBuffer[Index],\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- (VOID **) &Fvb\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = Fvb->GetPhysicalAddress (Fvb, &BaseAddress);\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) BaseAddress);\r
-\r
- if ((FtwLiteDevice->WorkSpaceAddress >= BaseAddress) &&\r
- ((FtwLiteDevice->WorkSpaceAddress + FtwLiteDevice->WorkSpaceLength) <= (BaseAddress + FwVolHeader->FvLength))\r
- ) {\r
- FtwLiteDevice->FtwFvBlock = Fvb;\r
- //\r
- // To get the LBA of work space\r
- //\r
- if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) {\r
- //\r
- // FV may have multiple types of BlockLength\r
- //\r
- FvbMapEntry = &FwVolHeader->BlockMap[0];\r
- while (!((FvbMapEntry->NumBlocks == 0) && (FvbMapEntry->Length == 0))) {\r
- for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) {\r
- if ((FtwLiteDevice->WorkSpaceAddress >= (BaseAddress + FvbMapEntry->Length * (LbaIndex - 1)))\r
- && (FtwLiteDevice->WorkSpaceAddress < (BaseAddress + FvbMapEntry->Length * LbaIndex))) {\r
- FtwLiteDevice->FtwWorkSpaceLba = LbaIndex - 1;\r
- //\r
- // Get the Work space size and Base(Offset)\r
- //\r
- FtwLiteDevice->FtwWorkSpaceSize = FtwLiteDevice->WorkSpaceLength;\r
- FtwLiteDevice->FtwWorkSpaceBase = (UINTN) (FtwLiteDevice->WorkSpaceAddress - (BaseAddress + FvbMapEntry->Length * (LbaIndex - 1)));\r
- break;\r
- }\r
- }\r
- //\r
- // end for\r
- //\r
- if (LbaIndex <= FvbMapEntry->NumBlocks) {\r
- //\r
- // Work space range is found.\r
- //\r
- break;\r
- }\r
- FvbMapEntry++;\r
- }\r
- //\r
- // end while\r
- //\r
- }\r
- }\r
-\r
- if ((FtwLiteDevice->SpareAreaAddress >= BaseAddress) &&\r
- ((FtwLiteDevice->SpareAreaAddress + FtwLiteDevice->SpareAreaLength) <= (BaseAddress + FwVolHeader->FvLength))\r
- ) {\r
- FtwLiteDevice->FtwBackupFvb = Fvb;\r
- //\r
- // To get the LBA of spare\r
- //\r
- if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) {\r
- //\r
- // FV may have multiple types of BlockLength\r
- //\r
- FvbMapEntry = &FwVolHeader->BlockMap[0];\r
- while (!((FvbMapEntry->NumBlocks == 0) && (FvbMapEntry->Length == 0))) {\r
- for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) {\r
- if ((FtwLiteDevice->SpareAreaAddress >= (BaseAddress + FvbMapEntry->Length * (LbaIndex - 1)))\r
- && (FtwLiteDevice->SpareAreaAddress < (BaseAddress + FvbMapEntry->Length * LbaIndex))) {\r
- //\r
- // Get the NumberOfSpareBlock and BlockSize\r
- //\r
- FtwLiteDevice->FtwSpareLba = LbaIndex - 1;\r
- FtwLiteDevice->BlockSize = FvbMapEntry->Length;\r
- FtwLiteDevice->NumberOfSpareBlock = FtwLiteDevice->SpareAreaLength / FtwLiteDevice->BlockSize;\r
- //\r
- // Check the range of spare area to make sure that it's in FV range\r
- // To do delete\r
- //\r
- ASSERT ((FtwLiteDevice->FtwSpareLba + FtwLiteDevice->NumberOfSpareBlock) <= FvbMapEntry->NumBlocks);\r
- break;\r
- }\r
- }\r
- if (LbaIndex <= FvbMapEntry->NumBlocks) {\r
- //\r
- // Spare FV range is found.\r
- //\r
- break;\r
- }\r
- FvbMapEntry++;\r
- }\r
- //\r
- // end while\r
- //\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Calculate the start LBA of working block. Working block is an area which\r
- // contains working space in its last block and has the same size as spare\r
- // block, unless there are not enough blocks before the block that contains\r
- // working space.\r
- //\r
- FtwLiteDevice->FtwWorkBlockLba = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->NumberOfSpareBlock + 1;\r
- if ((INT64) (FtwLiteDevice->FtwWorkBlockLba) < 0) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: The spare block range is too large than the working block range!\n"));\r
- FreePool (FtwLiteDevice);\r
- return EFI_ABORTED;\r
- }\r
-\r
- if ((FtwLiteDevice->FtwFvBlock == NULL) ||\r
- (FtwLiteDevice->FtwBackupFvb == NULL) ||\r
- (FtwLiteDevice->FtwWorkSpaceLba == (EFI_LBA) (-1)) ||\r
- (FtwLiteDevice->FtwSpareLba == (EFI_LBA) (-1))\r
- ) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Working or spare FVB not ready\n"));\r
- FreePool (FtwLiteDevice);\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Refresh workspace data from working block\r
- //\r
- Status = WorkSpaceRefresh (FtwLiteDevice);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // If the working block workspace is not valid, try the spare block\r
- //\r
- if (!IsValidWorkSpace (FtwLiteDevice->FtwWorkSpaceHeader)) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Workspace invalid, read from backup\n"));\r
- //\r
- // Read from spare block\r
- //\r
- Length = FtwLiteDevice->FtwWorkSpaceSize;\r
- Status = FtwLiteDevice->FtwBackupFvb->Read (\r
- FtwLiteDevice->FtwBackupFvb,\r
- FtwLiteDevice->FtwSpareLba,\r
- FtwLiteDevice->FtwWorkSpaceBase,\r
- &Length,\r
- FtwLiteDevice->FtwWorkSpace\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // If spare block is valid, then replace working block content.\r
- //\r
- if (IsValidWorkSpace (FtwLiteDevice->FtwWorkSpaceHeader)) {\r
- Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice);\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Restart working block in Init() - %r\n", Status));\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- FtwAbort (FtwLiteDevice);\r
- //\r
- // Refresh work space.\r
- //\r
- Status = WorkSpaceRefresh (FtwLiteDevice);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (FtwLiteDevice);\r
- return EFI_ABORTED;\r
- }\r
- } else {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Both are invalid, init workspace\n"));\r
- //\r
- // If both are invalid, then initialize work space.\r
- //\r
- SetMem (\r
- FtwLiteDevice->FtwWorkSpace,\r
- FtwLiteDevice->FtwWorkSpaceSize,\r
- FTW_ERASED_BYTE\r
- );\r
- InitWorkSpaceHeader (FtwLiteDevice->FtwWorkSpaceHeader);\r
- //\r
- // Initialize the work space\r
- //\r
- Status = FtwReclaimWorkSpace (FtwLiteDevice, FALSE);\r
-\r
- if (EFI_ERROR (Status)) {\r
- FreePool (FtwLiteDevice);\r
- return EFI_ABORTED;\r
- }\r
- }\r
- }\r
- //\r
- // Hook the protocol API\r
- //\r
- FtwLiteDevice->FtwLiteInstance.Write = FtwLiteWrite;\r
-\r
- //\r
- // Install protocol interface\r
- //\r
- Status = gBS->InstallProtocolInterface (\r
- &FtwLiteDevice->Handle,\r
- &gEfiFaultTolerantWriteLiteProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &FtwLiteDevice->FtwLiteInstance\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (FtwLiteDevice);\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // If (!SpareCompleted) THEN Abort to rollback.\r
- //\r
- if ((FtwLiteDevice->FtwLastRecord->WriteAllocated == FTW_VALID_STATE) &&\r
- (FtwLiteDevice->FtwLastRecord->SpareCompleted != FTW_VALID_STATE)\r
- ) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Init.. record not SpareCompleted, abort()\n"));\r
- FtwAbort (FtwLiteDevice);\r
- }\r
- //\r
- // if (SpareCompleted) THEN Restart to fault tolerant write.\r
- //\r
- if ((FtwLiteDevice->FtwLastRecord->SpareCompleted == FTW_VALID_STATE) &&\r
- (FtwLiteDevice->FtwLastRecord->WriteCompleted != FTW_VALID_STATE)\r
- ) {\r
-\r
- Status = FtwRestart (FtwLiteDevice);\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Restart last write - %r\n", Status));\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
- //\r
- // To check the workspace buffer behind last records is EMPTY or not.\r
- // If it's not EMPTY, FTW_LITE also need to call reclaim().\r
- //\r
- Record = FtwLiteDevice->FtwLastRecord;\r
- Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;\r
- if (FtwLiteDevice->FtwWorkSpace[Offset] != FTW_ERASED_BYTE) {\r
- Offset += FTW_LITE_RECORD_SIZE;\r
- }\r
-\r
- if (!IsErasedFlashBuffer (\r
- FTW_ERASE_POLARITY,\r
- FtwLiteDevice->FtwWorkSpace + Offset,\r
- FtwLiteDevice->FtwWorkSpaceSize - Offset\r
- )) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Workspace is dirty, call reclaim...\n"));\r
- Status = FtwReclaimWorkSpace (FtwLiteDevice, TRUE);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Workspace reclaim - %r\n", Status));\r
- FreePool (FtwLiteDevice);\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
+++ /dev/null
-/** @file\r
-\r
- The internal header file includes the common header files, defines\r
- internal structure and functions used by FtwLite module.\r
-\r
-Copyright (c) 2006 - 2008, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-#ifndef _EFI_FAULT_TOLERANT_WRITE_LITE_H_\r
-#define _EFI_FAULT_TOLERANT_WRITE_LITE_H_\r
-\r
-\r
-#include <PiDxe.h>\r
-\r
-#include <Guid/SystemNvDataGuid.h>\r
-#include <Protocol/FaultTolerantWriteLite.h>\r
-#include <Protocol/FirmwareVolumeBlock.h>\r
-\r
-#include <Library/PcdLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/DevicePathLib.h>\r
-\r
-//\r
-// Flash erase polarity is 1\r
-//\r
-#define FTW_ERASE_POLARITY 1\r
-\r
-#define FTW_VALID_STATE 0\r
-#define FTW_INVALID_STATE 1\r
-\r
-#define FTW_ERASED_BYTE ((UINT8) (255))\r
-#define FTW_POLARITY_REVERT ((UINT8) (255))\r
-\r
-typedef struct {\r
- UINT8 WriteAllocated : 1;\r
- UINT8 SpareCompleted : 1;\r
- UINT8 WriteCompleted : 1;\r
- UINT8 Reserved : 5;\r
-#define WRITE_ALLOCATED 0x1\r
-#define SPARE_COMPLETED 0x2\r
-#define WRITE_COMPLETED 0x4\r
-\r
- EFI_DEV_PATH DevPath;\r
- EFI_LBA Lba;\r
- UINTN Offset;\r
- UINTN NumBytes;\r
- //\r
- // UINTN SpareAreaOffset;\r
- //\r
-} EFI_FTW_LITE_RECORD;\r
-\r
-#define FTW_LITE_DEVICE_SIGNATURE SIGNATURE_32 ('F', 'T', 'W', 'L')\r
-\r
-//\r
-// MACRO for FTW header and record\r
-//\r
-#define FTW_LITE_RECORD_SIZE (sizeof (EFI_FTW_LITE_RECORD))\r
-\r
-//\r
-// EFI Fault tolerant protocol private data structure\r
-//\r
-typedef struct {\r
- UINTN Signature;\r
- EFI_HANDLE Handle;\r
- EFI_FTW_LITE_PROTOCOL FtwLiteInstance;\r
- EFI_PHYSICAL_ADDRESS WorkSpaceAddress; // Base address of working space range in flash.\r
- UINTN WorkSpaceLength; // Size of working space range in flash.\r
- EFI_PHYSICAL_ADDRESS SpareAreaAddress; // Base address of spare range in flash.\r
- UINTN SpareAreaLength; // Size of spare range in flash.\r
- UINTN NumberOfSpareBlock; // Number of the blocks in spare block.\r
- UINTN BlockSize; // Block size in bytes of the blocks in flash\r
- EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FtwWorkSpaceHeader;// Pointer to Working Space Header in memory buffer\r
- EFI_FTW_LITE_RECORD *FtwLastRecord; // Pointer to last record in memory buffer\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FtwFvBlock; // FVB of working block\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FtwBackupFvb; // FVB of spare block\r
- EFI_LBA FtwSpareLba; // Start LBA of spare block\r
- EFI_LBA FtwWorkBlockLba; // Start LBA of working block that contains working space in its last block.\r
- EFI_LBA FtwWorkSpaceLba; // Start LBA of working space\r
- UINTN FtwWorkSpaceBase; // Offset into the FtwWorkSpaceLba block.\r
- UINTN FtwWorkSpaceSize; // Size of working space range that stores write record.\r
- UINT8 *FtwWorkSpace; // Point to Work Space in memory buffer \r
- //\r
- // Following a buffer of FtwWorkSpace[FTW_WORK_SPACE_SIZE],\r
- // Allocated with EFI_FTW_LITE_DEVICE.\r
- //\r
-} EFI_FTW_LITE_DEVICE;\r
-\r
-#define FTW_LITE_CONTEXT_FROM_THIS(a) CR (a, EFI_FTW_LITE_DEVICE, FtwLiteInstance, FTW_LITE_DEVICE_SIGNATURE)\r
-\r
-//\r
-// Driver entry point\r
-//\r
-/**\r
- This function is the entry point of the Fault Tolerant Write driver.\r
-\r
-\r
- @param ImageHandle A handle for the image that is initializing\r
- this driver\r
- @param SystemTable A pointer to the EFI system table\r
-\r
- @retval EFI_SUCCESS FTW has finished the initialization\r
- @retval EFI_ABORTED FTW initialization error\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeFtwLite (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- );\r
-\r
-//\r
-// Fault Tolerant Write Protocol API\r
-//\r
-/**\r
- Starts a target block update. This function will record data about write\r
- in fault tolerant storage and will complete the write in a recoverable\r
- manner, ensuring at all times that either the original contents or\r
- the modified contents are available.\r
-\r
-\r
- @param This Calling context\r
- @param FvbHandle The handle of FVB protocol that provides services for\r
- reading, writing, and erasing the target block.\r
- @param Lba The logical block address of the target block.\r
- @param Offset The offset within the target block to place the data.\r
- @param NumBytes The number of bytes to write to the target block.\r
- @param Buffer The data to write.\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_BAD_BUFFER_SIZE The write would span a target block, which is not\r
- a valid action.\r
- @retval EFI_ACCESS_DENIED No writes have been allocated.\r
- @retval EFI_NOT_FOUND Cannot find FVB by handle.\r
- @retval EFI_OUT_OF_RESOURCES Cannot allocate memory.\r
- @retval EFI_ABORTED The function could not complete successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FtwLiteWrite (\r
- IN EFI_FTW_LITE_PROTOCOL *This,\r
- IN EFI_HANDLE FvbHandle,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN OUT UINTN *NumBytes,\r
- IN VOID *Buffer\r
- );\r
-\r
-//\r
-// Internal functions\r
-//\r
-/**\r
- Restarts a previously interrupted write. The caller must provide the\r
- block protocol needed to complete the interrupted write.\r
-\r
-\r
- @param FtwLiteDevice The private data of FTW_LITE driver\r
- FvbHandle - The handle of FVB protocol that provides services for\r
- reading, writing, and erasing the target block.\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ACCESS_DENIED No pending writes exist\r
- @retval EFI_NOT_FOUND FVB protocol not found by the handle\r
- @retval EFI_ABORTED The function could not complete successfully\r
-\r
-**/\r
-EFI_STATUS\r
-FtwRestart (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
- );\r
-\r
-/**\r
- Aborts all previous allocated writes.\r
-\r
-\r
- @param FtwLiteDevice The private data of FTW_LITE driver\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ABORTED The function could not complete successfully.\r
- @retval EFI_NOT_FOUND No allocated writes exist.\r
-\r
-**/\r
-EFI_STATUS\r
-FtwAbort (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
- );\r
-\r
-\r
-/**\r
- Write a record with fault tolerant mannaer.\r
- Since the content has already backuped in spare block, the write is\r
- guaranteed to be completed with fault tolerant manner.\r
-\r
-\r
- @param FtwLiteDevice The private data of FTW_LITE driver\r
- @param Fvb The FVB protocol that provides services for\r
- reading, writing, and erasing the target block.\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ABORTED The function could not complete successfully\r
-\r
-**/\r
-EFI_STATUS\r
-FtwWriteRecord (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb\r
- );\r
-\r
-/**\r
- To erase the block with the spare block size.\r
-\r
-\r
- @param FtwLiteDevice Calling context\r
- @param FvBlock FVB Protocol interface\r
- @param Lba Lba of the firmware block\r
-\r
- @retval EFI_SUCCESS Block LBA is Erased successfully\r
- @retval Others Error occurs\r
-\r
-**/\r
-EFI_STATUS\r
-FtwEraseBlock (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
- EFI_LBA Lba\r
- );\r
-\r
-/**\r
-\r
- Erase spare block.\r
-\r
-\r
- @param FtwLiteDevice Calling context\r
-\r
- @retval EFI_SUCCESS The erase request was successfully\r
- completed.\r
- \r
- @retval EFI_ACCESS_DENIED The firmware volume is in the\r
- WriteDisabled state.\r
- @retval EFI_DEVICE_ERROR The block device is not functioning\r
- correctly and could not be written.\r
- The firmware device may have been\r
- partially erased.\r
- @retval EFI_INVALID_PARAMETER One or more of the LBAs listed\r
- in the variable argument list do\r
- not exist in the firmware volume. \r
-\r
-**/\r
-EFI_STATUS\r
-FtwEraseSpareBlock (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
- );\r
-\r
-/**\r
- Retrive the proper FVB protocol interface by HANDLE.\r
-\r
-\r
- @param FvBlockHandle The handle of FVB protocol that provides services for\r
- reading, writing, and erasing the target block.\r
- @param FvBlock The interface of FVB protocol\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ABORTED The function could not complete successfully\r
-\r
-**/\r
-EFI_STATUS\r
-FtwGetFvbByHandle (\r
- IN EFI_HANDLE FvBlockHandle,\r
- OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock\r
- );\r
-\r
-/**\r
-\r
- Get firmware block by address.\r
-\r
-\r
- @param Address Address specified the block\r
- @param FvBlock The block caller wanted\r
-\r
- @retval EFI_SUCCESS The protocol instance if found.\r
- @retval EFI_NOT_FOUND Block not found\r
-\r
-**/\r
-EFI_STATUS\r
-GetFvbByAddress (\r
- IN EFI_PHYSICAL_ADDRESS Address,\r
- OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock\r
- );\r
-\r
-/**\r
-\r
- Is it in working block?\r
-\r
-\r
- @param FtwLiteDevice Calling context\r
- @param FvBlock Fvb protocol instance\r
- @param Lba The block specified\r
-\r
- @return A BOOLEAN value indicating in working block or not.\r
-\r
-**/\r
-BOOLEAN\r
-IsInWorkingBlock (\r
- EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
- EFI_LBA Lba\r
- );\r
-\r
-/**\r
- Copy the content of spare block to a target block. Size is FTW_BLOCK_SIZE.\r
- Spare block is accessed by FTW backup FVB protocol interface. LBA is\r
- FtwLiteDevice->FtwSpareLba.\r
- Target block is accessed by FvBlock protocol interface. LBA is Lba.\r
-\r
-\r
- @param FtwLiteDevice The private data of FTW_LITE driver\r
- @param FvBlock FVB Protocol interface to access target block\r
- @param Lba Lba of the target block\r
-\r
- @retval EFI_SUCCESS Spare block content is copied to target block\r
- @retval EFI_INVALID_PARAMETER Input parameter error\r
- @retval EFI_OUT_OF_RESOURCES Allocate memory error\r
- @retval EFI_ABORTED The function could not complete successfully\r
-\r
-**/\r
-EFI_STATUS\r
-FlushSpareBlockToTargetBlock (\r
- EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
- EFI_LBA Lba\r
- );\r
-\r
-/**\r
- Copy the content of spare block to working block. Size is FTW_BLOCK_SIZE.\r
- Spare block is accessed by FTW backup FVB protocol interface. LBA is\r
- FtwLiteDevice->FtwSpareLba.\r
- Working block is accessed by FTW working FVB protocol interface. LBA is\r
- FtwLiteDevice->FtwWorkBlockLba.\r
-\r
-\r
- @param FtwLiteDevice The private data of FTW_LITE driver\r
-\r
- @retval EFI_SUCCESS Spare block content is copied to target block\r
- @retval EFI_OUT_OF_RESOURCES Allocate memory error\r
- @retval EFI_ABORTED The function could not complete successfully\r
- Notes:\r
- Since the working block header is important when FTW initializes, the\r
- state of the operation should be handled carefully. The Crc value is\r
- calculated without STATE element.\r
-\r
-**/\r
-EFI_STATUS\r
-FlushSpareBlockToWorkingBlock (\r
- EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
- );\r
-\r
-/**\r
- Update a bit of state on a block device. The location of the bit is\r
- calculated by the (Lba, Offset, bit). Here bit is determined by the\r
- the name of a certain bit.\r
-\r
-\r
- @param FvBlock FVB Protocol interface to access SrcBlock and DestBlock\r
- @param Lba Lba of a block\r
- @param Offset Offset on the Lba\r
- @param NewBit New value that will override the old value if it can be change\r
-\r
- @retval EFI_SUCCESS A state bit has been updated successfully\r
- @retval Others Access block device error.\r
- Notes:\r
- Assume all bits of State are inside the same BYTE.\r
- @retval EFI_ABORTED Read block fail\r
-\r
-**/\r
-EFI_STATUS\r
-FtwUpdateFvState (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN UINT8 NewBit\r
- );\r
-\r
-/**\r
- Get the last Write record pointer.\r
- The last record is the record whose 'complete' state hasn't been set.\r
- After all, this header may be a EMPTY header entry for next Allocate.\r
-\r
-\r
- @param FtwLiteDevice Private data of this driver\r
- @param FtwLastRecord Pointer to retrieve the last write record\r
-\r
- @retval EFI_SUCCESS Get the last write record successfully\r
- @retval EFI_ABORTED The FTW work space is damaged\r
-\r
-**/\r
-EFI_STATUS\r
-FtwGetLastRecord (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
- OUT EFI_FTW_LITE_RECORD **FtwLastRecord\r
- );\r
-\r
-/**\r
-\r
- Check whether a flash buffer is erased.\r
-\r
-\r
- @param Polarity All 1 or all 0\r
- @param Buffer Buffer to check\r
- @param BufferSize Size of the buffer\r
-\r
- @return A BOOLEAN value indicating erased or not.\r
-\r
-**/\r
-BOOLEAN\r
-IsErasedFlashBuffer (\r
- IN BOOLEAN Polarity,\r
- IN UINT8 *Buffer,\r
- IN UINTN BufferSize\r
- );\r
-\r
-/**\r
- Initialize a work space when there is no work space.\r
-\r
-\r
- @param WorkingHeader Pointer of working block header\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ABORTED The function could not complete successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-InitWorkSpaceHeader (\r
- IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader\r
- );\r
-\r
-/**\r
- Read from working block to refresh the work space in memory.\r
-\r
-\r
- @param FtwLiteDevice Point to private data of FTW driver\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ABORTED The function could not complete successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-WorkSpaceRefresh (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
- );\r
-\r
-/**\r
- Check to see if it is a valid work space.\r
-\r
-\r
- @param WorkingHeader Pointer of working block header\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ABORTED The function could not complete successfully.\r
-\r
-**/\r
-BOOLEAN\r
-IsValidWorkSpace (\r
- IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader\r
- );\r
-\r
-/**\r
- Reclaim the work space on the working block.\r
-\r
-\r
- @param FtwLiteDevice Point to private data of FTW driver\r
- @param PreserveRecord Whether to preserve the working record is needed\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_OUT_OF_RESOURCES Allocate memory error\r
- @retval EFI_ABORTED The function could not complete successfully\r
-\r
-**/\r
-EFI_STATUS\r
-FtwReclaimWorkSpace (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
- IN BOOLEAN PreserveRecord\r
- );\r
-\r
-#endif\r
+++ /dev/null
-#/** @file\r
-# This driver provides lite version of fault tolerant capability for writing operation on flash devices.\r
-# Its implementation depends on the full functionality FVB protocol that support read, write/erase flash access.\r
-#\r
-# Copyright (c) 2006 - 2009, Intel Corporation\r
-#\r
-# All rights reserved. This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-#**/\r
-\r
-[Defines]\r
- INF_VERSION = 0x00010005\r
- BASE_NAME = FtwLite\r
- FILE_GUID = 4C862FC6-0E54-4e36-8C8F-FF6F3167951F\r
- MODULE_TYPE = DXE_DRIVER\r
- VERSION_STRING = 1.0\r
- ENTRY_POINT = InitializeFtwLite\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
-#\r
-\r
-[Sources.common]\r
- FtwWorkSpace.c\r
- FtwMisc.c\r
- FtwLite.c\r
- FtwLite.h\r
-\r
-[Packages]\r
- MdePkg/MdePkg.dec\r
- MdeModulePkg/MdeModulePkg.dec\r
-\r
-[LibraryClasses]\r
- UefiBootServicesTableLib\r
- MemoryAllocationLib\r
- BaseMemoryLib\r
- UefiDriverEntryPoint\r
- DebugLib\r
- PcdLib\r
- DevicePathLib\r
- \r
-[Guids]\r
- gEfiSystemNvDataFvGuid ## CONSUMED ## FV Signature of Working Space Header\r
-\r
-[Protocols]\r
- gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMED\r
- gEfiFaultTolerantWriteLiteProtocolGuid ## PRODUCED\r
-\r
-[Pcd.common]\r
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize\r
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase\r
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize\r
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase\r
-\r
-[Depex]\r
- gEfiFirmwareVolumeBlockProtocolGuid AND gEfiAlternateFvBlockGuid ## gEfiAlternateFvBlockGuid specifies FVB protocol with read, write/erase flash access.\r
-
\ No newline at end of file
+++ /dev/null
-/** @file\r
-\r
- Internal generic functions to operate flash block.\r
-\r
-Copyright (c) 2006 - 2008, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-#include "FtwLite.h"\r
-\r
-/**\r
-\r
- Check whether a flash buffer is erased.\r
-\r
-\r
- @param Polarity All 1 or all 0\r
- @param Buffer Buffer to check\r
- @param BufferSize Size of the buffer\r
-\r
- @return A BOOLEAN value indicating erased or not.\r
-\r
-**/\r
-BOOLEAN\r
-IsErasedFlashBuffer (\r
- IN BOOLEAN Polarity,\r
- IN UINT8 *Buffer,\r
- IN UINTN BufferSize\r
- )\r
-{\r
- UINT8 ErasedValue;\r
- UINT8 *Ptr;\r
-\r
- if (Polarity) {\r
- ErasedValue = 0xFF;\r
- } else {\r
- ErasedValue = 0;\r
- }\r
-\r
- Ptr = Buffer;\r
- while ((BufferSize--) != 0) {\r
- if (*Ptr++ != ErasedValue) {\r
- return FALSE;\r
- }\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- To erase the block with the spare block size.\r
-\r
-\r
- @param FtwLiteDevice Calling context\r
- @param FvBlock FVB Protocol interface\r
- @param Lba Lba of the firmware block\r
-\r
- @retval EFI_SUCCESS Block LBA is Erased successfully\r
- @retval Others Error occurs\r
-\r
-**/\r
-EFI_STATUS\r
-FtwEraseBlock (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
- EFI_LBA Lba\r
- )\r
-{\r
- return FvBlock->EraseBlocks (\r
- FvBlock,\r
- Lba,\r
- FtwLiteDevice->NumberOfSpareBlock,\r
- EFI_LBA_LIST_TERMINATOR\r
- );\r
-}\r
-\r
-/**\r
-\r
- Erase spare block.\r
-\r
-\r
- @param FtwLiteDevice Calling context\r
-\r
- @retval EFI_SUCCESS The erase request was successfully\r
- completed.\r
- \r
- @retval EFI_ACCESS_DENIED The firmware volume is in the\r
- WriteDisabled state.\r
- @retval EFI_DEVICE_ERROR The block device is not functioning\r
- correctly and could not be written.\r
- The firmware device may have been\r
- partially erased.\r
- @retval EFI_INVALID_PARAMETER One or more of the LBAs listed\r
- in the variable argument list do\r
- not exist in the firmware volume. \r
-\r
-\r
-**/\r
-EFI_STATUS\r
-FtwEraseSpareBlock (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
- )\r
-{\r
- return FtwLiteDevice->FtwBackupFvb->EraseBlocks (\r
- FtwLiteDevice->FtwBackupFvb,\r
- FtwLiteDevice->FtwSpareLba,\r
- FtwLiteDevice->NumberOfSpareBlock,\r
- EFI_LBA_LIST_TERMINATOR\r
- );\r
-}\r
-\r
-/**\r
- Retrive the proper FVB protocol interface by HANDLE.\r
-\r
-\r
- @param FvBlockHandle The handle of FVB protocol that provides services for\r
- reading, writing, and erasing the target block.\r
- @param FvBlock The interface of FVB protocol\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ABORTED The function could not complete successfully\r
-\r
-**/\r
-EFI_STATUS\r
-FtwGetFvbByHandle (\r
- IN EFI_HANDLE FvBlockHandle,\r
- OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock\r
- )\r
-{\r
- //\r
- // To get the FVB protocol interface on the handle\r
- //\r
- return gBS->HandleProtocol (\r
- FvBlockHandle,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- (VOID **) FvBlock\r
- );\r
-}\r
-\r
-/**\r
-\r
- Get firmware block by address.\r
-\r
-\r
- @param Address Address specified the block\r
- @param FvBlock The block caller wanted\r
-\r
- @retval EFI_SUCCESS The protocol instance if found.\r
- @retval EFI_NOT_FOUND Block not found\r
-\r
-**/\r
-EFI_STATUS\r
-GetFvbByAddress (\r
- IN EFI_PHYSICAL_ADDRESS Address,\r
- OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN HandleCount;\r
- UINTN Index;\r
- EFI_PHYSICAL_ADDRESS FvbBaseAddress;\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;\r
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
-\r
- *FvBlock = NULL;\r
- //\r
- // Locate all handles of Fvb protocol\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
- //\r
- // Search all FVB until find the right one\r
- //\r
- for (Index = 0; Index < HandleCount; Index += 1) {\r
- Status = gBS->HandleProtocol (\r
- HandleBuffer[Index],\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- (VOID **) &Fvb\r
- );\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_NOT_FOUND;\r
- break;\r
- }\r
- //\r
- // Compare the address and select the right one\r
- //\r
- Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);\r
- if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + (FwVolHeader->FvLength - 1)))) {\r
- *FvBlock = Fvb;\r
- Status = EFI_SUCCESS;\r
- break;\r
- }\r
- }\r
-\r
- FreePool (HandleBuffer);\r
- return Status;\r
-}\r
-\r
-/**\r
-\r
- Is it in working block?\r
-\r
-\r
- @param FtwLiteDevice Calling context\r
- @param FvBlock Fvb protocol instance\r
- @param Lba The block specified\r
-\r
- @return A BOOLEAN value indicating in working block or not.\r
-\r
-**/\r
-BOOLEAN\r
-IsInWorkingBlock (\r
- EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
- EFI_LBA Lba\r
- )\r
-{\r
- //\r
- // If matching the following condition, the target block is in working block.\r
- // 1. Target block is on the FV of working block (Using the same FVB protocol instance).\r
- // 2. Lba falls into the range of working block.\r
- //\r
- return (BOOLEAN)\r
- (\r
- (FvBlock == FtwLiteDevice->FtwFvBlock) &&\r
- (Lba >= FtwLiteDevice->FtwWorkBlockLba) &&\r
- (Lba <= FtwLiteDevice->FtwWorkSpaceLba)\r
- );\r
-}\r
-\r
-/**\r
- Copy the content of spare block to a target block. Size is FTW_BLOCK_SIZE.\r
- Spare block is accessed by FTW backup FVB protocol interface. LBA is\r
- FtwLiteDevice->FtwSpareLba.\r
- Target block is accessed by FvBlock protocol interface. LBA is Lba.\r
-\r
-\r
- @param FtwLiteDevice The private data of FTW_LITE driver\r
- @param FvBlock FVB Protocol interface to access target block\r
- @param Lba Lba of the target block\r
-\r
- @retval EFI_SUCCESS Spare block content is copied to target block\r
- @retval EFI_INVALID_PARAMETER Input parameter error\r
- @retval EFI_OUT_OF_RESOURCES Allocate memory error\r
- @retval EFI_ABORTED The function could not complete successfully\r
-\r
-**/\r
-EFI_STATUS\r
-FlushSpareBlockToTargetBlock (\r
- EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
- EFI_LBA Lba\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Length;\r
- UINT8 *Buffer;\r
- UINTN Count;\r
- UINT8 *Ptr;\r
- UINTN Index;\r
-\r
- if ((FtwLiteDevice == NULL) || (FvBlock == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Allocate a memory buffer\r
- //\r
- Length = FtwLiteDevice->SpareAreaLength;\r
- Buffer = AllocatePool (Length);\r
- if (Buffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Read all content of spare block to memory buffer\r
- //\r
- Ptr = Buffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- Count = FtwLiteDevice->BlockSize;\r
- Status = FtwLiteDevice->FtwBackupFvb->Read (\r
- FtwLiteDevice->FtwBackupFvb,\r
- FtwLiteDevice->FtwSpareLba + Index,\r
- 0,\r
- &Count,\r
- Ptr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Buffer);\r
- return Status;\r
- }\r
-\r
- Ptr += Count;\r
- }\r
- //\r
- // Erase the target block\r
- //\r
- Status = FtwEraseBlock (FtwLiteDevice, FvBlock, Lba);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Buffer);\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Write memory buffer to block, using the FvbBlock protocol interface\r
- //\r
- Ptr = Buffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- Count = FtwLiteDevice->BlockSize;\r
- Status = FvBlock->Write (FvBlock, Lba + Index, 0, &Count, Ptr);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: FVB Write block - %r\n", Status));\r
- FreePool (Buffer);\r
- return Status;\r
- }\r
-\r
- Ptr += Count;\r
- }\r
-\r
- FreePool (Buffer);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Copy the content of spare block to working block. Size is FTW_BLOCK_SIZE.\r
- Spare block is accessed by FTW backup FVB protocol interface. LBA is\r
- FtwLiteDevice->FtwSpareLba.\r
- Working block is accessed by FTW working FVB protocol interface. LBA is\r
- FtwLiteDevice->FtwWorkBlockLba.\r
-\r
-\r
- @param FtwLiteDevice The private data of FTW_LITE driver\r
-\r
- @retval EFI_SUCCESS Spare block content is copied to target block\r
- @retval EFI_OUT_OF_RESOURCES Allocate memory error\r
- @retval EFI_ABORTED The function could not complete successfully\r
- Notes:\r
- Since the working block header is important when FTW initializes, the\r
- state of the operation should be handled carefully. The Crc value is\r
- calculated without STATE element.\r
-\r
-**/\r
-EFI_STATUS\r
-FlushSpareBlockToWorkingBlock (\r
- EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Length;\r
- UINT8 *Buffer;\r
- EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader;\r
- EFI_LBA WorkSpaceLbaOffset;\r
- UINTN Count;\r
- UINT8 *Ptr;\r
- UINTN Index;\r
-\r
- //\r
- // Allocate a memory buffer\r
- //\r
- Length = FtwLiteDevice->SpareAreaLength;\r
- Buffer = AllocatePool (Length);\r
- if (Buffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // To guarantee that the WorkingBlockValid is set on spare block\r
- //\r
- // Offset = OFFSET_OF(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER,\r
- // WorkingBlockValid);\r
- // To skip Signature and Crc: sizeof(EFI_GUID)+sizeof(UINT32).\r
- //\r
- WorkSpaceLbaOffset = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba;\r
- FtwUpdateFvState (\r
- FtwLiteDevice->FtwBackupFvb,\r
- FtwLiteDevice->FtwSpareLba + WorkSpaceLbaOffset,\r
- FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),\r
- WORKING_BLOCK_VALID\r
- );\r
- //\r
- // Read from spare block to memory buffer\r
- //\r
- Ptr = Buffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- Count = FtwLiteDevice->BlockSize;\r
- Status = FtwLiteDevice->FtwBackupFvb->Read (\r
- FtwLiteDevice->FtwBackupFvb,\r
- FtwLiteDevice->FtwSpareLba + Index,\r
- 0,\r
- &Count,\r
- Ptr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Buffer);\r
- return Status;\r
- }\r
-\r
- Ptr += Count;\r
- }\r
- //\r
- // Clear the CRC and STATE, copy data from spare to working block.\r
- //\r
- WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (Buffer + (UINTN) WorkSpaceLbaOffset * FtwLiteDevice->BlockSize + FtwLiteDevice->FtwWorkSpaceBase);\r
- InitWorkSpaceHeader (WorkingBlockHeader);\r
- WorkingBlockHeader->WorkingBlockValid = FTW_ERASE_POLARITY;\r
- WorkingBlockHeader->WorkingBlockInvalid = FTW_ERASE_POLARITY;\r
-\r
- //\r
- // target block is working block, then\r
- // Set WorkingBlockInvalid in EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER\r
- // before erase the working block.\r
- //\r
- // Offset = OFFSET_OF(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER,\r
- // WorkingBlockInvalid);\r
- // To skip Signature and Crc: sizeof(EFI_GUID)+sizeof(UINT32).\r
- //\r
- Status = FtwUpdateFvState (\r
- FtwLiteDevice->FtwFvBlock,\r
- FtwLiteDevice->FtwWorkSpaceLba,\r
- FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),\r
- WORKING_BLOCK_INVALID\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Buffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- FtwLiteDevice->FtwWorkSpaceHeader->WorkingBlockInvalid = FTW_VALID_STATE;\r
-\r
- //\r
- // Erase the working block\r
- //\r
- Status = FtwEraseBlock (\r
- FtwLiteDevice,\r
- FtwLiteDevice->FtwFvBlock,\r
- FtwLiteDevice->FtwWorkBlockLba\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (Buffer);\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Write memory buffer to working block, using the FvbBlock protocol interface\r
- //\r
- Ptr = Buffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- Count = FtwLiteDevice->BlockSize;\r
- Status = FtwLiteDevice->FtwFvBlock->Write (\r
- FtwLiteDevice->FtwFvBlock,\r
- FtwLiteDevice->FtwWorkBlockLba + Index,\r
- 0,\r
- &Count,\r
- Ptr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: FVB Write block - %r\n", Status));\r
- FreePool (Buffer);\r
- return Status;\r
- }\r
-\r
- Ptr += Count;\r
- }\r
- //\r
- // Since the memory buffer will not be used, free memory Buffer.\r
- //\r
- FreePool (Buffer);\r
-\r
- //\r
- // Update the VALID of the working block\r
- //\r
- // Offset = OFFSET_OF(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER,\r
- // WorkingBlockValid);\r
- // Hardcode offset sizeof(EFI_GUID)+sizeof(UINT32), to skip Signature and Crc\r
- //\r
- Status = FtwUpdateFvState (\r
- FtwLiteDevice->FtwFvBlock,\r
- FtwLiteDevice->FtwWorkSpaceLba,\r
- FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),\r
- WORKING_BLOCK_VALID\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- FtwLiteDevice->FtwWorkSpaceHeader->WorkingBlockValid = FTW_VALID_STATE;\r
-\r
- return EFI_SUCCESS;\r
-}\r
+++ /dev/null
-/** @file\r
-\r
- Internal functions to operate Working Block Space.\r
-\r
-Copyright (c) 2006 - 2008, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-\r
-#include "FtwLite.h"\r
-\r
-/**\r
- Check to see if it is a valid work space.\r
-\r
-\r
- @param WorkingHeader Pointer of working block header\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ABORTED The function could not complete successfully.\r
-\r
-**/\r
-BOOLEAN\r
-IsValidWorkSpace (\r
- IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER WorkingBlockHeader;\r
-\r
- ASSERT (WorkingHeader != NULL);\r
- if (WorkingHeader->WorkingBlockValid != FTW_VALID_STATE) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Work block header valid bit check error\n"));\r
- return FALSE;\r
- }\r
- //\r
- // Check signature with gEfiSystemNvDataFvGuid\r
- //\r
- if (!CompareGuid (&gEfiSystemNvDataFvGuid, &WorkingHeader->Signature)) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Work block header signature check error\n"));\r
- return FALSE;\r
- }\r
- //\r
- // Check the CRC of header\r
- //\r
- CopyMem (\r
- &WorkingBlockHeader,\r
- WorkingHeader,\r
- sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)\r
- );\r
-\r
- //\r
- // Filter out the Crc and State fields\r
- //\r
- SetMem (\r
- &WorkingBlockHeader.Crc,\r
- sizeof (UINT32),\r
- FTW_ERASED_BYTE\r
- );\r
- WorkingBlockHeader.WorkingBlockValid = FTW_ERASE_POLARITY;\r
- WorkingBlockHeader.WorkingBlockInvalid = FTW_ERASE_POLARITY;\r
-\r
- //\r
- // Calculate the Crc of woking block header\r
- //\r
- Status = gBS->CalculateCrc32 (\r
- (UINT8 *) &WorkingBlockHeader,\r
- sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),\r
- &WorkingBlockHeader.Crc\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- if (WorkingBlockHeader.Crc != WorkingHeader->Crc) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Work block header CRC check error\n"));\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Initialize a work space when there is no work space.\r
-\r
-\r
- @param WorkingHeader Pointer of working block header\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ABORTED The function could not complete successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-InitWorkSpaceHeader (\r
- IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- ASSERT (WorkingHeader != NULL);\r
-\r
- //\r
- // Here using gEfiSystemNvDataFvGuid as the signature.\r
- //\r
- CopyMem (\r
- &WorkingHeader->Signature,\r
- &gEfiSystemNvDataFvGuid,\r
- sizeof (EFI_GUID)\r
- );\r
- WorkingHeader->WriteQueueSize = (UINT64) (PcdGet32 (PcdFlashNvStorageFtwWorkingSize) - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER));\r
-\r
- //\r
- // Crc is calculated with all the fields except Crc and STATE\r
- //\r
- WorkingHeader->WorkingBlockValid = FTW_ERASE_POLARITY;\r
- WorkingHeader->WorkingBlockInvalid = FTW_ERASE_POLARITY;\r
- SetMem (&WorkingHeader->Crc, sizeof (UINT32), FTW_ERASED_BYTE);\r
-\r
- //\r
- // Calculate the CRC value\r
- //\r
- Status = gBS->CalculateCrc32 (\r
- (UINT8 *) WorkingHeader,\r
- sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),\r
- &WorkingHeader->Crc\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Restore the WorkingBlockValid flag to VALID state\r
- //\r
- WorkingHeader->WorkingBlockValid = FTW_VALID_STATE;\r
- WorkingHeader->WorkingBlockInvalid = FTW_INVALID_STATE;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Update a bit of state on a block device. The location of the bit is\r
- calculated by the (Lba, Offset, bit). Here bit is determined by the\r
- the name of a certain bit.\r
-\r
-\r
- @param FvBlock FVB Protocol interface to access SrcBlock and DestBlock\r
- @param Lba Lba of a block\r
- @param Offset Offset on the Lba\r
- @param NewBit New value that will override the old value if it can be change\r
-\r
- @retval EFI_SUCCESS A state bit has been updated successfully\r
- @retval Others Access block device error.\r
- Notes:\r
- Assume all bits of State are inside the same BYTE.\r
- @retval EFI_ABORTED Read block fail\r
-\r
-**/\r
-EFI_STATUS\r
-FtwUpdateFvState (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN UINT8 NewBit\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 State;\r
- UINTN Length;\r
-\r
- //\r
- // Read state from device, assume State is only one byte.\r
- //\r
- Length = sizeof (UINT8);\r
- Status = FvBlock->Read (FvBlock, Lba, Offset, &Length, &State);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- State ^= FTW_POLARITY_REVERT;\r
- State = (UINT8) (State | NewBit);\r
- State ^= FTW_POLARITY_REVERT;\r
-\r
- //\r
- // Write state back to device\r
- //\r
- Length = sizeof (UINT8);\r
- Status = FvBlock->Write (FvBlock, Lba, Offset, &Length, &State);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Get the last Write record pointer.\r
- The last record is the record whose 'complete' state hasn't been set.\r
- After all, this header may be a EMPTY header entry for next Allocate.\r
-\r
-\r
- @param FtwLiteDevice Private data of this driver\r
- @param FtwLastRecord Pointer to retrieve the last write record\r
-\r
- @retval EFI_SUCCESS Get the last write record successfully\r
- @retval EFI_ABORTED The FTW work space is damaged\r
-\r
-**/\r
-EFI_STATUS\r
-FtwGetLastRecord (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
- OUT EFI_FTW_LITE_RECORD **FtwLastRecord\r
- )\r
-{\r
- EFI_FTW_LITE_RECORD *Record;\r
-\r
- *FtwLastRecord = NULL;\r
- Record = (EFI_FTW_LITE_RECORD *) (FtwLiteDevice->FtwWorkSpaceHeader + 1);\r
- while (Record->WriteCompleted == FTW_VALID_STATE) {\r
- //\r
- // If Offset exceed the FTW work space boudary, return error.\r
- //\r
- if ((UINTN) ((UINT8 *) Record - FtwLiteDevice->FtwWorkSpace) > FtwLiteDevice->FtwWorkSpaceSize) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- Record++;\r
- }\r
- //\r
- // Last write record is found\r
- //\r
- *FtwLastRecord = Record;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Read from working block to refresh the work space in memory.\r
-\r
-\r
- @param FtwLiteDevice Point to private data of FTW driver\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_ABORTED The function could not complete successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-WorkSpaceRefresh (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Length;\r
- UINTN Offset;\r
- EFI_FTW_LITE_RECORD *Record;\r
-\r
- //\r
- // Initialize WorkSpace as FTW_ERASED_BYTE\r
- //\r
- SetMem (\r
- FtwLiteDevice->FtwWorkSpace,\r
- FtwLiteDevice->FtwWorkSpaceSize,\r
- FTW_ERASED_BYTE\r
- );\r
-\r
- //\r
- // Read from working block\r
- //\r
- Length = FtwLiteDevice->FtwWorkSpaceSize;\r
- Status = FtwLiteDevice->FtwFvBlock->Read (\r
- FtwLiteDevice->FtwFvBlock,\r
- FtwLiteDevice->FtwWorkSpaceLba,\r
- FtwLiteDevice->FtwWorkSpaceBase,\r
- &Length,\r
- FtwLiteDevice->FtwWorkSpace\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Refresh the FtwLastRecord\r
- //\r
- Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);\r
-\r
- Record = FtwLiteDevice->FtwLastRecord;\r
- Offset = (UINTN) (UINT8 *) Record - (UINTN) FtwLiteDevice->FtwWorkSpace;\r
-\r
- //\r
- // If work space has error or Record is out of the workspace limit, THEN\r
- // call reclaim.\r
- //\r
- if (EFI_ERROR (Status) || (Offset + FTW_LITE_RECORD_SIZE >= FtwLiteDevice->FtwWorkSpaceSize)) {\r
- //\r
- // reclaim work space in working block.\r
- //\r
- Status = FtwReclaimWorkSpace (FtwLiteDevice, TRUE);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "FtwLite: Reclaim workspace - %r\n", Status));\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Reclaim the work space on the working block.\r
-\r
-\r
- @param FtwLiteDevice Point to private data of FTW driver\r
- @param PreserveRecord Whether get the last record or not\r
-\r
- @retval EFI_SUCCESS The function completed successfully\r
- @retval EFI_OUT_OF_RESOURCES Allocate memory error\r
- @retval EFI_ABORTED The function could not complete successfully\r
-\r
-**/\r
-EFI_STATUS\r
-FtwReclaimWorkSpace (\r
- IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
- IN BOOLEAN PreserveRecord\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 *TempBuffer;\r
- UINTN TempBufferSize;\r
- UINT8 *Ptr;\r
- UINTN Length;\r
- UINTN Index;\r
- UINTN SpareBufferSize;\r
- UINT8 *SpareBuffer;\r
- EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader;\r
- EFI_FTW_LITE_RECORD *Record;\r
-\r
- DEBUG ((EFI_D_ERROR, "FtwLite: start to reclaim work space\n"));\r
-\r
- //\r
- // Read all original data from working block to a memory buffer\r
- //\r
- TempBufferSize = FtwLiteDevice->SpareAreaLength;\r
- TempBuffer = AllocateZeroPool (TempBufferSize);\r
- if (TempBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Ptr = TempBuffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- Length = FtwLiteDevice->BlockSize;\r
- Status = FtwLiteDevice->FtwFvBlock->Read (\r
- FtwLiteDevice->FtwFvBlock,\r
- FtwLiteDevice->FtwWorkBlockLba + Index,\r
- 0,\r
- &Length,\r
- Ptr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (TempBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Ptr += Length;\r
- }\r
- //\r
- // Clean up the workspace, remove all the completed records.\r
- //\r
- Ptr = TempBuffer +\r
- ((UINTN) (FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba)) *\r
- FtwLiteDevice->BlockSize + FtwLiteDevice->FtwWorkSpaceBase;\r
-\r
- //\r
- // Clear the content of buffer that will save the new work space data\r
- //\r
- SetMem (Ptr, FtwLiteDevice->FtwWorkSpaceSize, FTW_ERASED_BYTE);\r
-\r
- //\r
- // Copy EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER to buffer\r
- //\r
- CopyMem (\r
- Ptr,\r
- FtwLiteDevice->FtwWorkSpaceHeader,\r
- sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)\r
- );\r
- if (PreserveRecord) {\r
- //\r
- // Get the last record\r
- //\r
- Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);\r
- Record = FtwLiteDevice->FtwLastRecord;\r
- if (!EFI_ERROR (Status) &&\r
- Record != NULL &&\r
- Record->WriteAllocated == FTW_VALID_STATE &&\r
- Record->WriteCompleted != FTW_VALID_STATE) {\r
- CopyMem (\r
- (UINT8 *) Ptr + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),\r
- Record,\r
- FTW_LITE_RECORD_SIZE\r
- );\r
- }\r
- }\r
-\r
- CopyMem (\r
- FtwLiteDevice->FtwWorkSpace,\r
- Ptr,\r
- FtwLiteDevice->FtwWorkSpaceSize\r
- );\r
-\r
- Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);\r
-\r
- //\r
- // Set the WorkingBlockValid and WorkingBlockInvalid as INVALID\r
- //\r
- WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) Ptr;\r
- WorkingBlockHeader->WorkingBlockValid = FTW_INVALID_STATE;\r
- WorkingBlockHeader->WorkingBlockInvalid = FTW_INVALID_STATE;\r
-\r
- //\r
- // Try to keep the content of spare block\r
- // Save spare block into a spare backup memory buffer (Sparebuffer)\r
- //\r
- SpareBufferSize = FtwLiteDevice->SpareAreaLength;\r
- SpareBuffer = AllocatePool (SpareBufferSize);\r
- if (SpareBuffer == NULL) {\r
- FreePool (TempBuffer);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Ptr = SpareBuffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- Length = FtwLiteDevice->BlockSize;\r
- Status = FtwLiteDevice->FtwBackupFvb->Read (\r
- FtwLiteDevice->FtwBackupFvb,\r
- FtwLiteDevice->FtwSpareLba + Index,\r
- 0,\r
- &Length,\r
- Ptr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (TempBuffer);\r
- FreePool (SpareBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Ptr += Length;\r
- }\r
- //\r
- // Write the memory buffer to spare block\r
- //\r
- Status = FtwEraseSpareBlock (FtwLiteDevice);\r
- Ptr = TempBuffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- Length = FtwLiteDevice->BlockSize;\r
- Status = FtwLiteDevice->FtwBackupFvb->Write (\r
- FtwLiteDevice->FtwBackupFvb,\r
- FtwLiteDevice->FtwSpareLba + Index,\r
- 0,\r
- &Length,\r
- Ptr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (TempBuffer);\r
- FreePool (SpareBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Ptr += Length;\r
- }\r
- //\r
- // Free TempBuffer\r
- //\r
- FreePool (TempBuffer);\r
-\r
- //\r
- // Write the spare block to working block\r
- //\r
- Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (SpareBuffer);\r
- return Status;\r
- }\r
- //\r
- // Restore spare backup buffer into spare block , if no failure happened during FtwWrite.\r
- //\r
- Status = FtwEraseSpareBlock (FtwLiteDevice);\r
- Ptr = SpareBuffer;\r
- for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {\r
- Length = FtwLiteDevice->BlockSize;\r
- Status = FtwLiteDevice->FtwBackupFvb->Write (\r
- FtwLiteDevice->FtwBackupFvb,\r
- FtwLiteDevice->FtwSpareLba + Index,\r
- 0,\r
- &Length,\r
- Ptr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (SpareBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- Ptr += Length;\r
- }\r
-\r
- FreePool (SpareBuffer);\r
-\r
- DEBUG ((EFI_D_ERROR, "FtwLite: reclaim work space success\n"));\r
-\r
- return EFI_SUCCESS;\r
-}\r
IN UINTN BufferSize\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_HANDLE FvbHandle;\r
- EFI_FTW_LITE_PROTOCOL *FtwLiteProtocol;\r
- EFI_LBA VarLba;\r
- UINTN VarOffset;\r
- UINT8 *FtwBuffer;\r
- UINTN FtwBufferSize;\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE FvbHandle;\r
+ EFI_LBA VarLba;\r
+ UINTN VarOffset;\r
+ UINT8 *FtwBuffer;\r
+ UINTN FtwBufferSize;\r
+ EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;\r
\r
//\r
// Locate fault tolerant write protocol\r
//\r
Status = gBS->LocateProtocol (\r
- &gEfiFaultTolerantWriteLiteProtocolGuid,\r
+ &gEfiFaultTolerantWriteProtocolGuid,\r
NULL,\r
- (VOID **) &FtwLiteProtocol\r
+ (VOID **) &FtwProtocol\r
);\r
if (EFI_ERROR (Status)) {\r
return EFI_NOT_FOUND;\r
//\r
// FTW write record\r
//\r
- Status = FtwLiteProtocol->Write (\r
- FtwLiteProtocol,\r
- FvbHandle,\r
+ Status = FtwProtocol->Write (\r
+ FtwProtocol,\r
VarLba, // LBA\r
VarOffset, // Offset\r
- &FtwBufferSize, // NumBytes\r
- FtwBuffer\r
+ FtwBufferSize, // NumBytes\r
+ NULL, // PrivateData NULL\r
+ FvbHandle, // Fvb Handle\r
+ FtwBuffer // write buffer\r
);\r
\r
FreePool (FtwBuffer);\r
\r
#include <PiDxe.h>\r
#include <Protocol/VariableWrite.h>\r
-#include <Protocol/FaultTolerantWriteLite.h>\r
+#include <Protocol/FaultTolerantWrite.h>\r
#include <Protocol/FirmwareVolumeBlock.h>\r
#include <Protocol/Variable.h>\r
#include <Library/PcdLib.h>\r
\r
[Protocols]\r
gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES\r
- gEfiFaultTolerantWriteLiteProtocolGuid ## SOMETIMES_CONSUMES\r
gEfiVariableWriteArchProtocolGuid ## ALWAYS_PRODUCES\r
gEfiVariableArchProtocolGuid ## ALWAYS_PRODUCES\r
+ gEfiFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES\r
\r
[Guids]\r
gEfiVariableGuid ## PRODUCES ## Configuration Table Guid \r
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.)\r
\r
[Depex]\r
- gEfiFirmwareVolumeBlockProtocolGuid AND gEfiFaultTolerantWriteLiteProtocolGuid\r
+ gEfiFirmwareVolumeBlockProtocolGuid AND gEfiFaultTolerantWriteProtocolGuid\r
\r
# [Event]\r
# ##\r