3 Responsibility of this module is to load the DXE Core from a Firmware Volume.
5 Copyright (c) 2016 HP Development Company, L.P.
6 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 // Module Globals used in the DXE to PEI hand off
22 // These must be module globals, so the stack can be switched
24 CONST EFI_DXE_IPL_PPI mDxeIplPpi
= {
28 CONST EFI_PEI_PPI_DESCRIPTOR mDxeIplPpiList
= {
29 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
34 CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi
= {
35 CustomGuidedSectionExtract
38 CONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi
= {
42 CONST EFI_PEI_PPI_DESCRIPTOR mDecompressPpiList
= {
43 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
44 &gEfiPeiDecompressPpiGuid
,
45 (VOID
*) &mDecompressPpi
48 CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi
= {
49 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
50 &gEfiEndOfPeiSignalPpiGuid
,
54 CONST EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList
= {
55 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
56 &gEfiPeiMemoryDiscoveredPpiGuid
,
57 InstallIplPermanentMemoryPpis
61 Entry point of DXE IPL PEIM.
63 This function installs DXE IPL PPI. It also reloads
64 itself to memory on non-S3 resume boot path.
66 @param FileHandle Handle of the file being invoked.
67 @param PeiServices Describes the list of possible PEI Services.
69 @retval EFI_SUCESS The entry point of DXE IPL PEIM executes successfully.
70 @retval Others Some error occurs during the execution of this function.
75 PeimInitializeDxeIpl (
76 IN EFI_PEI_FILE_HANDLE FileHandle
,
77 IN CONST EFI_PEI_SERVICES
**PeiServices
81 EFI_BOOT_MODE BootMode
;
84 BootMode
= GetBootModeHob ();
86 if (BootMode
!= BOOT_ON_S3_RESUME
) {
87 Status
= PeiServicesRegisterForShadow (FileHandle
);
88 if (Status
== EFI_SUCCESS
) {
90 // EFI_SUCESS means it is the first time to call register for shadow.
96 // Ensure that DXE IPL is shadowed to permanent memory.
98 ASSERT (Status
== EFI_ALREADY_STARTED
);
101 // DXE core load requires permanent memory.
103 Status
= PeiServicesLocatePpi (
104 &gEfiPeiMemoryDiscoveredPpiGuid
,
109 ASSERT_EFI_ERROR (Status
);
110 if (EFI_ERROR (Status
)) {
115 // Now the permanent memory exists, install the PPIs for decompression
116 // and section extraction.
118 Status
= InstallIplPermanentMemoryPpis (NULL
, NULL
, NULL
);
119 ASSERT_EFI_ERROR (Status
);
122 // Install memory discovered PPI notification to install PPIs for
123 // decompression and section extraction.
125 Status
= PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList
);
126 ASSERT_EFI_ERROR (Status
);
130 // Install DxeIpl PPI.
132 Status
= PeiServicesInstallPpi (&mDxeIplPpiList
);
133 ASSERT_EFI_ERROR(Status
);
139 This function installs the PPIs that require permanent memory.
141 @param PeiServices Indirect reference to the PEI Services Table.
142 @param NotifyDescriptor Address of the notification descriptor data structure.
143 @param Ppi Address of the PPI that was installed.
145 @return EFI_SUCCESS The PPIs were installed successfully.
146 @return Others Some error occurs during the execution of this function.
151 InstallIplPermanentMemoryPpis (
152 IN EFI_PEI_SERVICES
**PeiServices
,
153 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
158 EFI_GUID
*ExtractHandlerGuidTable
;
159 UINTN ExtractHandlerNumber
;
160 EFI_PEI_PPI_DESCRIPTOR
*GuidPpi
;
163 // Get custom extract guided section method guid list
165 ExtractHandlerNumber
= ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable
);
168 // Install custom guided section extraction PPI
170 if (ExtractHandlerNumber
> 0) {
171 GuidPpi
= (EFI_PEI_PPI_DESCRIPTOR
*) AllocatePool (ExtractHandlerNumber
* sizeof (EFI_PEI_PPI_DESCRIPTOR
));
172 ASSERT (GuidPpi
!= NULL
);
173 while (ExtractHandlerNumber
-- > 0) {
174 GuidPpi
->Flags
= EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
;
175 GuidPpi
->Ppi
= (VOID
*) &mCustomGuidedSectionExtractionPpi
;
176 GuidPpi
->Guid
= &ExtractHandlerGuidTable
[ExtractHandlerNumber
];
177 Status
= PeiServicesInstallPpi (GuidPpi
++);
178 ASSERT_EFI_ERROR(Status
);
183 // Install Decompress PPI.
185 Status
= PeiServicesInstallPpi (&mDecompressPpiList
);
186 ASSERT_EFI_ERROR(Status
);
192 Validate variable data for the MemoryTypeInformation.
194 @param MemoryData Variable data.
195 @param MemoryDataSize Variable data length.
197 @return TRUE The variable data is valid.
198 @return FALSE The variable data is invalid.
202 ValidateMemoryTypeInfoVariable (
203 IN EFI_MEMORY_TYPE_INFORMATION
*MemoryData
,
204 IN UINTN MemoryDataSize
210 // Check the input parameter.
211 if (MemoryData
== NULL
) {
216 Count
= MemoryDataSize
/ sizeof (*MemoryData
);
219 if (Count
* sizeof(*MemoryData
) != MemoryDataSize
) {
223 // Check last entry type filed.
224 if (MemoryData
[Count
- 1].Type
!= EfiMaxMemoryType
) {
228 // Check the type filed.
229 for (Index
= 0; Index
< Count
- 1; Index
++) {
230 if (MemoryData
[Index
].Type
>= EfiMaxMemoryType
) {
239 Main entry point to last PEIM.
241 This function finds DXE Core in the firmware volume and transfer the control to
244 @param This Entry point for DXE IPL PPI.
245 @param PeiServices General purpose services available to every PEIM.
246 @param HobList Address to the Pei HOB list.
248 @return EFI_SUCCESS DXE core was successfully loaded.
249 @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core.
255 IN CONST EFI_DXE_IPL_PPI
*This
,
256 IN EFI_PEI_SERVICES
**PeiServices
,
257 IN EFI_PEI_HOB_POINTERS HobList
261 EFI_FV_FILE_INFO DxeCoreFileInfo
;
262 EFI_PHYSICAL_ADDRESS DxeCoreAddress
;
264 EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint
;
265 EFI_BOOT_MODE BootMode
;
266 EFI_PEI_FILE_HANDLE FileHandle
;
267 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
;
268 EFI_PEI_LOAD_FILE_PPI
*LoadFile
;
270 UINT32 AuthenticationState
;
272 EFI_PEI_S3_RESUME2_PPI
*S3Resume
;
273 EFI_PEI_RECOVERY_MODULE_PPI
*PeiRecovery
;
274 EFI_MEMORY_TYPE_INFORMATION MemoryData
[EfiMaxMemoryType
+ 1];
277 // if in S3 Resume, restore configure
279 BootMode
= GetBootModeHob ();
281 if (BootMode
== BOOT_ON_S3_RESUME
) {
282 Status
= PeiServicesLocatePpi (
283 &gEfiPeiS3Resume2PpiGuid
,
288 if (EFI_ERROR (Status
)) {
290 // Report Status code that S3Resume PPI can not be found
293 EFI_ERROR_CODE
| EFI_ERROR_MAJOR
,
294 (EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND
)
297 ASSERT_EFI_ERROR (Status
);
299 Status
= S3Resume
->S3RestoreConfig2 (S3Resume
);
300 ASSERT_EFI_ERROR (Status
);
301 } else if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
302 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_PC_RECOVERY_BEGIN
));
303 Status
= PeiServicesLocatePpi (
304 &gEfiPeiRecoveryModulePpiGuid
,
307 (VOID
**) &PeiRecovery
310 if (EFI_ERROR (Status
)) {
311 DEBUG ((DEBUG_ERROR
, "Locate Recovery PPI Failed.(Status = %r)\n", Status
));
313 // Report Status code the failure of locating Recovery PPI
316 EFI_ERROR_CODE
| EFI_ERROR_MAJOR
,
317 (EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND
)
322 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_PC_CAPSULE_LOAD
));
323 Status
= PeiRecovery
->LoadRecoveryCapsule (PeiServices
, PeiRecovery
);
324 if (EFI_ERROR (Status
)) {
325 DEBUG ((DEBUG_ERROR
, "Load Recovery Capsule Failed.(Status = %r)\n", Status
));
327 // Report Status code that recovery image can not be found
330 EFI_ERROR_CODE
| EFI_ERROR_MAJOR
,
331 (EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE
)
335 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_PC_CAPSULE_START
));
337 // Now should have a HOB with the DXE core
341 if (GetFirstGuidHob ((CONST EFI_GUID
*)&gEfiMemoryTypeInformationGuid
) == NULL
) {
343 // Don't build GuidHob if GuidHob has been installed.
345 Status
= PeiServicesLocatePpi (
346 &gEfiPeiReadOnlyVariable2PpiGuid
,
351 if (!EFI_ERROR (Status
)) {
352 DataSize
= sizeof (MemoryData
);
353 Status
= Variable
->GetVariable (
355 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME
,
356 &gEfiMemoryTypeInformationGuid
,
361 if (!EFI_ERROR (Status
) && ValidateMemoryTypeInfoVariable(MemoryData
, DataSize
)) {
363 // Build the GUID'd HOB for DXE
366 &gEfiMemoryTypeInformationGuid
,
375 // Look in all the FVs present in PEI and find the DXE Core FileHandle
377 FileHandle
= DxeIplFindDxeCore ();
380 // Load the DXE Core from a Firmware Volume.
384 Status
= PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid
, Instance
++, NULL
, (VOID
**) &LoadFile
);
386 // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully.
388 ASSERT_EFI_ERROR (Status
);
390 Status
= LoadFile
->LoadFile (
398 } while (EFI_ERROR (Status
));
401 // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name.
403 Status
= PeiServicesFfsGetFileInfo (FileHandle
, &DxeCoreFileInfo
);
404 ASSERT_EFI_ERROR (Status
);
407 // Add HOB for the DXE Core
410 &DxeCoreFileInfo
.FileName
,
412 ALIGN_VALUE (DxeCoreSize
, EFI_PAGE_SIZE
),
417 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
419 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_SOFTWARE_PEI_CORE
| EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
));
421 DEBUG ((DEBUG_INFO
| DEBUG_LOAD
, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID
*)(UINTN
)DxeCoreAddress
, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint
)));
424 // Transfer control to the DXE Core
425 // The hand off state is simply a pointer to the HOB list
427 HandOffToDxeCore (DxeCoreEntryPoint
, HobList
);
429 // If we get here, then the DXE Core returned. This is an error
430 // DxeCore should not return.
435 return EFI_OUT_OF_RESOURCES
;
440 Searches DxeCore in all firmware Volumes and loads the first
441 instance that contains DxeCore.
443 @return FileHandle of DxeCore to load DxeCore.
453 EFI_PEI_FV_HANDLE VolumeHandle
;
454 EFI_PEI_FILE_HANDLE FileHandle
;
459 // Traverse all firmware volume instances
461 Status
= PeiServicesFfsFindNextVolume (Instance
, &VolumeHandle
);
463 // If some error occurs here, then we cannot find any firmware
464 // volume that may contain DxeCore.
466 if (EFI_ERROR (Status
)) {
467 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_CORE_EC_DXE_CORRUPT
));
469 ASSERT_EFI_ERROR (Status
);
472 // Find the DxeCore file type from the beginning in this firmware volume.
475 Status
= PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE
, VolumeHandle
, &FileHandle
);
476 if (!EFI_ERROR (Status
)) {
478 // Find DxeCore FileHandle in this volume, then we skip other firmware volume and
479 // return the FileHandle.
484 // We cannot find DxeCore in this firmware volume, then search the next volume.
493 The ExtractSection() function processes the input section and
494 returns a pointer to the section contents. If the section being
495 extracted does not require processing (if the section
496 GuidedSectionHeader.Attributes has the
497 EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
498 OutputBuffer is just updated to point to the start of the
499 section's contents. Otherwise, *Buffer must be allocated
500 from PEI permanent memory.
502 @param This Indicates the
503 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
504 Buffer containing the input GUIDed section to be
505 processed. OutputBuffer OutputBuffer is
506 allocated from PEI permanent memory and contains
507 the new section stream.
508 @param InputSection A pointer to the input buffer, which contains
509 the input section to be processed.
510 @param OutputBuffer A pointer to a caller-allocated buffer, whose
511 size is specified by the contents of OutputSize.
512 @param OutputSize A pointer to a caller-allocated
513 UINTN in which the size of *OutputBuffer
514 allocation is stored. If the function
515 returns anything other than EFI_SUCCESS,
516 the value of OutputSize is undefined.
517 @param AuthenticationStatus A pointer to a caller-allocated
518 UINT32 that indicates the
519 authentication status of the
520 output buffer. If the input
521 section's GuidedSectionHeader.
522 Attributes field has the
523 EFI_GUIDED_SECTION_AUTH_STATUS_VALID
525 AuthenticationStatus must return
526 zero. These bits reflect the
527 status of the extraction
528 operation. If the function
529 returns anything other than
530 EFI_SUCCESS, the value of
531 AuthenticationStatus is
534 @retval EFI_SUCCESS The InputSection was
535 successfully processed and the
536 section contents were returned.
538 @retval EFI_OUT_OF_RESOURCES The system has insufficient
539 resources to process the request.
541 @retval EFI_INVALID_PARAMETER The GUID in InputSection does
542 not match this instance of the
543 GUIDed Section Extraction PPI.
548 CustomGuidedSectionExtract (
549 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*This
,
550 IN CONST VOID
*InputSection
,
551 OUT VOID
**OutputBuffer
,
552 OUT UINTN
*OutputSize
,
553 OUT UINT32
*AuthenticationStatus
557 UINT8
*ScratchBuffer
;
558 UINT32 ScratchBufferSize
;
559 UINT32 OutputBufferSize
;
560 UINT16 SectionAttribute
;
563 // Init local variable
565 ScratchBuffer
= NULL
;
568 // Call GetInfo to get the size and attribute of input guided section data.
570 Status
= ExtractGuidedSectionGetInfo (
577 if (EFI_ERROR (Status
)) {
578 DEBUG ((DEBUG_ERROR
, "GetInfo from guided section Failed - %r\n", Status
));
582 if (ScratchBufferSize
!= 0) {
584 // Allocate scratch buffer
586 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
587 if (ScratchBuffer
== NULL
) {
588 return EFI_OUT_OF_RESOURCES
;
592 if (((SectionAttribute
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) != 0) && OutputBufferSize
> 0) {
594 // Allocate output buffer
596 *OutputBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize
));
597 if (*OutputBuffer
== NULL
) {
598 return EFI_OUT_OF_RESOURCES
;
600 DEBUG ((DEBUG_INFO
, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize
, *OutputBuffer
));
603 Status
= ExtractGuidedSectionDecode (
609 if (EFI_ERROR (Status
)) {
613 DEBUG ((DEBUG_ERROR
, "Extract guided section Failed - %r\n", Status
));
617 *OutputSize
= (UINTN
) OutputBufferSize
;
625 Decompresses a section to the output buffer.
627 This function looks up the compression type field in the input section and
628 applies the appropriate compression algorithm to compress the section to a
629 callee allocated buffer.
631 @param This Points to this instance of the
632 EFI_PEI_DECOMPRESS_PEI PPI.
633 @param CompressionSection Points to the compressed section.
634 @param OutputBuffer Holds the returned pointer to the decompressed
636 @param OutputSize Holds the returned size of the decompress
639 @retval EFI_SUCCESS The section was decompressed successfully.
640 OutputBuffer contains the resulting data and
641 OutputSize contains the resulting size.
647 IN CONST EFI_PEI_DECOMPRESS_PPI
*This
,
648 IN CONST EFI_COMPRESSION_SECTION
*CompressionSection
,
649 OUT VOID
**OutputBuffer
,
650 OUT UINTN
*OutputSize
655 UINT8
*ScratchBuffer
;
656 UINT32 DstBufferSize
;
657 UINT32 ScratchBufferSize
;
658 VOID
*CompressionSource
;
659 UINT32 CompressionSourceSize
;
660 UINT32 UncompressedLength
;
661 UINT8 CompressionType
;
663 if (CompressionSection
->CommonHeader
.Type
!= EFI_SECTION_COMPRESSION
) {
665 return EFI_INVALID_PARAMETER
;
668 if (IS_SECTION2 (CompressionSection
)) {
669 CompressionSource
= (VOID
*) ((UINT8
*) CompressionSection
+ sizeof (EFI_COMPRESSION_SECTION2
));
670 CompressionSourceSize
= (UINT32
) (SECTION2_SIZE (CompressionSection
) - sizeof (EFI_COMPRESSION_SECTION2
));
671 UncompressedLength
= ((EFI_COMPRESSION_SECTION2
*) CompressionSection
)->UncompressedLength
;
672 CompressionType
= ((EFI_COMPRESSION_SECTION2
*) CompressionSection
)->CompressionType
;
674 CompressionSource
= (VOID
*) ((UINT8
*) CompressionSection
+ sizeof (EFI_COMPRESSION_SECTION
));
675 CompressionSourceSize
= (UINT32
) (SECTION_SIZE (CompressionSection
) - sizeof (EFI_COMPRESSION_SECTION
));
676 UncompressedLength
= CompressionSection
->UncompressedLength
;
677 CompressionType
= CompressionSection
->CompressionType
;
681 // This is a compression set, expand it
683 switch (CompressionType
) {
684 case EFI_STANDARD_COMPRESSION
:
685 if (FeaturePcdGet(PcdDxeIplSupportUefiDecompress
)) {
687 // Load EFI standard compression.
688 // For compressed data, decompress them to destination buffer.
690 Status
= UefiDecompressGetInfo (
692 CompressionSourceSize
,
696 if (EFI_ERROR (Status
)) {
700 DEBUG ((DEBUG_ERROR
, "Decompress GetInfo Failed - %r\n", Status
));
701 return EFI_NOT_FOUND
;
704 // Allocate scratch buffer
706 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
707 if (ScratchBuffer
== NULL
) {
708 return EFI_OUT_OF_RESOURCES
;
711 // Allocate destination buffer
713 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
));
714 if (DstBuffer
== NULL
) {
715 return EFI_OUT_OF_RESOURCES
;
718 // Call decompress function
720 Status
= UefiDecompress (
725 if (EFI_ERROR (Status
)) {
729 DEBUG ((DEBUG_ERROR
, "Decompress Failed - %r\n", Status
));
730 return EFI_NOT_FOUND
;
735 // PcdDxeIplSupportUefiDecompress is FALSE
736 // Don't support UEFI decompression algorithm.
739 return EFI_NOT_FOUND
;
742 case EFI_NOT_COMPRESSED
:
744 // Allocate destination buffer
746 DstBufferSize
= UncompressedLength
;
747 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
));
748 if (DstBuffer
== NULL
) {
749 return EFI_OUT_OF_RESOURCES
;
752 // stream is not actually compressed, just encapsulated. So just copy it.
754 CopyMem (DstBuffer
, CompressionSource
, DstBufferSize
);
759 // Don't support other unknown compression type.
762 return EFI_NOT_FOUND
;
765 *OutputSize
= DstBufferSize
;
766 *OutputBuffer
= DstBuffer
;
773 Updates the Stack HOB passed to DXE phase.
775 This function traverses the whole HOB list and update the stack HOB to
776 reflect the real stack that is used by DXE core.
778 @param BaseAddress The lower address of stack used by DxeCore.
779 @param Length The length of stack used by DxeCore.
784 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
788 EFI_PEI_HOB_POINTERS Hob
;
790 Hob
.Raw
= GetHobList ();
791 while ((Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION
, Hob
.Raw
)) != NULL
) {
792 if (CompareGuid (&gEfiHobMemoryAllocStackGuid
, &(Hob
.MemoryAllocationStack
->AllocDescriptor
.Name
))) {
794 // Build a new memory allocation HOB with old stack info with EfiBootServicesData type. Need to
795 // avoid this region be reclaimed by DXE core as the IDT built in SEC might be on stack, and some
796 // PEIMs may also keep key information on stack
798 BuildMemoryAllocationHob (
799 Hob
.MemoryAllocationStack
->AllocDescriptor
.MemoryBaseAddress
,
800 Hob
.MemoryAllocationStack
->AllocDescriptor
.MemoryLength
,
804 // Update the BSP Stack Hob to reflect the new stack info.
806 Hob
.MemoryAllocationStack
->AllocDescriptor
.MemoryBaseAddress
= BaseAddress
;
807 Hob
.MemoryAllocationStack
->AllocDescriptor
.MemoryLength
= Length
;
810 Hob
.Raw
= GET_NEXT_HOB (Hob
);