public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Star Zeng <star.zeng@intel.com>
To: edk2-devel@lists.01.org
Cc: Star Zeng <star.zeng@intel.com>,
	Liming Gao <liming.gao@intel.com>,
	Jiewen Yao <jiewen.yao@intel.com>
Subject: [PATCH 2/2] MdeModulePkg DxeCore: Handle multiple FV images in one FV file
Date: Wed, 29 Aug 2018 17:37:46 +0800	[thread overview]
Message-ID: <1535535466-62348-3-git-send-email-star.zeng@intel.com> (raw)
In-Reply-To: <1535535466-62348-1-git-send-email-star.zeng@intel.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1131

PI spec and BaseTools supports 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>
---
 MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c | 241 ++++++++++++++------------
 1 file changed, 128 insertions(+), 113 deletions(-)

diff --git a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
index f72c47a9e54c..086a590ef4e3 100644
--- a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
@@ -184,14 +184,13 @@ CoreAddToDriverList (
   );
 
 /**
-  Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.
+  Get Fv image(s) from the FV through file name, and produce FVB protocol for every Fv image(s).
 
   @param  Fv                    The FIRMWARE_VOLUME protocol installed on the FV.
   @param  FvHandle              The handle which FVB protocol installed on.
   @param  DriverName            The driver guid specified.
 
   @retval EFI_OUT_OF_RESOURCES  No enough memory or other resource.
-  @retval EFI_VOLUME_CORRUPTED  Corrupted volume.
   @retval EFI_SUCCESS           Function successfully returned.
 
 **/
@@ -199,7 +198,7 @@ EFI_STATUS
 CoreProcessFvImageFile (
   IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
   IN  EFI_HANDLE                      FvHandle,
-  IN  EFI_GUID                        *DriverName
+  IN  EFI_GUID                        *FileName
   );
 
 
@@ -1004,14 +1003,13 @@ GetFvUsedSize (
 }
 
 /**
-  Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.
+  Get Fv image(s) from the FV through file name, and produce FVB protocol for every Fv image(s).
 
   @param  Fv                    The FIRMWARE_VOLUME protocol installed on the FV.
   @param  FvHandle              The handle which FVB protocol installed on.
   @param  DriverName            The driver guid specified.
 
   @retval EFI_OUT_OF_RESOURCES  No enough memory or other resource.
-  @retval EFI_VOLUME_CORRUPTED  Corrupted volume.
   @retval EFI_SUCCESS           Function successfully returned.
 
 **/
