From 5d7f312635c8c6580e80868b2a2d7dd971ac7f88 Mon Sep 17 00:00:00 2001 From: Liming Gao Date: Wed, 9 Oct 2013 05:39:51 +0000 Subject: Update PeiCore to support load PEIM into memory on S3 boot path. Signed-off-by: Liming Gao Reviewed-by: Star Zeng git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14757 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 4 +- MdeModulePkg/Core/Pei/Image/Image.c | 90 ++++++++++++++++++--------- MdeModulePkg/Core/Pei/PeiMain.inf | 4 +- 3 files changed, 65 insertions(+), 33 deletions(-) (limited to 'MdeModulePkg/Core') 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.
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
# # 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 -- cgit v1.2.3