]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c
Cache FvImage at buffer with its required alignment.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / SectionExtraction / CoreSectionExtraction.c
index 70c71c6db409303147bad1d55713eb453dbc7f2c..67dd803861d7ba8e73f5b04e566283ca0fd83569 100644 (file)
@@ -214,7 +214,7 @@ IsValidSectionStream (
   );\r
 \r
 EFI_STATUS\r
-CustomDecompressExtractSection (\r
+CustomGuidedSectionExtract (\r
   IN CONST  EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This,\r
   IN CONST  VOID                                   *InputSection,\r
   OUT       VOID                                   **OutputBuffer,\r
@@ -234,8 +234,8 @@ EFI_SECTION_EXTRACTION_PROTOCOL mSectionExtraction = {
   CloseSectionStream\r
 };\r
 \r
-EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL mCustomDecompressExtraction = {\r
-  CustomDecompressExtractSection\r
+EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL mCustomGuidedSectionExtractionProtocol = {\r
+  CustomGuidedSectionExtract\r
 };\r
                                              \r
 EFI_STATUS\r
@@ -261,8 +261,8 @@ Returns:
 --*/\r
 {\r
   EFI_STATUS                         Status;\r
-  EFI_GUID                           **DecompressGuidList;\r
-  UINTN                              DecompressMethodNumber;\r
+  EFI_GUID                           *ExtractHandlerGuidTable;\r
+  UINTN                              ExtractHandlerNumber;\r
 \r
   //\r
   // Install SEP to a new handle\r
@@ -276,32 +276,22 @@ Returns:
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
-  // Get custom decompress method guid list \r
+  // Get custom extract guided section method guid list \r
   //\r
-  DecompressGuidList     = NULL;\r
-  DecompressMethodNumber = 0;\r
-  Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);\r
-  if (Status == EFI_OUT_OF_RESOURCES) {\r
-    DecompressGuidList = (EFI_GUID **) CoreAllocateBootServicesPool (DecompressMethodNumber * sizeof (EFI_GUID *));\r
-    ASSERT (DecompressGuidList != NULL);\r
-    Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);\r
-  }\r
-  ASSERT_EFI_ERROR(Status);\r
+  ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);\r
 \r
   //\r
-  // Install custom decompress guided extraction protocol \r
+  // Install custom guided extraction protocol \r
   //\r
-  while (DecompressMethodNumber-- > 0) {\r
+  while (ExtractHandlerNumber-- > 0) {\r
     Status = CoreInstallProtocolInterface (\r
               &mSectionExtractionHandle,\r
-              DecompressGuidList [DecompressMethodNumber],\r
+              &ExtractHandlerGuidTable [ExtractHandlerNumber],\r
               EFI_NATIVE_INTERFACE,\r
-              &mCustomDecompressExtraction\r
+              &mCustomGuidedSectionExtractionProtocol\r
               );\r
     ASSERT_EFI_ERROR (Status);\r
   }\r
-  \r
-  CoreFreePool (DecompressGuidList);\r
 \r
   return Status;\r
 }\r
@@ -422,11 +412,14 @@ Returns:
   UINTN                                                 Instance;\r
   UINT8                                                 *CopyBuffer;\r
   UINTN                                                 SectionSize;\r
+  EFI_FIRMWARE_VOLUME_HEADER                            *FvHeader;\r
+  UINT32                                                FvAlignment;  \r
+  \r
   \r
-\r
   OldTpl = CoreRaiseTpl (TPL_NOTIFY);\r
   Instance = SectionInstance + 1;\r
-  \r
+  FvHeader = NULL;\r
+  FvAlignment = 0;\r
   //\r
   // Locate target stream\r
   //\r
@@ -479,8 +472,19 @@ Returns:
   } else {\r
     //\r
     // Callee allocated buffer.  Allocate buffer and return size.\r
+    // For FvImage, the buffer is allocated at its required alignment.\r
     //\r
-    *Buffer = CoreAllocateBootServicesPool (CopySize);\r
+    if (*SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
+      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) CopyBuffer;\r
+      FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
+      //\r
+      // FvAlignment must be more than 8 bytes required by FvHeader structure.\r
+      // \r
+      if (FvAlignment < 8) {\r
+        FvAlignment = 8;\r
+      }\r
+    }\r
+    *Buffer = AllocateAlignedPool ((UINTN) CopySize, (UINTN) FvAlignment);\r
     if (*Buffer == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto GetSection_Done;\r
@@ -1464,7 +1468,7 @@ Returns:
 \r
 **/\r
 EFI_STATUS\r
-CustomDecompressExtractSection (\r
+CustomGuidedSectionExtract (\r
   IN CONST  EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This,\r
   IN CONST  VOID                                   *InputSection,\r
   OUT       VOID                                   **OutputBuffer,\r
@@ -1473,77 +1477,97 @@ CustomDecompressExtractSection (
   )\r
 {\r
   EFI_STATUS      Status;\r
-  UINT8           *ScratchBuffer;\r
-  UINT32          DestinationSize;\r
-  UINT32          ScratchSize;\r
-  UINT32          SectionLength;  \r
+  VOID            *ScratchBuffer;\r
+  VOID            *AllocatedOutputBuffer;\r
+  UINT32          OutputBufferSize;\r
+  UINT32          ScratchBufferSize;\r
+  UINT16          SectionAttribute;\r
   \r
   //\r
-  // Set authentic value to zero.\r
-  //\r
-  *AuthenticationStatus = 0;\r
+  // Init local variable\r
   //\r
-  // Calculate Section data Size\r
-  //\r
-  SectionLength   = *(UINT32 *) (((EFI_COMMON_SECTION_HEADER *) InputSection)->Size) & 0x00ffffff;\r
+  ScratchBuffer         = NULL;\r
+  AllocatedOutputBuffer = NULL;\r
+\r
   //\r
-  // Get compressed data information\r
+  // Call GetInfo to get the size and attribute of input guided section data.\r
   //\r
-  Status = CustomDecompressGetInfo (\r
-             (GUID *) ((UINT8 *) InputSection + sizeof (EFI_COMMON_SECTION_HEADER)),\r
-             (UINT8 *) InputSection + sizeof (EFI_GUID_DEFINED_SECTION),\r
-             SectionLength - sizeof (EFI_GUID_DEFINED_SECTION),\r
-             &DestinationSize,\r
-             &ScratchSize\r
-             );\r
+  Status = ExtractGuidedSectionGetInfo (\r
+            InputSection,\r
+            &OutputBufferSize,\r
+            &ScratchBufferSize,\r
+            &SectionAttribute\r
+           );\r
+  \r
   if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "GetInfo from guided section Failed - %r\n", Status));\r
+    return Status;\r
+  }\r
+  \r
+  if (ScratchBufferSize != 0) {\r
     //\r
-    // GetInfo failed\r
+    // Allocate scratch buffer\r
     //\r
-    DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));\r
-    return Status;\r
+    ScratchBuffer = CoreAllocateBootServicesPool (ScratchBufferSize);\r
+    if (ScratchBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
   }\r
 \r
