/** @file\r
Implements functions to read firmware file\r
\r
-Copyright (c) 2006 - 2009, 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 - 2020, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "FwVolDriver.h"\r
\r
/**\r
-Required Alignment Alignment Value in FFS Alignment Value in\r
-(bytes) Attributes Field Firmware Volume Interfaces\r
-1 0 0\r
-2 0 1\r
-4 0 2\r
-8 0 3\r
-16 1 4\r
-128 2 7\r
-512 3 9\r
-1 KB 4 10\r
-4 KB 5 12\r
-32 KB 6 15\r
-64 KB 7 16\r
+Required Alignment Alignment Value in FFS FFS_ATTRIB_DATA_ALIGNMENT2 Alignment Value in\r
+(bytes) Attributes Field in FFS Attributes Field Firmware Volume Interfaces\r
+1 0 0 0\r
+16 1 0 4\r
+128 2 0 7\r
+512 3 0 9\r
+1 KB 4 0 10\r
+4 KB 5 0 12\r
+32 KB 6 0 15\r
+64 KB 7 0 16\r
+128 KB 0 1 17\r
+256 KB 1 1 18\r
+512 KB 2 1 19\r
+1 MB 3 1 20\r
+2 MB 4 1 21\r
+4 MB 5 1 22\r
+8 MB 6 1 23\r
+16 MB 7 1 24\r
**/\r
-UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16};\r
-\r
-\r
+UINT8 mFvAttributes[] = { 0, 4, 7, 9, 10, 12, 15, 16 };\r
+UINT8 mFvAttributes2[] = { 17, 18, 19, 20, 21, 22, 23, 24 };\r
\r
/**\r
Convert the FFS File Attributes to FV File Attributes\r
**/\r
EFI_FV_FILE_ATTRIBUTES\r
FfsAttributes2FvFileAttributes (\r
- IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes\r
+ IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes\r
)\r
{\r
- FfsAttributes = (EFI_FFS_FILE_ATTRIBUTES)((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);\r
- ASSERT (FfsAttributes < 8);\r
+ UINT8 DataAlignment;\r
+ EFI_FV_FILE_ATTRIBUTES FileAttribute;\r
\r
- return (EFI_FV_FILE_ATTRIBUTES) mFvAttributes[FfsAttributes];\r
-}\r
+ DataAlignment = (UINT8)((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);\r
+ ASSERT (DataAlignment < 8);\r
+\r
+ if ((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT_2) != 0) {\r
+ FileAttribute = (EFI_FV_FILE_ATTRIBUTES)mFvAttributes2[DataAlignment];\r
+ } else {\r
+ FileAttribute = (EFI_FV_FILE_ATTRIBUTES)mFvAttributes[DataAlignment];\r
+ }\r
\r
+ if ((FfsAttributes & FFS_ATTRIB_FIXED) == FFS_ATTRIB_FIXED) {\r
+ FileAttribute |= EFI_FV_FILE_ATTRIB_FIXED;\r
+ }\r
\r
+ return FileAttribute;\r
+}\r
\r
/**\r
Given the input key, search for the next matching file in the volume.\r
EFI_STATUS\r
EFIAPI\r
FvGetNextFile (\r
- IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,\r
- IN OUT VOID *Key,\r
- IN OUT EFI_FV_FILETYPE *FileType,\r
- OUT EFI_GUID *NameGuid,\r
- OUT EFI_FV_FILE_ATTRIBUTES *Attributes,\r
- OUT UINTN *Size\r
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,\r
+ IN OUT VOID *Key,\r
+ IN OUT EFI_FV_FILETYPE *FileType,\r
+ OUT EFI_GUID *NameGuid,\r
+ OUT EFI_FV_FILE_ATTRIBUTES *Attributes,\r
+ OUT UINTN *Size\r
)\r
{\r
- EFI_STATUS Status;\r
- FV_DEVICE *FvDevice;\r
- EFI_FV_ATTRIBUTES FvAttributes;\r
- EFI_FFS_FILE_HEADER *FfsFileHeader;\r
- UINTN *KeyValue;\r
- LIST_ENTRY *Link;\r
- FFS_FILE_LIST_ENTRY *FfsFileEntry;\r
- UINTN FileLength;\r
+ EFI_STATUS Status;\r
+ FV_DEVICE *FvDevice;\r
+ EFI_FV_ATTRIBUTES FvAttributes;\r
+ EFI_FFS_FILE_HEADER *FfsFileHeader;\r
+ UINTN *KeyValue;\r
+ LIST_ENTRY *Link;\r
+ FFS_FILE_LIST_ENTRY *FfsFileEntry;\r
\r
FvDevice = FV_DEVICE_FROM_THIS (This);\r
\r
Status = FvGetVolumeAttributes (This, &FvAttributes);\r
- if (EFI_ERROR (Status)){\r
+ if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
return EFI_ACCESS_DENIED;\r
}\r
\r
- if (*FileType > EFI_FV_FILETYPE_SMM_CORE) {\r
+ if (*FileType > EFI_FV_FILETYPE_MM_CORE_STANDALONE) {\r
//\r
- // File type needs to be in 0 - 0x0D\r
+ // File type needs to be in 0 - 0x0F\r
//\r
return EFI_NOT_FOUND;\r
}\r
\r
KeyValue = (UINTN *)Key;\r
- for (;;) {\r
+ for ( ; ;) {\r
if (*KeyValue == 0) {\r
//\r
// Search for 1st matching file\r
return EFI_NOT_FOUND;\r
}\r
\r
- FfsFileEntry = (FFS_FILE_LIST_ENTRY *)Link->ForwardLink;\r
+ FfsFileEntry = (FFS_FILE_LIST_ENTRY *)Link->ForwardLink;\r
FfsFileHeader = (EFI_FFS_FILE_HEADER *)FfsFileEntry->FfsHeader;\r
\r
//\r
//\r
break;\r
}\r
-\r
}\r
\r
//\r
*FileType = FfsFileHeader->Type;\r
CopyGuid (NameGuid, &FfsFileHeader->Name);\r
*Attributes = FfsAttributes2FvFileAttributes (FfsFileHeader->Attributes);\r
-\r
- //\r
- // Read four bytes out of the 3 byte array and throw out extra data\r
- //\r
- FileLength = *(UINT32 *)&FfsFileHeader->Size[0] & 0x00FFFFFF;\r
+ if ((FvDevice->FwVolHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) {\r
+ *Attributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED;\r
+ }\r
\r
//\r
// we need to substract the header size\r
//\r
- *Size = FileLength - sizeof(EFI_FFS_FILE_HEADER);\r
+ if (IS_FFS_FILE2 (FfsFileHeader)) {\r
+ *Size = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);\r
+ } else {\r
+ *Size = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);\r
+ }\r
\r
return EFI_SUCCESS;\r
}\r
\r
-\r
-\r
/**\r
Locates a file in the firmware volume and\r
copies it to the supplied buffer.\r
EFI_STATUS\r
EFIAPI\r
FvReadFile (\r
- IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,\r
- IN CONST EFI_GUID *NameGuid,\r
- IN OUT VOID **Buffer,\r
- IN OUT UINTN *BufferSize,\r
- OUT EFI_FV_FILETYPE *FoundType,\r
- OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,\r
- OUT UINT32 *AuthenticationStatus\r
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,\r
+ IN CONST EFI_GUID *NameGuid,\r
+ IN OUT VOID **Buffer,\r
+ IN OUT UINTN *BufferSize,\r
+ OUT EFI_FV_FILETYPE *FoundType,\r
+ OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,\r
+ OUT UINT32 *AuthenticationStatus\r
)\r
{\r
- EFI_STATUS Status;\r
- FV_DEVICE *FvDevice;\r
- EFI_GUID SearchNameGuid;\r
- EFI_FV_FILETYPE LocalFoundType;\r
- EFI_FV_FILE_ATTRIBUTES LocalAttributes;\r
- UINTN FileSize;\r
- UINT8 *SrcPtr;\r
- EFI_FFS_FILE_HEADER *FfsHeader;\r
- UINTN InputBufferSize;\r
+ EFI_STATUS Status;\r
+ FV_DEVICE *FvDevice;\r
+ EFI_GUID SearchNameGuid;\r
+ EFI_FV_FILETYPE LocalFoundType;\r
+ EFI_FV_FILE_ATTRIBUTES LocalAttributes;\r
+ UINTN FileSize;\r
+ UINT8 *SrcPtr;\r
+ EFI_FFS_FILE_HEADER *FfsHeader;\r
+ UINTN InputBufferSize;\r
+ UINTN WholeFileSize;\r
\r
if (NameGuid == NULL) {\r
return EFI_INVALID_PARAMETER;\r
\r
FvDevice = FV_DEVICE_FROM_THIS (This);\r
\r
-\r
//\r
// Keep looking until we find the matching NameGuid.\r
- // The Key is really an FfsFileEntry\r
+ // The Key is really a FfsFileEntry\r
//\r
FvDevice->LastKey = 0;\r
do {\r
LocalFoundType = 0;\r
- Status = FvGetNextFile (\r
- This,\r
- &FvDevice->LastKey,\r
- &LocalFoundType,\r
- &SearchNameGuid,\r
- &LocalAttributes,\r
- &FileSize\r
- );\r
+ Status = FvGetNextFile (\r
+ This,\r
+ &FvDevice->LastKey,\r
+ &LocalFoundType,\r
+ &SearchNameGuid,\r
+ &LocalAttributes,\r
+ &FileSize\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_NOT_FOUND;\r
}\r
// Get a pointer to the header\r
//\r
FfsHeader = FvDevice->LastKey->FfsHeader;\r
+ if (FvDevice->IsMemoryMapped) {\r
+ //\r
+ // Memory mapped FV has not been cached, so here is to cache by file.\r
+ //\r
+ if (!FvDevice->LastKey->FileCached) {\r
+ //\r
+ // Cache FFS file to memory buffer.\r
+ //\r
+ WholeFileSize = IS_FFS_FILE2 (FfsHeader) ? FFS_FILE2_SIZE (FfsHeader) : FFS_FILE_SIZE (FfsHeader);\r
+ FfsHeader = AllocateCopyPool (WholeFileSize, FfsHeader);\r
+ if (FfsHeader == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Let FfsHeader in FfsFileEntry point to the cached file buffer.\r
+ //\r
+ FvDevice->LastKey->FfsHeader = FfsHeader;\r
+ FvDevice->LastKey->FileCached = TRUE;\r
+ }\r
+ }\r
\r
//\r
// Remember callers buffer size\r
//\r
// Calculate return values\r
//\r
- *FoundType = FfsHeader->Type;\r
+ *FoundType = FfsHeader->Type;\r
*FileAttributes = FfsAttributes2FvFileAttributes (FfsHeader->Attributes);\r
- *AuthenticationStatus = 0;\r
- *BufferSize = FileSize;\r
+ if ((FvDevice->FwVolHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) {\r
+ *FileAttributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED;\r
+ }\r
+\r
+ //\r
+ // Inherit the authentication status.\r
+ //\r
+ *AuthenticationStatus = FvDevice->AuthenticationStatus;\r
+ *BufferSize = FileSize;\r
\r
if (Buffer == NULL) {\r
//\r
//\r
// Skip over file header\r
//\r
- SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);\r
+ if (IS_FFS_FILE2 (FfsHeader)) {\r
+ SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER2);\r
+ } else {\r
+ SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);\r
+ }\r
\r
Status = EFI_SUCCESS;\r
if (*Buffer == NULL) {\r
//\r
// Callers buffer was not big enough\r
//\r
- Status = EFI_WARN_BUFFER_TOO_SMALL;\r
+ Status = EFI_WARN_BUFFER_TOO_SMALL;\r
FileSize = InputBufferSize;\r
}\r
\r
return Status;\r
}\r
\r
-\r
-\r
/**\r
Locates a section in a given FFS File and\r
copies it to the supplied buffer (not including section header).\r
OUT UINT32 *AuthenticationStatus\r
)\r
{\r
- EFI_STATUS Status;\r
- FV_DEVICE *FvDevice;\r
- EFI_FV_FILETYPE FileType;\r
- EFI_FV_FILE_ATTRIBUTES FileAttributes;\r
- UINTN FileSize;\r
- UINT8 *FileBuffer;\r
- FFS_FILE_LIST_ENTRY *FfsEntry;\r
-\r
- if (NameGuid == NULL || Buffer == NULL) {\r
+ EFI_STATUS Status;\r
+ FV_DEVICE *FvDevice;\r
+ EFI_FV_FILETYPE FileType;\r
+ EFI_FV_FILE_ATTRIBUTES FileAttributes;\r
+ UINTN FileSize;\r
+ UINT8 *FileBuffer;\r
+ FFS_FILE_LIST_ENTRY *FfsEntry;\r
+\r
+ if ((NameGuid == NULL) || (Buffer == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
FvDevice = FV_DEVICE_FROM_THIS (This);\r
\r
//\r
- // Read the whole file into buffer\r
+ // Read the file\r
//\r
- FileBuffer = NULL;\r
Status = FvReadFile (\r
- This,\r
- NameGuid,\r
- (VOID **)&FileBuffer,\r
- &FileSize,\r
- &FileType,\r
- &FileAttributes,\r
- AuthenticationStatus\r
- );\r
+ This,\r
+ NameGuid,\r
+ NULL,\r
+ &FileSize,\r
+ &FileType,\r
+ &FileAttributes,\r
+ AuthenticationStatus\r
+ );\r
//\r
// Get the last key used by our call to FvReadFile as it is the FfsEntry for this file.\r
//\r
- FfsEntry = (FFS_FILE_LIST_ENTRY *) FvDevice->LastKey;\r
+ FfsEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->LastKey;\r
\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
+ if (IS_FFS_FILE2 (FfsEntry->FfsHeader)) {\r
+ FileBuffer = ((UINT8 *)FfsEntry->FfsHeader) + sizeof (EFI_FFS_FILE_HEADER2);\r
+ } else {\r
+ FileBuffer = ((UINT8 *)FfsEntry->FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);\r
+ }\r
+\r
//\r
// Check to see that the file actually HAS sections before we go any further.\r
//\r
}\r
\r
//\r
- // Use FfsEntry to cache Section Extraction Protocol Inforomation\r
+ // Use FfsEntry to cache Section Extraction Protocol Information\r
//\r
if (FfsEntry->StreamHandle == 0) {\r
Status = OpenSectionStream (\r
(SectionType == 0) ? 0 : SectionInstance,\r
Buffer,\r
BufferSize,\r
- AuthenticationStatus\r
+ AuthenticationStatus,\r
+ FvDevice->IsFfs3Fv\r
);\r
\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Inherit the authentication status.\r
+ //\r
+ *AuthenticationStatus |= FvDevice->AuthenticationStatus;\r
+ }\r
+\r
//\r
// Close of stream defered to close of FfsHeader list to allow SEP to cache data\r
//\r
\r
Done:\r
- CoreFreePool (FileBuffer);\r
-\r
return Status;\r
}\r
-\r
-\r