]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
Enable PeiCore to dispatch the encapsulated fv images with depex expression. This...
[mirror_edk2.git] / MdeModulePkg / Core / DxeIplPeim / DxeLoad.c
index e62142f24c4845c42bf422ee2fa29e8f33f3ed05..65d0e86d75402a09acc2295533614b92762d8984 100644 (file)
@@ -130,16 +130,16 @@ PeimInitializeDxeIpl (
        }\r
       }\r
     } else {\r
-      ASSERT_EFI_ERROR (FALSE);\r
+      ASSERT (FALSE);\r
     }\r
   }\r
   \r
   //\r
-  // Install FvFileLoader and DxeIpl PPIs.\r
+  // Install DxeIpl and Decompress PPIs.\r
   //\r
   Status = PeiServicesInstallPpi (mPpiList);\r
-  ASSERT_EFI_ERROR(Status);  \r
-       \r
+  ASSERT_EFI_ERROR(Status);\r
+\r
   return Status;\r
 }\r
 \r
@@ -167,9 +167,10 @@ DxeLoadCore (
   UINT64                                    DxeCoreSize;\r
   EFI_PHYSICAL_ADDRESS                      DxeCoreEntryPoint;\r
   EFI_BOOT_MODE                             BootMode;\r
-  EFI_PEI_FV_HANDLE                         VolumeHandle;\r
   EFI_PEI_FILE_HANDLE                       FileHandle;\r
-  UINTN                                     Instance;\r
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI           *Variable;\r
+  UINTN                                     DataSize;\r
+  EFI_MEMORY_TYPE_INFORMATION               MemoryData [EfiMaxMemoryType + 1];\r
 \r
   //\r
   // if in S3 Resume, restore configure\r
@@ -191,23 +192,47 @@ DxeLoadCore (
     // Now should have a HOB with the DXE core w/ the old HOB destroyed\r
     //\r
   }\r
-  \r
-  //\r
-  // If any FV contains an encapsulated FV extract that FV\r
-  //\r
-  DxeIplAddEncapsulatedFirmwareVolumes ();\r
-  \r
+\r
+  Status = PeiServicesLocatePpi (\r
+             &gEfiPeiReadOnlyVariable2PpiGuid,\r
+             0,\r
+             NULL,\r
+             (VOID **)&Variable\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  DataSize = sizeof (MemoryData);\r
+  Status = Variable->GetVariable ( \r
+                       Variable, \r
+                       EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,\r
+                       &gEfiMemoryTypeInformationGuid,\r
+                       NULL,\r
+                       &DataSize,\r
+                       &MemoryData\r
+                       );\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Build the GUID'd HOB for DXE\r
+    //\r
+    BuildGuidDataHob (\r
+      &gEfiMemoryTypeInformationGuid,\r
+      MemoryData,\r
+      DataSize\r
+      );\r
+  }\r
+\r
   //\r
   // Look in all the FVs present in PEI and find the DXE Core\r
   //\r
-  Instance = 0;\r
-  Status = DxeIplFindFirmwareVolumeInstance (&Instance, EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);\r
+  FileHandle = NULL;\r
+  Status = DxeIplFindDxeCore (&FileHandle);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   CopyMem(&DxeCoreFileName, &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name), sizeof (EFI_GUID));\r
 \r
   //\r
-  // Load the DXE Core from a Firmware Volume\r
+  // Load the DXE Core from a Firmware Volume, may use LoadFile ppi to do this for save code size.\r
   //\r
   Status = PeiLoadFile (\r
             FileHandle,\r
@@ -236,11 +261,25 @@ DxeLoadCore (
     EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT\r
     );\r
 \r
+  DEBUG_CODE_BEGIN ();\r
+\r
+    EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION       PtrPeImage;\r
+    PtrPeImage.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) DxeCoreAddress + ((EFI_IMAGE_DOS_HEADER *) (UINTN) DxeCoreAddress)->e_lfanew);\r
+    \r
+    if (PtrPeImage.Pe32->FileHeader.Machine != IMAGE_FILE_MACHINE_IA64) {\r
+      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DXE CORE at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)DxeCoreAddress, (VOID *)(UINTN)DxeCoreEntryPoint));\r
+    } else {\r
+      //\r
+      // For IPF Image, the real entry point should be print.\r
+      //\r
+      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DXE CORE at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)DxeCoreAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)DxeCoreEntryPoint)));\r
+    }\r
+\r
+  DEBUG_CODE_END ();\r
   //\r
   // Transfer control to the DXE Core\r
   // The handoff state is simply a pointer to the HOB list\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
@@ -252,171 +291,38 @@ DxeLoadCore (
   return EFI_OUT_OF_RESOURCES;\r
 }\r
 \r
