]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.c
MdeModulePkg/FaultTolerantWrite: Consume Variable Flash Info
[mirror_edk2.git] / MdeModulePkg / Universal / FaultTolerantWritePei / FaultTolerantWritePei.c
index ca5d5b4a2257ac0ed2267a4bacd5c39801e1514b..8c152dcbad98bd89971405cc94e726a3085680ab 100644 (file)
@@ -16,8 +16,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/HobLib.h>\r
+#include <Library/SafeIntLib.h>\r
+#include <Library/VariableFlashInfoLib.h>\r
 \r
-EFI_PEI_PPI_DESCRIPTOR     mPpiListVariable = {\r
+EFI_PEI_PPI_DESCRIPTOR  mPpiListVariable = {\r
   (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
   &gEdkiiFaultTolerantWriteGuid,\r
   NULL\r
@@ -44,11 +46,11 @@ FtwGetLastWriteHeader (
   OUT EFI_FAULT_TOLERANT_WRITE_HEADER         **FtwWriteHeader\r
   )\r
 {\r
-  UINTN                           Offset;\r
-  EFI_FAULT_TOLERANT_WRITE_HEADER *FtwHeader;\r
+  UINTN                            Offset;\r
+  EFI_FAULT_TOLERANT_WRITE_HEADER  *FtwHeader;\r
 \r
   *FtwWriteHeader = NULL;\r
-  FtwHeader       = (EFI_FAULT_TOLERANT_WRITE_HEADER *) (FtwWorkSpaceHeader + 1);\r
+  FtwHeader       = (EFI_FAULT_TOLERANT_WRITE_HEADER *)(FtwWorkSpaceHeader + 1);\r
   Offset          = sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER);\r
 \r
   while (FtwHeader->Complete == FTW_VALID_STATE) {\r
@@ -61,8 +63,9 @@ FtwGetLastWriteHeader (
       return EFI_ABORTED;\r
     }\r
 \r
-    FtwHeader = (EFI_FAULT_TOLERANT_WRITE_HEADER *) ((UINT8 *) FtwWorkSpaceHeader + Offset);\r
+    FtwHeader = (EFI_FAULT_TOLERANT_WRITE_HEADER *)((UINT8 *)FtwWorkSpaceHeader + Offset);\r
   }\r
+\r
   //\r
   // Last write header is found\r
   //\r
@@ -86,15 +89,15 @@ FtwGetLastWriteHeader (
 **/\r
 EFI_STATUS\r
 FtwGetLastWriteRecord (\r
-  IN EFI_FAULT_TOLERANT_WRITE_HEADER          *FtwWriteHeader,\r
-  OUT EFI_FAULT_TOLERANT_WRITE_RECORD         **FtwWriteRecord\r
+  IN EFI_FAULT_TOLERANT_WRITE_HEADER   *FtwWriteHeader,\r
+  OUT EFI_FAULT_TOLERANT_WRITE_RECORD  **FtwWriteRecord\r
   )\r
 {\r
-  UINTN                           Index;\r
-  EFI_FAULT_TOLERANT_WRITE_RECORD *FtwRecord;\r
+  UINTN                            Index;\r
+  EFI_FAULT_TOLERANT_WRITE_RECORD  *FtwRecord;\r
 \r
   *FtwWriteRecord = NULL;\r
-  FtwRecord       = (EFI_FAULT_TOLERANT_WRITE_RECORD *) (FtwWriteHeader + 1);\r
+  FtwRecord       = (EFI_FAULT_TOLERANT_WRITE_RECORD *)(FtwWriteHeader + 1);\r
 \r
   //\r
   // Try to find the last write record "that has not completed"\r
@@ -111,9 +114,10 @@ FtwGetLastWriteRecord (
     FtwRecord++;\r
 \r
     if (FtwWriteHeader->PrivateDataSize != 0) {\r
-      FtwRecord = (EFI_FAULT_TOLERANT_WRITE_RECORD *) ((UINTN) FtwRecord + (UINTN) FtwWriteHeader->PrivateDataSize);\r
+      FtwRecord = (EFI_FAULT_TOLERANT_WRITE_RECORD *)((UINTN)FtwRecord + (UINTN)FtwWriteHeader->PrivateDataSize);\r
     }\r
   }\r
+\r
   //\r
   //  if Index == NumberOfWrites, then\r
   //  the last record has been written successfully,\r
@@ -121,7 +125,7 @@ FtwGetLastWriteRecord (
   //  also return the last record.\r
   //\r
   if (Index == FtwWriteHeader->NumberOfWrites) {\r
-    *FtwWriteRecord = (EFI_FAULT_TOLERANT_WRITE_RECORD *) ((UINTN) FtwRecord - FTW_RECORD_SIZE (FtwWriteHeader->PrivateDataSize));\r
+    *FtwWriteRecord = (EFI_FAULT_TOLERANT_WRITE_RECORD *)((UINTN)FtwRecord - FTW_RECORD_SIZE (FtwWriteHeader->PrivateDataSize));\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -141,11 +145,11 @@ FtwGetLastWriteRecord (
 **/\r
 BOOLEAN\r
 IsValidWorkSpace (\r
-  IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER    *WorkingHeader,\r
-  IN UINTN                                      WorkingLength\r
+  IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER  *WorkingHeader,\r
+  IN UINTN                                    WorkingLength\r
   )\r
 {\r
-  UINT8 Data;\r
+  UINT8  Data;\r
 \r
   if (WorkingHeader == NULL) {\r
     return FALSE;\r
@@ -172,7 +176,7 @@ IsValidWorkSpace (
     if (!CompareGuid (&gEfiSystemNvDataFvGuid, &WorkingHeader->Signature)) {\r
       return FALSE;\r
     } else {\r
-      Data = *(UINT8 *) (WorkingHeader + 1);\r
+      Data = *(UINT8 *)(WorkingHeader + 1);\r
       if (Data != 0xff) {\r
         DEBUG ((DEBUG_ERROR, "FtwPei: Old format FTW structure can't be handled\n"));\r
         ASSERT (FALSE);\r
@@ -182,7 +186,6 @@ IsValidWorkSpace (
   }\r
 \r
   return TRUE;\r
-\r
 }\r
 \r
 /**\r
@@ -202,39 +205,47 @@ PeimFaultTolerantWriteInitialize (
   IN CONST EFI_PEI_SERVICES     **PeiServices\r
   )\r
 {\r
-  EFI_STATUS                                Status;\r
-  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER   *FtwWorkingBlockHeader;\r
-  EFI_FAULT_TOLERANT_WRITE_HEADER           *FtwLastWriteHeader;\r
-  EFI_FAULT_TOLERANT_WRITE_RECORD           *FtwLastWriteRecord;\r
-  EFI_PHYSICAL_ADDRESS                      WorkSpaceAddress;\r
-  UINTN                                     WorkSpaceLength;\r
-  EFI_PHYSICAL_ADDRESS                      SpareAreaAddress;\r
-  UINTN                                     SpareAreaLength;\r
-  EFI_PHYSICAL_ADDRESS                      WorkSpaceInSpareArea;\r
-  FAULT_TOLERANT_WRITE_LAST_WRITE_DATA      FtwLastWrite;\r
+  EFI_STATUS                               Status;\r
+  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER  *FtwWorkingBlockHeader;\r
+  EFI_FAULT_TOLERANT_WRITE_HEADER          *FtwLastWriteHeader;\r
+  EFI_FAULT_TOLERANT_WRITE_RECORD          *FtwLastWriteRecord;\r
+  EFI_PHYSICAL_ADDRESS                     WorkSpaceAddress;\r
+  UINTN                                    WorkSpaceLength;\r
+  EFI_PHYSICAL_ADDRESS                     SpareAreaAddress;\r
+  UINTN                                    SpareAreaLength;\r
+  EFI_PHYSICAL_ADDRESS                     WorkSpaceInSpareArea;\r
+  UINT64                                   Size;\r
+  FAULT_TOLERANT_WRITE_LAST_WRITE_DATA     FtwLastWrite;\r
 \r
   FtwWorkingBlockHeader = NULL;\r
-  FtwLastWriteHeader = NULL;\r
-  FtwLastWriteRecord = NULL;\r
+  FtwLastWriteHeader    = NULL;\r
+  FtwLastWriteRecord    = NULL;\r
 \r
-  WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageFtwWorkingBase64);\r
-  if (WorkSpaceAddress == 0) {\r
-    WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwWorkingBase);\r
-  }\r
-  WorkSpaceLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwWorkingSize);\r
+  SpareAreaAddress = 0;\r
+  SpareAreaLength  = 0;\r
+  WorkSpaceAddress = 0;\r
+  WorkSpaceLength  = 0;\r
 \r
-  SpareAreaAddress = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageFtwSpareBase64);\r
-  if (SpareAreaAddress == 0) {\r
-    SpareAreaAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwSpareBase);\r
-  }\r
-  SpareAreaLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwSpareSize);\r
+  Status = GetVariableFlashFtwWorkingInfo (&WorkSpaceAddress, &Size);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = SafeUint64ToUintn (Size, &WorkSpaceLength);\r
+  // This driver currently assumes the size will be UINTN so assert the value is safe for now.\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = GetVariableFlashFtwSpareInfo (&SpareAreaAddress, &Size);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = SafeUint64ToUintn (Size, &SpareAreaLength);\r
+  // This driver currently assumes the size will be UINTN so assert the value is safe for now.\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
   // The address of FTW working base and spare base must not be 0.\r
   //\r
   ASSERT ((WorkSpaceAddress != 0) && (SpareAreaAddress != 0));\r
 \r
-  FtwWorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (UINTN) WorkSpaceAddress;\r
+  FtwWorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *)(UINTN)WorkSpaceAddress;\r
   if (IsValidWorkSpace (FtwWorkingBlockHeader, WorkSpaceLength)) {\r
     Status = FtwGetLastWriteHeader (\r
                FtwWorkingBlockHeader,\r
@@ -257,16 +268,17 @@ PeimFaultTolerantWriteInitialize (
         // but the target buffer has not been writen in target block from spare block, we need to build\r
         // FAULT_TOLERANT_WRITE_LAST_WRITE_DATA GUID hob to hold the FTW last write data.\r
         //\r
-        FtwLastWrite.TargetAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) ((INT64) SpareAreaAddress + FtwLastWriteRecord->RelativeOffset);\r
-        FtwLastWrite.SpareAddress = SpareAreaAddress;\r
-        FtwLastWrite.Length = SpareAreaLength;\r
+        FtwLastWrite.TargetAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)((INT64)SpareAreaAddress + FtwLastWriteRecord->RelativeOffset);\r
+        FtwLastWrite.SpareAddress  = SpareAreaAddress;\r
+        FtwLastWrite.Length        = SpareAreaLength;\r
         DEBUG ((\r
           DEBUG_INFO,\r
           "FtwPei last write data: TargetAddress - 0x%x SpareAddress - 0x%x Length - 0x%x\n",\r
-          (UINTN) FtwLastWrite.TargetAddress,\r
-          (UINTN) FtwLastWrite.SpareAddress,\r
-          (UINTN) FtwLastWrite.Length));\r
-        BuildGuidDataHob (&gEdkiiFaultTolerantWriteGuid, (VOID *) &FtwLastWrite, sizeof (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA));\r
+          (UINTN)FtwLastWrite.TargetAddress,\r
+          (UINTN)FtwLastWrite.SpareAddress,\r
+          (UINTN)FtwLastWrite.Length\r
+          ));\r
+        BuildGuidDataHob (&gEdkiiFaultTolerantWriteGuid, (VOID *)&FtwLastWrite, sizeof (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA));\r
       }\r
     }\r
   } else {\r
@@ -276,30 +288,33 @@ PeimFaultTolerantWriteInitialize (
     //\r
     WorkSpaceInSpareArea = SpareAreaAddress + SpareAreaLength - WorkSpaceLength;\r
     while (WorkSpaceInSpareArea >= SpareAreaAddress) {\r
-      if (CompareGuid (&gEdkiiWorkingBlockSignatureGuid, (EFI_GUID *) (UINTN) WorkSpaceInSpareArea)) {\r
+      if (CompareGuid (&gEdkiiWorkingBlockSignatureGuid, (EFI_GUID *)(UINTN)WorkSpaceInSpareArea)) {\r
         //\r
         // Found the workspace.\r
         //\r
-        DEBUG ((DEBUG_INFO, "FtwPei: workspace in spare block is at 0x%x.\n", (UINTN) WorkSpaceInSpareArea));\r
-        FtwWorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (UINTN) WorkSpaceInSpareArea;\r
+        DEBUG ((DEBUG_INFO, "FtwPei: workspace in spare block is at 0x%x.\n", (UINTN)WorkSpaceInSpareArea));\r
+        FtwWorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *)(UINTN)WorkSpaceInSpareArea;\r
         break;\r
       }\r
+\r
       WorkSpaceInSpareArea = WorkSpaceInSpareArea - sizeof (EFI_GUID);\r
     }\r
+\r
     if ((FtwWorkingBlockHeader != NULL) && IsValidWorkSpace (FtwWorkingBlockHeader, WorkSpaceLength)) {\r
       //\r
       // It was workspace self reclaim, build FAULT_TOLERANT_WRITE_LAST_WRITE_DATA GUID hob for it.\r
       //\r
       FtwLastWrite.TargetAddress = WorkSpaceAddress - (WorkSpaceInSpareArea - SpareAreaAddress);\r
-      FtwLastWrite.SpareAddress = SpareAreaAddress;\r
-      FtwLastWrite.Length = SpareAreaLength;\r
+      FtwLastWrite.SpareAddress  = SpareAreaAddress;\r
+      FtwLastWrite.Length        = SpareAreaLength;\r
       DEBUG ((\r
         DEBUG_INFO,\r
         "FtwPei last write data: TargetAddress - 0x%x SpareAddress - 0x%x Length - 0x%x\n",\r
-        (UINTN) FtwLastWrite.TargetAddress,\r
-        (UINTN) FtwLastWrite.SpareAddress,\r
-        (UINTN) FtwLastWrite.Length));\r
-      BuildGuidDataHob (&gEdkiiFaultTolerantWriteGuid, (VOID *) &FtwLastWrite, sizeof (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA));\r
+        (UINTN)FtwLastWrite.TargetAddress,\r
+        (UINTN)FtwLastWrite.SpareAddress,\r
+        (UINTN)FtwLastWrite.Length\r
+        ));\r
+      BuildGuidDataHob (&gEdkiiFaultTolerantWriteGuid, (VOID *)&FtwLastWrite, sizeof (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA));\r
     } else {\r
       //\r
       // Both are invalid.\r