/** @file\r
Pei Core Load Image Support\r
\r
-Copyright (c) 2006 - 2007, 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
\r
**/\r
\r
-#include <PeiMain.h>\r
+#include "PeiMain.h"\r
\r
-/**\r
- Routine for loading file image.\r
-\r
- @param PeiServices The PEI core services table.\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
- @retval EFI_SUCCESS - Image is successfully loaded.\r
- @retval EFI_NOT_FOUND - Fail to locate necessary PPI\r
- @retval Others - Fail to load file.\r
-\r
-**/\r
-EFI_STATUS\r
-PeiLoadImageLoadImage (\r
- IN EFI_PEI_SERVICES **PeiServices,\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
-\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
\r
-STATIC EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = {\r
+EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = {\r
PeiLoadImageLoadImageWrapper\r
};\r
\r
\r
-STATIC EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {\r
+EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {\r
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
&gEfiPeiLoadFilePpiGuid,\r
&mPeiLoadImagePpi\r
PeiImageRead (\r
IN VOID *FileHandle,\r
IN UINTN FileOffset,\r
- IN OUT UINTN *ReadSize,\r
+ IN UINTN *ReadSize,\r
OUT VOID *Buffer\r
)\r
{\r
\r
Destination8 = Buffer;\r
Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
- Length = *ReadSize;\r
- while (Length--) {\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
\r
/**\r
\r
- Support routine to return the Image Read.\r
+ Support routine to get the Image read file function.\r
\r
@param ImageContext - The context of the image being loaded\r
\r
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
+ 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
+ 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
\r
@retval EFI_SUCCESS The file was loaded and relocated\r
@retval EFI_OUT_OF_RESOURCES There was not enough memory to load and relocate the PE/COFF file\r
+ @retval EFI_INVALID_PARAMETER The image withou .reloc section can't be relocated.\r
\r
**/\r
EFI_STATUS\r
{\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
//\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
//\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
}\r
\r
/**\r
- Routine for loading file image.\r
+ Loads a PEIM into memory for subsequent execution. If there are compressed \r
+ images or images that need to be relocated into memory for performance reasons, \r
+ this service performs that transformation.\r
\r
- @param PeiServices The PEI core services table.\r
+ @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\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
- @retval EFI_SUCCESS - Image is successfully loaded.\r
- @retval EFI_NOT_FOUND - Fail to locate necessary PPI\r
- @retval Others - Fail to load file.\r
+ @retval EFI_SUCCESS Image is successfully loaded.\r
+ @retval EFI_NOT_FOUND Fail to locate necessary PPI.\r
+ @retval EFI_UNSUPPORTED Image Machine Type is not supported.\r
\r
**/\r
EFI_STATUS\r
PeiLoadImageLoadImage (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
+ IN CONST EFI_PEI_SERVICES **PeiServices,\r
IN EFI_PEI_FILE_HANDLE FileHandle,\r
OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL\r
OUT UINT64 *ImageSizeArg, OPTIONAL\r
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
\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
//\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
}\r
\r
/**\r
+ Routine to load image file for subsequent execution by LoadFile Ppi.\r
+ If any LoadFile Ppi is not found, the build-in support function for the PE32+/TE \r
+ XIP image format is used.\r
\r
- Routine for load image file.\r
-\r
-\r
- @param PeiServices - The PEI core services table.\r
+ @param PeiServices - An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
@param FileHandle - Pointer to the FFS file header of the 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
EFI_STATUS\r
PeiLoadImage (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
+ IN CONST EFI_PEI_SERVICES **PeiServices,\r
IN EFI_PEI_FILE_HANDLE FileHandle,\r
OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
OUT UINT32 *AuthenticationState\r
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