\r
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r
\r
- if ((Private->PeiMemoryInstalled && !(Private->HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME)) &&\r
+ if (Private->PeiMemoryInstalled && ((Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) || PcdGetBool (PcdShadowPeimOnS3Boot)) &&\r
(EFI_IMAGE_MACHINE_TYPE_SUPPORTED(EFI_IMAGE_MACHINE_X64) || EFI_IMAGE_MACHINE_TYPE_SUPPORTED(EFI_IMAGE_MACHINE_IA32))) {\r
// \r
// Shadow algorithm makes lots of non ANSI C assumptions and only works for IA32 and X64 \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_WARN_BUFFER_TOO_SMALL \r
+ There is not enough heap to allocate the requested size.\r
+ This will not prevent the XIP image from being invoked.\r
\r
**/\r
EFI_STATUS\r
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
PEI_CORE_INSTANCE *Private;\r
UINT64 AlignImageSize;\r
+ BOOLEAN IsXipImage;\r
+ EFI_STATUS ReturnStatus;\r
\r
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r
\r
+ ReturnStatus = EFI_SUCCESS;\r
+ IsXipImage = FALSE;\r
ZeroMem (&ImageContext, sizeof (ImageContext));\r
ImageContext.Handle = Pe32Data;\r
Status = GetImageReadFunction (&ImageContext);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+ \r
+ //\r
+ // XIP image that ImageAddress is same to Image handle.\r
+ //\r
+ if (ImageContext.ImageAddress == (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data) {\r
+ IsXipImage = TRUE;\r
+ }\r
+\r
//\r
// When Image has no reloc section, it can't be relocated into memory.\r
//\r
- if (ImageContext.RelocationsStripped && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
+ if (ImageContext.RelocationsStripped && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {\r
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN) Pe32Data));\r
}\r
\r
//\r
// Allocate Memory for the image when memory is ready, boot mode is not S3, and image is relocatable.\r
//\r
- if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
+ if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {\r
//\r
// Allocate more buffer to avoid buffer overflow.\r
//\r
AlignImageSize += ImageContext.SectionAlignment;\r
}\r
\r
- if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {\r
+ if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
Status = GetPeCoffImageFixLoadingAssignedAddress(&ImageContext, Private);\r
if (EFI_ERROR (Status)){\r
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));\r
} else {\r
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) AlignImageSize));\r
}\r
- ASSERT (ImageContext.ImageAddress != 0);\r
- if (ImageContext.ImageAddress == 0) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Adjust the Image Address to make sure it is section alignment.\r
- //\r
- if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {\r
- ImageContext.ImageAddress =\r
- (ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) &\r
- ~((UINTN)ImageContext.SectionAlignment - 1);\r
- }\r
- //\r
- // Fix alignment requirement when Load IPF TeImage into memory.\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 (ImageContext.ImageAddress != 0) {\r
+ //\r
+ // Adjust the Image Address to make sure it is section alignment.\r
+ //\r
+ if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {\r
+ ImageContext.ImageAddress =\r
+ (ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) &\r
+ ~((UINTN)ImageContext.SectionAlignment - 1);\r
+ }\r
+ //\r
+ // Fix alignment requirement when Load IPF TeImage into memory.\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
+ //\r
+ // No enough memory resource.\r
+ //\r
+ if (IsXipImage) {\r
+ //\r
+ // XIP image can still be invoked.\r
+ //\r
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data;\r
+ ReturnStatus = EFI_WARN_BUFFER_TOO_SMALL;\r
+ } else {\r
+ //\r
+ // Non XIP image can't be loaded because no enough memory is allocated.\r
+ //\r
+ ASSERT (FALSE);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
}\r
}\r
\r
//\r
// Flush the instruction cache so the image data is written before we execute it\r
//\r
- if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
+ if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data) {\r
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
}\r
\r
*ImageSize = ImageContext.ImageSize;\r
*EntryPoint = ImageContext.EntryPoint;\r
\r
- return EFI_SUCCESS;\r
+ return ReturnStatus;\r
}\r
\r
/**\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
+ @retval EFI_WARN_BUFFER_TOO_SMALL \r
+ There is not enough heap to allocate the requested size.\r
+ This will not prevent the XIP image from being invoked.\r
\r
**/\r
EFI_STATUS\r
EntryPoint,\r
AuthenticationState\r
);\r
- if (!EFI_ERROR (Status)) {\r
+ if (!EFI_ERROR (Status) || Status == EFI_WARN_BUFFER_TOO_SMALL) {\r
//\r
// The shadowed PEIM must be relocatable.\r
//\r
if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *) (UINTN) ImageAddress))) {\r
return EFI_UNSUPPORTED;\r
}\r
- return Status;\r
+ return EFI_SUCCESS;\r
}\r
}\r
Index++;\r