[edk2-devel] [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2

GregX Yeh posted 1 patch 3 years, 5 months ago
Failed in applying to current master (apply log)
There is a newer version of this series
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(-)
[edk2-devel] [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2
Posted by GregX Yeh 3 years, 5 months ago
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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#66913): https://edk2.groups.io/g/devel/message/66913
Mute This Topic: https://groups.io/mt/78000880/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2
Posted by Bob Feng 3 years, 5 months ago
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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#66920): https://edk2.groups.io/g/devel/message/66920
Mute This Topic: https://groups.io/mt/78000880/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2
Posted by GregX Yeh 3 years, 5 months ago
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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#66951): https://edk2.groups.io/g/devel/message/66951
Mute This Topic: https://groups.io/mt/78000880/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2
Posted by Bob Feng 3 years, 5 months ago
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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67220): https://edk2.groups.io/g/devel/message/67220
Mute This Topic: https://groups.io/mt/78000880/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-