-  //\r
-  // Allocate scratch buffer\r
-  //\r
-  ScratchBuffer = CoreAllocateBootServicesPool (ScratchSize);\r
-  if (ScratchBuffer == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  //\r
-  // Allocate destination buffer\r
-  //\r
-  *OutputSize = (UINTN) DestinationSize;\r
-  *OutputBuffer = CoreAllocateBootServicesPool (*OutputSize);\r
-  if (*OutputBuffer == NULL) {\r
-    CoreFreePool (ScratchBuffer);\r
-    return EFI_OUT_OF_RESOURCES;\r
+  if (OutputBufferSize > 0) {  \r
+    //\r
+    // Allocate output buffer\r
+    //\r
+    AllocatedOutputBuffer = CoreAllocateBootServicesPool (OutputBufferSize);\r
+    if (AllocatedOutputBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    *OutputBuffer = AllocatedOutputBuffer;\r
   }\r
 \r
   //\r
-  // Call decompress function\r
+  // Call decode function to extract raw data from the guided section.\r
   //\r
-  Status = CustomDecompress (\r
-             (GUID *) ((UINT8 *) InputSection + sizeof (EFI_COMMON_SECTION_HEADER)),\r
-             (UINT8 *) InputSection + sizeof (EFI_GUID_DEFINED_SECTION),\r
-             *OutputBuffer,\r
-             ScratchBuffer\r
-             );\r
+  Status = ExtractGuidedSectionDecode (\r
+             InputSection, \r
+             OutputBuffer,\r
+             ScratchBuffer,\r
+             AuthenticationStatus\r
+           );\r
   if (EFI_ERROR (Status)) {\r
     //\r
-    // Decompress failed\r
+    // Decode failed\r
     //\r
-    CoreFreePool (ScratchBuffer);\r
-    CoreFreePool (*OutputBuffer);\r
+    if (AllocatedOutputBuffer != NULL) {\r
+      CoreFreePool (AllocatedOutputBuffer);\r
+    }\r
+    if (ScratchBuffer != NULL) {\r
+      CoreFreePool (ScratchBuffer);\r
+    }\r
     DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));\r
     return Status;\r
   }\r
-  \r
+\r
+  if (*OutputBuffer != AllocatedOutputBuffer) {\r
+    //\r
+    // OutputBuffer was returned as a different value, \r
+    // so copy section contents to the allocated memory buffer.\r
+    // \r
+    CopyMem (AllocatedOutputBuffer, *OutputBuffer, OutputBufferSize);\r
+    *OutputBuffer = AllocatedOutputBuffer;\r
+  }\r
+\r
+  //\r
+  // Set real size of output buffer.\r
+  //\r
+  *OutputSize = (UINTN) OutputBufferSize;\r
+\r
   //\r
   // Free unused scratch buffer.\r
   //\r
-  CoreFreePool (ScratchBuffer);\r
-  \r
+  if (ScratchBuffer != NULL) {\r
+    CoreFreePool (ScratchBuffer);\r
+  }\r
+\r
   return EFI_SUCCESS;\r
-}
\ No newline at end of file
+}\r