public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2
@ 2020-11-03  5:47 GregX Yeh
  2020-11-03  9:09 ` Bob Feng
  0 siblings, 1 reply; 4+ messages in thread
From: GregX Yeh @ 2020-11-03  5:47 UTC (permalink / raw)
  To: devel; +Cc: Bob Feng, Liming Gao

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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2
  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
  0 siblings, 1 reply; 4+ messages in thread
From: Bob Feng @ 2020-11-03  9:09 UTC (permalink / raw)
  To: Yeh, GregX, devel@edk2.groups.io; +Cc: Liming Gao

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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2
  2020-11-03  9:09 ` Bob Feng
@ 2020-11-04  2:06   ` GregX Yeh
  2020-11-10  9:43     ` Bob Feng
  0 siblings, 1 reply; 4+ messages in thread
From: GregX Yeh @ 2020-11-04  2:06 UTC (permalink / raw)
  To: Feng, Bob C, devel@edk2.groups.io; +Cc: Liming Gao

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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2
  2020-11-04  2:06   ` GregX Yeh
@ 2020-11-10  9:43     ` Bob Feng
  0 siblings, 0 replies; 4+ messages in thread
From: Bob Feng @ 2020-11-10  9:43 UTC (permalink / raw)
  To: Yeh, GregX, devel@edk2.groups.io; +Cc: Liming Gao, fengyunhua

Greg,

I found there is a regression issue after applying this patch. It happens when the FMMT delete a ffs file from an FV which is in a multiple level FV layout image.

Thanks,
Bob

-----Original Message-----
From: Yeh, GregX <gregx.yeh@intel.com> 
Sent: Wednesday, November 4, 2020 10:07 AM
To: Feng, Bob C <bob.c.feng@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 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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-11-10  9:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
2020-11-10  9:43     ` Bob Feng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox