3 The internal header file includes the common header files, defines
4 internal structure and functions used by FtwLite module.
6 Copyright (c) 2006 - 2008, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #ifndef _EFI_FAULT_TOLERANT_WRITE_H_
18 #define _EFI_FAULT_TOLERANT_WRITE_H_
22 #include <Guid/SystemNvDataGuid.h>
23 #include <Protocol/FaultTolerantWrite.h>
24 #include <Protocol/FirmwareVolumeBlock.h>
25 #include <Protocol/SwapAddressRange.h>
27 #include <Library/PcdLib.h>
28 #include <Library/DebugLib.h>
29 #include <Library/UefiDriverEntryPoint.h>
30 #include <Library/BaseMemoryLib.h>
31 #include <Library/MemoryAllocationLib.h>
32 #include <Library/UefiBootServicesTableLib.h>
35 // Flash erase polarity is 1
37 #define FTW_ERASE_POLARITY 1
39 #define FTW_VALID_STATE 0
40 #define FTW_INVALID_STATE 1
42 #define FTW_ERASED_BYTE ((UINT8) (255))
43 #define FTW_POLARITY_REVERT ((UINT8) (255))
46 // EFI Fault tolerant block update write queue entry
49 UINT8 HeaderAllocated
: 1;
50 UINT8 WritesAllocated
: 1;
52 #define HEADER_ALLOCATED 0x1
53 #define WRITES_ALLOCATED 0x2
54 #define WRITES_COMPLETED 0x4
58 UINTN PrivateDataSize
;
59 } EFI_FAULT_TOLERANT_WRITE_HEADER
;
62 // EFI Fault tolerant block update write queue record
65 UINT8 BootBlockUpdate
: 1;
66 UINT8 SpareComplete
: 1;
67 UINT8 DestinationComplete
: 1;
68 #define BOOT_BLOCK_UPDATE 0x1
69 #define SPARE_COMPLETED 0x2
70 #define DEST_COMPLETED 0x4
75 EFI_PHYSICAL_ADDRESS FvBaseAddress
;
77 // UINT8 PrivateData[PrivateDataSize]
79 } EFI_FAULT_TOLERANT_WRITE_RECORD
;
82 #define RECORD_SIZE(PrivateDataSize) (sizeof (EFI_FAULT_TOLERANT_WRITE_RECORD) + PrivateDataSize)
84 #define RECORD_TOTAL_SIZE(NumberOfWrites, PrivateDataSize) \
85 ((NumberOfWrites) * (sizeof (EFI_FAULT_TOLERANT_WRITE_RECORD) + PrivateDataSize))
87 #define WRITE_TOTAL_SIZE(NumberOfWrites, PrivateDataSize) \
89 sizeof (EFI_FAULT_TOLERANT_WRITE_HEADER) + (NumberOfWrites) * \
90 (sizeof (EFI_FAULT_TOLERANT_WRITE_RECORD) + PrivateDataSize) \
93 #define FTW_DEVICE_SIGNATURE SIGNATURE_32 ('F', 'T', 'W', 'D')
96 // EFI Fault tolerant protocol private data structure
101 EFI_FAULT_TOLERANT_WRITE_PROTOCOL FtwInstance
;
102 EFI_PHYSICAL_ADDRESS WorkSpaceAddress
; // Base address of working space range in flash.
103 EFI_PHYSICAL_ADDRESS SpareAreaAddress
; // Base address of spare range in flash.
104 UINTN WorkSpaceLength
; // Size of working space range in flash.
105 UINTN SpareAreaLength
; // Size of spare range in flash.
106 UINTN NumberOfSpareBlock
; // Number of the blocks in spare block.
107 UINTN BlockSize
; // Block size in bytes of the blocks in flash
108 EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER
*FtwWorkSpaceHeader
;// Pointer to Working Space Header in memory buffer
109 EFI_FAULT_TOLERANT_WRITE_HEADER
*FtwLastWriteHeader
;// Pointer to last record header in memory buffer
110 EFI_FAULT_TOLERANT_WRITE_RECORD
*FtwLastWriteRecord
;// Pointer to last record in memory buffer
111 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*FtwFvBlock
; // FVB of working block
112 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*FtwBackupFvb
; // FVB of spare block
113 EFI_LBA FtwSpareLba
; // Start LBA of spare block
114 EFI_LBA FtwWorkBlockLba
; // Start LBA of working block that contains working space in its last block.
115 EFI_LBA FtwWorkSpaceLba
; // Start LBA of working space
116 UINTN FtwWorkSpaceBase
; // Offset into the FtwWorkSpaceLba block.
117 UINTN FtwWorkSpaceSize
; // Size of working space range that stores write record.
118 UINT8
*FtwWorkSpace
; // Point to Work Space in memory buffer
120 // Following a buffer of FtwWorkSpace[FTW_WORK_SPACE_SIZE],
121 // Allocated with EFI_FTW_DEVICE.
125 #define FTW_CONTEXT_FROM_THIS(a) CR (a, EFI_FTW_DEVICE, FtwInstance, FTW_DEVICE_SIGNATURE)
128 // Driver entry point
131 This function is the entry point of the Fault Tolerant Write driver.
133 @param ImageHandle A handle for the image that is initializing this driver
134 @param SystemTable A pointer to the EFI system table
136 @return EFI_SUCCESS FTW has finished the initialization
137 @retval EFI_NOT_FOUND Locate FVB protocol error
138 @retval EFI_OUT_OF_RESOURCES Allocate memory error
139 @retval EFI_VOLUME_CORRUPTED Firmware volume is error
140 @retval EFI_ABORTED FTW initialization error
145 InitializeFaultTolerantWrite (
146 IN EFI_HANDLE ImageHandle
,
147 IN EFI_SYSTEM_TABLE
*SystemTable
151 // Fault Tolerant Write Protocol API
155 Query the largest block that may be updated in a fault tolerant manner.
158 @param This Indicates a pointer to the calling context.
159 @param BlockSize A pointer to a caller allocated UINTN that is updated to
160 indicate the size of the largest block that can be updated.
162 @return EFI_SUCCESS The function completed successfully
168 IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL
*This
,
173 Allocates space for the protocol to maintain information about writes.
174 Since writes must be completed in a fault tolerant manner and multiple
175 updates will require more resources to be successful, this function
176 enables the protocol to ensure that enough space exists to track
177 information about the upcoming writes.
179 All writes must be completed or aborted before another fault tolerant write can occur.
181 @param This Indicates a pointer to the calling context.
182 @param CallerId The GUID identifying the write.
183 @param PrivateDataSize The size of the caller's private data
184 that must be recorded for each write.
185 @param NumberOfWrites The number of fault tolerant block writes
186 that will need to occur.
188 @return EFI_SUCCESS The function completed successfully
189 @retval EFI_ABORTED The function could not complete successfully.
190 @retval EFI_ACCESS_DENIED All allocated writes have not been completed.
196 IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL
*This
,
197 IN EFI_GUID
*CallerId
,
198 IN UINTN PrivateDataSize
,
199 IN UINTN NumberOfWrites
203 Starts a target block update. This function will record data about write
204 in fault tolerant storage and will complete the write in a recoverable
205 manner, ensuring at all times that either the original contents or
206 the modified contents are available.
209 @param This Calling context
210 @param Lba The logical block address of the target block.
211 @param Offset The offset within the target block to place the data.
212 @param Length The number of bytes to write to the target block.
213 @param PrivateData A pointer to private data that the caller requires to
214 complete any pending writes in the event of a fault.
215 @param FvBlockHandle The handle of FVB protocol that provides services for
216 reading, writing, and erasing the target block.
217 @param Buffer The data to write.
219 @retval EFI_SUCCESS The function completed successfully
220 @retval EFI_ABORTED The function could not complete successfully.
221 @retval EFI_BAD_BUFFER_SIZE The input data can't fit within the spare block.
222 Offset + *NumBytes > SpareAreaLength.
223 @retval EFI_ACCESS_DENIED No writes have been allocated.
224 @retval EFI_OUT_OF_RESOURCES Cannot allocate enough memory resource.
225 @retval EFI_NOT_FOUND Cannot find FVB protocol by handle.
231 IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL
*This
,
235 IN VOID
*PrivateData
,
236 IN EFI_HANDLE FvBlockHandle
,
241 Restarts a previously interrupted write. The caller must provide the
242 block protocol needed to complete the interrupted write.
244 @param This Calling context.
245 @param FvBlockHandle The handle of FVB protocol that provides services for
246 reading, writing, and erasing the target block.
248 @retval EFI_SUCCESS The function completed successfully
249 @retval EFI_ACCESS_DENIED No pending writes exist
250 @retval EFI_NOT_FOUND FVB protocol not found by the handle
251 @retval EFI_ABORTED The function could not complete successfully
257 IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL
*This
,
258 IN EFI_HANDLE FvBlockHandle
262 Aborts all previous allocated writes.
264 @param This Calling context
266 @retval EFI_SUCCESS The function completed successfully
267 @retval EFI_ABORTED The function could not complete successfully.
268 @retval EFI_NOT_FOUND No allocated writes exist.
274 IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL
*This
278 Starts a target block update. This records information about the write
279 in fault tolerant storage and will complete the write in a recoverable
280 manner, ensuring at all times that either the original contents or
281 the modified contents are available.
283 @param This Indicates a pointer to the calling context.
284 @param CallerId The GUID identifying the last write.
285 @param Lba The logical block address of the last write.
286 @param Offset The offset within the block of the last write.
287 @param Length The length of the last write.
288 @param PrivateDataSize bytes from the private data
289 stored for this write.
290 @param PrivateData A pointer to a buffer. The function will copy
291 @param Complete A Boolean value with TRUE indicating
292 that the write was completed.
294 @retval EFI_SUCCESS The function completed successfully
295 @retval EFI_ABORTED The function could not complete successfully
296 @retval EFI_NOT_FOUND No allocated writes exist
297 @retval EFI_BUFFER_TOO_SMALL Input buffer is not larget enough
303 IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL
*This
,
304 OUT EFI_GUID
*CallerId
,
308 IN OUT UINTN
*PrivateDataSize
,
309 OUT VOID
*PrivateData
,
310 OUT BOOLEAN
*Complete
316 @param FtwDevice The private data of FTW driver
318 @retval EFI_SUCCESS The erase request was successfully completed.
319 @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.
320 @retval EFI_DEVICE_ERROR The block device is not functioning
321 correctly and could not be written.
322 The firmware device may have been
324 @retval EFI_INVALID_PARAMETER One or more of the LBAs listed
325 in the variable argument list do
326 not exist in the firmware volume.
332 IN EFI_FTW_DEVICE
*FtwDevice
336 Retrive the proper FVB protocol interface by HANDLE.
339 @param FvBlockHandle The handle of FVB protocol that provides services for
340 reading, writing, and erasing the target block.
341 @param FvBlock The interface of FVB protocol
343 @retval EFI_SUCCESS The function completed successfully
344 @retval EFI_ABORTED The function could not complete successfully
349 IN EFI_HANDLE FvBlockHandle
,
350 OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
**FvBlock
355 Is it in working block?
357 @param FtwDevice The private data of FTW driver
358 @param FvBlock Fvb protocol instance
359 @param Lba The block specified
361 @return A BOOLEAN value indicating in working block or not.
366 EFI_FTW_DEVICE
*FtwDevice
,
367 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*FvBlock
,
375 @param FtwDevice The private data of FTW driver
376 @param FvBlock Fvb protocol instance
377 @param Lba The block specified
379 @return A BOOLEAN value indicating in boot block or not.
384 EFI_FTW_DEVICE
*FtwDevice
,
385 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*FvBlock
,
390 Copy the content of spare block to a target block. Size is FTW_BLOCK_SIZE.
391 Spare block is accessed by FTW backup FVB protocol interface. LBA is 1.
392 Target block is accessed by FvbBlock protocol interface. LBA is Lba.
395 @param FtwDevice The private data of FTW driver
396 @param FvBlock FVB Protocol interface to access target block
397 @param Lba Lba of the target block
399 @retval EFI_SUCCESS Spare block content is copied to target block
400 @retval EFI_INVALID_PARAMETER Input parameter error
401 @retval EFI_OUT_OF_RESOURCES Allocate memory error
402 @retval EFI_ABORTED The function could not complete successfully
406 FlushSpareBlockToTargetBlock (
407 EFI_FTW_DEVICE
*FtwDevice
,
408 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*FvBlock
,
413 Copy the content of spare block to working block. Size is FTW_BLOCK_SIZE.
414 Spare block is accessed by FTW backup FVB protocol interface. LBA is
415 FtwDevice->FtwSpareLba.
416 Working block is accessed by FTW working FVB protocol interface. LBA is
417 FtwDevice->FtwWorkBlockLba.
419 Since the working block header is important when FTW initializes, the
420 state of the operation should be handled carefully. The Crc value is
421 calculated without STATE element.
423 @param FtwDevice The private data of FTW driver
425 @retval EFI_SUCCESS Spare block content is copied to target block
426 @retval EFI_OUT_OF_RESOURCES Allocate memory error
427 @retval EFI_ABORTED The function could not complete successfully
431 FlushSpareBlockToWorkingBlock (
432 EFI_FTW_DEVICE
*FtwDevice
436 Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.
437 Spare block is accessed by FTW working FVB protocol interface. LBA is 1.
438 Target block is accessed by FvbBlock protocol interface. LBA is Lba.
440 FTW will do extra work on boot block update.
441 FTW should depend on a protocol of EFI_ADDRESS_RANGE_SWAP_PROTOCOL,
442 which is produced by a chipset driver.
443 FTW updating boot block steps may be:
444 1. GetRangeLocation(), if the Range is inside the boot block, FTW know
445 that boot block will be update. It shall add a FLAG in the working block.
446 2. When spare block is ready,
447 3. SetSwapState(EFI_SWAPPED)
448 4. erasing boot block,
449 5. programming boot block until the boot block is ok.
450 6. SetSwapState(UNSWAPPED)
451 FTW shall not allow to update boot block when battery state is error.
453 @param FtwDevice The private data of FTW driver
455 @retval EFI_SUCCESS Spare block content is copied to boot block
456 @retval EFI_INVALID_PARAMETER Input parameter error
457 @retval EFI_OUT_OF_RESOURCES Allocate memory error
458 @retval EFI_ABORTED The function could not complete successfully
462 FlushSpareBlockToBootBlock (
463 EFI_FTW_DEVICE
*FtwDevice
467 Update a bit of state on a block device. The location of the bit is
468 calculated by the (Lba, Offset, bit). Here bit is determined by the
469 the name of a certain bit.
472 @param FvBlock FVB Protocol interface to access SrcBlock and DestBlock
473 @param Lba Lba of a block
474 @param Offset Offset on the Lba
475 @param NewBit New value that will override the old value if it can be change
477 @retval EFI_SUCCESS A state bit has been updated successfully
478 @retval Others Access block device error.
480 Assume all bits of State are inside the same BYTE.
481 @retval EFI_ABORTED Read block fail
486 IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*FvBlock
,
493 Get the last Write Header pointer.
494 The last write header is the header whose 'complete' state hasn't been set.
495 After all, this header may be a EMPTY header entry for next Allocate.
498 @param FtwWorkSpaceHeader Pointer of the working block header
499 @param FtwWorkSpaceSize Size of the work space
500 @param FtwWriteHeader Pointer to retrieve the last write header
502 @retval EFI_SUCCESS Get the last write record successfully
503 @retval EFI_ABORTED The FTW work space is damaged
507 FtwGetLastWriteHeader (
508 IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER
*FtwWorkSpaceHeader
,
509 IN UINTN FtwWorkSpaceSize
,
510 OUT EFI_FAULT_TOLERANT_WRITE_HEADER
**FtwWriteHeader
514 Get the last Write Record pointer. The last write Record is the Record
515 whose DestinationCompleted state hasn't been set. After all, this Record
516 may be a EMPTY record entry for next write.
519 @param FtwWriteHeader Pointer to the write record header
520 @param FtwWriteRecord Pointer to retrieve the last write record
522 @retval EFI_SUCCESS Get the last write record successfully
523 @retval EFI_ABORTED The FTW work space is damaged
527 FtwGetLastWriteRecord (
528 IN EFI_FAULT_TOLERANT_WRITE_HEADER
*FtwWriteHeader
,
529 OUT EFI_FAULT_TOLERANT_WRITE_RECORD
**FtwWriteRecord
533 To check if FtwRecord is the first record of FtwHeader.
535 @param FtwHeader Pointer to the write record header
536 @param FtwRecord Pointer to the write record
538 @retval TRUE FtwRecord is the first Record of the FtwHeader
539 @retval FALSE FtwRecord is not the first Record of the FtwHeader
543 IsFirstRecordOfWrites (
544 IN EFI_FAULT_TOLERANT_WRITE_HEADER
*FtwHeader
,
545 IN EFI_FAULT_TOLERANT_WRITE_RECORD
*FtwRecord
549 To check if FtwRecord is the last record of FtwHeader. Because the
550 FtwHeader has NumberOfWrites & PrivateDataSize, the FtwRecord can be
551 determined if it is the last record of FtwHeader.
553 @param FtwHeader Pointer to the write record header
554 @param FtwRecord Pointer to the write record
556 @retval TRUE FtwRecord is the last Record of the FtwHeader
557 @retval FALSE FtwRecord is not the last Record of the FtwHeader
561 IsLastRecordOfWrites (
562 IN EFI_FAULT_TOLERANT_WRITE_HEADER
*FtwHeader
,
563 IN EFI_FAULT_TOLERANT_WRITE_RECORD
*FtwRecord
567 To check if FtwRecord is the first record of FtwHeader.
569 @param FtwHeader Pointer to the write record header
570 @param FtwRecord Pointer to retrieve the previous write record
572 @retval EFI_ACCESS_DENIED Input record is the first record, no previous record is return.
573 @retval EFI_SUCCESS The previous write record is found.
577 GetPreviousRecordOfWrites (
578 IN EFI_FAULT_TOLERANT_WRITE_HEADER
*FtwHeader
,
579 IN OUT EFI_FAULT_TOLERANT_WRITE_RECORD
**FtwRecord
584 Check whether a flash buffer is erased.
586 @param Buffer Buffer to check
587 @param BufferSize Size of the buffer
589 @return A BOOLEAN value indicating erased or not.
593 IsErasedFlashBuffer (
598 Initialize a work space when there is no work space.
600 @param WorkingHeader Pointer of working block header
602 @retval EFI_SUCCESS The function completed successfully
603 @retval EFI_ABORTED The function could not complete successfully.
607 InitWorkSpaceHeader (
608 IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER
*WorkingHeader
611 Read from working block to refresh the work space in memory.
613 @param FtwDevice Point to private data of FTW driver
615 @retval EFI_SUCCESS The function completed successfully
616 @retval EFI_ABORTED The function could not complete successfully.
621 IN EFI_FTW_DEVICE
*FtwDevice
624 Check to see if it is a valid work space.
627 @param WorkingHeader Pointer of working block header
629 @retval EFI_SUCCESS The function completed successfully
630 @retval EFI_ABORTED The function could not complete successfully.
635 IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER
*WorkingHeader
638 Reclaim the work space on the working block.
640 @param FtwDevice Point to private data of FTW driver
641 @param PreserveRecord Whether to preserve the working record is needed
643 @retval EFI_SUCCESS The function completed successfully
644 @retval EFI_OUT_OF_RESOURCES Allocate memory error
645 @retval EFI_ABORTED The function could not complete successfully
649 FtwReclaimWorkSpace (
650 IN EFI_FTW_DEVICE
*FtwDevice
,
651 IN BOOLEAN PreserveRecord
656 Get firmware block by address.
659 @param Address Address specified the block
660 @param FvBlock The block caller wanted
662 @retval EFI_SUCCESS The protocol instance if found.
663 @retval EFI_NOT_FOUND Block not found
668 IN EFI_PHYSICAL_ADDRESS Address
,
669 OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
**FvBlock