-/**@file\r
+/** @file\r
Last PEIM.\r
Responsibility of this module is to load the DXE Core from a Firmware Volume.\r
\r
-Copyright (c) 2006 - 2007 Intel Corporation\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
-#include <Ppi/GuidedSectionExtraction.h>\r
-#include <FrameworkPei.h>\r
\r
-EFI_STATUS\r
-CustomGuidedSectionExtract (\r
- IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,\r
- IN CONST VOID *InputSection,\r
- OUT VOID **OutputBuffer,\r
- OUT UINTN *OutputSize,\r
- OUT UINT32 *AuthenticationStatus\r
-);\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI \r
-Decompress (\r
- IN CONST EFI_PEI_DECOMPRESS_PPI *This,\r
- IN CONST EFI_COMPRESSION_SECTION *InputSection,\r
- OUT VOID **OutputBuffer,\r
- OUT UINTN *OutputSize\r
-);\r
-\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
-static EFI_DXE_IPL_PPI mDxeIplPpi = {\r
+CONST EFI_DXE_IPL_PPI mDxeIplPpi = {\r
DxeLoadCore\r
};\r
\r
-STATIC EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {\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
\r
-STATIC EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {\r
+CONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {\r
Decompress\r
};\r
\r
-static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {\r
- {\r
- EFI_PEI_PPI_DESCRIPTOR_PPI,\r
- &gEfiDxeIplPpiGuid,\r
- &mDxeIplPpi\r
- },\r
- {\r
- (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
- &gEfiPeiDecompressPpiGuid,\r
- &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
-static EFI_PEI_PPI_DESCRIPTOR mPpiSignal = {\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
- @param FfsHandle The handle of FFS file.\r
- @param PeiServices General purpose services available to\r
- every PEIM.\r
- @return EFI_SUCESS \r
-*/ \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
PeimInitializeDxeIpl (\r
- IN EFI_PEI_FILE_HANDLE FfsHandle,\r
- IN EFI_PEI_SERVICES **PeiServices\r
+ IN EFI_PEI_FILE_HANDLE FileHandle,\r
+ IN CONST EFI_PEI_SERVICES **PeiServices\r
)\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
- Status = PeiServicesGetBootMode (&BootMode);\r
- ASSERT_EFI_ERROR (Status);\r
+ VOID *Dummy;\r
+\r
+ BootMode = GetBootModeHob ();\r
\r
if (BootMode != BOOT_ON_S3_RESUME) {\r
- Status = PeiServicesRegisterForShadow (FfsHandle);\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
- gInMemory = TRUE;\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 = NULL;\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 = &mCustomGuidedSectionExtractionPpi;\r
- GuidPpi->Guid = &(ExtractHandlerGuidTable [ExtractHandlerNumber]);\r
- Status = PeiServicesInstallPpi (GuidPpi++);\r
- ASSERT_EFI_ERROR(Status);\r
- }\r
- }\r
- } else {\r
- ASSERT_EFI_ERROR (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 FvFileLoader and DxeIpl PPIs.\r
+ // Install Decompress PPI.\r
//\r
- Status = PeiServicesInstallPpi (mPpiList);\r
- ASSERT_EFI_ERROR(Status); \r
- \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
- @param This Entry point for DXE IPL PPI\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
+ @param HobList Address to the Pei HOB list.\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_STATUS\r
EFIAPI\r
DxeLoadCore (\r
- IN EFI_DXE_IPL_PPI *This,\r
+ IN CONST EFI_DXE_IPL_PPI *This,\r
IN EFI_PEI_SERVICES **PeiServices,\r
IN EFI_PEI_HOB_POINTERS HobList\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_GUID DxeCoreFileName;\r
+ EFI_FV_FILE_INFO DxeCoreFileInfo;\r
EFI_PHYSICAL_ADDRESS DxeCoreAddress;\r
UINT64 DxeCoreSize;\r
EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;\r
EFI_BOOT_MODE BootMode;\r
- EFI_PEI_FV_HANDLE VolumeHandle;\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
// if in S3 Resume, restore configure\r
//\r
- Status = PeiServicesGetBootMode (&BootMode);\r
- ASSERT_EFI_ERROR(Status);\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 ((EFI_D_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
+\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
+ 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
//\r
- // If any FV contains an encapsulated FV extract that FV\r
+ // Look in all the FVs present in PEI and find the DXE Core FileHandle\r
//\r
- DxeIplAddEncapsulatedFirmwareVolumes ();\r
- \r
+ FileHandle = DxeIplFindDxeCore ();\r
+\r
//\r
- // Look in all the FVs present in PEI and find the DXE Core\r
+ // Load the DXE Core from a Firmware Volume.\r
//\r
Instance = 0;\r
- Status = DxeIplFindFirmwareVolumeInstance (&Instance, EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);\r
- ASSERT_EFI_ERROR (Status);\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
- CopyMem(&DxeCoreFileName, &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name), sizeof (EFI_GUID));\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
- // Load the DXE Core from a Firmware Volume\r
+ // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name.\r
//\r
- Status = PeiLoadFile (\r
- FileHandle,\r
- &DxeCoreAddress,\r
- &DxeCoreSize,\r
- &DxeCoreEntryPoint\r
- );\r
-\r
+ Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo);\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
// Add HOB for the DXE Core\r
//\r
BuildModuleHob (\r
- &DxeCoreFileName,\r
+ &DxeCoreFileInfo.FileName,\r
DxeCoreAddress,\r
- EFI_SIZE_TO_PAGES ((UINT32) 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
- EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT\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
- DEBUG ((EFI_D_INFO, "DXE Core Entry Point 0x%08x\n", (UINTN) DxeCoreEntryPoint));\r
- HandOffToDxeCore (DxeCoreEntryPoint, HobList, &mPpiSignal);\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
}\r
\r
\r
-STATIC\r
-EFI_STATUS\r
-GetFvAlignment (\r
- IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,\r
- OUT UINT32 *FvAlignment\r
- )\r
-{\r
- //\r
- // Because FvLength in FvHeader is UINT64 type, \r
- // so FvHeader must meed at least 8 bytes alignment.\r
- // Get the appropriate alignment requirement.\r
- // \r
- if ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) < EFI_FVB2_ALIGNMENT_8) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- \r
- *FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
- return EFI_SUCCESS;\r
-}\r
-\r
/**\r
- Search EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE image and expand \r
- as memory FV \r
- \r
- @return EFI_OUT_OF_RESOURCES There are no memory space to exstract FV\r
- @return EFI_SUCESS Sucess to find the FV \r
+ Searches DxeCore in all firmware Volumes and loads the first\r
+ instance that contains DxeCore.\r
+\r
+ @return FileHandle of DxeCore to load DxeCore.\r
+\r
**/\r
-EFI_STATUS\r
-DxeIplAddEncapsulatedFirmwareVolumes (\r
+EFI_PEI_FILE_HANDLE\r
+DxeIplFindDxeCore (\r
VOID\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_STATUS VolumeStatus;\r
- UINTN Index;\r
- EFI_FV_INFO VolumeInfo; \r
- EFI_PEI_FV_HANDLE VolumeHandle;\r
- EFI_PEI_FILE_HANDLE FileHandle;\r
- UINT32 SectionLength;\r
- EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
- EFI_FIRMWARE_VOLUME_IMAGE_SECTION *SectionHeader;\r
- VOID *DstBuffer;\r
- UINT32 FvAlignment;\r
-\r
- Status = EFI_NOT_FOUND;\r
- Index = 0;\r
+ EFI_STATUS Status;\r
+ UINTN Instance;\r
+ EFI_PEI_FV_HANDLE VolumeHandle;\r
+ EFI_PEI_FILE_HANDLE FileHandle;\r
\r
- do {\r
- VolumeStatus = DxeIplFindFirmwareVolumeInstance (\r
- &Index, \r
- EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, \r
- &VolumeHandle, \r
- &FileHandle\r
- );\r
- \r
- if (!EFI_ERROR (VolumeStatus)) {\r
- Status = PeiServicesFfsFindSectionData (\r
- EFI_SECTION_FIRMWARE_VOLUME_IMAGE, \r
- (EFI_FFS_FILE_HEADER *)FileHandle, \r
- (VOID **)&FvHeader\r
- );\r
- \r
- if (!EFI_ERROR (Status)) {\r
- if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
- //\r
- // Because FvLength in FvHeader is UINT64 type, \r
- // so FvHeader must meed at least 8 bytes alignment.\r
- // If current FvImage base address doesn't meet its alignment,\r
- // we need to reload this FvImage to another correct memory address.\r
- //\r
- Status = GetFvAlignment(FvHeader, &FvAlignment); \r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- if (((UINTN) FvHeader % FvAlignment) != 0) {\r
- SectionHeader = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*)((UINTN)FvHeader - sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION));\r
- SectionLength = *(UINT32 *)SectionHeader->Size & 0x00FFFFFF;\r
- \r
- DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), FvAlignment);\r
- if (DstBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- CopyMem (DstBuffer, FvHeader, (UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER));\r
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer; \r
- }\r
-\r
- //\r
- // This new Firmware Volume comes from a firmware file within a firmware volume.\r
- // Record the original Firmware Volume Name.\r
- //\r
- PeiServicesFfsGetVolumeInfo (&VolumeHandle, &VolumeInfo);\r
-\r
- PiLibInstallFvInfoPpi (\r
- NULL,\r
- FvHeader,\r
- (UINT32) FvHeader->FvLength,\r
- &(VolumeInfo.FvName),\r
- &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name)\r
- );\r
-\r
- //\r
- // Inform HOB consumer phase, i.e. DXE core, the existance of this FV\r
- //\r
- BuildFvHob (\r
- (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
- FvHeader->FvLength\r
- );\r
- \r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Makes the encapsulated volume show up in DXE phase to skip processing of\r
- // encapsulated file again.\r
- //\r
- BuildFv2Hob (\r
- (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,\r
- FvHeader->FvLength, \r
- &VolumeInfo.FvName,\r
- &(((EFI_FFS_FILE_HEADER *)FileHandle)->Name)\r
- );\r
- return Status;\r
- }\r
- }\r
+ Instance = 0;\r
+ while (TRUE) {\r
+ //\r
+ // Traverse all firmware volume instances\r
+ //\r
+ Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);\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
- } while (!EFI_ERROR (VolumeStatus));\r
- \r
- return Status;\r
-}\r
-\r
-/**\r
- Find the First Volume that contains the first FileType.\r
-\r
- @param Instance The Fv instance.\r
- @param SeachType The type of file to search.\r
- @param VolumeHandle Pointer to Fv which contains the file to search. \r
- @param FileHandle Pointer to FFS file to search.\r
- \r
- @return EFI_SUCESS Success to find the FFS in specificed FV\r
- @return others Fail to find the FFS in specificed FV\r
- */\r
-EFI_STATUS\r
-DxeIplFindFirmwareVolumeInstance (\r
- IN OUT UINTN *Instance,\r
- IN EFI_FV_FILETYPE SeachType,\r
- OUT EFI_PEI_FV_HANDLE *VolumeHandle,\r
- OUT EFI_PEI_FILE_HANDLE *FileHandle\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS VolumeStatus;\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- do {\r
- VolumeStatus = PeiServicesFfsFindNextVolume (*Instance, VolumeHandle);\r
- if (!EFI_ERROR (VolumeStatus)) {\r
- *FileHandle = NULL;\r
- Status = PeiServicesFfsFindNextFile (SeachType, *VolumeHandle, FileHandle);\r
- if (!EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
+ //\r
+ // Find the DxeCore file type from the beginning in this firmware volume.\r
+ //\r
+ FileHandle = NULL;\r
+ Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Find DxeCore FileHandle in this volume, then we skip other firmware volume and\r
+ // return the FileHandle.\r
+ //\r
+ return FileHandle;\r
}\r
- *Instance += 1;\r
- } while (!EFI_ERROR (VolumeStatus));\r
-\r
- return VolumeStatus;\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
-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
- // First try to find the required section in this ffs file.\r
- //\r
- Status = PeiServicesFfsFindSectionData (\r
- EFI_SECTION_PE32,\r
- FileHandle,\r
- &Pe32Data\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- Status = PeiServicesFfsFindSectionData (\r
- EFI_SECTION_TE,\r
- FileHandle,\r
- &Pe32Data\r
- );\r
- }\r
- \r
- if (EFI_ERROR (Status)) {\r
//\r
- // NO image types we support so exit.\r
+ // We cannot find DxeCore in this firmware volume, then search the next volume.\r
//\r
- return Status;\r
+ Instance++;\r
}\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
- ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));\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
The ExtractSection() function processes the input section and\r
processed. OutputBuffer OutputBuffer is\r
allocated from PEI permanent memory and contains\r
the new section stream.\r
- \r
+ @param InputSection A pointer to the input buffer, which contains\r
+ the input section to be processed.\r
+ @param OutputBuffer A pointer to a caller-allocated buffer, whose\r
+ size is specified by the contents of OutputSize.\r
@param OutputSize A pointer to a caller-allocated\r
UINTN in which the size of *OutputBuffer\r
allocation is stored. If the function\r
returns anything other than EFI_SUCCESS,\r
the value of OutputSize is undefined.\r
- \r
@param AuthenticationStatus A pointer to a caller-allocated\r
UINT32 that indicates the\r
authentication status of the\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
- @reteval EFI_INVALID_PARAMETER The GUID in InputSection does\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
// Call GetInfo to get the size and attribute of input guided section data.\r
//\r
Status = ExtractGuidedSectionGetInfo (\r
- InputSection,\r
- &OutputBufferSize,\r
- &ScratchBufferSize,\r
- &SectionAttribute\r
- );\r
- \r
+ InputSection,\r
+ &OutputBufferSize,\r
+ &ScratchBufferSize,\r
+ &SectionAttribute\r
+ );\r
+\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "GetInfo from guided section Failed - %r\n", 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) && OutputBufferSize > 0) { \r
+ if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {\r
//\r
// Allocate output buffer\r
//\r
if (*OutputBuffer == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\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
+ );\r
if (EFI_ERROR (Status)) {\r
//\r
// Decode failed\r
//\r
- DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));\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
-STATIC\r
+\r
+\r
+/**\r
+ Decompresses a section to the output buffer.\r
+\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
+ @param This Points to this instance of the\r
+ EFI_PEI_DECOMPRESS_PEI PPI.\r
+ @param CompressionSection Points to the compressed section.\r
+ @param OutputBuffer Holds the returned pointer to the decompressed\r
+ sections.\r
+ @param OutputSize Holds the returned size of the decompress\r
+ section streams.\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 ((EFI_D_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\r
- //\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
- (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
+ // Allocate destination buffer\r
//\r
- // Decompress failed\r
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+ if (DstBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
//\r
- DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));\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
- // porting note the original branch for customized compress is removed, it should be change to use GUID compress\r
\r
case EFI_NOT_COMPRESSED:\r
//\r
// Allocate destination buffer\r
//\r
- DstBufferSize = CompressionSection->UncompressedLength;\r
+ DstBufferSize = UncompressedLength;\r
DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
if (DstBuffer == NULL) {\r
return EFI_OUT_OF_RESOURCES;\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
return EFI_SUCCESS;\r
}\r
\r
+\r
+/**\r
+ Updates the Stack HOB passed to DXE phase.\r
+\r
+ This function traverses the whole HOB list and update the stack HOB to\r
+ reflect the real stack that is used by DXE core.\r
+\r
+ @param BaseAddress The lower address of stack used by DxeCore.\r
+ @param Length The length of stack used by DxeCore.\r
+\r
+**/\r
+VOID\r
+UpdateStackHob (\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length\r
+ )\r
+{\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+\r
+ Hob.Raw = GetHobList ();\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 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
+ EfiBootServicesData\r
+ );\r
+ //\r
+ // Update the BSP Stack Hob to reflect the new stack info.\r
+ //\r
+ Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
+ Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;\r
+ break;\r
+ }\r
+ Hob.Raw = GET_NEXT_HOB (Hob);\r
+ }\r
+}\r
+\r