]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/FwVol/FwVol.c
MdeModulePkg DxeCore: Handle FFS file with FFS_ATTRIB_CHECKSUM set for not cache...
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / FwVol / FwVol.c
index d3447a57ac2eb3c8486872947896e1646858c1ca..4fa177ed7c93359af1adf79ec6423037b3139dbf 100644 (file)
@@ -320,6 +320,12 @@ FvCheck (
   UINT8                                 *TopFvAddress;\r
   UINTN                                 TestLength;\r
   EFI_PHYSICAL_ADDRESS                  PhysicalAddress;\r
+  BOOLEAN                               FileCached;\r
+  UINTN                                 WholeFileSize;\r
+  EFI_FFS_FILE_HEADER                   *CacheFfsHeader;\r
+\r
+  FileCached = FALSE;\r
+  CacheFfsHeader = NULL;\r
 \r
   Fvb = FvDevice->Fvb;\r
   FwVolHeader = FvDevice->FwVolHeader;\r
@@ -460,6 +466,11 @@ FvCheck (
   TopFvAddress = FvDevice->EndOfCachedFv;\r
   while ((UINT8 *) FfsHeader < TopFvAddress) {\r
 \r
+    if (FileCached) {\r
+      CoreFreePool (CacheFfsHeader);\r
+      FileCached = FALSE;\r
+    }\r
+\r
     TestLength = TopFvAddress - ((UINT8 *) FfsHeader);\r
     if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) {\r
       TestLength = sizeof (EFI_FFS_FILE_HEADER);\r
@@ -493,7 +504,25 @@ FvCheck (
       }\r
     }\r
 \r
-    if (!IsValidFfsFile (FvDevice->ErasePolarity, FfsHeader)) {\r
+    CacheFfsHeader = FfsHeader;\r
+    if ((CacheFfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {\r
+      if (FvDevice->IsMemoryMapped) {\r
+        //\r
+        // Memory mapped FV has not been cached.\r
+        // Here is to cache FFS file to memory buffer for following checksum calculating.\r
+        // And then, the cached file buffer can be also used for FvReadFile.\r
+        //\r
+        WholeFileSize = IS_FFS_FILE2 (CacheFfsHeader) ? FFS_FILE2_SIZE (CacheFfsHeader): FFS_FILE_SIZE (CacheFfsHeader);\r
+        CacheFfsHeader = AllocateCopyPool (WholeFileSize, CacheFfsHeader);\r
+        if (CacheFfsHeader == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Done;\r
+        }\r
+        FileCached = TRUE;\r
+      }\r
+    }\r
+\r
+    if (!IsValidFfsFile (FvDevice->ErasePolarity, CacheFfsHeader)) {\r
       //\r
       // File system is corrupted\r
       //\r
@@ -501,11 +530,11 @@ FvCheck (
       goto Done;\r
     }\r
 \r
-    if (IS_FFS_FILE2 (FfsHeader)) {\r
-      ASSERT (FFS_FILE2_SIZE (FfsHeader) > 0x00FFFFFF);\r
+    if (IS_FFS_FILE2 (CacheFfsHeader)) {\r
+      ASSERT (FFS_FILE2_SIZE (CacheFfsHeader) > 0x00FFFFFF);\r
       if (!FvDevice->IsFfs3Fv) {\r
-        DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsHeader->Name));\r
-        FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + FFS_FILE2_SIZE (FfsHeader));\r
+        DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &CacheFfsHeader->Name));\r
+        FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + FFS_FILE2_SIZE (CacheFfsHeader));\r
         //\r
         // Adjust pointer to the next 8-byte aligned boundry.\r
         //\r
@@ -514,7 +543,7 @@ FvCheck (
       }\r
     }\r
 \r
-    FileState = GetFileState (FvDevice->ErasePolarity, FfsHeader);\r
+    FileState = GetFileState (FvDevice->ErasePolarity, CacheFfsHeader);\r
 \r
     //\r
     // check for non-deleted file\r
@@ -529,14 +558,16 @@ FvCheck (
         goto Done;\r
       }\r
 \r
-      FfsFileEntry->FfsHeader = FfsHeader;\r
+      FfsFileEntry->FfsHeader = CacheFfsHeader;\r
+      FfsFileEntry->FileCached = FileCached;\r
+      FileCached = FALSE;\r
       InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link);\r
     }\r
 \r
-    if (IS_FFS_FILE2 (FfsHeader)) {\r
-      FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + FFS_FILE2_SIZE (FfsHeader));\r
+    if (IS_FFS_FILE2 (CacheFfsHeader)) {\r
+      FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + FFS_FILE2_SIZE (CacheFfsHeader));\r
     } else {\r
-      FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + FFS_FILE_SIZE (FfsHeader));\r
+      FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + FFS_FILE_SIZE (CacheFfsHeader));\r
     }\r
 \r
     //\r
@@ -548,6 +579,10 @@ FvCheck (
 \r
 Done:\r
   if (EFI_ERROR (Status)) {\r
+    if (FileCached) {\r
+      CoreFreePool (CacheFfsHeader);\r
+      FileCached = FALSE;\r
+    }\r
     FreeFvDeviceResource (FvDevice);\r
   }\r
 \r