]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StandaloneMmPkg/Core/FwVol.c
StandaloneMmPkg/Core: permit encapsulated firmware volumes
[mirror_edk2.git] / StandaloneMmPkg / Core / FwVol.c
index 5abf98c247973bed684b09c5baf233750c1e2042..d95491f252f9e5abec567e404d98390d41740085 100644 (file)
@@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "StandaloneMmCore.h"\r
 #include <Library/FvLib.h>\r
+#include <Library/ExtractGuidedSectionLib.h>\r
 \r
 //\r
 // List of file types supported by dispatcher\r
@@ -65,15 +66,25 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_STATUS          Status;\r
-  EFI_STATUS          DepexStatus;\r
-  EFI_FFS_FILE_HEADER *FileHeader;\r
-  EFI_FV_FILETYPE     FileType;\r
-  VOID                *Pe32Data;\r
-  UINTN               Pe32DataSize;\r
-  VOID                *Depex;\r
-  UINTN               DepexSize;\r
-  UINTN               Index;\r
+  EFI_STATUS                              Status;\r
+  EFI_STATUS                              DepexStatus;\r
+  EFI_FFS_FILE_HEADER                     *FileHeader;\r
+  EFI_FV_FILETYPE                         FileType;\r
+  VOID                                    *Pe32Data;\r
+  UINTN                                   Pe32DataSize;\r
+  VOID                                    *Depex;\r
+  UINTN                                   DepexSize;\r
+  UINTN                                   Index;\r
+  EFI_COMMON_SECTION_HEADER               *Section;\r
+  VOID                                    *SectionData;\r
+  UINTN                                   SectionDataSize;\r
+  UINT32                                  DstBufferSize;\r
+  VOID                                    *ScratchBuffer;\r
+  UINT32                                  ScratchBufferSize;\r
+  VOID                                    *DstBuffer;\r
+  UINT16                                  SectionAttribute;\r
+  UINT32                                  AuthenticationStatus;\r
+  EFI_FIRMWARE_VOLUME_HEADER              *InnerFvHeader;\r
 \r
   DEBUG ((DEBUG_INFO, "MmCoreFfsFindMmDriver - 0x%x\n", FwVolHeader));\r
 \r
@@ -83,6 +94,71 @@ Returns:
 \r
   FvIsBeingProcesssed (FwVolHeader);\r
 \r
+  //\r
+  // First check for encapsulated compressed firmware volumes\r
+  //\r
+  FileHeader = NULL;\r
+  do {\r
+    Status = FfsFindNextFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
+               FwVolHeader, &FileHeader);\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+    Status = FfsFindSectionData (EFI_SECTION_GUID_DEFINED, FileHeader,\r
+               &SectionData, &SectionDataSize);\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+    Section = (EFI_COMMON_SECTION_HEADER *)(FileHeader + 1);\r
+    Status = ExtractGuidedSectionGetInfo (Section, &DstBufferSize,\r
+               &ScratchBufferSize, &SectionAttribute);\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Allocate scratch buffer\r
+    //\r
+    ScratchBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
+    if (ScratchBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    //\r
+    // Allocate destination buffer, extra one page for adjustment\r
+    //\r
+    DstBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+    if (DstBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    //\r
+    // Call decompress function\r
+    //\r
+    Status = ExtractGuidedSectionDecode (Section, &DstBuffer, ScratchBuffer,\r
+                &AuthenticationStatus);\r
+    FreePages (ScratchBuffer, EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
+    if (EFI_ERROR (Status)) {\r
+      goto FreeDstBuffer;\r
+    }\r
+\r
+    DEBUG ((DEBUG_INFO,\r
+      "Processing compressed firmware volume (AuthenticationStatus == %x)\n",\r
+      AuthenticationStatus));\r
+\r
+    Status = FindFfsSectionInSections (DstBuffer, DstBufferSize,\r
+               EFI_SECTION_FIRMWARE_VOLUME_IMAGE, &Section);\r
+    if (EFI_ERROR (Status)) {\r
+      goto FreeDstBuffer;\r
+    }\r
+\r
+    InnerFvHeader = (VOID *)(Section + 1);\r
+    Status = MmCoreFfsFindMmDriver (InnerFvHeader);\r
+    if (EFI_ERROR (Status)) {\r
+      goto FreeDstBuffer;\r
+    }\r
+  } while (TRUE);\r
+\r
   for (Index = 0; Index < sizeof (mMmFileTypes) / sizeof (mMmFileTypes[0]); Index++) {\r
     DEBUG ((DEBUG_INFO, "Check MmFileTypes - 0x%x\n", mMmFileTypes[Index]));\r
     FileType = mMmFileTypes[Index];\r
@@ -100,5 +176,10 @@ Returns:
     } while (!EFI_ERROR (Status));\r
   }\r
 \r
+  return EFI_SUCCESS;\r
+\r
+FreeDstBuffer:\r
+  FreePages (DstBuffer, EFI_SIZE_TO_PAGES (DstBufferSize));\r
+\r
   return Status;\r
 }\r