]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWrite.h
MdeModulePkg/FaultTolerantWriteDxe: implement standalone MM version
[mirror_edk2.git] / MdeModulePkg / Universal / FaultTolerantWriteDxe / FaultTolerantWrite.h
index a75db426fd7abc3600f9089088bb16fca2d0c9fa..a23cb620e2f20f3eaa4ae6c703f6a68919b1a201 100644 (file)
@@ -1,16 +1,16 @@
 /** @file\r
 \r
   The internal header file includes the common header files, defines\r
-  internal structure and functions used by FtwLite module.\r
+  internal structure and functions used by Ftw module.\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>\r
-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
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+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
@@ -20,6 +20,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <PiDxe.h>\r
 \r
 #include <Guid/SystemNvDataGuid.h>\r
+#include <Guid/ZeroGuid.h>\r
 #include <Protocol/FaultTolerantWrite.h>\r
 #include <Protocol/FirmwareVolumeBlock.h>\r
 #include <Protocol/SwapAddressRange.h>\r
@@ -30,66 +31,25 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiDriverEntryPoint.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/ReportStatusCodeLib.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
-//\r
-// EFI Fault tolerant block update write queue entry\r
-//\r
-typedef struct {\r
-  UINT8     HeaderAllocated : 1;\r
-  UINT8     WritesAllocated : 1;\r
-  UINT8     Complete : 1;\r
 #define HEADER_ALLOCATED  0x1\r
 #define WRITES_ALLOCATED  0x2\r
 #define WRITES_COMPLETED  0x4\r
-  UINT8     Reserved : 5;\r
-  EFI_GUID  CallerId;\r
-  UINTN     NumberOfWrites;\r
-  UINTN     PrivateDataSize;\r
-} EFI_FAULT_TOLERANT_WRITE_HEADER;\r
 \r
-//\r
-// EFI Fault tolerant block update write queue record\r
-//\r
-typedef struct {\r
-  UINT8   BootBlockUpdate : 1;\r
-  UINT8   SpareComplete : 1;\r
-  UINT8   DestinationComplete : 1;\r
 #define BOOT_BLOCK_UPDATE 0x1\r
 #define SPARE_COMPLETED   0x2\r
 #define DEST_COMPLETED    0x4\r
-  UINT8   Reserved : 5;\r
-  EFI_LBA Lba;\r
-  UINTN   Offset;\r
-  UINTN   Length;\r
-  EFI_PHYSICAL_ADDRESS  FvBaseAddress;\r
-  //\r
-  // UINT8                PrivateData[PrivateDataSize]\r
-  //\r
-} EFI_FAULT_TOLERANT_WRITE_RECORD;\r
-\r
 \r
-#define RECORD_SIZE(PrivateDataSize)  (sizeof (EFI_FAULT_TOLERANT_WRITE_RECORD) + PrivateDataSize)\r
-\r
-#define RECORD_TOTAL_SIZE(NumberOfWrites, PrivateDataSize) \\r
-    ((NumberOfWrites) * (sizeof (EFI_FAULT_TOLERANT_WRITE_RECORD) + PrivateDataSize))\r
-\r
-#define WRITE_TOTAL_SIZE(NumberOfWrites, PrivateDataSize) \\r
-    ( \\r
-      sizeof (EFI_FAULT_TOLERANT_WRITE_HEADER) + (NumberOfWrites) * \\r
-        (sizeof (EFI_FAULT_TOLERANT_WRITE_RECORD) + PrivateDataSize) \\r
-    )\r
+#define FTW_BLOCKS(Length, BlockSize) ((UINTN) ((Length) / (BlockSize) + (((Length) & ((BlockSize) - 1)) ? 1 : 0)))\r
 \r
 #define FTW_DEVICE_SIGNATURE  SIGNATURE_32 ('F', 'T', 'W', 'D')\r
 \r
@@ -103,9 +63,11 @@ typedef struct {
   EFI_PHYSICAL_ADDRESS                    WorkSpaceAddress;   // Base address of working space range in flash.\r
   EFI_PHYSICAL_ADDRESS                    SpareAreaAddress;   // Base address of spare range in flash.\r
   UINTN                                   WorkSpaceLength;    // Size of working space range in flash.\r
+  UINTN                                   NumberOfWorkSpaceBlock; // Number of the blocks in work block for work space.\r
+  UINTN                                   WorkBlockSize;      // Block size in bytes of the work blocks 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
+  UINTN                                   SpareBlockSize;     // Block size in bytes of the spare blocks in flash\r
   EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FtwWorkSpaceHeader;// Pointer to Working Space Header in memory buffer\r
   EFI_FAULT_TOLERANT_WRITE_HEADER         *FtwLastWriteHeader;// Pointer to last record header in memory buffer\r
   EFI_FAULT_TOLERANT_WRITE_RECORD         *FtwLastWriteRecord;// Pointer to last record in memory buffer\r
@@ -113,10 +75,13 @@ typedef struct {
   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
+  UINTN                                   NumberOfWorkBlock;  // Number of the blocks in work 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
+  EFI_LBA                                 FtwWorkSpaceLbaInSpare; // Start LBA of working space in spare block.\r
+  UINTN                                   FtwWorkSpaceBaseInSpare;// Offset into the FtwWorkSpaceLbaInSpare block.\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_DEVICE.\r
@@ -217,11 +182,11 @@ FtwAllocate (
                          reading, writing, and erasing 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
+  @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_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
@@ -324,7 +289,7 @@ FtwGetLastWrite (
                                 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
+                                not exist in the firmware volume.\r
 \r
 \r
 **/\r