@@ -1019,7 +1017,7 @@ EFI_STATUS
 CoreProcessFvImageFile (
   IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
   IN  EFI_HANDLE                      FvHandle,
-  IN  EFI_GUID                        *DriverName
+  IN  EFI_GUID                        *FileName
   )
 {
   EFI_STATUS                          Status;
@@ -1033,141 +1031,158 @@ CoreProcessFvImageFile (
   EFI_DEVICE_PATH_PROTOCOL            *FvFileDevicePath;
   UINT32                              FvUsedSize;
   UINT8                               EraseByte;
+  UINTN                               Index;
 
   //
-  // Read the first (and only the first) firmware volume section
+  // Read firmware volume section(s)
   //
   SectionType   = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;
-  FvHeader      = NULL;
-  FvAlignment   = 0;
-  Buffer        = NULL;
-  BufferSize    = 0;
-  AlignedBuffer = NULL;
-  Status = Fv->ReadSection (
-                 Fv,
-                 DriverName,
-                 SectionType,
-                 0,
-                 &Buffer,
-                 &BufferSize,
-                 &AuthenticationStatus
-                 );
-  if (!EFI_ERROR (Status)) {
-     //
-    // Evaluate the authentication status of the Firmware Volume through
-    // Security Architectural Protocol
-    //
-    if (gSecurity != NULL) {
-      FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);
-      Status = gSecurity->FileAuthenticationState (
-                            gSecurity,
-                            AuthenticationStatus,
-                            FvFileDevicePath
-                            );
-      if (FvFileDevicePath != NULL) {
-        FreePool (FvFileDevicePath);
-      }
 
-      if (Status != EFI_SUCCESS) {
-        //
-        // Security check failed. The firmware volume should not be used for any purpose.
-        //
-        if (Buffer != NULL) {
-          FreePool (Buffer);
+  Index = 0;
+  do {
+    FvHeader      = NULL;
+    FvAlignment   = 0;
+    Buffer        = NULL;
+    BufferSize    = 0;
+    AlignedBuffer = NULL;
+    Status = Fv->ReadSection (
+                   Fv,
+                   FileName,
+                   SectionType,
+                   Index,
+                   &Buffer,
+                   &BufferSize,
+                   &AuthenticationStatus
+                   );
+    if (!EFI_ERROR (Status)) {
+       //
+      // Evaluate the authentication status of the Firmware Volume through
+      // Security Architectural Protocol
+      //
+      if (gSecurity != NULL) {
+        FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, FileName);
+        Status = gSecurity->FileAuthenticationState (
+                              gSecurity,
+                              AuthenticationStatus,
+                              FvFileDevicePath
+                              );
+        if (FvFileDevicePath != NULL) {
+          FreePool (FvFileDevicePath);
+        }
+
+        if (Status != EFI_SUCCESS) {
+          //
+          // Security check failed. The firmware volume should not be used for any purpose.
+          //
+          if (Buffer != NULL) {
+            FreePool (Buffer);
+          }
+          break;
         }
-        return Status;
       }
-    }
 
-    //
-    // FvImage should be at its required alignment.
-    //
-    FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;
-    //
-    // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
-    // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
-    // its initial linked location and maintain its alignment.
-    //
-    if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {
       //
-      // Get FvHeader alignment
+      // FvImage should be at its required alignment.
       //
-      FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);
+      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;
       //
-      // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
+      // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
+      // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
+      // its initial linked location and maintain its alignment.
       //
-      if (FvAlignment < 8) {
-        FvAlignment = 8;
-      }
+      if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {
+        //
+        // Get FvHeader alignment
+        //
+        FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);
+        //
+        // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
+        //
+        if (FvAlignment < 8) {
+          FvAlignment = 8;
+        }
 
-      DEBUG ((
-        DEBUG_INFO,
-        "%a() FV at 0x%x, FvAlignment required is 0x%x\n",
-        __FUNCTION__,
-        FvHeader,
-        FvAlignment
-        ));
+        DEBUG ((
+          DEBUG_INFO,
+          "%a() FV at 0x%x, FvAlignment required is 0x%x\n",
+          __FUNCTION__,
+          FvHeader,
+          FvAlignment
+          ));
 
-      //
-      // Check FvImage alignment.
-      //
-      if ((UINTN) FvHeader % FvAlignment != 0) {
         //
-        // Allocate the aligned buffer for the FvImage.
+        // Check FvImage alignment.
         //
-        AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);
-        if (AlignedBuffer == NULL) {
-          FreePool (Buffer);
-          return EFI_OUT_OF_RESOURCES;
-        } else {
+        if ((UINTN) FvHeader % FvAlignment != 0) {
           //
-          // Move FvImage into the aligned buffer and release the original buffer.
+          // Allocate the aligned buffer for the FvImage.
           //
-          if (GetFvUsedSize (FvHeader, &FvUsedSize, &EraseByte)) {
+          AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);
+          if (AlignedBuffer == NULL) {
+            FreePool (Buffer);
+            Status = EFI_OUT_OF_RESOURCES;
+            break;
+          } else {
             //
-            // Copy the used bytes and fill the rest with the erase value.
+            // Move FvImage into the aligned buffer and release the original buffer.
             //
-            CopyMem (AlignedBuffer, FvHeader, (UINTN) FvUsedSize);
-            SetMem (
-              (UINT8 *) AlignedBuffer + FvUsedSize,
-              (UINTN) (BufferSize - FvUsedSize),
-              EraseByte
-              );
-          } else {
-            CopyMem (AlignedBuffer, Buffer, BufferSize);
+            if (GetFvUsedSize (FvHeader, &FvUsedSize, &EraseByte)) {
+              //
+              // Copy the used bytes and fill the rest with the erase value.
+              //
+              CopyMem (AlignedBuffer, FvHeader, (UINTN) FvUsedSize);
+              SetMem (
+                (UINT8 *) AlignedBuffer + FvUsedSize,
+                (UINTN) (BufferSize - FvUsedSize),
+                EraseByte
+                );
+            } else {
+              CopyMem (AlignedBuffer, Buffer, BufferSize);
+            }
+            FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) AlignedBuffer;
+            FreePool (Buffer);
+            Buffer = NULL;
           }
-          FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) AlignedBuffer;
-          CoreFreePool (Buffer);
-          Buffer = NULL;
         }
       }
+      //
+      // Produce a FVB protocol for the file
+      //
+      Status = ProduceFVBProtocolOnBuffer (
+                (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,
+                (UINT64)BufferSize,
+                FvHandle,
+                AuthenticationStatus,
+                NULL
+                );
     }
-    //
-    // Produce a FVB protocol for the file
-    //
-    Status = ProduceFVBProtocolOnBuffer (
-              (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,
-              (UINT64)BufferSize,
-              FvHandle,
-              AuthenticationStatus,
-              NULL
-              );
-  }
 
-  if (EFI_ERROR (Status)) {
-    //
-    // ReadSection or Produce FVB failed, Free data buffer
-    //
-    if (Buffer != NULL) {
-      FreePool (Buffer);
-    }
+    if (EFI_ERROR (Status)) {
+      //
+      // ReadSection or Produce FVB failed, Free data buffer
+      //
+      if (Buffer != NULL) {
+        FreePool (Buffer);
+      }
+
+      if (AlignedBuffer != NULL) {
+        FreeAlignedPages (AlignedBuffer, EFI_SIZE_TO_PAGES (BufferSize));
+      }
 
-    if (AlignedBuffer != NULL) {
-      FreeAlignedPages (AlignedBuffer, EFI_SIZE_TO_PAGES (BufferSize));
+      break;
+    } else {
+      Index++;
     }
-  }
+  } while (TRUE);
 
-  return Status;
+  if (Index > 0) {
+    //
+    // At least one FvImage has been processed successfully.
+    //
+    return EFI_SUCCESS;
+  } else {
+    return Status;
+  }
 }
 
 
-- 
2.7.0.windows.1



  parent reply	other threads:[~2018-08-29  9:37 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-29  9:37 [PATCH 0/2] Core: Handle multiple FV images in one FV file Star Zeng
2018-08-29  9:37 ` [PATCH 1/2] MdeModulePkg PeiCore: " Star Zeng
2018-08-30 10:02   ` Gao, Liming
2018-08-29  9:37 ` Star Zeng [this message]
2018-08-30  9:54   ` [PATCH 2/2] MdeModulePkg DxeCore: " Gao, Liming
2018-08-30  9:59     ` Zeng, Star

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1535535466-62348-3-git-send-email-star.zeng@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox