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
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
}\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
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
}\r
}\r
\r
- FileState = GetFileState (FvDevice->ErasePolarity, FfsHeader);\r
+ FileState = GetFileState (FvDevice->ErasePolarity, CacheFfsHeader);\r
\r
//\r
// check for non-deleted file\r
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
\r
Done:\r
if (EFI_ERROR (Status)) {\r
+ if (FileCached) {\r
+ CoreFreePool (CacheFfsHeader);\r
+ FileCached = FALSE;\r
+ }\r
FreeFvDeviceResource (FvDevice);\r
}\r
\r