@@ -334,7 +299,7 @@ FtwEraseSpareBlock (
   );\r
 \r
 /**\r
-  Retrive the proper FVB protocol interface by HANDLE.\r
+  Retrieve the proper FVB protocol interface by HANDLE.\r
 \r
 \r
   @param FvBlockHandle   The handle of FVB protocol that provides services for\r
@@ -375,7 +340,6 @@ IsWorkingBlock (
 \r
   @param FtwDevice       The private data of FTW driver\r
   @param FvBlock         Fvb protocol instance\r
-  @param Lba             The block specified\r
 \r
   @return A BOOLEAN value indicating in boot block or not.\r
 \r
@@ -383,19 +347,20 @@ IsWorkingBlock (
 BOOLEAN\r
 IsBootBlock (\r
   EFI_FTW_DEVICE                      *FtwDevice,\r
-  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,\r
-  EFI_LBA                             Lba\r
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock\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 1.\r
-  Target block is accessed by FvbBlock protocol interface. LBA is Lba.\r
+  Spare block is accessed by FTW backup FVB protocol interface.\r
+  Target block is accessed by FvBlock protocol interface.\r
 \r
 \r
   @param FtwDevice       The private data of FTW driver\r
   @param FvBlock         FVB Protocol interface to access target block\r
   @param Lba             Lba of the target block\r
+  @param BlockSize       The size of the block\r
+  @param NumberOfBlocks  The number of consecutive blocks starting with Lba\r
 \r
   @retval  EFI_SUCCESS               Spare block content is copied to target block\r
   @retval  EFI_INVALID_PARAMETER     Input parameter error\r
@@ -407,7 +372,9 @@ EFI_STATUS
 FlushSpareBlockToTargetBlock (\r
   EFI_FTW_DEVICE                      *FtwDevice,\r
   EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,\r
-  EFI_LBA                             Lba\r
+  EFI_LBA                             Lba,\r
+  UINTN                               BlockSize,\r
+  UINTN                               NumberOfBlocks\r
   );\r
 \r
 /**\r
@@ -435,8 +402,8 @@ FlushSpareBlockToWorkingBlock (
 \r
 /**\r
   Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.\r
-  Spare block is accessed by FTW working FVB protocol interface. LBA is 1.\r
-  Target block is accessed by FvbBlock protocol interface. LBA is Lba.\r
+  Spare block is accessed by FTW working FVB protocol interface.\r
+  Target block is accessed by FvBlock protocol interface.\r
 \r
   FTW will do extra work on boot block update.\r
   FTW should depend on a protocol of EFI_ADDRESS_RANGE_SWAP_PROTOCOL,\r
@@ -445,7 +412,7 @@ FlushSpareBlockToWorkingBlock (
   1. GetRangeLocation(), if the Range is inside the boot block, FTW know\r
   that boot block will be update. It shall add a FLAG in the working block.\r
   2. When spare block is ready,\r
-  3. SetSwapState(EFI_SWAPPED)\r
+  3. SetSwapState(SWAPPED)\r
   4. erasing boot block,\r
   5. programming boot block until the boot block is ok.\r
   6. SetSwapState(UNSWAPPED)\r
@@ -471,6 +438,7 @@ FlushSpareBlockToBootBlock (
 \r
 \r
   @param FvBlock         FVB Protocol interface to access SrcBlock and DestBlock\r
+  @param BlockSize       The size of the block\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
@@ -485,6 +453,7 @@ FlushSpareBlockToBootBlock (
 EFI_STATUS\r
 FtwUpdateFvState (\r
   IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,\r
+  IN UINTN                               BlockSize,\r
   IN EFI_LBA                             Lba,\r
   IN UINTN                               Offset,\r
   IN UINT8                               NewBit\r
@@ -654,7 +623,7 @@ FtwReclaimWorkSpace (
 \r
 /**\r
 \r
-  Get firmware block by address.\r
+  Get firmware volume block by address.\r
 \r
 \r
   @param Address         Address specified the block\r
@@ -670,4 +639,152 @@ GetFvbByAddress (
   OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock\r
   );\r
 \r
+/**\r
+  Retrieve the proper Swap Address Range protocol interface.\r
+\r
+  @param[out] SarProtocol       The interface of SAR protocol\r
+\r
+  @retval EFI_SUCCESS           The SAR protocol instance was found and returned in SarProtocol.\r
+  @retval EFI_NOT_FOUND         The SAR protocol instance was not found.\r
+  @retval EFI_INVALID_PARAMETER SarProtocol is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+FtwGetSarProtocol (\r
+  OUT VOID                                **SarProtocol\r
+  );\r
+\r
+/**\r
+  Function returns an array of handles that support the FVB protocol\r
+  in a buffer allocated from pool.\r
+\r
+  @param[out]  NumberHandles    The number of handles returned in Buffer.\r
+  @param[out]  Buffer           A pointer to the buffer to return the requested\r
+                                array of  handles that support FVB protocol.\r
+\r
+  @retval EFI_SUCCESS           The array of handles was returned in Buffer, and the number of\r
+                                handles in Buffer was returned in NumberHandles.\r
+  @retval EFI_NOT_FOUND         No FVB handle was found.\r
+  @retval EFI_OUT_OF_RESOURCES  There is not enough pool memory to store the matching results.\r
+  @retval EFI_INVALID_PARAMETER NumberHandles is NULL or Buffer is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+GetFvbCountAndBuffer (\r
+  OUT UINTN                               *NumberHandles,\r
+  OUT EFI_HANDLE                          **Buffer\r
+  );\r
+\r
+\r
+/**\r
+  Allocate private data for FTW driver and initialize it.\r
+\r
+  @param[out] FtwData           Pointer to the FTW device structure\r
+\r
+  @retval EFI_SUCCESS           Initialize the FTW device successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  Allocate memory error\r
+  @retval EFI_INVALID_PARAMETER Workspace or Spare block does not exist\r
+\r
+**/\r
+EFI_STATUS\r
+InitFtwDevice (\r
+  OUT EFI_FTW_DEVICE               **FtwData\r
+  );\r
+\r
+\r
+/**\r
+  Initialization for Fault Tolerant Write is done in this handler.\r
+\r
+  @param[in, out] FtwDevice     Pointer to the FTW device structure\r
+\r
+  @retval EFI_SUCCESS           Initialize the FTW protocol successfully.\r
+  @retval EFI_NOT_FOUND         No proper FVB protocol was found.\r
+\r
+**/\r
+EFI_STATUS\r
+InitFtwProtocol (\r
+  IN OUT EFI_FTW_DEVICE               *FtwDevice\r
+  );\r
+\r
+/**\r
+  Initialize a local work space header.\r
+\r
+  Since Signature and WriteQueueSize have been known, Crc can be calculated out,\r
+  then the work space header will be fixed.\r
+**/\r
+VOID\r
+InitializeLocalWorkSpaceHeader (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Read work space data from work block or spare block.\r
+\r
+  @param FvBlock        FVB Protocol interface to access the block.\r
+  @param BlockSize      The size of the block.\r
+  @param Lba            Lba of the block.\r
+  @param Offset         The offset within the block.\r
+  @param Length         The number of bytes to read from the block.\r
+  @param Buffer         The data is read.\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
+ReadWorkSpaceData (\r
+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
+  IN UINTN                              BlockSize,\r
+  IN EFI_LBA                            Lba,\r
+  IN UINTN                              Offset,\r
+  IN UINTN                              Length,\r
+  OUT UINT8                             *Buffer\r
+  );\r
+\r
+/**\r
+  Write data to work block.\r
+\r
+  @param FvBlock        FVB Protocol interface to access the block.\r
+  @param BlockSize      The size of the block.\r
+  @param Lba            Lba of the block.\r
+  @param Offset         The offset within the block to place the data.\r
+  @param Length         The number of bytes to write to the 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
+\r
+**/\r
+EFI_STATUS\r
+WriteWorkSpaceData (\r
+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
+  IN UINTN                              BlockSize,\r
+  IN EFI_LBA                            Lba,\r
+  IN UINTN                              Offset,\r
+  IN UINTN                              Length,\r
+  IN UINT8                              *Buffer\r
+  );\r
+\r
+/**\r
+  Internal implementation of CRC32. Depending on the execution context\r
+  (traditional SMM or DXE vs standalone MM), this function is implemented\r
+  via a call to the CalculateCrc32 () boot service, or via a library\r
+  call.\r
+\r
+  If Buffer is NULL, then ASSERT().\r
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+  @param[in]  Buffer       A pointer to the buffer on which the 32-bit CRC is\r
+                           to be computed.\r
+  @param[in]  Length       The number of bytes in the buffer Data.\r
+\r
+  @retval Crc32            The 32-bit CRC was computed for the data buffer.\r
+\r
+**/\r
+UINT32\r
+FtwCalculateCrc32 (\r
+  IN  VOID                         *Buffer,\r
+  IN  UINTN                        Length\r
+  );\r
+\r
 #endif\r