X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FCore%2FDxe%2FFwVol%2FFwVolRead.c;h=2ff22c93aad48d7e5342231d716d3f550a8707b2;hb=1436aea4d5707e672672a11bda72be2c63c936c3;hp=0b53af27d1fd8902b7caea6c8fed7891a43feaa4;hpb=d613c2a88b3db6b7b451d0b90b08343666792d04;p=mirror_edk2.git
diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c b/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c
index 0b53af27d1..2ff22c93aa 100644
--- a/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c
+++ b/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c
@@ -1,14 +1,8 @@
/** @file
Implements functions to read firmware file
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -16,23 +10,27 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "FwVolDriver.h"
/**
-Required Alignment Alignment Value in FFS Alignment Value in
-(bytes) Attributes Field Firmware Volume Interfaces
-1 0 0
-2 0 1
-4 0 2
-8 0 3
-16 1 4
-128 2 7
-512 3 9
-1 KB 4 10
-4 KB 5 12
-32 KB 6 15
-64 KB 7 16
+Required Alignment Alignment Value in FFS FFS_ATTRIB_DATA_ALIGNMENT2 Alignment Value in
+(bytes) Attributes Field in FFS Attributes Field Firmware Volume Interfaces
+1 0 0 0
+16 1 0 4
+128 2 0 7
+512 3 0 9
+1 KB 4 0 10
+4 KB 5 0 12
+32 KB 6 0 15
+64 KB 7 0 16
+128 KB 0 1 17
+256 KB 1 1 18
+512 KB 2 1 19
+1 MB 3 1 20
+2 MB 4 1 21
+4 MB 5 1 22
+8 MB 6 1 23
+16 MB 7 1 24
**/
-UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16};
-
-
+UINT8 mFvAttributes[] = { 0, 4, 7, 9, 10, 12, 15, 16 };
+UINT8 mFvAttributes2[] = { 17, 18, 19, 20, 21, 22, 23, 24 };
/**
Convert the FFS File Attributes to FV File Attributes
@@ -44,16 +42,27 @@ UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16};
**/
EFI_FV_FILE_ATTRIBUTES
FfsAttributes2FvFileAttributes (
- IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes
+ IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes
)
{
- FfsAttributes = (EFI_FFS_FILE_ATTRIBUTES)((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);
- ASSERT (FfsAttributes < 8);
+ UINT8 DataAlignment;
+ EFI_FV_FILE_ATTRIBUTES FileAttribute;
- return (EFI_FV_FILE_ATTRIBUTES) mFvAttributes[FfsAttributes];
-}
+ DataAlignment = (UINT8)((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);
+ ASSERT (DataAlignment < 8);
+
+ if ((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT_2) != 0) {
+ FileAttribute = (EFI_FV_FILE_ATTRIBUTES)mFvAttributes2[DataAlignment];
+ } else {
+ FileAttribute = (EFI_FV_FILE_ATTRIBUTES)mFvAttributes[DataAlignment];
+ }
+ if ((FfsAttributes & FFS_ATTRIB_FIXED) == FFS_ATTRIB_FIXED) {
+ FileAttribute |= EFI_FV_FILE_ATTRIB_FIXED;
+ }
+ return FileAttribute;
+}
/**
Given the input key, search for the next matching file in the volume.
@@ -104,27 +113,26 @@ FfsAttributes2FvFileAttributes (
EFI_STATUS
EFIAPI
FvGetNextFile (
- IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
- IN OUT VOID *Key,
- IN OUT EFI_FV_FILETYPE *FileType,
- OUT EFI_GUID *NameGuid,
- OUT EFI_FV_FILE_ATTRIBUTES *Attributes,
- OUT UINTN *Size
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN OUT VOID *Key,
+ IN OUT EFI_FV_FILETYPE *FileType,
+ OUT EFI_GUID *NameGuid,
+ OUT EFI_FV_FILE_ATTRIBUTES *Attributes,
+ OUT UINTN *Size
)
{
- EFI_STATUS Status;
- FV_DEVICE *FvDevice;
- EFI_FV_ATTRIBUTES FvAttributes;
- EFI_FFS_FILE_HEADER *FfsFileHeader;
- UINTN *KeyValue;
- LIST_ENTRY *Link;
- FFS_FILE_LIST_ENTRY *FfsFileEntry;
- UINTN FileLength;
+ EFI_STATUS Status;
+ FV_DEVICE *FvDevice;
+ EFI_FV_ATTRIBUTES FvAttributes;
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ UINTN *KeyValue;
+ LIST_ENTRY *Link;
+ FFS_FILE_LIST_ENTRY *FfsFileEntry;
FvDevice = FV_DEVICE_FROM_THIS (This);
Status = FvGetVolumeAttributes (This, &FvAttributes);
- if (EFI_ERROR (Status)){
+ if (EFI_ERROR (Status)) {
return Status;
}
@@ -135,15 +143,15 @@ FvGetNextFile (
return EFI_ACCESS_DENIED;
}
- if (*FileType > EFI_FV_FILETYPE_SMM_CORE) {
+ if (*FileType > EFI_FV_FILETYPE_MM_CORE_STANDALONE) {
//
- // File type needs to be in 0 - 0x0D
+ // File type needs to be in 0 - 0x0F
//
return EFI_NOT_FOUND;
}
KeyValue = (UINTN *)Key;
- for (;;) {
+ for ( ; ;) {
if (*KeyValue == 0) {
//
// Search for 1st matching file
@@ -163,7 +171,7 @@ FvGetNextFile (
return EFI_NOT_FOUND;
}
- FfsFileEntry = (FFS_FILE_LIST_ENTRY *)Link->ForwardLink;
+ FfsFileEntry = (FFS_FILE_LIST_ENTRY *)Link->ForwardLink;
FfsFileHeader = (EFI_FFS_FILE_HEADER *)FfsFileEntry->FfsHeader;
//
@@ -191,7 +199,6 @@ FvGetNextFile (
//
break;
}
-
}
//
@@ -200,22 +207,22 @@ FvGetNextFile (
*FileType = FfsFileHeader->Type;
CopyGuid (NameGuid, &FfsFileHeader->Name);
*Attributes = FfsAttributes2FvFileAttributes (FfsFileHeader->Attributes);
-
- //
- // Read four bytes out of the 3 byte array and throw out extra data
- //
- FileLength = *(UINT32 *)&FfsFileHeader->Size[0] & 0x00FFFFFF;
+ if ((FvDevice->FwVolHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) {
+ *Attributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED;
+ }
//
// we need to substract the header size
//
- *Size = FileLength - sizeof(EFI_FFS_FILE_HEADER);
+ if (IS_FFS_FILE2 (FfsFileHeader)) {
+ *Size = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
+ } else {
+ *Size = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
+ }
return EFI_SUCCESS;
}
-
-
/**
Locates a file in the firmware volume and
copies it to the supplied buffer.
@@ -259,24 +266,25 @@ FvGetNextFile (
EFI_STATUS
EFIAPI
FvReadFile (
- IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
- IN CONST EFI_GUID *NameGuid,
- IN OUT VOID **Buffer,
- IN OUT UINTN *BufferSize,
- OUT EFI_FV_FILETYPE *FoundType,
- OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
- OUT UINT32 *AuthenticationStatus
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN CONST EFI_GUID *NameGuid,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_FV_FILETYPE *FoundType,
+ OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
+ OUT UINT32 *AuthenticationStatus
)
{
- EFI_STATUS Status;
- FV_DEVICE *FvDevice;
- EFI_GUID SearchNameGuid;
- EFI_FV_FILETYPE LocalFoundType;
- EFI_FV_FILE_ATTRIBUTES LocalAttributes;
- UINTN FileSize;
- UINT8 *SrcPtr;
- EFI_FFS_FILE_HEADER *FfsHeader;
- UINTN InputBufferSize;
+ EFI_STATUS Status;
+ FV_DEVICE *FvDevice;
+ EFI_GUID SearchNameGuid;
+ EFI_FV_FILETYPE LocalFoundType;
+ EFI_FV_FILE_ATTRIBUTES LocalAttributes;
+ UINTN FileSize;
+ UINT8 *SrcPtr;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+ UINTN InputBufferSize;
+ UINTN WholeFileSize;
if (NameGuid == NULL) {
return EFI_INVALID_PARAMETER;
@@ -284,22 +292,21 @@ FvReadFile (
FvDevice = FV_DEVICE_FROM_THIS (This);
-
//
// Keep looking until we find the matching NameGuid.
- // The Key is really an FfsFileEntry
+ // The Key is really a FfsFileEntry
//
FvDevice->LastKey = 0;
do {
LocalFoundType = 0;
- Status = FvGetNextFile (
- This,
- &FvDevice->LastKey,
- &LocalFoundType,
- &SearchNameGuid,
- &LocalAttributes,
- &FileSize
- );
+ Status = FvGetNextFile (
+ This,
+ &FvDevice->LastKey,
+ &LocalFoundType,
+ &SearchNameGuid,
+ &LocalAttributes,
+ &FileSize
+ );
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
@@ -309,6 +316,27 @@ FvReadFile (
// Get a pointer to the header
//
FfsHeader = FvDevice->LastKey->FfsHeader;
+ if (FvDevice->IsMemoryMapped) {
+ //
+ // Memory mapped FV has not been cached, so here is to cache by file.
+ //
+ if (!FvDevice->LastKey->FileCached) {
+ //
+ // Cache FFS file to memory buffer.
+ //
+ WholeFileSize = IS_FFS_FILE2 (FfsHeader) ? FFS_FILE2_SIZE (FfsHeader) : FFS_FILE_SIZE (FfsHeader);
+ FfsHeader = AllocateCopyPool (WholeFileSize, FfsHeader);
+ if (FfsHeader == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Let FfsHeader in FfsFileEntry point to the cached file buffer.
+ //
+ FvDevice->LastKey->FfsHeader = FfsHeader;
+ FvDevice->LastKey->FileCached = TRUE;
+ }
+ }
//
// Remember callers buffer size
@@ -318,10 +346,17 @@ FvReadFile (
//
// Calculate return values
//
- *FoundType = FfsHeader->Type;
+ *FoundType = FfsHeader->Type;
*FileAttributes = FfsAttributes2FvFileAttributes (FfsHeader->Attributes);
- *AuthenticationStatus = 0;
- *BufferSize = FileSize;
+ if ((FvDevice->FwVolHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) {
+ *FileAttributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED;
+ }
+
+ //
+ // Inherit the authentication status.
+ //
+ *AuthenticationStatus = FvDevice->AuthenticationStatus;
+ *BufferSize = FileSize;
if (Buffer == NULL) {
//
@@ -333,7 +368,11 @@ FvReadFile (
//
// Skip over file header
//
- SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);
+ if (IS_FFS_FILE2 (FfsHeader)) {
+ SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER2);
+ } else {
+ SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);
+ }
Status = EFI_SUCCESS;
if (*Buffer == NULL) {
@@ -348,7 +387,7 @@ FvReadFile (
//
// Callers buffer was not big enough
//
- Status = EFI_WARN_BUFFER_TOO_SMALL;
+ Status = EFI_WARN_BUFFER_TOO_SMALL;
FileSize = InputBufferSize;
}
@@ -360,8 +399,6 @@ FvReadFile (
return Status;
}
-
-
/**
Locates a section in a given FFS File and
copies it to the supplied buffer (not including section header).
@@ -402,42 +439,47 @@ FvReadFileSection (
OUT UINT32 *AuthenticationStatus
)
{
- EFI_STATUS Status;
- FV_DEVICE *FvDevice;
- EFI_FV_FILETYPE FileType;
- EFI_FV_FILE_ATTRIBUTES FileAttributes;
- UINTN FileSize;
- UINT8 *FileBuffer;
- FFS_FILE_LIST_ENTRY *FfsEntry;
-
- if (NameGuid == NULL || Buffer == NULL) {
+ EFI_STATUS Status;
+ FV_DEVICE *FvDevice;
+ EFI_FV_FILETYPE FileType;
+ EFI_FV_FILE_ATTRIBUTES FileAttributes;
+ UINTN FileSize;
+ UINT8 *FileBuffer;
+ FFS_FILE_LIST_ENTRY *FfsEntry;
+
+ if ((NameGuid == NULL) || (Buffer == NULL)) {
return EFI_INVALID_PARAMETER;
}
FvDevice = FV_DEVICE_FROM_THIS (This);
//
- // Read the whole file into buffer
+ // Read the file
//
- FileBuffer = NULL;
Status = FvReadFile (
- This,
- NameGuid,
- (VOID **)&FileBuffer,
- &FileSize,
- &FileType,
- &FileAttributes,
- AuthenticationStatus
- );
+ This,
+ NameGuid,
+ NULL,
+ &FileSize,
+ &FileType,
+ &FileAttributes,
+ AuthenticationStatus
+ );
//
// Get the last key used by our call to FvReadFile as it is the FfsEntry for this file.
//
- FfsEntry = (FFS_FILE_LIST_ENTRY *) FvDevice->LastKey;
+ FfsEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->LastKey;
if (EFI_ERROR (Status)) {
return Status;
}
+ if (IS_FFS_FILE2 (FfsEntry->FfsHeader)) {
+ FileBuffer = ((UINT8 *)FfsEntry->FfsHeader) + sizeof (EFI_FFS_FILE_HEADER2);
+ } else {
+ FileBuffer = ((UINT8 *)FfsEntry->FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);
+ }
+
//
// Check to see that the file actually HAS sections before we go any further.
//
@@ -447,7 +489,7 @@ FvReadFileSection (
}
//
- // Use FfsEntry to cache Section Extraction Protocol Inforomation
+ // Use FfsEntry to cache Section Extraction Protocol Information
//
if (FfsEntry->StreamHandle == 0) {
Status = OpenSectionStream (
@@ -470,17 +512,21 @@ FvReadFileSection (
(SectionType == 0) ? 0 : SectionInstance,
Buffer,
BufferSize,
- AuthenticationStatus
+ AuthenticationStatus,
+ FvDevice->IsFfs3Fv
);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Inherit the authentication status.
+ //
+ *AuthenticationStatus |= FvDevice->AuthenticationStatus;
+ }
+
//
// Close of stream defered to close of FfsHeader list to allow SEP to cache data
//
Done:
- CoreFreePool (FileBuffer);
-
return Status;
}
-
-