]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Pei/Image/Image.c
Update PEI Core LoadImage() service to always call LoadAndRelocatePeCoffImage() even...
[mirror_edk2.git] / MdeModulePkg / Core / Pei / Image / Image.c
index 23e9ee58d6d3b5a18c6d9f34fa547c20ccdf9128..2928248c7bbf4812c5a96819033d55aa434e1beb 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Pei Core Load Image Support\r
   \r
-Copyright (c) 2006 - 2008, Intel Corporation                                                         \r
+Copyright (c) 2006 - 2009, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -14,29 +14,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "PeiMain.h"\r
 \r
-/**\r
-  The wrapper function of PeiLoadImageLoadImage().\r
-\r
-  @param This            - Pointer to EFI_PEI_LOAD_FILE_PPI.\r
-  @param FileHandle      - Pointer to the FFS file header of the image.\r
-  @param ImageAddressArg - Pointer to PE/TE image.\r
-  @param ImageSizeArg    - Size of PE/TE image.\r
-  @param EntryPoint      - Pointer to entry point of specified image file for output.\r
-  @param AuthenticationState - Pointer to attestation authentication state of image.\r
-\r
-  @return Status of PeiLoadImageLoadImage().\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PeiLoadImageLoadImageWrapper (\r
-  IN     CONST EFI_PEI_LOAD_FILE_PPI  *This,\r
-  IN     EFI_PEI_FILE_HANDLE          FileHandle,\r
-  OUT    EFI_PHYSICAL_ADDRESS         *ImageAddressArg,  OPTIONAL\r
-  OUT    UINT64                       *ImageSizeArg,     OPTIONAL\r
-  OUT    EFI_PHYSICAL_ADDRESS         *EntryPoint,\r
-  OUT    UINT32                       *AuthenticationState\r
-  );\r
 \r
 EFI_PEI_LOAD_FILE_PPI   mPeiLoadImagePpi = {\r
   PeiLoadImageLoadImageWrapper\r
@@ -77,9 +54,11 @@ PeiImageRead (
 \r
   Destination8  = Buffer;\r
   Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
-  Length        = *ReadSize;\r
-  while ((Length--) > 0) {\r
-    *(Destination8++) = *(Source8++);\r
+  if (Destination8 != Source8) {\r
+    Length        = *ReadSize;\r
+    while ((Length--) > 0) {\r
+      *(Destination8++) = *(Source8++);\r
+    }\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -99,14 +78,21 @@ GetImageReadFunction (
   IN      PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext\r
   )\r
 {\r
+  PEI_CORE_INSTANCE  *Private;\r
   VOID*  MemoryBuffer;\r
 \r
-  MemoryBuffer = AllocatePages (0x400 / EFI_PAGE_SIZE + 1);\r
-  ASSERT (MemoryBuffer != NULL);\r
+  Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r
 \r
-  CopyMem (MemoryBuffer, (CONST VOID *) (UINTN) PeiImageRead, 0x400);\r
+  if (!Private->PeiMemoryInstalled) {\r
+    ImageContext->ImageRead = PeiImageRead;\r
+  } else {\r
+    MemoryBuffer = AllocatePages (0x400 / EFI_PAGE_SIZE + 1);\r
+    ASSERT (MemoryBuffer != NULL);\r
+\r
+    CopyMem (MemoryBuffer, (CONST VOID *) (UINTN) PeiImageRead, 0x400);\r
 \r
-  ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;\r
+    ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -136,6 +122,9 @@ LoadAndRelocatePeCoffImage (
 {\r
   EFI_STATUS                            Status;\r
   PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;\r
+  PEI_CORE_INSTANCE                     *Private;\r
+\r
+  Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r
 \r
   ZeroMem (&ImageContext, sizeof (ImageContext));\r
   ImageContext.Handle = Pe32Data;\r
@@ -152,21 +141,24 @@ LoadAndRelocatePeCoffImage (
   //\r
   if (ImageContext.RelocationsStripped) {\r
     DEBUG ((EFI_D_ERROR, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN) Pe32Data));\r
-    return EFI_INVALID_PARAMETER;\r
   }\r
   //\r
   // Allocate Memory for the image\r
   //\r
-  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
+  if (Private->PeiMemoryInstalled) {\r
+    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
+  } else {\r
+    ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data;\r
   }\r
 \r
   //\r
@@ -187,7 +179,9 @@ LoadAndRelocatePeCoffImage (
   //\r
   // Flush the instruction cache so the image data is written before we execute it\r
   //\r
-  InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
+  if (Private->PeiMemoryInstalled) {\r
+    InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
+  }\r
 \r
   *ImageAddress = ImageContext.ImageAddress;\r
   *ImageSize    = ImageContext.ImageSize;\r
@@ -230,7 +224,6 @@ PeiLoadImageLoadImage (
   EFI_PHYSICAL_ADDRESS        ImageEntryPoint;\r
   UINT16                      Machine;\r
   PEI_CORE_INSTANCE           *Private;\r
-  VOID                        *EntryPointArg;\r
   EFI_SECTION_TYPE            SearchType1;\r
   EFI_SECTION_TYPE            SearchType2;\r
 \r
@@ -274,43 +267,35 @@ PeiLoadImageLoadImage (
   \r
   Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
 \r
-  if (Private->PeiMemoryInstalled && \r
-      (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
-    //\r
-    // If memory is installed, perform the shadow operations\r
-    //\r
-    Status = LoadAndRelocatePeCoffImage (\r
-      Pe32Data,\r
-      &ImageAddress,\r
-      &ImageSize,\r
-      &ImageEntryPoint\r
-    );\r
+  //\r
+  // If memory is installed, perform the shadow operations\r
+  //\r
+  Status = LoadAndRelocatePeCoffImage (\r
+    Pe32Data,\r
+    &ImageAddress,\r
+    &ImageSize,\r
+    &ImageEntryPoint\r
+  );\r
 \r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-    //\r
-    // Got the entry point from the loaded Pe32Data\r
-    //\r
-    Pe32Data    = (VOID *) ((UINTN) ImageAddress);\r
-    *EntryPoint = ImageEntryPoint;\r
-  } else {\r
-    //\r
-    // Retrieve the entry point from the PE/COFF or TE image header\r
-    //\r
-    ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;\r
-    Status = PeCoffLoaderGetEntryPoint (Pe32Data, &EntryPointArg);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-    *EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) EntryPointArg;\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
   }\r
+\r
+  //\r
+  // Got the entry point from the loaded Pe32Data\r
+  //\r
+  Pe32Data    = (VOID *) ((UINTN) ImageAddress);\r
+  *EntryPoint = ImageEntryPoint;\r
   \r
   Machine = PeCoffLoaderGetMachineType (Pe32Data);\r
   \r
   if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) {\r
-    return EFI_UNSUPPORTED;  \r
+    if (!EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Machine)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
   }\r
 \r
   if (ImageAddressArg != NULL) {\r
@@ -330,7 +315,7 @@ PeiLoadImageLoadImage (
     //\r
     // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi\r
     //\r
-    if (Machine != IMAGE_FILE_MACHINE_IA64) {\r
+    if (Machine != EFI_IMAGE_MACHINE_IA64) {\r
       DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)*EntryPoint));\r
     } else {\r
       //\r
@@ -455,25 +440,20 @@ PeiLoadImage (
                           AuthenticationState\r
                           );\r
       if (!EFI_ERROR (Status)) {\r
+        //\r
+        // The image to be started must have the machine type supported by PeiCore.\r
+        //\r
+        ASSERT (EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *) (UINTN) ImageAddress)));\r
+        if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *) (UINTN) ImageAddress))) {\r
+          return EFI_UNSUPPORTED;\r
+        }\r
         return Status;\r
       }\r
     }\r
     Index++;\r
   } while (!EFI_ERROR (PpiStatus));\r
 \r
-  //\r
-  // If no instances reports EFI_SUCCESS, then build-in support for\r
-  // the PE32+/TE XIP image format is used.\r
-  //\r
-  Status = PeiLoadImageLoadImage (\r
-            PeiServices, \r
-            FileHandle, \r
-            NULL, \r
-            NULL, \r
-            EntryPoint, \r
-            AuthenticationState\r
-            );\r
-  return Status;\r
+  return PpiStatus;\r
 }\r
 \r
 \r