]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg PeiCore: Handle multiple FV images in one FV file
authorStar Zeng <star.zeng@intel.com>
Wed, 29 Aug 2018 03:08:09 +0000 (11:08 +0800)
committerStar Zeng <star.zeng@intel.com>
Mon, 3 Sep 2018 09:04:57 +0000 (17:04 +0800)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1131

PI spec and BaseTools support to generate multiple FV images
in one FV file.
This patch is to update PeiCore to handle the case.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
MdeModulePkg/Core/Pei/FwVol/FwVol.c
MdeModulePkg/Core/Pei/PeiMain.h

index 65c485549718430eb50253adfe52d4790cd4fc20..7ea503a10fb5009bd298eba6aff8fd96c8124b11 100644 (file)
@@ -1358,7 +1358,7 @@ GetFvUsedSize (
 }\r
 \r
 /**\r
-  Get Fv image from the FV type file, then install FV INFO(2) ppi, Build FV hob.\r
+  Get Fv image(s) from the FV type file, then install FV INFO(2) ppi, Build FV(2, 3) hob.\r
 \r
   @param PrivateData          PeiCore's private data structure\r
   @param ParentFvCoreHandle   Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image.\r
@@ -1391,6 +1391,7 @@ ProcessFvFile (
   UINT32                        AuthenticationStatus;\r
   UINT32                        FvUsedSize;\r
   UINT8                         EraseByte;\r
+  UINTN                         Index;\r
 \r
   //\r
   // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already\r
@@ -1412,144 +1413,164 @@ ProcessFvFile (
   ParentFvPpi    = ParentFvCoreHandle->FvPpi;\r
 \r
   //\r
-  // Find FvImage in FvFile\r
+  // Find FvImage(s) in FvFile\r
   //\r
-  AuthenticationStatus = 0;\r
-  if ((ParentFvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&\r
-      (ParentFvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION)) {\r
-    Status = ParentFvPpi->FindSectionByType2 (\r
-                            ParentFvPpi,\r
-                            EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
-                            0,\r
-                            ParentFvFileHandle,\r
-                            (VOID **)&FvHeader,\r
-                            &AuthenticationStatus\r
-                            );\r
-  } else {\r
-    Status = ParentFvPpi->FindSectionByType (\r
-                            ParentFvPpi,\r
-                            EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
-                            ParentFvFileHandle,\r
-                            (VOID **)&FvHeader\r
-                            );\r
-  }\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = VerifyPeim (PrivateData, ParentFvHandle, ParentFvFileHandle, AuthenticationStatus);\r
-  if (Status == EFI_SECURITY_VIOLATION) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume\r
-  // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from\r
-  // its initial linked location and maintain its alignment.\r
-  //\r
-  if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {\r
-    //\r
-    // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.\r
-    //\r
-    FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);\r
-    if (FvAlignment < 8) {\r
-      FvAlignment = 8;\r
+  Index = 0;\r
+  do {\r
+    AuthenticationStatus = 0;\r
+    if ((ParentFvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&\r
+        (ParentFvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION)) {\r
+      Status = ParentFvPpi->FindSectionByType2 (\r
+                              ParentFvPpi,\r
+                              EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
+                              Index,\r
+                              ParentFvFileHandle,\r
+                              (VOID **)&FvHeader,\r
+                              &AuthenticationStatus\r
+                              );\r
+    } else {\r
+      //\r
+      // Old FvPpi has no parameter to input SearchInstance,\r
+      // only one instance is supported.\r
+      //\r
+      if (Index > 0) {\r
+        break;\r
+      }\r
+      Status = ParentFvPpi->FindSectionByType (\r
+                              ParentFvPpi,\r
+                              EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
+                              ParentFvFileHandle,\r
+                              (VOID **)&FvHeader\r
+                              );\r
+    }\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
     }\r
 \r
-    DEBUG ((\r
-      DEBUG_INFO,\r
-      "%a() FV at 0x%x, FvAlignment required is 0x%x\n",\r
-      __FUNCTION__,\r
-      FvHeader,\r
-      FvAlignment\r
-      ));\r
+    Status = VerifyPeim (PrivateData, ParentFvHandle, ParentFvFileHandle, AuthenticationStatus);\r
+    if (Status == EFI_SECURITY_VIOLATION) {\r
+      break;\r
+    }\r
 \r
     //\r
-    // Check FvImage alignment.\r
+    // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume\r
+    // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from\r
+    // its initial linked location and maintain its alignment.\r
     //\r
-    if ((UINTN) FvHeader % FvAlignment != 0) {\r
-      FvLength    = ReadUnaligned64 (&FvHeader->FvLength);\r
-      NewFvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvLength), FvAlignment);\r
-      if (NewFvBuffer == NULL) {\r
-        return EFI_OUT_OF_RESOURCES;\r
+    if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {\r
+      //\r
+      // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.\r
+      //\r
+      FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);\r
+      if (FvAlignment < 8) {\r
+        FvAlignment = 8;\r
       }\r
-      if (GetFvUsedSize (FvHeader, &FvUsedSize, &EraseByte)) {\r
-        //\r
-        // Copy the used bytes and fill the rest with the erase value.\r
-        //\r
-        CopyMem (NewFvBuffer, FvHeader, (UINTN) FvUsedSize);\r
-        SetMem (\r
-          (UINT8 *) NewFvBuffer + FvUsedSize,\r
-          (UINTN) (FvLength - FvUsedSize),\r
-          EraseByte\r
-          );\r
-      } else {\r
-        CopyMem (NewFvBuffer, FvHeader, (UINTN) FvLength);\r
+\r
+      DEBUG ((\r
+        DEBUG_INFO,\r
+        "%a() FV at 0x%x, FvAlignment required is 0x%x\n",\r
+        __FUNCTION__,\r
+        FvHeader,\r
+        FvAlignment\r
+        ));\r
+\r
+      //\r
+      // Check FvImage alignment.\r
+      //\r
+      if ((UINTN) FvHeader % FvAlignment != 0) {\r
+        FvLength    = ReadUnaligned64 (&FvHeader->FvLength);\r
+        NewFvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvLength), FvAlignment);\r
+        if (NewFvBuffer == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          break;\r
+        }\r
+        if (GetFvUsedSize (FvHeader, &FvUsedSize, &EraseByte)) {\r
+          //\r
+          // Copy the used bytes and fill the rest with the erase value.\r
+          //\r
+          CopyMem (NewFvBuffer, FvHeader, (UINTN) FvUsedSize);\r
+          SetMem (\r
+            (UINT8 *) NewFvBuffer + FvUsedSize,\r
+            (UINTN) (FvLength - FvUsedSize),\r
+            EraseByte\r
+            );\r
+        } else {\r
+          CopyMem (NewFvBuffer, FvHeader, (UINTN) FvLength);\r
+        }\r
+        FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) NewFvBuffer;\r
       }\r
-      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) NewFvBuffer;\r
     }\r
-  }\r
 \r
-  Status = ParentFvPpi->GetVolumeInfo (ParentFvPpi, ParentFvHandle, &ParentFvImageInfo);\r
-  ASSERT_EFI_ERROR (Status);\r
+    Status = ParentFvPpi->GetVolumeInfo (ParentFvPpi, ParentFvHandle, &ParentFvImageInfo);\r
+    ASSERT_EFI_ERROR (Status);\r
 \r
-  Status = ParentFvPpi->GetFileInfo (ParentFvPpi, ParentFvFileHandle, &FileInfo);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Install FvInfo(2) Ppi\r
-  // NOTE: FvInfo2 must be installed before FvInfo so that recursive processing of encapsulated\r
-  // FVs inherit the proper AuthenticationStatus.\r
-  //\r
-  PeiServicesInstallFvInfo2Ppi(\r
-    &FvHeader->FileSystemGuid,\r
-    (VOID**)FvHeader,\r
-    (UINT32)FvHeader->FvLength,\r
-    &ParentFvImageInfo.FvName,\r
-    &FileInfo.FileName,\r
-    AuthenticationStatus\r
-    );\r
+    Status = ParentFvPpi->GetFileInfo (ParentFvPpi, ParentFvFileHandle, &FileInfo);\r
+    ASSERT_EFI_ERROR (Status);\r
 \r
-  PeiServicesInstallFvInfoPpi (\r
-    &FvHeader->FileSystemGuid,\r
-    (VOID**) FvHeader,\r
-    (UINT32) FvHeader->FvLength,\r
-    &ParentFvImageInfo.FvName,\r
-    &FileInfo.FileName\r
-    );\r
+    //\r
+    // Install FvInfo(2) Ppi\r
+    // NOTE: FvInfo2 must be installed before FvInfo so that recursive processing of encapsulated\r
+    // FVs inherit the proper AuthenticationStatus.\r
+    //\r
+    PeiServicesInstallFvInfo2Ppi(\r
+      &FvHeader->FileSystemGuid,\r
+      (VOID**)FvHeader,\r
+      (UINT32)FvHeader->FvLength,\r
+      &ParentFvImageInfo.FvName,\r
+      &FileInfo.FileName,\r
+      AuthenticationStatus\r
+      );\r
+\r
+    PeiServicesInstallFvInfoPpi (\r
+      &FvHeader->FileSystemGuid,\r
+      (VOID**) FvHeader,\r
+      (UINT32) FvHeader->FvLength,\r
+      &ParentFvImageInfo.FvName,\r
+      &FileInfo.FileName\r
+      );\r
 \r
-  //\r
-  // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase\r
-  //\r
-  BuildFvHob (\r
-    (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
-    FvHeader->FvLength\r
-    );\r
+    //\r
+    // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase\r
+    //\r
+    BuildFvHob (\r
+      (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
+      FvHeader->FvLength\r
+      );\r
 \r
-  //\r
-  // Makes the encapsulated volume show up in DXE phase to skip processing of\r
-  // encapsulated file again.\r
-  //\r
-  BuildFv2Hob (\r
-    (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
-    FvHeader->FvLength,\r
-    &ParentFvImageInfo.FvName,\r
-    &FileInfo.FileName\r
-    );\r
+    //\r
+    // Makes the encapsulated volume show up in DXE phase to skip processing of\r
+    // encapsulated file again.\r
+    //\r
+    BuildFv2Hob (\r
+      (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
+      FvHeader->FvLength,\r
+      &ParentFvImageInfo.FvName,\r
+      &FileInfo.FileName\r
+      );\r
 \r
-  //\r
-  // Build FV3 HOB with authentication status to be propagated to DXE.\r
-  //\r
-  BuildFv3Hob (\r
-    (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
-    FvHeader->FvLength,\r
-    AuthenticationStatus,\r
-    TRUE,\r
-    &ParentFvImageInfo.FvName,\r
-    &FileInfo.FileName\r
-    );\r
+    //\r
+    // Build FV3 HOB with authentication status to be propagated to DXE.\r
+    //\r
+    BuildFv3Hob (\r
+      (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
+      FvHeader->FvLength,\r
+      AuthenticationStatus,\r
+      TRUE,\r
+      &ParentFvImageInfo.FvName,\r
+      &FileInfo.FileName\r
+      );\r
+\r
+    Index++;\r
+  } while (TRUE);\r
 \r
-  return EFI_SUCCESS;\r
+  if (Index > 0) {\r
+    //\r
+    // At least one FvImage has been processed successfully.\r
+    //\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    return Status;\r
+  }\r
 }\r
 \r
 /**\r
index e2f8cd9c775841213b6ec98ed8beb0da802ae2ba..6469436b8f79319d7df802541b394029fd930201 100644 (file)
@@ -1258,7 +1258,7 @@ SecurityPpiNotifyCallback (
   );\r
 \r
 /**\r
-  Get Fv image from the FV type file, then install FV INFO(2) ppi, Build FV hob.\r
+  Get Fv image(s) from the FV type file, then install FV INFO(2) ppi, Build FV(2, 3) hob.\r
 \r
   @param PrivateData          PeiCore's private data structure\r
   @param ParentFvCoreHandle   Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image.\r