From: "GregX Yeh" <gregx.yeh@intel.com>
To: "Feng, Bob C" <bob.c.feng@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Subject: Re: [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2
Date: Wed, 4 Nov 2020 02:06:46 +0000 [thread overview]
Message-ID: <BYAPR11MB336832EA6BCD993491E7C9DDFAEF0@BYAPR11MB3368.namprd11.prod.outlook.com> (raw)
In-Reply-To: <DM6PR11MB4073D991E248EF3FA6459DEFC9110@DM6PR11MB4073.namprd11.prod.outlook.com>
Hi Bob,
This problem can be reproduced on APL. We want to replace new BT FW by FMMT.
BT FW is located at FV level 3
FvOptional (level1)
|--FvCnvUnCompact(Level2)
|--FvBlueToothDxeUnCompact(level3)
|--BT FW
We can replace BT FW successfully when BT FW at FV level 2.
But fail when BT FW at FV level 3.
Thanks!
Greg
-----Original Message-----
From: Feng, Bob C <bob.c.feng@intel.com>
Sent: Tuesday, November 3, 2020 5:10 PM
To: Yeh, GregX <gregx.yeh@intel.com>; devel@edk2.groups.io
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Subject: RE: [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2
Hi Greg,
Could you provide more details about problems that this patch fix? It would be great if you can share the test case.
FMMT tool is in the edk2-staging repo, so the patch title for FMMT should add [edk2-staging] tag.
Thanks,
Bob
-----Original Message-----
From: Yeh, GregX <gregx.yeh@intel.com>
Sent: Tuesday, November 3, 2020 1:47 PM
To: devel@edk2.groups.io
Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>
Subject: [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2
Fixed replace file failure when FFS in multi level FV and FV level over 2.
Signed-off-by: GregX Yeh <gregx.yeh@intel.com>
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
---
BaseTools/Source/C/FMMT/FirmwareModuleManagement.c | 2 +-
BaseTools/Source/C/FMMT/FirmwareModuleManagement.h | 3 +-
BaseTools/Source/C/FMMT/FmmtLib.c | 171 ++++++++++++++-------
3 files changed, 118 insertions(+), 58 deletions(-)
diff --git a/BaseTools/Source/C/FMMT/FirmwareModuleManagement.c b/BaseTools/Source/C/FMMT/FirmwareModuleManagement.c
index 38056153fb..dfad02838b 100644
--- a/BaseTools/Source/C/FMMT/FirmwareModuleManagement.c
+++ b/BaseTools/Source/C/FMMT/FirmwareModuleManagement.c
@@ -615,7 +615,7 @@ static UINT32 FindFile(FV_INFORMATION *FvInFd, UINT8 FvLevel, CHAR8 *File, UINT3
return 0;
}
LibAscii2Unicode(File, UIName);
- for (Index = 0; Index <= FvInFd->FfsNumbers; Index++) {
+ for (Index = 0; Index < FvInFd->FfsNumbers; Index++) {
//
// Compare the New File Name with UI Name of FFS
// NOTE: The UI Name is Unicode, but the New File Name is Ascii.
diff --git a/BaseTools/Source/C/FMMT/FirmwareModuleManagement.h b/BaseTools/Source/C/FMMT/FirmwareModuleManagement.h
index 9d09c9160a..da9eb1a4b9 100644
--- a/BaseTools/Source/C/FMMT/FirmwareModuleManagement.h
+++ b/BaseTools/Source/C/FMMT/FirmwareModuleManagement.h
@@ -2,7 +2,7 @@
Structures and functions declaration.
- Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -284,6 +284,7 @@ typedef struct _FFS_INFOMATION{
UINT8 *Depex;
UINT32 DepexLen;
BOOLEAN FfsFoundFlag;
+ UINT8 FvLevel;
struct _FFS_INFOMATION *Next;
} FFS_INFORMATION;
diff --git a/BaseTools/Source/C/FMMT/FmmtLib.c b/BaseTools/Source/C/FMMT/FmmtLib.c
index b945e9b63d..9bccd634bb 100644
--- a/BaseTools/Source/C/FMMT/FmmtLib.c
+++ b/BaseTools/Source/C/FMMT/FmmtLib.c
@@ -523,7 +523,7 @@ LibReadFvHeader (
FvExtHeader->FvName.Data4[6],
FvExtHeader->FvName.Data4[7]);
LibExtractFvUiName(FvExtHeader, &FvUiName);
- if (FvUiName != NULL && FvLevel == 1) {
+ if (FvUiName != NULL && (FvLevel - 1) != 0) {
printf("%sFV UI Name: %s\n\n", BlankSpace, FvUiName);
}
free(FvUiName);
@@ -709,10 +709,10 @@ LibGenFfsFile (
free(FfsFileName);
FfsFileName = NULL;
- CurrentFv->FfsNumbers = *FfsCount;
-
*FfsCount += 1;
+ CurrentFv->FfsNumbers = *FfsCount;
+
if (ErasePolarity) {
CurrentFile->State = (UINT8)~(CurrentFile->State);
}
@@ -789,7 +789,8 @@ LibParseSection (
UINT8 *FvCount,
BOOLEAN ViewFlag,
BOOLEAN ErasePolarity,
- BOOLEAN *IsFfsGenerated
+ BOOLEAN *IsFfsGenerated,
+ UINT32 *FfsIndex
)
{
UINT32 ParsedLength;
@@ -1147,19 +1148,21 @@ LibParseSection (
return EFI_SECTION_ERROR;
}
- Status = LibParseSection ( UncompressedBuffer,
- UncompressedLength,
- CurrentFv,
- FvName,
- CurrentFile,
- Level,
- &LocalEncapData,
- FfsLevel,
- FfsCount,
- FvCount,
- ViewFlag,
- ErasePolarity,
- IsFfsGenerated);
+ Status = LibParseSection (UncompressedBuffer,
+ UncompressedLength,
+ CurrentFv,
+ FvName,
+ CurrentFile,
+ Level,
+ &LocalEncapData,
+ FfsLevel,
+ FfsCount,
+ FvCount,
+ ViewFlag,
+ ErasePolarity,
+ IsFfsGenerated,
+ FfsIndex
+ );
if (CompressionType == EFI_STANDARD_COMPRESSION) {
//
@@ -1216,7 +1219,8 @@ LibParseSection (
FvCount,
ViewFlag,
ErasePolarity,
- IsFfsGenerated
+ IsFfsGenerated,
+ FfsIndex
);
if (EFI_ERROR(Status)) {
Error(NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL); @@ -1471,7 +1475,8 @@ LibParseSection (
FvCount,
ViewFlag,
ErasePolarity,
- IsFfsGenerated
+ IsFfsGenerated,
+ FfsIndex
);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL); @@ -1491,7 +1496,8 @@ LibParseSection (
FvCount,
ViewFlag,
ErasePolarity,
- IsFfsGenerated
+ IsFfsGenerated,
+ FfsIndex
);
if (ExtractionTool != NULL) {
free (ExtractionTool);
@@ -1527,6 +1533,7 @@ LibParseSection (
if (!*IsFfsGenerated) {
LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
*IsFfsGenerated = TRUE;
+ *FfsIndex = *FfsCount;
}
}
@@ -1538,6 +1545,7 @@ LibParseSection (
if (!*IsFfsGenerated) {
LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
*IsFfsGenerated = TRUE;
+ *FfsIndex = *FfsCount;
}
}
@@ -1549,6 +1557,7 @@ LibParseSection (
if (!*IsFfsGenerated) {
LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
*IsFfsGenerated = TRUE;
+ *FfsIndex = *FfsCount;
}
}
@@ -1560,6 +1569,7 @@ LibParseSection (
if (!*IsFfsGenerated) {
LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
*IsFfsGenerated = TRUE;
+ *FfsIndex = *FfsCount;
}
}
break;
@@ -1571,6 +1581,7 @@ LibParseSection (
if (!*IsFfsGenerated) {
LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
*IsFfsGenerated = TRUE;
+ *FfsIndex = *FfsCount;
}
}
break;
@@ -1582,6 +1593,7 @@ LibParseSection (
if (!*IsFfsGenerated) {
LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
*IsFfsGenerated = TRUE;
+ *FfsIndex = *FfsCount;
}
}
break;
@@ -1665,11 +1677,11 @@ LibParseSection (
// If Ffs file has been generated, then the FfsCount should decrease 1.
//
if (*IsFfsGenerated) {
- memcpy (CurrentFv->FfsAttuibutes[*FfsCount -1].UiName, UIName, UINameSize);
- CurrentFv->FfsAttuibutes[*FfsCount -1].UiNameSize = UINameSize;
+ memcpy (CurrentFv->FfsAttuibutes[*FfsIndex - 1].UiName, UIName, UINameSize);
+ CurrentFv->FfsAttuibutes[*FfsIndex - 1].UiNameSize =
+ UINameSize;
} else {
- memcpy (CurrentFv->FfsAttuibutes[*FfsCount].UiName, UIName, UINameSize);
- CurrentFv->FfsAttuibutes[*FfsCount].UiNameSize = UINameSize;
+ memcpy (CurrentFv->FfsAttuibutes[*FfsIndex].UiName, UIName, UINameSize);
+ CurrentFv->FfsAttuibutes[*FfsIndex].UiNameSize = UINameSize;
}
HasDepexSection = FALSE;
@@ -1682,7 +1694,9 @@ LibParseSection (
}
ParsedLength += SectionLength;
- FirstInFlag = FALSE;
+ if (Type != EFI_SECTION_PEI_DEPEX && Type != EFI_SECTION_DXE_DEPEX) {
+ FirstInFlag = FALSE;
+ }
//
// We make then next section begin on a 4-byte boundary
//
@@ -1872,12 +1886,14 @@ LibGetFileInfo (
BOOLEAN IsGeneratedFfs;
UINT32 FfsFileHeaderSize;
CHAR8 *BlankChar;
+ UINT32 FfsIndex;
Status = EFI_SUCCESS;
LocalEncapData = NULL;
EncapDataNeedUpdateFlag = TRUE;
IsGeneratedFfs = FALSE;
+ FfsIndex = 0xFFFFFFFF;
BlankChar = NULL;
FfsFileHeaderSize = GetFfsHeaderLength ((EFI_FFS_FILE_HEADER *) CurrentFile); @@ -2083,24 +2099,25 @@ LibGetFileInfo (
} else if( CurrentFile->Type == EFI_FV_FILETYPE_FFS_PAD){
//EFI_FV_FILETYPE_FFS_PAD
} else {
- //
- // All other files have sections
- //
- Status = LibParseSection (
- (UINT8 *) ((UINTN) CurrentFile + FfsFileHeaderSize),
- FileLength - FfsFileHeaderSize,
- CurrentFv,
- FvName,
- CurrentFile,
- Level,
- &LocalEncapData,
- Level,
- FfsCount,
- FvCount,
- ViewFlag,
- ErasePolarity,
- &IsGeneratedFfs
- );
+ //
+ // All other files have sections
+ //
+ Status = LibParseSection (
+ (UINT8 *) ((UINTN) CurrentFile + FfsFileHeaderSize),
+ FileLength - FfsFileHeaderSize,
+ CurrentFv,
+ FvName,
+ CurrentFile,
+ Level,
+ &LocalEncapData,
+ Level,
+ FfsCount,
+ FvCount,
+ ViewFlag,
+ ErasePolarity,
+ &IsGeneratedFfs,
+ &FfsIndex
+ );
}
if (EFI_ERROR (Status)) {
printf ("ERROR: Parsing the FFS file.\n"); @@ -2144,6 +2161,7 @@ LibGetFvInfo (
EFI_FIRMWARE_VOLUME_EXT_HEADER *ExtHdrPtr;
EFI_FIRMWARE_VOLUME_HEADER *FvHdr;
UINT8 PreFvId;
+ UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];
NumberOfFiles = 0;
Key = 0;
@@ -2344,9 +2362,10 @@ LibGetFvInfo (
CurrentFv->FfsAttuibutes[*FfsCount].FvLevel = CurrentFv->FvLevel;
CurrentFv->FfsAttuibutes[*FfsCount].FvId = PreFvId;
- if (CurrentFv->FvLevel > CurrentFv->MulFvLevel) {
+ if (CurrentFv->FvLevel > CurrentFv->MulFvLevel) {
CurrentFv->MulFvLevel = CurrentFv->FvLevel;
- }
+ }
+ PrintGuidToBuffer (&(CurrentFile->Name), GuidBuffer,
+ PRINTED_GUID_BUFFER_SIZE, FALSE);
//
// Display info about this file
//
@@ -4198,10 +4217,13 @@ LibEncapNewFvFile(
UINT32 header;
UINT8 AlignN;
UINT8 AlignV[1] = {0xFF};
+ UINT32 EntryFvId;
+
AlignN = 0;
Id = 0;
InputFileSize = 0;
TmpFileSize = 0;
+ AlignmentFileSize = 0;
EncapFvIndex = 0;
Index = 0;
OuterIndex = 0;
@@ -4224,7 +4246,7 @@ LibEncapNewFvFile(
IsLargeFile = FALSE;
OutputFileSize = 0;
LargeFileSize = 0x1000000;
-
+ EntryFvId = 0;
OutputFileNameList = (FFS_INFORMATION *)malloc(sizeof(FFS_INFORMATION));
if (OutputFileNameList == NULL) {
@@ -4240,6 +4262,7 @@ LibEncapNewFvFile(
OutputFileNameList->Depex = NULL;
OutputFileNameList->DepexLen = 0;
OutputFileNameList->FfsFoundFlag = FALSE;
+ OutputFileNameList->FvLevel = 0;
ChildFileNameList = (FFS_INFORMATION *)malloc(sizeof(FFS_INFORMATION));
if (ChildFileNameList == NULL) {
@@ -4258,12 +4281,16 @@ LibEncapNewFvFile(
//
// Encapsulate from the lowest FFS file level.
//
- LocalEncapData = CurrentEncapData;
- if (LocalEncapData == NULL) {
- LocalEncapData = FvInFd->EncapData;
- }
- Level = LocalEncapData->Level;
- Type = LocalEncapData->Type;
+ LocalEncapData = CurrentEncapData;
+ if (LocalEncapData == NULL) {
+ LocalEncapData = FvInFd->EncapData;
+ EntryFvId = 0xFFFFFFFF;
+ } else {
+ EntryFvId = LocalEncapData->FvId;
+ }
+
+ Level = LocalEncapData->Level;
+ Type = LocalEncapData->Type;
if (CurrentEncapData == NULL) {
LocalEncapData = FvInFd->EncapData; @@ -4278,6 +4305,7 @@ LibEncapNewFvFile(
ChildFileNameList->ParentLevel = LocalEncapDataTemp->Level -1;
if (FvInFd->ChildFvFFS == NULL) {
FvInFd->ChildFvFFS = ChildFileNameList;
+ NewFileNameList = FvInFd->ChildFvFFS;
} else {
NewFileNameList = FvInFd->ChildFvFFS;
while (NewFileNameList->Next != NULL) { @@ -4325,6 +4353,12 @@ LibEncapNewFvFile(
Type = LocalEncapData->Type;
}
LocalEncapData = LocalEncapData->NextNode;
+ if (LocalEncapData == NULL) {
+ if (Type == FMMT_ENCAP_TREE_FV) {
+ ParentLevel = Level;
+ ParentType = Type;
+ }
+ }
}
} else {
LocalEncapData = CurrentEncapData;
@@ -4349,6 +4383,28 @@ LibEncapNewFvFile(
LocalEncapDataTemp = LocalEncapDataTemp->RightNode;
}
}
+
+ if (LocalEncapData->FvId > EntryFvId && LocalEncapData->Type == FMMT_ENCAP_TREE_FFS) {
+ LocalEncapDataTemp = LocalEncapData->RightNode;
+
+ while (LocalEncapDataTemp != NULL) {
+ LocalEncapDataNext = LocalEncapDataTemp->NextNode;
+ if (LocalEncapDataNext != NULL && LocalEncapDataNext->NextNode != NULL) {
+ LibEncapNewFvFile(FvInFd, TemDir, LocalEncapDataTemp, LocalEncapDataTemp->Level - 1, &ChildFileNameList);
+ if (FvInFd->ChildFvFFS == NULL) {
+ FvInFd->ChildFvFFS = ChildFileNameList;
+ } else {
+ NewFileNameList = FvInFd->ChildFvFFS;
+ while (NewFileNameList->Next != NULL) {
+ NewFileNameList = NewFileNameList->Next;
+ }
+ NewFileNameList->Next = ChildFileNameList;
+ }
+ }
+ LocalEncapDataTemp = LocalEncapDataTemp->RightNode;
+ }
+ }
+
if (LocalEncapData->Level > Level) {
if (LocalEncapData->Type == FMMT_ENCAP_TREE_FFS) {
ParentLevel = Level;
@@ -4485,12 +4541,12 @@ LibEncapNewFvFile(
//
FfsFoundFlag = FALSE;
IsRootFv = FALSE;
- for (Index=0; Index <= FvInFd->FfsNumbers; Index++) {
+ for (Index=0; Index < FvInFd->FfsNumbers; Index++) {
if (OutputFileNameList != NULL && OutputFileNameList->FFSName != NULL && OutputFileNameList->IsFFS == FALSE){
break;
}
if (OutputFileNameList != NULL && OutputFileNameList->FFSName != NULL && OutputFileNameList->IsFFS == TRUE){
- if (Index == EncapFvIndex) {
+ if (Index == EncapFvStart) {
if (FirstInFlag) {
Status = LibAddFfsFileToFvInf (OutputFileNameList->FFSName, InfFile, TRUE);
FirstInFlag = FALSE; @@ -4601,7 +4657,7 @@ LibEncapNewFvFile(
}
}
// The Fv may has multiple level (> 2), when it is in the FvLevel == 2, we set the IsLastLevelFfs Flag
- if (Index <=FvInFd->FfsNumbers && FvInFd->FfsAttuibutes[Index].FvLevel <= FvInFd->MulFvLevel) {
+ if (Index < FvInFd->FfsNumbers &&
+ FvInFd->FfsAttuibutes[Index].FvLevel <= FvInFd->MulFvLevel) {
if (FvInFd->FfsAttuibutes[Index].FvLevel == 2) {
IsLastLevelFfs = FALSE;
}
@@ -4777,6 +4833,7 @@ LibEncapNewFvFile(
for (Id = FvInFd->FfsNumbers; Id <= FvInFd->FfsNumbers; Id--) {
if ((memcmp(&FvInFd->FfsAttuibutes[Id].GuidName, &(LocalEncapData->FvExtHeader->FvName), sizeof(EFI_GUID)) == 0)){
if (access(FvInFd->FfsAttuibutes[Id].FfsName, 0) != -1) {
+ OutputFileNameList->FvLevel =
+ FvInFd->FfsAttuibutes[Id].FvLevel;
Status = LibFmmtDeleteFile(FvInFd->FfsAttuibutes[Id].FfsName);
if (EFI_ERROR(Status)) {
Error("FMMT", 0, 0004, "error while encapsulate FD Image", "Delete the specified file failed!"); @@ -5079,7 +5136,9 @@ LibEncapNewFvFile(
} else {
if (OutputFileNameList != NULL && OutputFileNameList->FFSName != NULL && OutputFileNameList->IsFFS == TRUE) {
*OutputFile = OutputFileNameList;
- return EFI_SUCCESS;
+ if (OutputFileNameList->FvLevel < 2) {
+ return EFI_SUCCESS;
+ }
}
LocalEncapData = CurrentEncapData;
}
--
2.16.2.windows.1
next prev parent reply other threads:[~2020-11-04 2:08 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-03 5:47 [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2 GregX Yeh
2020-11-03 9:09 ` Bob Feng
2020-11-04 2:06 ` GregX Yeh [this message]
2020-11-10 9:43 ` Bob Feng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=BYAPR11MB336832EA6BCD993491E7C9DDFAEF0@BYAPR11MB3368.namprd11.prod.outlook.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox