]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Core/DxeIplX64Peim/DxeLoadX64.c
Fix gcc build break for this module.
[mirror_edk2.git] / EdkModulePkg / Core / DxeIplX64Peim / DxeLoadX64.c
index cbb7595dac7bdaf2ffe1762bbc250f6ef0157a45..8e4f1126b69c1121822af0a14ef741003b3a69c5 100644 (file)
@@ -26,15 +26,6 @@ Abstract:
 \r
 BOOLEAN gInMemory = FALSE;\r
 \r
-//\r
-// GUID for EM64T\r
-//\r
-#define EFI_PPI_NEEDED_BY_DXE \\r
-  { \\r
-    0x4d37da42, 0x3a0c, 0x4eda, 0xb9, 0xeb, 0xbc, 0x0e, 0x1d, 0xb4, 0x71, 0x3b \\r
-  }\r
-EFI_GUID mPpiNeededByDxeGuid = EFI_PPI_NEEDED_BY_DXE;\r
-\r
 //\r
 // Module Globals used in the DXE to PEI handoff\r
 // These must be module globals, so the stack can be switched\r
@@ -71,17 +62,17 @@ 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
@@ -216,7 +207,9 @@ Returns:
   EFI_PHYSICAL_ADDRESS                                      BaseOfStack;\r
   EFI_PHYSICAL_ADDRESS                                      BspStore;\r
   EFI_GUID                                                  DxeCoreFileName;\r
+  EFI_GUID                                                  FirmwareFileName;\r
   VOID                                                      *DxeCorePe32Data;\r
+  VOID                                                      *FvImageData;     \r
   EFI_PHYSICAL_ADDRESS                                      DxeCoreAddress;\r
   UINT64                                                    DxeCoreSize;\r
   EFI_PHYSICAL_ADDRESS                                      DxeCoreEntryPoint;\r
@@ -256,17 +249,9 @@ Returns:
   //\r
   // Install the PEI Protocols that are shared between PEI and DXE\r
   //\r
-#ifdef EFI_NT_EMULATOR\r
   PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();\r
   ASSERT (PeiEfiPeiPeCoffLoader != NULL);\r
-#else\r
-  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderX64Protocol ();\r
-#endif \r
 \r
-#if 0\r
-  Status = InstallEfiPeiPeCoffLoader64 (PeiServices, &PeiEfiPeiPeCoffLoader, NULL);\r
-  ASSERT_EFI_ERROR (Status);\r
-#endif\r
   //\r
   // Allocate 128KB for the Stack\r
   //\r
@@ -274,11 +259,21 @@ Returns:
   ASSERT (BaseOfStack != 0);\r
 \r
   //\r
-  // Compute the top of the stack we were allocated. Pre-allocate a 32 bytes\r
-  // for safety (PpisNeededByDxe and DxeCore).\r
+  // Compute the top of the stack we were allocated, which is used to load X64 dxe core. \r
+  // Pre-allocate a 32 bytes which confroms to x64 calling convention.\r
+  //\r
+  // The first four parameters to a function are passed in rcx, rdx, r8 and r9. \r
+  // Any further parameters are pushed on the stack. Furthermore, space (4 * 8bytes) for the \r
+  // register parameters is reserved on the stack, in case the called function \r
+  // wants to spill them; this is important if the function is variadic. \r
   //\r
   TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - 32;\r
 \r
+  //\r
+  //  X64 Calling Conventions requires that the stack must be aligned to 16 bytes\r
+  //\r
+  TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, 16);\r
+\r
   //\r
   // Add architecture-specifc HOBs (including the BspStore HOB)\r
   //\r
@@ -299,9 +294,24 @@ Returns:
 \r
     ASSERT_EFI_ERROR (Status);\r
     Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);\r
-    ASSERT_EFI_ERROR (Status);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));\r
+      CpuDeadLoop ();\r
+    }\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. \r
+  //\r
+  Status = PeiFindFile (\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
   //\r
@@ -314,17 +324,9 @@ Returns:
   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
-  // PEI_PERF_END (PeiServices, L"DxeIpl", NULL, 0);\r
-\r
-  Status = PeiServicesInstallPpi (&mPpiSignal);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA \\r
+  // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA\r
   // memory, it may be corrupted when copying FV to high-end memory \r
+  //\r
   LoadGo64Gdt();\r
 \r
   //\r
@@ -336,7 +338,7 @@ Returns:
   //\r
   // Load the DXE Core from a Firmware Volume\r
   //\r
-  Status = PeiLoadx64File (\r
+  Status = PeiLoadPeImage (\r
              PeiEfiPeiPeCoffLoader,\r
              DxeCorePe32Data,\r
              EfiBootServicesData,\r
@@ -346,6 +348,14 @@ Returns:
              );\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
+  ASSERT_EFI_ERROR (Status);\r
+\r
   //\r
   //\r
   // Add HOB for the DXE Core\r
@@ -380,8 +390,10 @@ Returns:
 \r
   //\r
   // If we get here, then the DXE Core returned.  This is an error\r
+  // Dxe Core should not return.\r
   //\r
-  ASSERT_EFI_ERROR (Status);\r
+  ASSERT (FALSE);\r
+  CpuDeadLoop ();\r
 \r
   return EFI_OUT_OF_RESOURCES;\r
 }\r
@@ -431,10 +443,11 @@ Returns:
   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
@@ -447,11 +460,14 @@ 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
+      if (!EFI_ERROR (Status)) {\r
+        return EFI_SUCCESS;\r
+      }\r
     }\r
     Hob.Raw = GET_NEXT_HOB (Hob);\r
   }\r
