-/**\r
- Loads and relocates a PE/COFF image into memory.\r
-\r
- @param FileHandle The image file handle\r
- @param ImageAddress The base address of the relocated PE/COFF image\r
- @param ImageSize The size of the relocated PE/COFF image\r
- @param EntryPoint The entry point of the relocated PE/COFF image\r
- \r
- @return EFI_SUCCESS The file was loaded and relocated\r
- @return EFI_OUT_OF_RESOURCES There was not enough memory to load and relocate the PE/COFF file\r
-\r
-**/\r
-EFI_STATUS\r
-PeiLoadFile (\r
- IN EFI_PEI_FILE_HANDLE FileHandle,\r
- OUT EFI_PHYSICAL_ADDRESS *ImageAddress,\r
- OUT UINT64 *ImageSize,\r
- OUT EFI_PHYSICAL_ADDRESS *EntryPoint\r
- )\r
-{\r
-\r
- EFI_STATUS Status;\r
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
- VOID *Pe32Data;\r
-\r
- //\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
- if (EFI_ERROR (Status)) {\r
- //\r
- // NO image types we support so exit.\r
- //\r
- return Status;\r
- }\r
-\r
- ZeroMem (&ImageContext, sizeof (ImageContext));\r
- ImageContext.Handle = Pe32Data;\r
- Status = GetImageReadFunction (&ImageContext);\r
-\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\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
- // Load the image to our new buffer\r
- //\r
- Status = PeCoffLoaderLoadImage (&ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Relocate the image in our new buffer\r
- //\r
- Status = PeCoffLoaderRelocateImage (&ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\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
-\r
- *ImageAddress = ImageContext.ImageAddress;\r
- *ImageSize = ImageContext.ImageSize;\r
- *EntryPoint = ImageContext.EntryPoint;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r