]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg DxeCore: Handle multiple FV images in one FV file
authorStar Zeng <star.zeng@intel.com>
Wed, 29 Aug 2018 03:08:25 +0000 (11:08 +0800)
committerStar Zeng <star.zeng@intel.com>
Mon, 3 Sep 2018 09:04:58 +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 DxeCore 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/Dxe/Dispatcher/Dispatcher.c

index f72c47a9e54ccb6d5f2a35d32305d56ddcf16453..2f6286944fe52591e9fc8b85e14d408ad9329808 100644 (file)
@@ -184,14 +184,13 @@ CoreAddToDriverList (
   );\r
 \r
 /**\r
-  Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.\r
+  Get Fv image(s) from the FV through file name, and produce FVB protocol for every Fv image(s).\r
 \r
   @param  Fv                    The FIRMWARE_VOLUME protocol installed on the FV.\r
   @param  FvHandle              The handle which FVB protocol installed on.\r
-  @param  DriverName            The driver guid specified.\r
+  @param  FileName              The file name guid specified.\r
 \r
   @retval EFI_OUT_OF_RESOURCES  No enough memory or other resource.\r
-  @retval EFI_VOLUME_CORRUPTED  Corrupted volume.\r
   @retval EFI_SUCCESS           Function successfully returned.\r
 \r
 **/\r
@@ -199,7 +198,7 @@ EFI_STATUS
 CoreProcessFvImageFile (\r
   IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
   IN  EFI_HANDLE                      FvHandle,\r
-  IN  EFI_GUID                        *DriverName\r
+  IN  EFI_GUID                        *FileName\r
   );\r
 \r
 \r
@@ -1004,14 +1003,13 @@ GetFvUsedSize (
 }\r
 \r
 /**\r
-  Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.\r
+  Get Fv image(s) from the FV through file name, and produce FVB protocol for every Fv image(s).\r
 \r
   @param  Fv                    The FIRMWARE_VOLUME protocol installed on the FV.\r
   @param  FvHandle              The handle which FVB protocol installed on.\r
-  @param  DriverName            The driver guid specified.\r
+  @param  FileName              The file name guid specified.\r
 \r
   @retval EFI_OUT_OF_RESOURCES  No enough memory or other resource.\r
-  @retval EFI_VOLUME_CORRUPTED  Corrupted volume.\r
   @retval EFI_SUCCESS           Function successfully returned.\r
 \r
 **/\r
