mirror of https://github.com/acidanthera/audk.git
Update PeiCore to support load PEIM into memory on S3 boot path.
Signed-off-by: Liming Gao <liming.gao@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14757 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
5ecc20b553
commit
5d7f312635
|
@ -653,7 +653,7 @@ PeiDispatcher (
|
||||||
PeimFileHandle = NULL;
|
PeimFileHandle = NULL;
|
||||||
EntryPoint = 0;
|
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
|
// 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.
|
// update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE.
|
||||||
|
@ -972,7 +972,7 @@ PeiDispatcher (
|
||||||
ProcessNotifyList (Private);
|
ProcessNotifyList (Private);
|
||||||
|
|
||||||
if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW) && \
|
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.
|
// 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.
|
// We call the entry point a 2nd time so the module knows it's shadowed.
|
||||||
|
|
|
@ -117,7 +117,7 @@ GetImageReadFunction (
|
||||||
|
|
||||||
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
|
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))) {
|
(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
|
// 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_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_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
|
EFI_STATUS
|
||||||
|
@ -349,9 +352,13 @@ LoadAndRelocatePeCoffImage (
|
||||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||||
PEI_CORE_INSTANCE *Private;
|
PEI_CORE_INSTANCE *Private;
|
||||||
UINT64 AlignImageSize;
|
UINT64 AlignImageSize;
|
||||||
|
BOOLEAN IsXipImage;
|
||||||
|
EFI_STATUS ReturnStatus;
|
||||||
|
|
||||||
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
|
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
|
||||||
|
|
||||||
|
ReturnStatus = EFI_SUCCESS;
|
||||||
|
IsXipImage = FALSE;
|
||||||
ZeroMem (&ImageContext, sizeof (ImageContext));
|
ZeroMem (&ImageContext, sizeof (ImageContext));
|
||||||
ImageContext.Handle = Pe32Data;
|
ImageContext.Handle = Pe32Data;
|
||||||
Status = GetImageReadFunction (&ImageContext);
|
Status = GetImageReadFunction (&ImageContext);
|
||||||
|
@ -362,10 +369,18 @@ LoadAndRelocatePeCoffImage (
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return 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.
|
// 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));
|
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.
|
// 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.
|
// Allocate more buffer to avoid buffer overflow.
|
||||||
//
|
//
|
||||||
|
@ -391,7 +406,7 @@ LoadAndRelocatePeCoffImage (
|
||||||
AlignImageSize += ImageContext.SectionAlignment;
|
AlignImageSize += ImageContext.SectionAlignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {
|
if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
|
||||||
Status = GetPeCoffImageFixLoadingAssignedAddress(&ImageContext, Private);
|
Status = GetPeCoffImageFixLoadingAssignedAddress(&ImageContext, Private);
|
||||||
if (EFI_ERROR (Status)){
|
if (EFI_ERROR (Status)){
|
||||||
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
|
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 {
|
} else {
|
||||||
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) AlignImageSize));
|
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) AlignImageSize));
|
||||||
}
|
}
|
||||||
ASSERT (ImageContext.ImageAddress != 0);
|
if (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 =
|
||||||
// Adjust the Image Address to make sure it is section alignment.
|
(ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) &
|
||||||
//
|
~((UINTN)ImageContext.SectionAlignment - 1);
|
||||||
if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
|
}
|
||||||
ImageContext.ImageAddress =
|
//
|
||||||
(ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) &
|
// Fix alignment requirement when Load IPF TeImage into memory.
|
||||||
~((UINTN)ImageContext.SectionAlignment - 1);
|
// Skip the reserved space for the stripped PeHeader when load TeImage into memory.
|
||||||
}
|
//
|
||||||
//
|
if (ImageContext.IsTeImage) {
|
||||||
// Fix alignment requirement when Load IPF TeImage into memory.
|
ImageContext.ImageAddress = ImageContext.ImageAddress +
|
||||||
// Skip the reserved space for the stripped PeHeader when load TeImage into memory.
|
((EFI_TE_IMAGE_HEADER *) Pe32Data)->StrippedSize -
|
||||||
//
|
sizeof (EFI_TE_IMAGE_HEADER);
|
||||||
if (ImageContext.IsTeImage) {
|
}
|
||||||
ImageContext.ImageAddress = ImageContext.ImageAddress +
|
} else {
|
||||||
((EFI_TE_IMAGE_HEADER *) Pe32Data)->StrippedSize -
|
//
|
||||||
sizeof (EFI_TE_IMAGE_HEADER);
|
// 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
|
// 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);
|
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,7 +482,7 @@ LoadAndRelocatePeCoffImage (
|
||||||
*ImageSize = ImageContext.ImageSize;
|
*ImageSize = ImageContext.ImageSize;
|
||||||
*EntryPoint = ImageContext.EntryPoint;
|
*EntryPoint = ImageContext.EntryPoint;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return ReturnStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -471,6 +500,9 @@ LoadAndRelocatePeCoffImage (
|
||||||
@retval EFI_SUCCESS Image is successfully loaded.
|
@retval EFI_SUCCESS Image is successfully loaded.
|
||||||
@retval EFI_NOT_FOUND Fail to locate necessary PPI.
|
@retval EFI_NOT_FOUND Fail to locate necessary PPI.
|
||||||
@retval EFI_UNSUPPORTED Image Machine Type is not supported.
|
@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
|
EFI_STATUS
|
||||||
|
@ -785,7 +817,7 @@ PeiLoadImage (
|
||||||
EntryPoint,
|
EntryPoint,
|
||||||
AuthenticationState
|
AuthenticationState
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status) || Status == EFI_WARN_BUFFER_TOO_SMALL) {
|
||||||
//
|
//
|
||||||
// The shadowed PEIM must be relocatable.
|
// The shadowed PEIM must be relocatable.
|
||||||
//
|
//
|
||||||
|
@ -804,7 +836,7 @@ PeiLoadImage (
|
||||||
if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *) (UINTN) ImageAddress))) {
|
if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *) (UINTN) ImageAddress))) {
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
return Status;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Index++;
|
Index++;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
# 2) Dispatch PEIM from discovered FV.
|
# 2) Dispatch PEIM from discovered FV.
|
||||||
# 3) Handoff control to DxeIpl to load DXE core and enter DXE phase.
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -98,4 +98,4 @@
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber ## SOMETIMES_CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber ## SOMETIMES_CONSUMES
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressRuntimeCodePageNumber ## SOMETIMES_CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressRuntimeCodePageNumber ## SOMETIMES_CONSUMES
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable ## CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable ## CONSUMES
|
||||||
|
gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot ## SOMETIMES_CONSUMES
|
||||||
|
|
|
@ -662,6 +662,9 @@
|
||||||
#
|
#
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxEfiSystemTablePointerAddress|0x0|UINT64|0x30001027
|
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.
|
## Default OEM ID for ACPI table creation, its length must be 0x6 bytes to follow ACPI specification.
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|"INTEL "|VOID*|0x30001034
|
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|"INTEL "|VOID*|0x30001034
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Load image file from fv to memory.
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -47,6 +47,9 @@ typedef struct _EFI_PEI_LOAD_FILE_PPI EFI_PEI_LOAD_FILE_PPI;
|
||||||
@retval EFI_INVALID_PARAMETER EntryPoint was NULL.
|
@retval EFI_INVALID_PARAMETER EntryPoint was NULL.
|
||||||
@retval EFI_UNSUPPORTED An image requires relocations or is not
|
@retval EFI_UNSUPPORTED An image requires relocations or is not
|
||||||
memory mapped.
|
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
|
typedef
|
||||||
|
|
Loading…
Reference in New Issue