From nobody Tue Feb 10 16:22:41 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1531494357451433.71262771818965; Fri, 13 Jul 2018 08:05:57 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 285FA209884C6; Fri, 13 Jul 2018 08:05:57 -0700 (PDT) Received: from foss.arm.com (usa-sjc-mx-foss1.foss.arm.com [217.140.101.70]) by ml01.01.org (Postfix) with ESMTP id BF2E3211F889D for ; Fri, 13 Jul 2018 08:05:55 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 792C17A9; Fri, 13 Jul 2018 08:05:55 -0700 (PDT) Received: from usa.arm.com (a074948-lin.blr.arm.com [10.162.4.138]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 765CD3F5B1; Fri, 13 Jul 2018 08:05:53 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=217.140.101.70; helo=foss.arm.com; envelope-from=sughosh.ganu@arm.com; receiver=edk2-devel@lists.01.org From: Sughosh Ganu To: edk2-devel@lists.01.org Date: Fri, 13 Jul 2018 20:35:22 +0530 Message-Id: <1531494330-1280-3-git-send-email-sughosh.ganu@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1531494330-1280-1-git-send-email-sughosh.ganu@arm.com> References: <1531494330-1280-1-git-send-email-sughosh.ganu@arm.com> Subject: [edk2] [PATCH v2 02/10] StandaloneMmPkg/FvLib: Add a common FV Library for management mode. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jiewen Yao MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Supreeth Venkatesh This patch implements a firmware volume library that can be used by the Standalone management mode core module to parse the firmware volume. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Supreeth Venkatesh Reviewed-by: Achin Gupta Reviewed-by: Jiewen Yao Signed-off-by: Sughosh Ganu --- StandaloneMmPkg/Include/Library/FvLib.h | 109 ++++++ StandaloneMmPkg/Library/FvLib/FvLib.c | 385 +++++++++++++++++= ++++ .../Library/FvLib/FvLib.inf | 29 +- 3 files changed, 509 insertions(+), 14 deletions(-) create mode 100644 StandaloneMmPkg/Include/Library/FvLib.h create mode 100644 StandaloneMmPkg/Library/FvLib/FvLib.c copy IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNul= l.inf =3D> StandaloneMmPkg/Library/FvLib/FvLib.inf (69%) diff --git a/StandaloneMmPkg/Include/Library/FvLib.h b/StandaloneMmPkg/Incl= ude/Library/FvLib.h new file mode 100644 index 000000000000..64e65b412d95 --- /dev/null +++ b/StandaloneMmPkg/Include/Library/FvLib.h @@ -0,0 +1,109 @@ +/** @file + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2016 - 2018, ARM Limited. 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 IMPLI= ED. + +**/ + +#ifndef _FV_LIB_H_ +#define _FV_LIB_H_ + +#include +#include +#include + +/** + Given the input file pointer, search for the next matching file in the + FFS volume as defined by SearchType. The search starts from FileHeader i= nside + the Firmware Volume defined by FwVolHeader. + + @param SearchType Filter to find only files of this type. + Type EFI_FV_FILETYPE_ALL causes no filtering to be d= one. + @param FwVolHeader Pointer to the FV header of the volume to search. + This parameter must point to a valid FFS volume. + @param FileHeader Pointer to the current file from which to begin sear= ching. + This pointer will be updated upon return to reflect = the file found. + + @retval EFI_NOT_FOUND No files matching the search criteria were found + @retval EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +FfsFindNextFile ( + IN EFI_FV_FILETYPE SearchType, + IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader, + IN OUT EFI_FFS_FILE_HEADER **FileHeader + ); + +/** + Given the input file pointer, search for the next matching section in the + FFS volume. + + @param SearchType Filter to find only sections of this type. + @param FfsFileHeader Pointer to the current file to search. + @param SectionHeader Pointer to the Section matching SectionType in Ffs= FileHeader. + NULL if section not found + + @retval EFI_NOT_FOUND No files matching the search criteria were found + @retval EFI_SUCCESS +**/ +EFI_STATUS +FfsFindSection ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_FFS_FILE_HEADER *FfsFileHeader, + IN OUT EFI_COMMON_SECTION_HEADER **SectionHeader + ); + +/** + Locates a section within a series of sections + with the specified section type. + + @param[in] Sections The sections to search + @param[in] SizeOfSections Total size of all sections + @param[in] SectionType The section type to locate + @param[out] FoundSection The FFS section if found + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted +**/ +EFI_STATUS +EFIAPI +FindFfsSectionInSections ( + IN VOID *Sections, + IN UINTN SizeOfSections, + IN EFI_SECTION_TYPE SectionType, + OUT EFI_COMMON_SECTION_HEADER **FoundSection + ); + +/** + Given the input file pointer, search for the next matching section in the + FFS volume. + + @param SearchType Filter to find only sections of this type. + @param FfsFileHeader Pointer to the current file to search. + @param SectionData Pointer to the Section matching SectionType in F= fsFileHeader. + NULL if section not found + @param SectionDataSize The size of SectionData + + @retval EFI_NOT_FOUND No files matching the search criteria were found + @retval EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +FfsFindSectionData ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_FFS_FILE_HEADER *FfsFileHeader, + OUT VOID **SectionData, + OUT UINTN *SectionDataSize + ); + +#endif diff --git a/StandaloneMmPkg/Library/FvLib/FvLib.c b/StandaloneMmPkg/Librar= y/FvLib/FvLib.c new file mode 100644 index 000000000000..b6d4916ffaf4 --- /dev/null +++ b/StandaloneMmPkg/Library/FvLib/FvLib.c @@ -0,0 +1,385 @@ +/** @file + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2016 - 2018, ARM Limited. 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 IMPLI= ED. + +**/ + +#include + +#include +#include +#include + +#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \ + (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((A= lignment) - 1)) + +/** + Returns the highest bit set of the State field + + @param ErasePolarity Erase Polarity as defined by EFI_FVB_ERASE_POLAR= ITY + in the Attributes field. + @param FfsHeader Pointer to FFS File Header. + + @return the highest bit in the State field +**/ +EFI_FFS_FILE_STATE +GetFileState ( + IN UINT8 ErasePolarity, + IN EFI_FFS_FILE_HEADER *FfsHeader + ) +{ + EFI_FFS_FILE_STATE FileState; + EFI_FFS_FILE_STATE HighestBit; + + FileState =3D FfsHeader->State; + + if (ErasePolarity !=3D 0) { + FileState =3D (EFI_FFS_FILE_STATE)~FileState; + } + + HighestBit =3D 0x80; + while (HighestBit !=3D 0 && (HighestBit & FileState) =3D=3D 0) { + HighestBit >>=3D 1; + } + + return HighestBit; +} + +/** + Calculates the checksum of the header of a file. + + @param FileHeader Pointer to FFS File Header. + + @return Checksum of the header. +**/ +UINT8 +CalculateHeaderChecksum ( + IN EFI_FFS_FILE_HEADER *FileHeader + ) +{ + UINT8 *ptr; + UINTN Index; + UINT8 Sum; + + Sum =3D 0; + ptr =3D (UINT8 *) FileHeader; + + for (Index =3D 0; Index < sizeof (EFI_FFS_FILE_HEADER) - 3; Index +=3D 4= ) { + Sum =3D (UINT8) (Sum + ptr[Index]); + Sum =3D (UINT8) (Sum + ptr[Index + 1]); + Sum =3D (UINT8) (Sum + ptr[Index + 2]); + Sum =3D (UINT8) (Sum + ptr[Index + 3]); + } + + for (; Index < sizeof (EFI_FFS_FILE_HEADER); Index++) { + Sum =3D (UINT8) (Sum + ptr[Index]); + } + // + // State field (since this indicates the different state of file). + // + Sum =3D (UINT8) (Sum - FileHeader->State); + // + // Checksum field of the file is not part of the header checksum. + // + Sum =3D (UINT8) (Sum - FileHeader->IntegrityCheck.Checksum.File); + + return Sum; +} + +/** + Given the input file pointer, search for the next matching file in the + FFS volume as defined by SearchType. The search starts from FileHeader i= nside + the Firmware Volume defined by FwVolHeader. + + @param SearchType Filter to find only files of this type. + Type EFI_FV_FILETYPE_ALL causes no filtering to be d= one. + @param FwVolHeader Pointer to the FV header of the volume to search. + This parameter must point to a valid FFS volume. + @param FileHeader Pointer to the current file from which to begin sear= ching. + This pointer will be updated upon return to reflect = the file found. + + @retval EFI_NOT_FOUND No files matching the search criteria were found + @retval EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +FfsFindNextFile ( + IN EFI_FV_FILETYPE SearchType, + IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader, + IN OUT EFI_FFS_FILE_HEADER **FileHeader + ) +{ + EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader; + + EFI_FFS_FILE_HEADER *FfsFileHeader; + UINT32 FileLength; + UINT32 FileOccupiedSize; + UINT32 FileOffset; + UINT64 FvLength; + UINT8 ErasePolarity; + UINT8 FileState; + + FvLength =3D FwVolHeader->FvLength; + if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) { + ErasePolarity =3D 1; + } else { + ErasePolarity =3D 0; + } + // + // If FileHeader is not specified (NULL) start with the first file in the + // firmware volume. Otherwise, start from the FileHeader. + // + if (*FileHeader =3D=3D NULL) { + + if (FwVolHeader->ExtHeaderOffset !=3D 0) { + + FvExtHeader =3D (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FwVolHea= der + + FwVolHeader->ExtHea= derOffset); + + FfsFileHeader =3D (EFI_FFS_FILE_HEADER *)((UINT8 *)FvExtHeader + + FvExtHeader->ExtHeaderSize); + + } else { + + FfsFileHeader =3D (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + + FwVolHeader->HeaderLength); + + } + + FfsFileHeader =3D (EFI_FFS_FILE_HEADER *)((UINTN)FwVolHeader + + ALIGN_VALUE((UINTN)FfsFileHead= er - + (UINTN)FwVolHeader= , 8)); + } else { + // + // Length is 24 bits wide so mask upper 8 bits + // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned. + // + FileLength =3D FFS_FILE_SIZE(*FileHeader); + FileOccupiedSize =3D GET_OCCUPIED_SIZE (FileLength, 8); + FfsFileHeader =3D (EFI_FFS_FILE_HEADER *) ((UINT8 *) *FileHeader += FileOccupiedSize); + } + + FileOffset =3D (UINT32) ((UINT8 *) FfsFileHeader - (UINT8 *) FwVolHeader= ); + + while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) { + // + // Get FileState which is the highest bit of the State + // + FileState =3D GetFileState (ErasePolarity, FfsFileHeader); + + switch (FileState) { + + case EFI_FILE_HEADER_INVALID: + FileOffset +=3D sizeof (EFI_FFS_FILE_HEADER); + FfsFileHeader =3D (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader += sizeof (EFI_FFS_FILE_HEADER)); + break; + + case EFI_FILE_DATA_VALID: + case EFI_FILE_MARKED_FOR_UPDATE: + if (CalculateHeaderChecksum (FfsFileHeader) =3D=3D 0) { + FileLength =3D FFS_FILE_SIZE(FfsFileHeader); + FileOccupiedSize =3D GET_OCCUPIED_SIZE (FileLength, 8); + + if ((SearchType =3D=3D FfsFileHeader->Type) || (SearchType =3D=3D = EFI_FV_FILETYPE_ALL)) { + + *FileHeader =3D FfsFileHeader; + + return EFI_SUCCESS; + } + + FileOffset +=3D FileOccupiedSize; + FfsFileHeader =3D (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader= + FileOccupiedSize); + } else { + return EFI_NOT_FOUND; + } + break; + + case EFI_FILE_DELETED: + FileLength =3D FFS_FILE_SIZE(FfsFileHeader); + FileOccupiedSize =3D GET_OCCUPIED_SIZE (FileLength, 8); + FileOffset +=3D FileOccupiedSize; + FfsFileHeader =3D (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader += FileOccupiedSize); + break; + + default: + return EFI_NOT_FOUND; + + } + } + + return EFI_NOT_FOUND; +} + +/** + Locates a section within a series of sections + with the specified section type. + + @param[in] Sections The sections to search + @param[in] SizeOfSections Total size of all sections + @param[in] SectionType The section type to locate + @param[out] FoundSection The FFS section if found + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted +**/ +EFI_STATUS +EFIAPI +FindFfsSectionInSections ( + IN VOID *Sections, + IN UINTN SizeOfSections, + IN EFI_SECTION_TYPE SectionType, + OUT EFI_COMMON_SECTION_HEADER **FoundSection + ) +{ + EFI_PHYSICAL_ADDRESS CurrentAddress; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfSections; + EFI_COMMON_SECTION_HEADER *Section; + EFI_PHYSICAL_ADDRESS EndOfSection; + + // + // Loop through the FFS file sections + // + EndOfSection =3D (EFI_PHYSICAL_ADDRESS)(UINTN) Sections; + EndOfSections =3D EndOfSection + SizeOfSections; + for (;;) { + if (EndOfSection =3D=3D EndOfSections) { + break; + } + CurrentAddress =3D EndOfSection; + + Section =3D (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress; + + Size =3D SECTION_SIZE (Section); + if (Size < sizeof (*Section)) { + return EFI_VOLUME_CORRUPTED; + } + + EndOfSection =3D CurrentAddress + Size; + if (EndOfSection > EndOfSections) { + return EFI_VOLUME_CORRUPTED; + } + Size =3D GET_OCCUPIED_SIZE (Size, 4); + + // + // Look for the requested section type + // + if (Section->Type =3D=3D SectionType) { + *FoundSection =3D Section; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +/** + Given the input file pointer, search for the next matching section in the + FFS volume. + + @param SearchType Filter to find only sections of this type. + @param FfsFileHeader Pointer to the current file to search. + @param SectionHeader Pointer to the Section matching SectionType in Ffs= FileHeader. + NULL if section not found + + @retval EFI_NOT_FOUND No files matching the search criteria were found + @retval EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +FfsFindSection ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_FFS_FILE_HEADER *FfsFileHeader, + IN OUT EFI_COMMON_SECTION_HEADER **SectionHeader + ) +{ + UINT32 FileSize; + EFI_COMMON_SECTION_HEADER *Section; + EFI_STATUS Status; + + // + // Size is 24 bits wide so mask upper 8 bits. + // Does not include FfsFileHeader header size + // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned. + // + Section =3D (EFI_COMMON_SECTION_HEADER *) (FfsFileHeader + 1); + FileSize =3D FFS_FILE_SIZE(FfsFileHeader); + FileSize -=3D sizeof (EFI_FFS_FILE_HEADER); + + Status =3D FindFfsSectionInSections ( + Section, + FileSize, + SectionType, + SectionHeader + ); + return Status; +} + +/** + Given the input file pointer, search for the next matching section in the + FFS volume. + + @param SearchType Filter to find only sections of this type. + @param FfsFileHeader Pointer to the current file to search. + @param SectionData Pointer to the Section matching SectionType in F= fsFileHeader. + NULL if section not found + @param SectionDataSize The size of SectionData + + @retval EFI_NOT_FOUND No files matching the search criteria were found + @retval EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +FfsFindSectionData ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_FFS_FILE_HEADER *FfsFileHeader, + IN OUT VOID **SectionData, + IN OUT UINTN *SectionDataSize + ) +{ + UINT32 FileSize; + EFI_COMMON_SECTION_HEADER *Section; + UINT32 SectionLength; + UINT32 ParsedLength; + + // + // Size is 24 bits wide so mask upper 8 bits. + // Does not include FfsFileHeader header size + // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned. + // + Section =3D (EFI_COMMON_SECTION_HEADER *) (FfsFileHeader + 1); + FileSize =3D FFS_FILE_SIZE(FfsFileHeader); + FileSize -=3D sizeof (EFI_FFS_FILE_HEADER); + + *SectionData =3D NULL; + ParsedLength =3D 0; + while (ParsedLength < FileSize) { + if (Section->Type =3D=3D SectionType) { + *SectionData =3D (VOID *) (Section + 1); + *SectionDataSize =3D SECTION_SIZE(Section); + return EFI_SUCCESS; + } + // + // Size is 24 bits wide so mask upper 8 bits. + // SectionLength is adjusted it is 4 byte aligned. + // Go to the next section + // + SectionLength =3D SECTION_SIZE(Section); + SectionLength =3D GET_OCCUPIED_SIZE (SectionLength, 4); + + ParsedLength +=3D SectionLength; + Section =3D (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + Section= Length); + } + + return EFI_NOT_FOUND; +} diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatfor= mLibNull.inf b/StandaloneMmPkg/Library/FvLib/FvLib.inf similarity index 69% copy from IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLi= bNull.inf copy to StandaloneMmPkg/Library/FvLib/FvLib.inf index e1cab05232e3..f768810ee53b 100644 --- a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNul= l.inf +++ b/StandaloneMmPkg/Library/FvLib/FvLib.inf @@ -1,12 +1,12 @@ ## @file -# NULL instance of Platform Sec Lib. # -# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the B= SD License # which accompanies this distribution. The full text of the license may b= e found at -# http://opensource.org/licenses/bsd-license.php. +# 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 IM= PLIED. # @@ -18,12 +18,12 @@ # ##########################################################################= ###### [Defines] - INF_VERSION =3D 0x00010005 - BASE_NAME =3D BaseFspSecPlatformLibNull - FILE_GUID =3D C128CADC-623E-4E41-97CB-A7138E627460 - MODULE_TYPE =3D SEC + INF_VERSION =3D 0x0001001A + BASE_NAME =3D FvLib + FILE_GUID =3D C20085E9-E3AB-4938-A727-C10935FEEE2B + MODULE_TYPE =3D BASE VERSION_STRING =3D 1.0 - LIBRARY_CLASS =3D FspSecPlatformLib + LIBRARY_CLASS =3D FvLib =20 # # The following information is for reference only and not required by the = build tools. @@ -38,11 +38,7 @@ [Defines] ##########################################################################= ###### =20 [Sources] - PlatformSecLibNull.c - -[Sources.IA32] - Ia32/Flat32.nasm - Ia32/SecCarInit.nasm + FvLib.c =20 ##########################################################################= ###### # @@ -53,4 +49,9 @@ [Sources.IA32] =20 [Packages] MdePkg/MdePkg.dec - IntelFsp2Pkg/IntelFsp2Pkg.dec + StandaloneMmPkg/StandaloneMmPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib --=20 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel