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; } - -