diff options
-rw-r--r-- | MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 4 | ||||
-rw-r--r-- | MdeModulePkg/Core/Pei/Image/Image.c | 90 | ||||
-rw-r--r-- | MdeModulePkg/Core/Pei/PeiMain.inf | 4 | ||||
-rw-r--r-- | MdeModulePkg/MdeModulePkg.dec | 3 | ||||
-rw-r--r-- | MdePkg/Include/Ppi/LoadFile.h | 7 |
5 files changed, 73 insertions, 35 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
diff --git a/MdePkg/Include/Ppi/LoadFile.h b/MdePkg/Include/Ppi/LoadFile.h index fdc9ce2605..03bfb32af0 100644 --- a/MdePkg/Include/Ppi/LoadFile.h +++ b/MdePkg/Include/Ppi/LoadFile.h @@ -1,7 +1,7 @@ /** @file
Load image file from fv to memory.
- Copyright (c) 2006 - 2011, 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
which accompanies this distribution. The full text of the license may be found at
@@ -47,7 +47,10 @@ typedef struct _EFI_PEI_LOAD_FILE_PPI EFI_PEI_LOAD_FILE_PPI; @retval EFI_INVALID_PARAMETER EntryPoint was NULL.
@retval EFI_UNSUPPORTED An image requires relocations or is not
memory mapped.
-
+ @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.
+
**/
typedef
EFI_STATUS
|