]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Core/DxeIplPeim/DxeLoad.c
Remove autogen.h from all dxs files, because autogen.h file has been included by...
[mirror_edk2.git] / EdkModulePkg / Core / DxeIplPeim / DxeLoad.c
index 8e1aeedac261b4ae56bb736e9ebffaa817cb4c9c..1133f6286074afa8d88cc1eaff040176316d0176 100644 (file)
@@ -20,7 +20,7 @@ Abstract:
 \r
 --*/\r
 \r
-#include <DxeIpl.h>\r
+#include "DxeIpl.h"\r
 \r
 BOOLEAN gInMemory = FALSE;\r
 \r
@@ -36,22 +36,17 @@ static EFI_PEI_FV_FILE_LOADER_PPI mLoadFilePpi = {
   DxeIplLoadFile\r
 };\r
 \r
-static EFI_PEI_PPI_DESCRIPTOR     mPpiLoadFile = {\r
-  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+static EFI_PEI_PPI_DESCRIPTOR     mPpiList[] = {\r
+  {\r
+  EFI_PEI_PPI_DESCRIPTOR_PPI,\r
   &gEfiPeiFvFileLoaderPpiGuid,\r
   &mLoadFilePpi\r
-};\r
-\r
-static EFI_PEI_PPI_DESCRIPTOR     mPpiList = {\r
+  },\r
+  {\r
   (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
   &gEfiDxeIplPpiGuid,\r
   &mDxeIplPpi\r
-};\r
-\r
-static EFI_PEI_PPI_DESCRIPTOR     mPpiPeiInMemory = {\r
-  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
-  &gPeiInMemoryGuid,\r
-  NULL\r
+  }\r
 };\r
 \r
 static EFI_PEI_PPI_DESCRIPTOR     mPpiSignal = {\r
@@ -60,38 +55,21 @@ static EFI_PEI_PPI_DESCRIPTOR     mPpiSignal = {
   NULL\r
 };\r
 \r
-DECOMPRESS_LIBRARY  gEfiDecompress = {\r
+GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY  gEfiDecompress = {\r
   UefiDecompressGetInfo,\r
   UefiDecompress\r
 };\r
 \r
-DECOMPRESS_LIBRARY  gTianoDecompress = {\r
+GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY  gTianoDecompress = {\r
   TianoDecompressGetInfo,\r
   TianoDecompress\r
 };\r
 \r
-DECOMPRESS_LIBRARY  gCustomDecompress = {\r
+GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY  gCustomDecompress = {\r
   CustomDecompressGetInfo,\r
   CustomDecompress\r
 };\r
 \r
-STATIC\r
-UINTN\r
-GetOccupiedSize (\r
-  IN UINTN   ActualSize,\r
-  IN UINTN   Alignment\r
-  )\r
-{\r
-  UINTN OccupiedSize;\r
-\r
-  OccupiedSize = ActualSize;\r
-  while ((OccupiedSize & (Alignment - 1)) != 0) {\r
-    OccupiedSize++;\r
-  }\r
-\r
-  return OccupiedSize;\r
-}\r
-\r
 EFI_STATUS\r
 EFIAPI\r
 PeimInitializeDxeIpl (\r
@@ -120,17 +98,9 @@ Returns:
   EFI_BOOT_MODE                             BootMode;\r
 \r
   Status = PeiServicesGetBootMode (&BootMode);\r
-\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  Status = PeiServicesLocatePpi (\r
-             &gPeiInMemoryGuid,\r
-             0,\r
-             NULL,\r
-             NULL\r
-             );\r
-\r
-  if (EFI_ERROR (Status) && (BootMode != BOOT_ON_S3_RESUME)) {\r
+  if (!gInMemory && (BootMode != BOOT_ON_S3_RESUME)) {   \r
     //\r
     // The DxeIpl has not yet been shadowed\r
     //\r
@@ -140,38 +110,15 @@ Returns:
     // Shadow DxeIpl and then re-run its entry point\r
     //\r
     Status = ShadowDxeIpl (FfsHeader, PeiEfiPeiPeCoffLoader);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
   } else {\r
-    if (BootMode != BOOT_ON_S3_RESUME) {\r
-    //\r
-    // The DxeIpl has been shadowed\r
     //\r
-    gInMemory = TRUE;\r
-\r
-    //\r
-    // Install LoadFile PPI\r
+    // Install FvFileLoader and DxeIpl PPIs.\r
     //\r
-    Status = PeiServicesInstallPpi (&mPpiLoadFile);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-      }\r
-    }\r
-    //\r
-    // Install DxeIpl PPI\r
-    //\r
-    PeiServicesInstallPpi (&mPpiList);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
+    Status = PeiServicesInstallPpi (mPpiList);\r
+    ASSERT_EFI_ERROR(Status);\r
   }\r
-\r
-  return EFI_SUCCESS;\r
+  \r
+  return Status;\r
 }\r
 \r
 EFI_STATUS\r
@@ -200,12 +147,10 @@ Returns:
 --*/\r
 {\r
   EFI_STATUS                                Status;\r
-  VOID                                      *TopOfStack;\r
-  VOID                                      *BaseOfStack;\r
-  EFI_PHYSICAL_ADDRESS                      BspStore;\r
   EFI_GUID                                  DxeCoreFileName;\r
   EFI_GUID                                  FirmwareFileName;\r
   VOID                                      *Pe32Data;\r
+  VOID                                      *FvImageData;     \r
   EFI_PHYSICAL_ADDRESS                      DxeCoreAddress;\r
   UINT64                                    DxeCoreSize;\r
   EFI_PHYSICAL_ADDRESS                      DxeCoreEntryPoint;\r
@@ -215,101 +160,25 @@ Returns:
   EFI_PEI_S3_RESUME_PPI                     *S3Resume;\r
 \r
 //  PERF_START (PeiServices, L"DxeIpl", NULL, 0);\r
-  TopOfStack  = NULL;\r
-  BaseOfStack = NULL;\r
-  BspStore    = 0;\r
-  Status      = EFI_SUCCESS;\r
 \r
   //\r
   // if in S3 Resume, restore configure\r
   //\r
   Status = PeiServicesGetBootMode (&BootMode);\r
+  ASSERT_EFI_ERROR(Status);\r
 \r
-  if (!EFI_ERROR (Status) && (BootMode == BOOT_ON_S3_RESUME)) {\r
+  if (BootMode == BOOT_ON_S3_RESUME) {\r
     Status = PeiServicesLocatePpi (\r
                &gEfiPeiS3ResumePpiGuid,\r
                0,\r
                NULL,\r
                (VOID **)&S3Resume\r
                );\r
-\r
     ASSERT_EFI_ERROR (Status);\r
 \r
     Status = S3Resume->S3RestoreConfig (PeiServices);\r
-\r
     ASSERT_EFI_ERROR (Status);\r
-  }\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  //\r
-  // Install the PEI Protocols that are shared between PEI and DXE\r
-  //\r
-  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();\r
-  ASSERT (PeiEfiPeiPeCoffLoader != NULL);\r
-\r
-\r
-  //\r
-  // Allocate 128KB for the Stack\r
-  //\r
-  BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));\r
-  ASSERT (BaseOfStack != NULL);\r
-\r
-  //\r
-  // Compute the top of the stack we were allocated. Pre-allocate a UINTN\r
-  // for safety.\r
-  //\r
-  TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - sizeof (UINTN));\r
-\r
-  //\r
-  // Add architecture-specifc HOBs (including the BspStore HOB)\r
-  //\r
-  Status = CreateArchSpecificHobs (&BspStore);\r
-\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Add HOB for the EFI Decompress Protocol\r
-  //\r
-  BuildGuidDataHob (\r
-    &gEfiDecompressProtocolGuid,\r
-    (VOID *)&gEfiDecompress,\r
-    sizeof (gEfiDecompress)\r
-    );\r
-\r
-  //\r
-  // Add HOB for the Tiano Decompress Protocol\r
-  //\r
-  BuildGuidDataHob (\r
-    &gEfiTianoDecompressProtocolGuid,\r
-    (VOID *)&gTianoDecompress,\r
-    sizeof (gTianoDecompress)\r
-    );\r
-\r
-  //\r
-  // Add HOB for the user customized Decompress Protocol\r
-  //\r
-  BuildGuidDataHob (\r
-    &gEfiCustomizedDecompressProtocolGuid,\r
-    (VOID *)&gCustomDecompress,\r
-    sizeof (gCustomDecompress)\r
-    );\r
-\r
-  //\r
-  // Add HOB for the PE/COFF Loader Protocol\r
-  //\r
-  BuildGuidDataHob (\r
-    &gEfiPeiPeCoffLoaderGuid,\r
-    (VOID *)&PeiEfiPeiPeCoffLoader,\r
-    sizeof (VOID *)\r
-    );\r
-\r
-  //\r
-  // See if we are in crisis recovery\r
-  //\r
-  Status = PeiServicesGetBootMode (&BootMode);\r
-\r
-  if (!EFI_ERROR (Status) && (BootMode == BOOT_IN_RECOVERY_MODE)) {\r
+  } else if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
 \r
     Status = PeiServicesLocatePpi (\r
                &gEfiPeiRecoveryModulePpiGuid,\r
@@ -317,8 +186,8 @@ Returns:
                NULL,\r
                (VOID **)&PeiRecovery\r
                );\r
-\r
     ASSERT_EFI_ERROR (Status);\r
+\r
     Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);\r
     if (EFI_ERROR (Status)) {\r
       DEBUG ((EFI_D_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));\r
@@ -331,19 +200,23 @@ Returns:
   }\r
 \r
   //\r
-  // Find the EFI_FV_FILETYPE_RAW type compressed Firmware Volume file in FTW spare block\r
+  // Install the PEI Protocols that are shared between PEI and DXE\r
+  //\r
+  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();\r
+  ASSERT (PeiEfiPeiPeCoffLoader != NULL);\r
+\r
+\r
+  //\r
+  // Find the EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE type compressed Firmware Volume file\r
   // The file found will be processed by PeiProcessFile: It will first be decompressed to\r
-  // a normal FV, then a corresponding FV type hob will be built which is provided for DXE\r
-  // core to find and dispatch drivers in this FV. Because PeiProcessFile typically checks\r
-  // for EFI_FV_FILETYPE_DXE_CORE type file, in this condition we need not check returned\r
-  // status\r
+  // a normal FV, then a corresponding FV type hob will be built. \r
   //\r
   Status = PeiFindFile (\r
-            EFI_FV_FILETYPE_RAW,\r
-            EFI_SECTION_PE32,\r
-            &FirmwareFileName,\r
-            &Pe32Data\r
-            );\r
+             EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
+             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
+             &FirmwareFileName,\r
+             &FvImageData\r
+             );\r
 \r
   //\r
   // Find the DXE Core in a Firmware Volume\r
@@ -354,29 +227,18 @@ Returns:
             &DxeCoreFileName,\r
             &Pe32Data\r
             );\r
-\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
   // Load the DXE Core from a Firmware Volume\r
   //\r
   Status = PeiLoadFile (\r
-            PeiEfiPeiPeCoffLoader,\r
-            Pe32Data,\r
-            &DxeCoreAddress,\r
-            &DxeCoreSize,\r
-            &DxeCoreEntryPoint\r
-            );\r
-\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Transfer control to the DXE Core\r
-  // The handoff state is simply a pointer to the HOB list\r
-  //\r
-\r
-  Status = PeiServicesInstallPpi (&mPpiSignal);\r
-\r
+             PeiEfiPeiPeCoffLoader,\r
+             Pe32Data,\r
+             &DxeCoreAddress,\r
+             &DxeCoreSize,\r
+             &DxeCoreEntryPoint\r
+             );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
@@ -397,15 +259,55 @@ Returns:
     EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT\r
     );\r
 \r