@@ -1019,7 +1017,7 @@ EFI_STATUS
 CoreProcessFvImageFile (\r
   IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
   IN  EFI_HANDLE                      FvHandle,\r
-  IN  EFI_GUID                        *DriverName\r
+  IN  EFI_GUID                        *FileName\r
   )\r
 {\r
   EFI_STATUS                          Status;\r
@@ -1033,141 +1031,158 @@ CoreProcessFvImageFile (
   EFI_DEVICE_PATH_PROTOCOL            *FvFileDevicePath;\r
   UINT32                              FvUsedSize;\r
   UINT8                               EraseByte;\r
+  UINTN                               Index;\r
 \r
   //\r
-  // Read the first (and only the first) firmware volume section\r
+  // Read firmware volume section(s)\r
   //\r
   SectionType   = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;\r
-  FvHeader      = NULL;\r
-  FvAlignment   = 0;\r
-  Buffer        = NULL;\r
-  BufferSize    = 0;\r
-  AlignedBuffer = NULL;\r
-  Status = Fv->ReadSection (\r
-                 Fv,\r
-                 DriverName,\r
-                 SectionType,\r
-                 0,\r
-                 &Buffer,\r
-                 &BufferSize,\r
-                 &AuthenticationStatus\r
-                 );\r
-  if (!EFI_ERROR (Status)) {\r
-     //\r
-    // Evaluate the authentication status of the Firmware Volume through\r
-    // Security Architectural Protocol\r
-    //\r
-    if (gSecurity != NULL) {\r
-      FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);\r
-      Status = gSecurity->FileAuthenticationState (\r
-                            gSecurity,\r
-                            AuthenticationStatus,\r
-                            FvFileDevicePath\r
-                            );\r
-      if (FvFileDevicePath != NULL) {\r
-        FreePool (FvFileDevicePath);\r
-      }\r
 \r
-      if (Status != EFI_SUCCESS) {\r
-        //\r
-        // Security check failed. The firmware volume should not be used for any purpose.\r
-        //\r
-        if (Buffer != NULL) {\r
-          FreePool (Buffer);\r
+  Index = 0;\r
+  do {\r
+    FvHeader      = NULL;\r
+    FvAlignment   = 0;\r
+    Buffer        = NULL;\r
+    BufferSize    = 0;\r
+    AlignedBuffer = NULL;\r
+    Status = Fv->ReadSection (\r
+                   Fv,\r
+                   FileName,\r
+                   SectionType,\r
+                   Index,\r
+                   &Buffer,\r
+                   &BufferSize,\r
+                   &AuthenticationStatus\r
+                   );\r
+    if (!EFI_ERROR (Status)) {\r
+       //\r
+      // Evaluate the authentication status of the Firmware Volume through\r
+      // Security Architectural Protocol\r
+      //\r
+      if (gSecurity != NULL) {\r
+        FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, FileName);\r
+        Status = gSecurity->FileAuthenticationState (\r
+                              gSecurity,\r
+                              AuthenticationStatus,\r
+                              FvFileDevicePath\r
+                              );\r
+        if (FvFileDevicePath != NULL) {\r
+          FreePool (FvFileDevicePath);\r
+        }\r
+\r
+        if (Status != EFI_SUCCESS) {\r
+          //\r
+          // Security check failed. The firmware volume should not be used for any purpose.\r
+          //\r
+          if (Buffer != NULL) {\r
+            FreePool (Buffer);\r
+          }\r
+          break;\r
         }\r
-        return Status;\r
       }\r
-    }\r
 \r
-    //\r
-    // FvImage should be at its required alignment.\r
-    //\r
-    FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;\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
-      // Get FvHeader alignment\r
+      // FvImage should be at its required alignment.\r
       //\r
-      FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);\r
+      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;\r
       //\r
-      // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.\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 (FvAlignment < 8) {\r
-        FvAlignment = 8;\r
-      }\r
+      if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {\r
+        //\r
+        // Get FvHeader alignment\r
+        //\r
+        FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);\r
+        //\r
+        // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.\r
+        //\r
+        if (FvAlignment < 8) {\r
+          FvAlignment = 8;\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
+        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
         //\r
-        // Allocate the aligned buffer for the FvImage.\r
+        // Check FvImage alignment.\r
         //\r
-        AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);\r
-        if (AlignedBuffer == NULL) {\r
-          FreePool (Buffer);\r
-          return EFI_OUT_OF_RESOURCES;\r
-        } else {\r
+        if ((UINTN) FvHeader % FvAlignment != 0) {\r
           //\r
-          // Move FvImage into the aligned buffer and release the original buffer.\r
+          // Allocate the aligned buffer for the FvImage.\r
           //\r
-          if (GetFvUsedSize (FvHeader, &FvUsedSize, &EraseByte)) {\r
+          AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);\r
+          if (AlignedBuffer == NULL) {\r
+            FreePool (Buffer);\r
+            Status = EFI_OUT_OF_RESOURCES;\r
+            break;\r
+          } else {\r
             //\r
-            // Copy the used bytes and fill the rest with the erase value.\r
+            // Move FvImage into the aligned buffer and release the original buffer.\r
             //\r
-            CopyMem (AlignedBuffer, FvHeader, (UINTN) FvUsedSize);\r
-            SetMem (\r
-              (UINT8 *) AlignedBuffer + FvUsedSize,\r
-              (UINTN) (BufferSize - FvUsedSize),\r
-              EraseByte\r
-              );\r
-          } else {\r
-            CopyMem (AlignedBuffer, Buffer, BufferSize);\r
+            if (GetFvUsedSize (FvHeader, &FvUsedSize, &EraseByte)) {\r
+              //\r
+              // Copy the used bytes and fill the rest with the erase value.\r
+              //\r
+              CopyMem (AlignedBuffer, FvHeader, (UINTN) FvUsedSize);\r
+              SetMem (\r
+                (UINT8 *) AlignedBuffer + FvUsedSize,\r
+                (UINTN) (BufferSize - FvUsedSize),\r
+                EraseByte\r
+                );\r
+            } else {\r
+              CopyMem (AlignedBuffer, Buffer, BufferSize);\r
+            }\r
+            FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) AlignedBuffer;\r
+            FreePool (Buffer);\r
+            Buffer = NULL;\r
           }\r
-          FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) AlignedBuffer;\r
-          CoreFreePool (Buffer);\r
-          Buffer = NULL;\r
         }\r
       }\r
+      //\r
+      // Produce a FVB protocol for the file\r
+      //\r
+      Status = ProduceFVBProtocolOnBuffer (\r
+                (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
+                (UINT64)BufferSize,\r
+                FvHandle,\r
+                AuthenticationStatus,\r
+                NULL\r
+                );\r
     }\r
-    //\r
-    // Produce a FVB protocol for the file\r
-    //\r
-    Status = ProduceFVBProtocolOnBuffer (\r
-              (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
-              (UINT64)BufferSize,\r
-              FvHandle,\r
-              AuthenticationStatus,\r
-              NULL\r
-              );\r
-  }\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // ReadSection or Produce FVB failed, Free data buffer\r
-    //\r
-    if (Buffer != NULL) {\r
-      FreePool (Buffer);\r
-    }\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // ReadSection or Produce FVB failed, Free data buffer\r
+      //\r
+      if (Buffer != NULL) {\r
+        FreePool (Buffer);\r
+      }\r
+\r
+      if (AlignedBuffer != NULL) {\r
+        FreeAlignedPages (AlignedBuffer, EFI_SIZE_TO_PAGES (BufferSize));\r
+      }\r
 \r
-    if (AlignedBuffer != NULL) {\r
-      FreeAlignedPages (AlignedBuffer, EFI_SIZE_TO_PAGES (BufferSize));\r
+      break;\r
+    } else {\r
+      Index++;\r
     }\r
-  }\r
+  } while (TRUE);\r
 \r
-  return Status;\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