@@ -459,7 +475,7 @@ Returns:
 }\r
 \r
 EFI_STATUS\r
-PeiLoadx64File (\r
+PeiLoadPeImage (\r
   IN  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader,\r
   IN  VOID                                      *Pe32Data,\r
   IN  EFI_MEMORY_TYPE                           MemoryType,\r
@@ -591,7 +607,7 @@ Returns:
   //\r
   // Relocate DxeIpl into memory by using loadfile service\r
   //\r
-  Status = PeiLoadx64File (\r
+  Status = PeiLoadPeImage (\r
             PeiEfiPeiPeCoffLoader,\r
             (VOID *) (Section + 1),\r
             EfiBootServicesData,\r
@@ -662,8 +678,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
@@ -672,7 +689,7 @@ Returns:
   //\r
   // Load the PE image from the FFS file\r
   //\r
-  Status = PeiLoadx64File (\r
+  Status = PeiLoadPeImage (\r
             PeiEfiPeiPeCoffLoader,\r
             Pe32Data,\r
             EfiBootServicesData,\r
@@ -687,8 +704,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
@@ -736,9 +754,7 @@ 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
+  UINT32                          FvAlignment;\r
 \r
   Status = PeiServicesFfsFindSectionData (\r
              EFI_SECTION_COMPRESSION,\r
@@ -747,7 +763,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
@@ -855,14 +871,24 @@ Returns:
 \r
         switch (CompressionSection->CompressionType) {\r
         case EFI_STANDARD_COMPRESSION:\r
-          DecompressLibrary = &gTianoDecompress;\r
+          if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) {\r
+            DecompressLibrary = &gTianoDecompress;\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
           //\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
@@ -913,31 +939,64 @@ Returns:
                     );\r
 \r
         CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;\r
-        if (CmpSection->Type == EFI_SECTION_RAW) {\r
-          //\r
-          // Skip the section header and\r
-          // adjust the pointer alignment to 16\r
+        if (CmpSection->Type == 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 *) (DstBuffer + 16);\r
+          FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);\r
 \r
-          if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
-            FfsFileHeader = NULL;\r
+          if (FvHeader->Signature == EFI_FVH_SIGNATURE) {            \r
+            //\r
+            // Adjust Fv Base Address Alignment based on Align Attributes in Fv Header\r
+            //\r
+            \r
+            //\r
+            // When FvImage support Alignment, we need to check whether \r
+            // its alignment is correct. \r
+            //\r
+            if (FvHeader->Attributes | EFI_FVB_ALIGNMENT_CAP) {\r
+              \r
+              //\r
+              // Calculate the mini alignment for this FvImage\r
+              //\r
+              FvAlignment = 1 << (LowBitSet32 (FvHeader->Attributes >> 16) + 1);\r
+              \r
+              //\r
+              // If current FvImage base address doesn't meet the its alignment,\r
+              // we need to reload this FvImage to another correct memory address.\r
+              //\r
+              if (((UINTN) FvHeader % FvAlignment) != 0) {\r
+                DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength), FvAlignment);\r
+                if (DstBuffer == NULL) {\r
+                  return EFI_OUT_OF_RESOURCES;\r
+                }\r
+                CopyMem (DstBuffer, FvHeader, (UINTN) FvHeader->FvLength);\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
-            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
+            // Set the original FvHob to unused.\r
+            //\r
+            if (OrigHob != NULL) {\r
+              OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;\r
             }\r
-\r
+            \r
             //\r
-            // Reture the FfsHeader that contain Pe32Data.\r
+            // when search FvImage Section return true.\r
             //\r
-            *RealFfsFileHeader = FfsFileHeader;\r
-            return PeiProcessFile (SectionType, RealFfsFileHeader, Pe32Data);\r
+            if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
+              *Pe32Data = (VOID *) FvHeader;\r
+              return EFI_SUCCESS;\r
+            } else {\r
+              return EFI_NOT_FOUND;\r
+            }\r
+\r
           }\r
         }\r
         //\r
@@ -960,6 +1019,9 @@ Returns:
           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
@@ -967,11 +1029,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
@@ -994,4 +1062,5 @@ Returns:
   *Pe32Data = SectionData;\r
 \r
   return EFI_SUCCESS;\r
-}
\ No newline at end of file
+}\r
+\r