-\r
-STATIC\r
-EFI_STATUS\r
-GetFvAlignment (\r
-  IN    EFI_FIRMWARE_VOLUME_HEADER   *FvHeader,\r
-  OUT   UINT32                      *FvAlignment\r
-  )\r
-{\r
-  //\r
-  // Because FvLength in FvHeader is UINT64 type, \r
-  // so FvHeader must meed at least 8 bytes alignment.\r
-  // Get the appropriate alignment requirement.\r
-  // \r
-  if ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) < EFI_FVB2_ALIGNMENT_8) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-  \r
-   *FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
-   return EFI_SUCCESS;\r
-}\r
-\r
 /**\r
-   Search EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE image and expand \r
-   as memory FV \r
-    \r
-   @return EFI_OUT_OF_RESOURCES There are no memory space to exstract FV\r
-   @return EFI_SUCESS           Sucess to find the FV \r
-**/\r
-EFI_STATUS\r
-DxeIplAddEncapsulatedFirmwareVolumes (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS                  Status;\r
-  EFI_STATUS                  VolumeStatus;\r
-  UINTN                       Index;\r
-  EFI_FV_INFO                 VolumeInfo; \r
-  EFI_PEI_FV_HANDLE           VolumeHandle;\r
-  EFI_PEI_FILE_HANDLE         FileHandle;\r
-  UINT32                      SectionLength;\r
-  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;\r
-  EFI_FIRMWARE_VOLUME_IMAGE_SECTION *SectionHeader;\r
-  VOID                        *DstBuffer;\r
-  UINT32                       FvAlignment;\r
-\r
-  Status = EFI_NOT_FOUND;\r
-  Index  = 0;\r
+   Find DxeCore driver from all First Volumes.\r
 \r
-  do {\r
-    VolumeStatus = DxeIplFindFirmwareVolumeInstance (\r
-                    &Index, \r
-                    EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, \r
-                    &VolumeHandle, \r
-                    &FileHandle\r
-                    );\r
-                    \r
-    if (!EFI_ERROR (VolumeStatus)) {\r
-         Status = PeiServicesFfsFindSectionData (\r
-                    EFI_SECTION_FIRMWARE_VOLUME_IMAGE, \r
-                    (EFI_FFS_FILE_HEADER *)FileHandle, \r
-                    (VOID **)&FvHeader\r
-                    );\r
-                    \r
-      if (!EFI_ERROR (Status)) {\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
-          Status = GetFvAlignment(FvHeader, &FvAlignment); \r
-          if (EFI_ERROR(Status)) {\r
-            return Status;\r
-          }\r
-          if (((UINTN) FvHeader % FvAlignment) != 0) {\r
-            SectionHeader = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*)((UINTN)FvHeader - sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION));\r
-            SectionLength =  *(UINT32 *)SectionHeader->Size & 0x00FFFFFF;\r
-            \r
-            DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), FvAlignment);\r
-            if (DstBuffer == NULL) {\r
-              return EFI_OUT_OF_RESOURCES;\r
-            }\r
-            CopyMem (DstBuffer, FvHeader, (UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER));\r
-            FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer;  \r
-          }\r
-\r
-          //\r
-          // This new Firmware Volume comes from a firmware file within a firmware volume.\r
-          // Record the original Firmware Volume Name.\r
-          //\r
-          PeiServicesFfsGetVolumeInfo (&VolumeHandle, &VolumeInfo);\r
-\r
-          PiLibInstallFvInfoPpi (\r
-            NULL,\r
-            FvHeader,\r
-            (UINT32) FvHeader->FvLength,\r
-            &(VolumeInfo.FvName),\r
-            &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name)\r
-            );\r
-\r
-          //\r
-          // Inform HOB consumer phase, i.e. DXE core, the existance of this FV\r
-          //\r
-          BuildFvHob (\r
-            (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
-            FvHeader->FvLength\r
-          );\r
-            \r
-          ASSERT_EFI_ERROR (Status);\r
-\r
-          //\r
-          // Makes the encapsulated volume show up in DXE phase to skip processing of\r
-          // encapsulated file again.\r
-          //\r
-          BuildFv2Hob (\r
-            (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,\r
-            FvHeader->FvLength, \r
-            &VolumeInfo.FvName,\r
-            &(((EFI_FFS_FILE_HEADER *)FileHandle)->Name)\r
-            );\r
-          return Status;\r
-        }\r
-      }\r
-    }\r
-  } while (!EFI_ERROR (VolumeStatus));\r
-  \r
-  return Status;\r
-}\r
-\r
-/**\r
-   Find the First Volume that contains the first FileType.\r
-\r
-   @param Instance      The Fv instance.\r
-   @param SeachType     The type of file to search.\r
-   @param VolumeHandle  Pointer to Fv which contains the file to search. \r
    @param FileHandle    Pointer to FFS file to search.\r
    \r
    @return EFI_SUCESS   Success to find the FFS in specificed FV\r
    @return others       Fail to find the FFS in specificed FV\r
  */\r
 EFI_STATUS\r