-  DEBUG ((EFI_D_INFO, "DXE Core Entry\n"));\r
-  SwitchIplStacks (\r
-    (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,\r
-    HobList.Raw,\r
-    NULL,\r
-    TopOfStack,\r
-    (VOID *) (UINTN) BspStore\r
-    );\r
+  if (FeaturePcdGet (PcdDxeIplBuildShareCodeHobs)) {\r
+    if (FeaturePcdGet (PcdDxeIplSupportEfiDecompress)) {\r
+      //\r
+      // Add HOB for the EFI Decompress Protocol\r
+      //\r
+      BuildGuidDataHob (\r
+        &gEfiDecompressProtocolGuid,\r
+        (VOID *)&gEfiDecompress,\r
+        sizeof (gEfiDecompress)\r
+        );\r
+    }\r
+    if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) {\r
+      //\r
+      // Add HOB for the Tiano Decompress Protocol\r
+      //\r
+      BuildGuidDataHob (\r
+        &gEfiTianoDecompressProtocolGuid,\r
+        (VOID *)&gTianoDecompress,\r
+        sizeof (gTianoDecompress)\r
+        );\r
+    }\r
+    if (FeaturePcdGet (PcdDxeIplSupportCustomDecompress)) {\r
+      //\r
+      // Add HOB for the user customized Decompress Protocol\r
+      //\r
+      BuildGuidDataHob (\r
+        &gEfiCustomizedDecompressProtocolGuid,\r
+        (VOID *)&gCustomDecompress,\r
+        sizeof (gCustomDecompress)\r
+        );\r
+    }\r
+\r
+    //\r
+    // Add HOB for the PE/COFF Loader Protocol\r
+    //\r
+    BuildGuidDataHob (\r
+      &gEfiPeiPeCoffLoaderGuid,\r
+      (VOID *)&PeiEfiPeiPeCoffLoader,\r
+      sizeof (VOID *)\r
+      );\r
+  }\r
 \r
