X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FCore%2FDxeIplPeim%2FDxeLoad.c;h=c6e5b8330927ed093cac6222b1591160cbf0b989;hp=3382cd409bd5528c4dfd319eada7596b9981a4a5;hb=9d510e61fceee7b92955ef9a3c20343752d8ce3f;hpb=310bc7635c9380d35c31c793cd9f46c8dfab255b
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
index 3382cd409b..c6e5b83309 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
@@ -2,33 +2,29 @@
Last PEIM.
Responsibility of this module is to load the DXE Core from a Firmware Volume.
-Copyright (c) 2006 - 2008, 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
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+Copyright (c) 2016 HP Development Company, L.P.
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "DxeIpl.h"
-//
-// This global variable indicates whether this module has been shadowed
-// to memory.
-//
-BOOLEAN gInMemory = FALSE;
//
-// Module Globals used in the DXE to PEI handoff
+// Module Globals used in the DXE to PEI hand off
// These must be module globals, so the stack can be switched
//
CONST EFI_DXE_IPL_PPI mDxeIplPpi = {
DxeLoadCore
};
+CONST EFI_PEI_PPI_DESCRIPTOR mDxeIplPpiList = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiDxeIplPpiGuid,
+ (VOID *) &mDxeIplPpi
+};
+
CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {
CustomGuidedSectionExtract
};
@@ -37,99 +33,213 @@ CONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {
Decompress
};
-CONST EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
- {
- EFI_PEI_PPI_DESCRIPTOR_PPI,
- &gEfiDxeIplPpiGuid,
- (VOID *) &mDxeIplPpi
- },
- {
- (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
- &gEfiPeiDecompressPpiGuid,
- (VOID *) &mDecompressPpi
- }
+CONST EFI_PEI_PPI_DESCRIPTOR mDecompressPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiDecompressPpiGuid,
+ (VOID *) &mDecompressPpi
};
-CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {
+CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiEndOfPeiSignalPpiGuid,
NULL
};
+CONST EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMemoryDiscoveredPpiGuid,
+ InstallIplPermanentMemoryPpis
+};
+
/**
- Initializes the Dxe Ipl PPI
+ Entry point of DXE IPL PEIM.
+
+ This function installs DXE IPL PPI. It also reloads
+ itself to memory on non-S3 resume boot path.
- @param FfsHandle The handle of FFS file.
- @param PeiServices General purpose services available to
- every PEIM.
- @return EFI_SUCESS
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCESS The entry point of DXE IPL PEIM executes successfully.
+ @retval Others Some error occurs during the execution of this function.
**/
EFI_STATUS
EFIAPI
PeimInitializeDxeIpl (
- IN EFI_PEI_FILE_HANDLE FfsHandle,
- IN CONST EFI_PEI_SERVICES **PeiServices
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
EFI_BOOT_MODE BootMode;
- EFI_GUID *ExtractHandlerGuidTable;
- UINTN ExtractHandlerNumber;
- EFI_PEI_PPI_DESCRIPTOR *GuidPpi;
-
+ VOID *Dummy;
+
BootMode = GetBootModeHob ();
if (BootMode != BOOT_ON_S3_RESUME) {
- Status = PeiServicesRegisterForShadow (FfsHandle);
+ Status = PeiServicesRegisterForShadow (FileHandle);
if (Status == EFI_SUCCESS) {
//
- // EFI_SUCESS means the first time call register for shadow
- //
- return Status;
- } else if (Status == EFI_ALREADY_STARTED) {
-
- //
- // Get custom extract guided section method guid list
- //
- ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
-
+ // EFI_SUCESS means it is the first time to call register for shadow.
//
- // Install custom extraction guid ppi
- //
- if (ExtractHandlerNumber > 0) {
- GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
- ASSERT (GuidPpi != NULL);
- while (ExtractHandlerNumber-- > 0) {
- GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
- GuidPpi->Ppi = (VOID *) &mCustomGuidedSectionExtractionPpi;
- GuidPpi->Guid = &(ExtractHandlerGuidTable [ExtractHandlerNumber]);
- Status = PeiServicesInstallPpi (GuidPpi++);
- ASSERT_EFI_ERROR(Status);
- }
- }
- } else {
- ASSERT (FALSE);
+ return Status;
+ }
+
+ //
+ // Ensure that DXE IPL is shadowed to permanent memory.
+ //
+ ASSERT (Status == EFI_ALREADY_STARTED);
+
+ //
+ // DXE core load requires permanent memory.
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiMemoryDiscoveredPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &Dummy
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Now the permanent memory exists, install the PPIs for decompression
+ // and section extraction.
+ //
+ Status = InstallIplPermanentMemoryPpis (NULL, NULL, NULL);
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ //
+ // Install memory discovered PPI notification to install PPIs for
+ // decompression and section extraction.
+ //
+ Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Install DxeIpl PPI.
+ //
+ Status = PeiServicesInstallPpi (&mDxeIplPpiList);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+/**
+ This function installs the PPIs that require permanent memory.
+
+ @param PeiServices Indirect reference to the PEI Services Table.
+ @param NotifyDescriptor Address of the notification descriptor data structure.
+ @param Ppi Address of the PPI that was installed.
+
+ @return EFI_SUCCESS The PPIs were installed successfully.
+ @return Others Some error occurs during the execution of this function.
+
+**/
+EFI_STATUS
+EFIAPI
+InstallIplPermanentMemoryPpis (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+ EFI_GUID *ExtractHandlerGuidTable;
+ UINTN ExtractHandlerNumber;
+ EFI_PEI_PPI_DESCRIPTOR *GuidPpi;
+
+ //
+ // Get custom extract guided section method guid list
+ //
+ ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
+
+ //
+ // Install custom guided section extraction PPI
+ //
+ if (ExtractHandlerNumber > 0) {
+ GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
+ ASSERT (GuidPpi != NULL);
+ while (ExtractHandlerNumber-- > 0) {
+ GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ GuidPpi->Ppi = (VOID *) &mCustomGuidedSectionExtractionPpi;
+ GuidPpi->Guid = &ExtractHandlerGuidTable[ExtractHandlerNumber];
+ Status = PeiServicesInstallPpi (GuidPpi++);
+ ASSERT_EFI_ERROR(Status);
}
}
-
+
//
- // Install DxeIpl and Decompress PPIs.
+ // Install Decompress PPI.
//
- Status = PeiServicesInstallPpi (mPpiList);
+ Status = PeiServicesInstallPpi (&mDecompressPpiList);
ASSERT_EFI_ERROR(Status);
return Status;
}
/**
- Main entry point to last PEIM.
-
+ Validate variable data for the MemoryTypeInformation.
+
+ @param MemoryData Variable data.
+ @param MemoryDataSize Variable data length.
+
+ @return TRUE The variable data is valid.
+ @return FALSE The variable data is invalid.
+
+**/
+BOOLEAN
+ValidateMemoryTypeInfoVariable (
+ IN EFI_MEMORY_TYPE_INFORMATION *MemoryData,
+ IN UINTN MemoryDataSize
+ )
+{
+ UINTN Count;
+ UINTN Index;
+
+ // Check the input parameter.
+ if (MemoryData == NULL) {
+ return FALSE;
+ }
+
+ // Get Count
+ Count = MemoryDataSize / sizeof (*MemoryData);
+
+ // Check Size
+ if (Count * sizeof(*MemoryData) != MemoryDataSize) {
+ return FALSE;
+ }
+
+ // Check last entry type filed.
+ if (MemoryData[Count - 1].Type != EfiMaxMemoryType) {
+ return FALSE;
+ }
+
+ // Check the type filed.
+ for (Index = 0; Index < Count - 1; Index++) {
+ if (MemoryData[Index].Type >= EfiMaxMemoryType) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ Main entry point to last PEIM.
+
+ This function finds DXE Core in the firmware volume and transfer the control to
+ DXE core.
+
@param This Entry point for DXE IPL PPI.
@param PeiServices General purpose services available to every PEIM.
@param HobList Address to the Pei HOB list.
-
- @return EFI_SUCCESS DXE core was successfully loaded.
+
+ @return EFI_SUCCESS DXE core was successfully loaded.
@return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core.
**/
@@ -149,7 +259,12 @@ DxeLoadCore (
EFI_BOOT_MODE BootMode;
EFI_PEI_FILE_HANDLE FileHandle;
EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
+ EFI_PEI_LOAD_FILE_PPI *LoadFile;
+ UINTN Instance;
+ UINT32 AuthenticationState;
UINTN DataSize;
+ EFI_PEI_S3_RESUME2_PPI *S3Resume;
+ EFI_PEI_RECOVERY_MODULE_PPI *PeiRecovery;
EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1];
//
@@ -158,45 +273,95 @@ DxeLoadCore (
BootMode = GetBootModeHob ();
if (BootMode == BOOT_ON_S3_RESUME) {
- Status = AcpiS3ResumeOs();
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiS3Resume2PpiGuid,
+ 0,
+ NULL,
+ (VOID **) &S3Resume
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Report Status code that S3Resume PPI can not be found
+ //
+ REPORT_STATUS_CODE (
+ EFI_ERROR_CODE | EFI_ERROR_MAJOR,
+ (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND)
+ );
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ Status = S3Resume->S3RestoreConfig2 (S3Resume);
ASSERT_EFI_ERROR (Status);
} else if (BootMode == BOOT_IN_RECOVERY_MODE) {
- Status = PeiRecoverFirmware ();
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN));
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiRecoveryModulePpiGuid,
+ 0,
+ NULL,
+ (VOID **) &PeiRecovery
+ );
+
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));
+ DEBUG ((DEBUG_ERROR, "Locate Recovery PPI Failed.(Status = %r)\n", Status));
+ //
+ // Report Status code the failure of locating Recovery PPI
+ //
+ REPORT_STATUS_CODE (
+ EFI_ERROR_CODE | EFI_ERROR_MAJOR,
+ (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND)
+ );
CpuDeadLoop ();
}
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD));
+ Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));
+ //
+ // Report Status code that recovery image can not be found
+ //
+ REPORT_STATUS_CODE (
+ EFI_ERROR_CODE | EFI_ERROR_MAJOR,
+ (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE)
+ );
+ CpuDeadLoop ();
+ }
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START));
//
- // Now should have a HOB with the DXE core w/ the old HOB destroyed
+ // Now should have a HOB with the DXE core
//
}
- Status = PeiServicesLocatePpi (
- &gEfiPeiReadOnlyVariable2PpiGuid,
- 0,
- NULL,
- (VOID **)&Variable
- );
- if (!EFI_ERROR (Status)) {
- DataSize = sizeof (MemoryData);
- Status = Variable->GetVariable (
- Variable,
- EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
- &gEfiMemoryTypeInformationGuid,
- NULL,
- &DataSize,
- &MemoryData
- );
+ if (GetFirstGuidHob ((CONST EFI_GUID *)&gEfiMemoryTypeInformationGuid) == NULL) {
+ //
+ // Don't build GuidHob if GuidHob has been installed.
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (VOID **)&Variable
+ );
if (!EFI_ERROR (Status)) {
- //
- // Build the GUID'd HOB for DXE
- //
- BuildGuidDataHob (
- &gEfiMemoryTypeInformationGuid,
- MemoryData,
- DataSize
- );
+ DataSize = sizeof (MemoryData);
+ Status = Variable->GetVariable (
+ Variable,
+ EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
+ &gEfiMemoryTypeInformationGuid,
+ NULL,
+ &DataSize,
+ &MemoryData
+ );
+ if (!EFI_ERROR (Status) && ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) {
+ //
+ // Build the GUID'd HOB for DXE
+ //
+ BuildGuidDataHob (
+ &gEfiMemoryTypeInformationGuid,
+ MemoryData,
+ DataSize
+ );
+ }
}
}
@@ -206,15 +371,25 @@ DxeLoadCore (
FileHandle = DxeIplFindDxeCore ();
//
- // Load the DXE Core from a Firmware Volume, may use LoadFile ppi to do this for save code size.
+ // Load the DXE Core from a Firmware Volume.
//
- Status = PeiLoadFile (
- FileHandle,
- &DxeCoreAddress,
- &DxeCoreSize,
- &DxeCoreEntryPoint
- );
- ASSERT_EFI_ERROR (Status);
+ Instance = 0;
+ do {
+ Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **) &LoadFile);
+ //
+ // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully.
+ //
+ ASSERT_EFI_ERROR (Status);
+
+ Status = LoadFile->LoadFile (
+ LoadFile,
+ FileHandle,
+ &DxeCoreAddress,
+ &DxeCoreSize,
+ &DxeCoreEntryPoint,
+ &AuthenticationState
+ );
+ } while (EFI_ERROR (Status));
//
// Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name.
@@ -228,28 +403,25 @@ DxeLoadCore (
BuildModuleHob (
&DxeCoreFileInfo.FileName,
DxeCoreAddress,
- EFI_SIZE_TO_PAGES ((UINTN) DxeCoreSize) * EFI_PAGE_SIZE,
+ ALIGN_VALUE (DxeCoreSize, EFI_PAGE_SIZE),
DxeCoreEntryPoint
);
//
// Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
//
- REPORT_STATUS_CODE (
- EFI_PROGRESS_CODE,
- PcdGet32(PcdStatusCodeValuePeiHandoffToDxe)
- );
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT));
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint)));
//
// Transfer control to the DXE Core
- // The handoff state is simply a pointer to the HOB list
+ // The hand off state is simply a pointer to the HOB list
//
HandOffToDxeCore (DxeCoreEntryPoint, HobList);
//
// If we get here, then the DXE Core returned. This is an error
- // Dxe Core should not return.
+ // DxeCore should not return.
//
ASSERT (FALSE);
CpuDeadLoop ();
@@ -263,7 +435,7 @@ DxeLoadCore (
instance that contains DxeCore.
@return FileHandle of DxeCore to load DxeCore.
-
+
**/
EFI_PEI_FILE_HANDLE
DxeIplFindDxeCore (
@@ -274,7 +446,7 @@ DxeIplFindDxeCore (
UINTN Instance;
EFI_PEI_FV_HANDLE VolumeHandle;
EFI_PEI_FILE_HANDLE FileHandle;
-
+
Instance = 0;
while (TRUE) {
//
@@ -285,8 +457,11 @@ DxeIplFindDxeCore (
// If some error occurs here, then we cannot find any firmware
// volume that may contain DxeCore.
//
+ if (EFI_ERROR (Status)) {
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT));
+ }
ASSERT_EFI_ERROR (Status);
-
+
//
// Find the DxeCore file type from the beginning in this firmware volume.
//
@@ -307,96 +482,6 @@ DxeIplFindDxeCore (
}
-/**
- Loads and relocates a PE/COFF image into memory.
-
- @param FileHandle The image file handle
- @param ImageAddress The base address of the relocated PE/COFF image
- @param ImageSize The size of the relocated PE/COFF image
- @param EntryPoint The entry point of the relocated PE/COFF image
-
- @return EFI_SUCCESS The file was loaded and relocated
- @return EFI_OUT_OF_RESOURCES There was not enough memory to load and relocate the PE/COFF file
-
-**/
-EFI_STATUS
-PeiLoadFile (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
- OUT UINT64 *ImageSize,
- OUT EFI_PHYSICAL_ADDRESS *EntryPoint
- )
-{
-
- EFI_STATUS Status;
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
- VOID *Pe32Data;
-
- //
- // First try to find the PE32 section in this ffs file.
- //
- Status = PeiServicesFfsFindSectionData (
- EFI_SECTION_PE32,
- FileHandle,
- &Pe32Data
- );
- if (EFI_ERROR (Status)) {
- //
- // NO image types we support so exit.
- //
- return Status;
- }
-
- ZeroMem (&ImageContext, sizeof (ImageContext));
- ImageContext.Handle = Pe32Data;
- Status = GetImageReadFunction (&ImageContext);
-
- ASSERT_EFI_ERROR (Status);
-
- Status = PeCoffLoaderGetImageInfo (&ImageContext);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Allocate Memory for the image
- //
- Status = PeiServicesAllocatePages (
- EfiBootServicesCode,
- EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize),
- &ImageContext.ImageAddress
- );
- ASSERT_EFI_ERROR (Status);
- ASSERT (ImageContext.ImageAddress != 0);
-
- //
- // Load the image to our new buffer
- //
- Status = PeCoffLoaderLoadImage (&ImageContext);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Relocate the image in our new buffer
- //
- Status = PeCoffLoaderRelocateImage (&ImageContext);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Flush the instruction cache so the image data is written before we execute it
- //
- InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
-
- *ImageAddress = ImageContext.ImageAddress;
- *ImageSize = ImageContext.ImageSize;
- *EntryPoint = ImageContext.EntryPoint;
-
- return EFI_SUCCESS;
-}
-
-
-
/**
The ExtractSection() function processes the input section and
@@ -429,7 +514,7 @@ PeiLoadFile (
output buffer. If the input
section's GuidedSectionHeader.
Attributes field has the
- EFI_GUIDED_SECTION_AUTH_STATUS_VALID
+ EFI_GUIDED_SECTION_AUTH_STATUS_VALID
bit as clear,
AuthenticationStatus must return
zero. These bits reflect the
@@ -439,20 +524,21 @@ PeiLoadFile (
EFI_SUCCESS, the value of
AuthenticationStatus is
undefined.
-
+
@retval EFI_SUCCESS The InputSection was
successfully processed and the
section contents were returned.
-
+
@retval EFI_OUT_OF_RESOURCES The system has insufficient
resources to process the request.
-
+
@retval EFI_INVALID_PARAMETER The GUID in InputSection does
not match this instance of the
GUIDed Section Extraction PPI.
**/
EFI_STATUS
+EFIAPI
CustomGuidedSectionExtract (
IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
IN CONST VOID *InputSection,
@@ -466,7 +552,7 @@ CustomGuidedSectionExtract (
UINT32 ScratchBufferSize;
UINT32 OutputBufferSize;
UINT16 SectionAttribute;
-
+
//
// Init local variable
//
@@ -481,12 +567,12 @@ CustomGuidedSectionExtract (
&ScratchBufferSize,
&SectionAttribute
);
-
+
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));
return Status;
}
-
+
if (ScratchBufferSize != 0) {
//
// Allocate scratch buffer
@@ -497,28 +583,23 @@ CustomGuidedSectionExtract (
}
}
- if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {
+ if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {
//
// Allocate output buffer
//
- *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);
+ *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize));
if (*OutputBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
- DEBUG ((DEBUG_INFO, "Customed Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
- //
- // *OutputBuffer still is one section. Adjust *OutputBuffer offset,
- // skip EFI section header to make section data at page alignment.
- //
- *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));
+ DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
}
-
+
Status = ExtractGuidedSectionDecode (
- InputSection,
+ InputSection,
OutputBuffer,
ScratchBuffer,
AuthenticationStatus
- );
+ );
if (EFI_ERROR (Status)) {
//
// Decode failed
@@ -526,9 +607,9 @@ CustomGuidedSectionExtract (
DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));
return Status;
}
-
+
*OutputSize = (UINTN) OutputBufferSize;
-
+
return EFI_SUCCESS;
}
@@ -537,10 +618,10 @@ CustomGuidedSectionExtract (
/**
Decompresses a section to the output buffer.
- This function lookes up the compression type field in the input section and
+ This function looks up the compression type field in the input section and
applies the appropriate compression algorithm to compress the section to a
callee allocated buffer.
-
+
@param This Points to this instance of the
EFI_PEI_DECOMPRESS_PEI PPI.
@param CompressionSection Points to the compressed section.
@@ -548,14 +629,14 @@ CustomGuidedSectionExtract (
sections.
@param OutputSize Holds the returned size of the decompress
section streams.
-
+
@retval EFI_SUCCESS The section was decompressed successfully.
OutputBuffer contains the resulting data and
OutputSize contains the resulting size.
**/
EFI_STATUS
-EFIAPI
+EFIAPI
Decompress (
IN CONST EFI_PEI_DECOMPRESS_PPI *This,
IN CONST EFI_COMPRESSION_SECTION *CompressionSection,
@@ -566,95 +647,105 @@ Decompress (
EFI_STATUS Status;
UINT8 *DstBuffer;
UINT8 *ScratchBuffer;
- UINTN DstBufferSize;
+ UINT32 DstBufferSize;
UINT32 ScratchBufferSize;
- EFI_COMMON_SECTION_HEADER *Section;
- UINTN SectionLength;
+ VOID *CompressionSource;
+ UINT32 CompressionSourceSize;
+ UINT32 UncompressedLength;
+ UINT8 CompressionType;
if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {
ASSERT (FALSE);
return EFI_INVALID_PARAMETER;
}
- Section = (EFI_COMMON_SECTION_HEADER *) CompressionSection;
- SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;
-
+ if (IS_SECTION2 (CompressionSection)) {
+ CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION2));
+ CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION2));
+ UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->UncompressedLength;
+ CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->CompressionType;
+ } else {
+ CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION));
+ CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION));
+ UncompressedLength = CompressionSection->UncompressedLength;
+ CompressionType = CompressionSection->CompressionType;
+ }
+
//
// This is a compression set, expand it
//
- switch (CompressionSection->CompressionType) {
+ switch (CompressionType) {
case EFI_STANDARD_COMPRESSION:
- //
- // Load EFI standard compression.
- // For compressed data, decompress them to dstbuffer.
- //
- Status = UefiDecompressGetInfo (
- (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
- (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
- (UINT32 *) &DstBufferSize,
- &ScratchBufferSize
- );
- if (EFI_ERROR (Status)) {
+ if (FeaturePcdGet(PcdDxeIplSupportUefiDecompress)) {
//
- // GetInfo failed
+ // Load EFI standard compression.
+ // For compressed data, decompress them to destination buffer.
//
- DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));
- return EFI_NOT_FOUND;
- }
- //
- // Allocate scratch buffer
- //
- ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
- if (ScratchBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Allocate destination buffer, extra one page for adjustment
- //
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
- if (DstBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
- // to make section data at page alignment.
- //
- DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
- //
- // Call decompress function
- //
- Status = UefiDecompress (
- (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
- DstBuffer,
- ScratchBuffer
- );
- if (EFI_ERROR (Status)) {
+ Status = UefiDecompressGetInfo (
+ CompressionSource,
+ CompressionSourceSize,
+ &DstBufferSize,
+ &ScratchBufferSize
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // GetInfo failed
+ //
+ DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Allocate scratch buffer
+ //
+ ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
+ if (ScratchBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
//
- // Decompress failed
+ // Allocate destination buffer
//
- DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
+ if (DstBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Call decompress function
+ //
+ Status = UefiDecompress (
+ CompressionSource,
+ DstBuffer,
+ ScratchBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Decompress failed
+ //
+ DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));
+ return EFI_NOT_FOUND;
+ }
+ break;
+ } else {
+ //
+ // PcdDxeIplSupportUefiDecompress is FALSE
+ // Don't support UEFI decompression algorithm.
+ //
+ ASSERT (FALSE);
return EFI_NOT_FOUND;
}
- break;
case EFI_NOT_COMPRESSED:
//
// Allocate destination buffer
//
- DstBufferSize = CompressionSection->UncompressedLength;
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
+ DstBufferSize = UncompressedLength;
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
if (DstBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
- // Adjust DstBuffer offset, skip EFI section header
- // to make section data at page alignment.
- //
- DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
- //
// stream is not actually compressed, just encapsulated. So just copy it.
//
- CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);
+ CopyMem (DstBuffer, CompressionSource, DstBufferSize);
break;
default:
@@ -672,8 +763,6 @@ Decompress (
}
-
-
/**
Updates the Stack HOB passed to DXE phase.
@@ -696,13 +785,14 @@ UpdateStackHob (
while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
//
- // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
- // to be reclaimed by DXE core.
+ // Build a new memory allocation HOB with old stack info with EfiBootServicesData type. Need to
+ // avoid this region be reclaimed by DXE core as the IDT built in SEC might be on stack, and some
+ // PEIMs may also keep key information on stack
//
BuildMemoryAllocationHob (
Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
- EfiConventionalMemory
+ EfiBootServicesData
);
//
// Update the BSP Stack Hob to reflect the new stack info.
@@ -714,3 +804,4 @@ UpdateStackHob (
Hob.Raw = GET_NEXT_HOB (Hob);
}
}
+