-DxeIplFindFirmwareVolumeInstance (\r
-  IN OUT UINTN              *Instance,\r
-  IN  EFI_FV_FILETYPE       SeachType,\r
-  OUT EFI_PEI_FV_HANDLE     *VolumeHandle,\r
+DxeIplFindDxeCore (\r
   OUT EFI_PEI_FILE_HANDLE   *FileHandle\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-  EFI_STATUS  VolumeStatus;\r
+  EFI_STATUS        Status;\r
+  EFI_STATUS        FileStatus;\r
+  UINTN             Instance;\r
+  EFI_PEI_FV_HANDLE VolumeHandle;\r
+  \r
+  Instance    = 0;\r
+  *FileHandle = NULL;\r
 \r
   do {\r
-    VolumeStatus = PeiServicesFfsFindNextVolume (*Instance, VolumeHandle);\r
-    if (!EFI_ERROR (VolumeStatus)) {\r
-      *FileHandle = NULL;\r
-      Status = PeiServicesFfsFindNextFile (SeachType, *VolumeHandle, FileHandle);\r
-      if (!EFI_ERROR (Status)) {\r
-        return Status;\r
+    Status = PeiServicesFfsFindNextVolume (Instance++, &VolumeHandle);\r
+    if (!EFI_ERROR (Status)) {\r
+      FileStatus = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, FileHandle);\r
+      if (!EFI_ERROR (FileStatus)) {\r
+        return FileStatus;\r
       }\r
     }\r
-    *Instance += 1;\r
-  } while (!EFI_ERROR (VolumeStatus));\r
+  } while (!EFI_ERROR (Status));\r
 \r
-  return VolumeStatus;\r
+  return EFI_NOT_FOUND;\r
 }\r
 \r
 /**\r
@@ -443,21 +349,13 @@ PeiLoadFile (
   PE_COFF_LOADER_IMAGE_CONTEXT      ImageContext;\r
   VOID                              *Pe32Data;\r
   //\r
-  // First try to find the required section in this ffs file.\r
+  // First try to find the PE32 section in this ffs file.\r
   //\r
   Status = PeiServicesFfsFindSectionData (\r
              EFI_SECTION_PE32,\r
              FileHandle,\r
              &Pe32Data\r
              );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    Status = PeiServicesFfsFindSectionData (\r
-               EFI_SECTION_TE,\r
-               FileHandle,\r
-               &Pe32Data\r
-               );\r
-  }\r
   \r
   if (EFI_ERROR (Status)) {\r
     //\r
@@ -482,15 +380,6 @@ PeiLoadFile (
   ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));\r
   ASSERT (ImageContext.ImageAddress != 0);\r
 \r
-  //\r
-  // Skip the reserved space for the stripped PeHeader when load TeImage into memory.\r
-  //\r
-  if (ImageContext.IsTeImage) {\r
-    ImageContext.ImageAddress = ImageContext.ImageAddress + \r
-                                ((EFI_TE_IMAGE_HEADER *) Pe32Data)->StrippedSize -\r
-                                sizeof (EFI_TE_IMAGE_HEADER);\r
-  }\r
-\r
   //\r
   // Load the image to our new buffer\r
   //\r
@@ -618,10 +507,16 @@ CustomGuidedSectionExtract (
     //\r
     // Allocate output buffer\r
     //\r
-    *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize));\r
+    *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);\r
     if (*OutputBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
+    DEBUG ((EFI_D_INFO, "Customed Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));\r
+    //\r
+    // *OutputBuffer still is one section. Adjust *OutputBuffer offset, \r
+    // skip EFI section header to make section data at page alignment.\r
+    //\r
+    *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));\r
   }\r
   \r
   Status = ExtractGuidedSectionDecode (\r
@@ -700,13 +595,18 @@ Decompress (
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     //\r
-    // Allocate destination buffer\r
+    // Allocate destination buffer, extra one page for adjustment \r
     //\r
-    DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+    DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
     if (DstBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     //\r
+    // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header\r
+    // to make section data at page alignment.\r
+    //\r
+    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
+    //\r
     // Call decompress function\r
     //\r
     Status = UefiDecompress (\r
@@ -723,18 +623,21 @@ Decompress (
     }\r
     break;\r
 \r
-  // porting note the original branch for customized compress is removed, it should be change to use GUID compress\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
+    DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
     if (DstBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     //\r
+    // Adjust DstBuffer offset, skip EFI section header\r
+    // to make section data at page alignment.\r
+    //\r
+    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
+    //\r
     // stream is not actually compressed, just encapsulated.  So just copy it.\r
     //\r
     CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
@@ -754,3 +657,33 @@ Decompress (
   return EFI_SUCCESS;\r
 }\r
 \r
+VOID\r
+UpdateStackHob (\r
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,\r
+  IN UINT64                      Length\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS           Hob;\r
+\r
+  Hob.Raw = GetHobList ();\r
+  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {\r
+    if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {\r
+      //\r
+      // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type\r
+      // to be reclaimed by DXE core.\r
+      //\r
+      BuildMemoryAllocationHob (\r
+        Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,\r
+        Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,\r
+        EfiConventionalMemory\r
+        );\r
+      //\r
+      // Update the BSP Stack Hob to reflect the new stack info.\r
+      //\r
+      Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
+      Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;\r
+      break;\r
+    }\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+  }\r
+}\r