+  //\r
+  // Transfer control to the DXE Core\r
+  // The handoff state is simply a pointer to the HOB list\r
+  //\r
+\r
+  DEBUG ((EFI_D_INFO, "DXE Core Entry Point 0x%08x\n", (UINTN) DxeCoreEntryPoint));\r
+  HandOffToDxeCore (DxeCoreEntryPoint, HobList, &mPpiSignal);\r
   //\r
   // If we get here, then the DXE Core returned.  This is an error\r
   // Dxe Core should not return.\r
@@ -453,22 +355,26 @@ Returns:
 {\r
   EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;\r
   EFI_FFS_FILE_HEADER         *FfsFileHeader;\r
-  VOID                        *SectionData;\r
   EFI_STATUS                  Status;\r
   EFI_PEI_HOB_POINTERS        Hob;\r
 \r
 \r
   FwVolHeader   = NULL;\r
   FfsFileHeader = NULL;\r
-  SectionData   = NULL;\r
+  Status        = EFI_SUCCESS;\r
 \r
   //\r
-  // Foreach Firmware Volume, look for a specified type\r
-  // of file and break out when one is found\r
+  // For each Firmware Volume, look for a specified type\r
+  // of file and break out until no one is found \r
   //\r
   Hob.Raw = GetHobList ();\r
   while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) {\r
     FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (Hob.FirmwareVolume->BaseAddress);\r
+    //\r
+    // Make sure the FV HOB does not get corrupted.\r
+    //\r
+    ASSERT (FwVolHeader->Signature == EFI_FVH_SIGNATURE);\r
+\r
     Status = PeiServicesFfsFindNextFile (\r
                Type,\r
                FwVolHeader,\r
@@ -477,11 +383,17 @@ Returns:
     if (!EFI_ERROR (Status)) {\r
       Status = PeiProcessFile (\r
                  SectionType,\r
-                 &FfsFileHeader,\r
-                 Pe32Data\r
+                 FfsFileHeader,\r
+                 Pe32Data,\r
+                 &Hob\r
                  );\r
       CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID));\r
-      return Status;\r
+      //\r
+      // Find all Fv type ffs to get all FvImage and add them into FvHob\r
+      //\r
+      if (!EFI_ERROR (Status) && (Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) {\r
+        return EFI_SUCCESS;\r
+      }\r
     }\r
     Hob.Raw = GET_NEXT_HOB (Hob);\r
   }\r
