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