summaryrefslogtreecommitdiff
path: root/MdeModulePkg
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg')
-rw-r--r--MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c4
-rw-r--r--MdeModulePkg/Core/Pei/Image/Image.c90
-rw-r--r--MdeModulePkg/Core/Pei/PeiMain.inf4
-rw-r--r--MdeModulePkg/MdeModulePkg.dec3
4 files changed, 68 insertions, 33 deletions
diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
index 2063fa4dbb..b0e4b6d12a 100644
--- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -653,7 +653,7 @@ PeiDispatcher (
PeimFileHandle = NULL;
EntryPoint = 0;
- if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
+ if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {
//
// Once real memory is available, shadow the RegisterForShadow modules. And meanwhile
// update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE.
@@ -972,7 +972,7 @@ PeiDispatcher (
ProcessNotifyList (Private);
if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW) && \
- (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
+ (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {
//
// If memory is availble we shadow images by default for performance reasons.
// We call the entry point a 2nd time so the module knows it's shadowed.
diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c
index 85e5e3fcf3..7a1d815b2b 100644
--- a/MdeModulePkg/Core/Pei/Image/Image.c
+++ b/MdeModulePkg/Core/Pei/Image/Image.c
@@ -117,7 +117,7 @@ GetImageReadFunction (
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
- if ((Private->PeiMemoryInstalled && !(Private->HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME)) &&
+ if (Private->PeiMemoryInstalled && ((Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) || PcdGetBool (PcdShadowPeimOnS3Boot)) &&
(EFI_IMAGE_MACHINE_TYPE_SUPPORTED(EFI_IMAGE_MACHINE_X64) || EFI_IMAGE_MACHINE_TYPE_SUPPORTED(EFI_IMAGE_MACHINE_IA32))) {
//
// Shadow algorithm makes lots of non ANSI C assumptions and only works for IA32 and X64
@@ -335,6 +335,9 @@ GetPeCoffImageFixLoadingAssignedAddress(
@retval EFI_SUCCESS The file was loaded and relocated
@retval EFI_OUT_OF_RESOURCES There was not enough memory to load and relocate the PE/COFF file
+ @retval EFI_WARN_BUFFER_TOO_SMALL
+ There is not enough heap to allocate the requested size.
+ This will not prevent the XIP image from being invoked.
**/
EFI_STATUS
@@ -349,9 +352,13 @@ LoadAndRelocatePeCoffImage (
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
PEI_CORE_INSTANCE *Private;
UINT64 AlignImageSize;
+ BOOLEAN IsXipImage;
+ EFI_STATUS ReturnStatus;
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
+ ReturnStatus = EFI_SUCCESS;
+ IsXipImage = FALSE;
ZeroMem (&ImageContext, sizeof (ImageContext));
ImageContext.Handle = Pe32Data;
Status = GetImageReadFunction (&ImageContext);
@@ -362,10 +369,18 @@ LoadAndRelocatePeCoffImage (
if (EFI_ERROR (Status)) {
return Status;
}
+
+ //
+ // XIP image that ImageAddress is same to Image handle.
+ //
+ if (ImageContext.ImageAddress == (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data) {
+ IsXipImage = TRUE;
+ }
+
//
// When Image has no reloc section, it can't be relocated into memory.
//
- if (ImageContext.RelocationsStripped && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
+ if (ImageContext.RelocationsStripped && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN) Pe32Data));
}
@@ -377,7 +392,7 @@ LoadAndRelocatePeCoffImage (
//
// Allocate Memory for the image when memory is ready, boot mode is not S3, and image is relocatable.
//
- if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
+ if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {
//
// Allocate more buffer to avoid buffer overflow.
//
@@ -391,7 +406,7 @@ LoadAndRelocatePeCoffImage (
AlignImageSize += ImageContext.SectionAlignment;
}
- if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {
+ if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
Status = GetPeCoffImageFixLoadingAssignedAddress(&ImageContext, Private);
if (EFI_ERROR (Status)){
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
@@ -403,27 +418,41 @@ LoadAndRelocatePeCoffImage (
} else {
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) AlignImageSize));
}
- ASSERT (ImageContext.ImageAddress != 0);
- if (ImageContext.ImageAddress == 0) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Adjust the Image Address to make sure it is section alignment.
- //
- if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
- ImageContext.ImageAddress =
- (ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) &
- ~((UINTN)ImageContext.SectionAlignment - 1);
- }
- //
- // Fix alignment requirement when Load IPF TeImage into memory.
- // Skip the reserved space for the stripped PeHeader when load TeImage into memory.
- //
- if (ImageContext.IsTeImage) {
- ImageContext.ImageAddress = ImageContext.ImageAddress +
- ((EFI_TE_IMAGE_HEADER *) Pe32Data)->StrippedSize -
- sizeof (EFI_TE_IMAGE_HEADER);
+ if (ImageContext.ImageAddress != 0) {
+ //
+ // Adjust the Image Address to make sure it is section alignment.
+ //
+ if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
+ ImageContext.ImageAddress =
+ (ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) &
+ ~((UINTN)ImageContext.SectionAlignment - 1);
+ }
+ //
+ // Fix alignment requirement when Load IPF TeImage into memory.
+ // Skip the reserved space for the stripped PeHeader when load TeImage into memory.
+ //
+ if (ImageContext.IsTeImage) {
+ ImageContext.ImageAddress = ImageContext.ImageAddress +
+ ((EFI_TE_IMAGE_HEADER *) Pe32Data)->StrippedSize -
+ sizeof (EFI_TE_IMAGE_HEADER);
+ }
+ } else {
+ //
+ // No enough memory resource.
+ //
+ if (IsXipImage) {
+ //
+ // XIP image can still be invoked.
+ //
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data;
+ ReturnStatus = EFI_WARN_BUFFER_TOO_SMALL;
+ } else {
+ //
+ // Non XIP image can't be loaded because no enough memory is allocated.
+ //
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
}
}
@@ -445,7 +474,7 @@ LoadAndRelocatePeCoffImage (
//
// Flush the instruction cache so the image data is written before we execute it
//
- if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
+ if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data) {
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
}
@@ -453,7 +482,7 @@ LoadAndRelocatePeCoffImage (
*ImageSize = ImageContext.ImageSize;
*EntryPoint = ImageContext.EntryPoint;
- return EFI_SUCCESS;
+ return ReturnStatus;
}
/**
@@ -471,6 +500,9 @@ LoadAndRelocatePeCoffImage (
@retval EFI_SUCCESS Image is successfully loaded.
@retval EFI_NOT_FOUND Fail to locate necessary PPI.
@retval EFI_UNSUPPORTED Image Machine Type is not supported.
+ @retval EFI_WARN_BUFFER_TOO_SMALL
+ There is not enough heap to allocate the requested size.
+ This will not prevent the XIP image from being invoked.
**/
EFI_STATUS
@@ -785,7 +817,7 @@ PeiLoadImage (
EntryPoint,
AuthenticationState
);
- if (!EFI_ERROR (Status)) {
+ if (!EFI_ERROR (Status) || Status == EFI_WARN_BUFFER_TOO_SMALL) {
//
// The shadowed PEIM must be relocatable.
//
@@ -804,7 +836,7 @@ PeiLoadImage (
if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *) (UINTN) ImageAddress))) {
return EFI_UNSUPPORTED;
}
- return Status;
+ return EFI_SUCCESS;
}
}
Index++;
diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf
index 2cf9df7ce1..7cfce0b31a 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.inf
+++ b/MdeModulePkg/Core/Pei/PeiMain.inf
@@ -4,7 +4,7 @@
# 2) Dispatch PEIM from discovered FV.
# 3) Handoff control to DxeIpl to load DXE core and enter DXE phase.
#
-# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -98,4 +98,4 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressRuntimeCodePageNumber ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable ## CONSUMES
-
+ gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot ## SOMETIMES_CONSUMES
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index d3fcf95f0b..fc9f9ccd99 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -662,6 +662,9 @@
#
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxEfiSystemTablePointerAddress|0x0|UINT64|0x30001027
+ ## This PCD specifies whether to shadow PEIM on S3 boot path after memory is ready.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot|FALSE|BOOLEAN|0x30001028
+
## Default OEM ID for ACPI table creation, its length must be 0x6 bytes to follow ACPI specification.
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|"INTEL "|VOID*|0x30001034