@@ -607,7 +519,7 @@ Returns:
 \r
   while ((Section->Type != EFI_SECTION_PE32) && (Section->Type != EFI_SECTION_TE)) {\r
     SectionLength         = *(UINT32 *) (Section->Size) & 0x00ffffff;\r
-    OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);\r
+    OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
     Section               = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);\r
   }\r
   //\r
@@ -623,14 +535,9 @@ Returns:
 \r
   if (Status == EFI_SUCCESS) {\r
     //\r
-    // Install PeiInMemory to indicate the Dxeipl is shadowed\r
+    // Set gInMemory global variable to TRUE to indicate the dxeipl is shadowed.\r
     //\r
-    Status = PeiServicesInstallPpi (&mPpiPeiInMemory);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
+    *(BOOLEAN *) ((UINTN) &gInMemory + (UINTN) DxeIplEntryPoint - (UINTN) _ModuleEntryPoint) = TRUE;\r
     Status = ((EFI_PEIM_ENTRY_POINT) (UINTN) DxeIplEntryPoint) (DxeIplFileHeader, GetPeiServicesTablePointer());\r
   }\r
 \r
@@ -688,8 +595,9 @@ Returns:
   //\r
   Status = PeiProcessFile (\r
             EFI_SECTION_PE32,\r
-            &FfsHeader,\r
-            &Pe32Data\r
+            FfsHeader,\r
+            &Pe32Data,\r
+            NULL\r
             );\r
 \r
   if (EFI_ERROR (Status)) {\r
@@ -712,8 +620,9 @@ Returns:
 EFI_STATUS\r
 PeiProcessFile (\r
   IN      UINT16                 SectionType,\r
-  IN OUT  EFI_FFS_FILE_HEADER    **RealFfsFileHeader,\r
-  OUT     VOID                   **Pe32Data\r
+  IN      EFI_FFS_FILE_HEADER    *FfsFileHeader,\r
+  OUT     VOID                   **Pe32Data,\r
+  IN      EFI_PEI_HOB_POINTERS   *OrigHob\r
   )\r
 /*++\r
 \r
@@ -751,7 +660,6 @@ Returns:
   UINTN                           SectionLength;\r
   UINTN                           OccupiedSectionLength;\r
   UINT64                          FileSize;\r
-  EFI_GUID_DEFINED_SECTION        *GuidedSectionHeader;\r
   UINT32                          AuthenticationStatus;\r
   EFI_PEI_SECTION_EXTRACTION_PPI  *SectionExtract;\r
   UINT32                          BufferSize;\r
@@ -761,9 +669,13 @@ Returns:
   EFI_GUID                        TempGuid;\r
   EFI_FIRMWARE_VOLUME_HEADER      *FvHeader;\r
   EFI_COMPRESSION_SECTION         *CompressionSection;\r
-  EFI_FFS_FILE_HEADER             *FfsFileHeader;\r
 \r
-  FfsFileHeader = *RealFfsFileHeader;\r
+  //\r
+  // Initialize local variables.\r
+  //\r
+  DecompressLibrary = NULL;\r
+  DstBuffer         = NULL;\r
+  DstBufferSize     = 0;\r
 \r
   Status = PeiServicesFfsFindSectionData (\r
              EFI_SECTION_COMPRESSION,\r
@@ -772,7 +684,7 @@ Returns:
              );\r
 \r
   //\r
-  // Upon finding a DXE Core file, see if there is first a compression section\r
+  // First process the compression section\r
   //\r
   if (!EFI_ERROR (Status)) {\r
     //\r
@@ -783,16 +695,12 @@ Returns:
 \r
     do {\r
       SectionLength         = *(UINT32 *) (Section->Size) & 0x00ffffff;\r
-      OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);\r
+      OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
 \r
       //\r
       // Was the DXE Core file encapsulated in a GUID'd section?\r
       //\r
       if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
-        //\r
-        // Locate the GUID'd Section Extractor\r
-        //\r
-        GuidedSectionHeader = (VOID *) (Section + 1);\r
 \r
         //\r
         // This following code constitutes the addition of the security model\r
@@ -880,111 +788,169 @@ Returns:
 \r
         switch (CompressionSection->CompressionType) {\r
         case EFI_STANDARD_COMPRESSION:\r
-          DecompressLibrary = &gTianoDecompress;\r
+          //\r
+          // Load EFI standard compression.\r
+          //\r
+          if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) {\r
+            DecompressLibrary = &gEfiDecompress;\r
+          } else {\r
+            ASSERT (FALSE);\r
+            return EFI_NOT_FOUND;\r
+          }\r
           break;\r
 \r
         case EFI_CUSTOMIZED_COMPRESSION:\r
           //\r
-          // Load user customized compression protocol.\r
+          // Load user customized compression.\r
           //\r
-          DecompressLibrary = &gCustomDecompress;\r
+          if (FeaturePcdGet (PcdDxeIplSupportCustomDecompress)) {\r
+            DecompressLibrary = &gCustomDecompress;\r
+          } else {\r
+            ASSERT (FALSE);\r
+            return EFI_NOT_FOUND;\r
+          }\r
           break;\r
 \r
         case EFI_NOT_COMPRESSED:\r
+          //\r
+          // Allocate destination buffer\r
+          //\r
+          DstBufferSize = CompressionSection->UncompressedLength;\r
+          DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+          if (DstBuffer == NULL) {\r
+            return EFI_OUT_OF_RESOURCES;\r
+          }\r
+          //\r
+          // stream is not actually compressed, just encapsulated.  So just copy it.\r
+          //\r
+          CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
+          break;\r
+\r
         default:\r
           //\r
-          // Need to support not compressed file\r
+          // Don't support other unknown compression type.\r
           //\r
           ASSERT_EFI_ERROR (Status);\r
           return EFI_NOT_FOUND;\r
         }\r
-\r
-        Status = DecompressLibrary->GetInfo (\r
-                   (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
-                   (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),\r
-                   &DstBufferSize,\r
-                   &ScratchBufferSize\r
-                   );\r
-        if (EFI_ERROR (Status)) {\r
+        \r
+        if (CompressionSection->CompressionType != EFI_NOT_COMPRESSED) {\r
           //\r
-          // GetInfo failed\r
+          // For compressed data, decompress them to dstbuffer.\r
           //\r
-          return EFI_NOT_FOUND;\r
-        }\r
-\r
-        //\r
-        // Allocate scratch buffer\r
-        //\r
-        ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
-        if (ScratchBuffer == NULL) {\r
-          return EFI_OUT_OF_RESOURCES;\r
-        }\r
-\r
-        //\r
-        // Allocate destination buffer\r
-        //\r
-        DstBuffer = 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 = DecompressLibrary->Decompress (\r
-                    (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
-                    DstBuffer,\r
-                    ScratchBuffer\r
-                    );\r
-\r
-        CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;\r
-        if (CmpSection->Type == EFI_SECTION_RAW) {\r
+          Status = DecompressLibrary->GetInfo (\r
+                     (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
+                     (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),\r
+                     &DstBufferSize,\r
+                     &ScratchBufferSize\r
+                     );\r
+          if (EFI_ERROR (Status)) {\r
+            //\r
+            // GetInfo failed\r
+            //\r
+            DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));\r
+            return EFI_NOT_FOUND;\r
+          }\r
+  \r
           //\r
-          // Skip the section header and\r
-          // adjust the pointer alignment to 16\r
+          // Allocate scratch buffer\r
           //\r
-          FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16);\r
-\r
-          if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
-            FfsFileHeader = NULL;\r
-            BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);\r
-            Status = PeiServicesFfsFindNextFile (\r
-                       EFI_FV_FILETYPE_DXE_CORE,\r
-                       FvHeader,\r
-                       &FfsFileHeader\r
-                       );\r
-\r
-            if (EFI_ERROR (Status)) {\r
-              return EFI_NOT_FOUND;\r
-            }\r
-\r
+          ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
+          if (ScratchBuffer == NULL) {\r
+            return EFI_OUT_OF_RESOURCES;\r
+          }\r
+  \r
+          //\r
+          // Allocate destination buffer\r
+          //\r
+          DstBuffer = 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 = DecompressLibrary->Decompress (\r
+                      (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
+                      DstBuffer,\r
+                      ScratchBuffer\r
+                      );\r
+          if (EFI_ERROR (Status)) {\r
             //\r
-            // Reture the FfsHeader that contain Pe32Data.\r
+            // Decompress failed\r
             //\r
-            *RealFfsFileHeader = FfsFileHeader;\r
-            return PeiProcessFile (SectionType, RealFfsFileHeader, Pe32Data);\r
+            DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));\r
+            return EFI_NOT_FOUND;\r
           }\r
         }\r
+\r
         //\r
         // Decompress successfully.\r
         // Loop the decompressed data searching for expected section.\r
         //\r
+        CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;\r
         CmpFileData = (VOID *) DstBuffer;\r
         CmpFileSize = DstBufferSize;\r
         do {\r
           CmpSectionLength = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;\r
-          if (CmpSection->Type == EFI_SECTION_PE32) {\r
+          if (CmpSection->Type == SectionType) {\r
             //\r
             // This is what we want\r
             //\r
-            *Pe32Data = (VOID *) (CmpSection + 1);\r
-            return EFI_SUCCESS;\r
+            if (SectionType == EFI_SECTION_PE32) {\r
+              *Pe32Data = (VOID *) (CmpSection + 1);\r
+              return EFI_SUCCESS;\r
+            } else if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
+              // \r
+              // Firmware Volume Image in this Section\r
+              // Skip the section header to get FvHeader\r
+              //\r
+              FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);\r
+    \r
+              if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
+                //\r
+                // Because FvLength in FvHeader is UINT64 type, \r
+                // so FvHeader must meed at least 8 bytes alignment.\r
+                // If current FvImage base address doesn't meet its alignment,\r
+                // we need to reload this FvImage to another correct memory address.\r
+                //\r
+                if (((UINTN) FvHeader % sizeof (UINT64)) != 0) {\r
+                  DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), sizeof (UINT64));\r
+                  if (DstBuffer == NULL) {\r
+                    return EFI_OUT_OF_RESOURCES;\r
+                  }\r
+                  CopyMem (DstBuffer, FvHeader, (UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER));\r
+                  FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer;  \r
+                }\r
+\r
+                //\r
+                // Build new FvHob for new decompressed Fv image.\r
+                //\r
+                BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);\r
+                \r
+                //\r
+                // Set the original FvHob to unused.\r
+                //\r
+                if (OrigHob != NULL) {\r
+                  OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;\r
+                }\r
+                \r
+                //\r
+                // return found FvImage data.\r
+                //\r
+                *Pe32Data = (VOID *) FvHeader;\r
+                return EFI_SUCCESS;\r
+              }\r
+            }\r
           }\r
-\r
-          OccupiedCmpSectionLength  = GetOccupiedSize (CmpSectionLength, 4);\r
+          OccupiedCmpSectionLength  = GET_OCCUPIED_SIZE (CmpSectionLength, 4);\r
           CmpSection                = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);\r
         } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);\r
       }\r
+      //\r
+      // End of the decompression activity\r
+      //\r
 \r
       Section   = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);\r
       FileSize  = FfsFileHeader->Size[0] & 0xFF;\r
@@ -992,11 +958,17 @@ Returns:
       FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;\r
       FileSize &= 0x00FFFFFF;\r
     } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize);\r
-\r
+    \r
     //\r
-    // End of the decompression activity\r
+    // search all sections (compression and non compression) in this FFS, don't \r
+    // find expected section.\r
     //\r
+    return EFI_NOT_FOUND;\r
   } else {\r
+    //\r
+    // For those FFS that doesn't contain compression section, directly search \r
+    // PE or TE section in this FFS.\r
+    //\r
 \r
     Status = PeiServicesFfsFindSectionData (\r
                EFI_SECTION_PE32,\r
@@ -1020,3 +992,4 @@ Returns:
 \r
   return EFI_SUCCESS;\r
 }\r
+\r