3 Responsibility of this module is to load the DXE Core from a Firmware Volume.
5 Copyright (c) 2006 - 2007 Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Ppi/GuidedSectionExtraction.h>
18 #include <FrameworkPei.h>
21 CustomGuidedSectionExtract (
22 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*This
,
23 IN CONST VOID
*InputSection
,
24 OUT VOID
**OutputBuffer
,
25 OUT UINTN
*OutputSize
,
26 OUT UINT32
*AuthenticationStatus
33 IN CONST EFI_PEI_DECOMPRESS_PPI
*This
,
34 IN CONST EFI_COMPRESSION_SECTION
*InputSection
,
35 OUT VOID
**OutputBuffer
,
40 BOOLEAN gInMemory
= FALSE
;
43 // Module Globals used in the DXE to PEI handoff
44 // These must be module globals, so the stack can be switched
46 static EFI_DXE_IPL_PPI mDxeIplPpi
= {
50 STATIC EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi
= {
51 CustomGuidedSectionExtract
54 STATIC EFI_PEI_DECOMPRESS_PPI mDecompressPpi
= {
58 static EFI_PEI_PPI_DESCRIPTOR mPpiList
[] = {
60 EFI_PEI_PPI_DESCRIPTOR_PPI
,
65 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
66 &gEfiPeiDecompressPpiGuid
,
71 static EFI_PEI_PPI_DESCRIPTOR mPpiSignal
= {
72 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
73 &gEfiEndOfPeiSignalPpiGuid
,
78 Initializes the Dxe Ipl PPI
80 @param FfsHandle The handle of FFS file.
81 @param PeiServices General purpose services available to
87 PeimInitializeDxeIpl (
88 IN EFI_PEI_FILE_HANDLE FfsHandle
,
89 IN EFI_PEI_SERVICES
**PeiServices
93 EFI_BOOT_MODE BootMode
;
94 EFI_GUID
*ExtractHandlerGuidTable
;
95 UINTN ExtractHandlerNumber
;
96 EFI_PEI_PPI_DESCRIPTOR
*GuidPpi
;
98 Status
= PeiServicesGetBootMode (&BootMode
);
99 ASSERT_EFI_ERROR (Status
);
101 if (BootMode
!= BOOT_ON_S3_RESUME
) {
102 Status
= PeiServicesRegisterForShadow (FfsHandle
);
103 if (Status
== EFI_SUCCESS
) {
105 // EFI_SUCESS means the first time call register for shadow
108 } else if (Status
== EFI_ALREADY_STARTED
) {
113 // Get custom extract guided section method guid list
115 ExtractHandlerNumber
= ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable
);
118 // Install custom extraction guid ppi
120 if (ExtractHandlerNumber
> 0) {
122 GuidPpi
= (EFI_PEI_PPI_DESCRIPTOR
*) AllocatePool (ExtractHandlerNumber
* sizeof (EFI_PEI_PPI_DESCRIPTOR
));
123 ASSERT (GuidPpi
!= NULL
);
124 while (ExtractHandlerNumber
-- > 0) {
125 GuidPpi
->Flags
= EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
;
126 GuidPpi
->Ppi
= &mCustomGuidedSectionExtractionPpi
;
127 GuidPpi
->Guid
= &(ExtractHandlerGuidTable
[ExtractHandlerNumber
]);
128 Status
= PeiServicesInstallPpi (GuidPpi
++);
129 ASSERT_EFI_ERROR(Status
);
138 // Install FvFileLoader and DxeIpl PPIs.
140 Status
= PeiServicesInstallPpi (mPpiList
);
141 ASSERT_EFI_ERROR(Status
);
147 Main entry point to last PEIM
149 @param This Entry point for DXE IPL PPI
150 @param PeiServices General purpose services available to every PEIM.
151 @param HobList Address to the Pei HOB list
153 @return EFI_SUCCESS DXE core was successfully loaded.
154 @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core.
159 IN EFI_DXE_IPL_PPI
*This
,
160 IN EFI_PEI_SERVICES
**PeiServices
,
161 IN EFI_PEI_HOB_POINTERS HobList
165 EFI_GUID DxeCoreFileName
;
166 EFI_PHYSICAL_ADDRESS DxeCoreAddress
;
168 EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint
;
169 EFI_BOOT_MODE BootMode
;
170 EFI_PEI_FV_HANDLE VolumeHandle
;
171 EFI_PEI_FILE_HANDLE FileHandle
;
173 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
;
175 EFI_MEMORY_TYPE_INFORMATION MemoryData
[EfiMaxMemoryType
+ 1];
178 // if in S3 Resume, restore configure
180 Status
= PeiServicesGetBootMode (&BootMode
);
181 ASSERT_EFI_ERROR(Status
);
183 if (BootMode
== BOOT_ON_S3_RESUME
) {
184 Status
= AcpiS3ResumeOs();
185 ASSERT_EFI_ERROR (Status
);
186 } else if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
187 Status
= PeiRecoverFirmware ();
188 if (EFI_ERROR (Status
)) {
189 DEBUG ((EFI_D_ERROR
, "Load Recovery Capsule Failed.(Status = %r)\n", Status
));
194 // Now should have a HOB with the DXE core w/ the old HOB destroyed
198 Status
= PeiServicesLocatePpi (
199 &gEfiPeiReadOnlyVariable2PpiGuid
,
204 ASSERT_EFI_ERROR (Status
);
206 DataSize
= sizeof (MemoryData
);
207 Status
= Variable
->GetVariable (
209 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME
,
210 &gEfiMemoryTypeInformationGuid
,
216 if (!EFI_ERROR (Status
)) {
218 // Build the GUID'd HOB for DXE
221 &gEfiMemoryTypeInformationGuid
,
227 // If any FV contains an encapsulated FV extract that FV
229 DxeIplAddEncapsulatedFirmwareVolumes ();
232 // Look in all the FVs present in PEI and find the DXE Core
235 Status
= DxeIplFindFirmwareVolumeInstance (&Instance
, EFI_FV_FILETYPE_DXE_CORE
, &VolumeHandle
, &FileHandle
);
236 ASSERT_EFI_ERROR (Status
);
238 CopyMem(&DxeCoreFileName
, &(((EFI_FFS_FILE_HEADER
*)FileHandle
)->Name
), sizeof (EFI_GUID
));
241 // Load the DXE Core from a Firmware Volume, may use LoadFile ppi to do this for save code size.
243 Status
= PeiLoadFile (
250 ASSERT_EFI_ERROR (Status
);
253 // Add HOB for the DXE Core
258 EFI_SIZE_TO_PAGES ((UINT32
) DxeCoreSize
) * EFI_PAGE_SIZE
,
263 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
267 EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
272 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION PtrPeImage
;
273 PtrPeImage
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) ((UINTN
) DxeCoreAddress
+ ((EFI_IMAGE_DOS_HEADER
*) (UINTN
) DxeCoreAddress
)->e_lfanew
);
275 if (PtrPeImage
.Pe32
->FileHeader
.Machine
!= IMAGE_FILE_MACHINE_IA64
) {
276 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Loading DXE CORE at 0x%10p EntryPoint=0x%10p\n", (VOID
*)(UINTN
)DxeCoreAddress
, (VOID
*)(UINTN
)DxeCoreEntryPoint
));
279 // For IPF Image, the real entry point should be print.
281 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Loading DXE CORE at 0x%10p EntryPoint=0x%10p\n", (VOID
*)(UINTN
)DxeCoreAddress
, (VOID
*)(UINTN
)(*(UINT64
*)(UINTN
)DxeCoreEntryPoint
)));
286 // Transfer control to the DXE Core
287 // The handoff state is simply a pointer to the HOB list
289 HandOffToDxeCore (DxeCoreEntryPoint
, HobList
, &mPpiSignal
);
291 // If we get here, then the DXE Core returned. This is an error
292 // Dxe Core should not return.
297 return EFI_OUT_OF_RESOURCES
;
304 IN EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
,
305 OUT UINT32
*FvAlignment
309 // Because FvLength in FvHeader is UINT64 type,
310 // so FvHeader must meed at least 8 bytes alignment.
311 // Get the appropriate alignment requirement.
313 if ((FvHeader
->Attributes
& EFI_FVB2_ALIGNMENT
) < EFI_FVB2_ALIGNMENT_8
) {
314 return EFI_UNSUPPORTED
;
317 *FvAlignment
= 1 << ((FvHeader
->Attributes
& EFI_FVB2_ALIGNMENT
) >> 16);
322 Search EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE image and expand
325 @return EFI_OUT_OF_RESOURCES There are no memory space to exstract FV
326 @return EFI_SUCESS Sucess to find the FV
329 DxeIplAddEncapsulatedFirmwareVolumes (
334 EFI_STATUS VolumeStatus
;
336 EFI_FV_INFO VolumeInfo
;
337 EFI_PEI_FV_HANDLE VolumeHandle
;
338 EFI_PEI_FILE_HANDLE FileHandle
;
339 UINT32 SectionLength
;
340 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
341 EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*SectionHeader
;
345 Status
= EFI_NOT_FOUND
;
349 VolumeStatus
= DxeIplFindFirmwareVolumeInstance (
351 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
356 if (!EFI_ERROR (VolumeStatus
)) {
357 Status
= PeiServicesFfsFindSectionData (
358 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
359 (EFI_FFS_FILE_HEADER
*)FileHandle
,
363 if (!EFI_ERROR (Status
)) {
364 if (FvHeader
->Signature
== EFI_FVH_SIGNATURE
) {
366 // Because FvLength in FvHeader is UINT64 type,
367 // so FvHeader must meed at least 8 bytes alignment.
368 // If current FvImage base address doesn't meet its alignment,
369 // we need to reload this FvImage to another correct memory address.
371 Status
= GetFvAlignment(FvHeader
, &FvAlignment
);
372 if (EFI_ERROR(Status
)) {
375 if (((UINTN
) FvHeader
% FvAlignment
) != 0) {
376 SectionHeader
= (EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*)((UINTN
)FvHeader
- sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION
));
377 SectionLength
= *(UINT32
*)SectionHeader
->Size
& 0x00FFFFFF;
379 DstBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN
) SectionLength
- sizeof (EFI_COMMON_SECTION_HEADER
)), FvAlignment
);
380 if (DstBuffer
== NULL
) {
381 return EFI_OUT_OF_RESOURCES
;
383 CopyMem (DstBuffer
, FvHeader
, (UINTN
) SectionLength
- sizeof (EFI_COMMON_SECTION_HEADER
));
384 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) DstBuffer
;
388 // This new Firmware Volume comes from a firmware file within a firmware volume.
389 // Record the original Firmware Volume Name.
391 PeiServicesFfsGetVolumeInfo (&VolumeHandle
, &VolumeInfo
);
393 PiLibInstallFvInfoPpi (
396 (UINT32
) FvHeader
->FvLength
,
397 &(VolumeInfo
.FvName
),
398 &(((EFI_FFS_FILE_HEADER
*)FileHandle
)->Name
)
402 // Inform HOB consumer phase, i.e. DXE core, the existance of this FV
405 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
409 ASSERT_EFI_ERROR (Status
);
412 // Makes the encapsulated volume show up in DXE phase to skip processing of
413 // encapsulated file again.
416 (EFI_PHYSICAL_ADDRESS
)(UINTN
)FvHeader
,
419 &(((EFI_FFS_FILE_HEADER
*)FileHandle
)->Name
)
425 } while (!EFI_ERROR (VolumeStatus
));
431 Find the First Volume that contains the first FileType.
433 @param Instance The Fv instance.
434 @param SeachType The type of file to search.
435 @param VolumeHandle Pointer to Fv which contains the file to search.
436 @param FileHandle Pointer to FFS file to search.
438 @return EFI_SUCESS Success to find the FFS in specificed FV
439 @return others Fail to find the FFS in specificed FV
442 DxeIplFindFirmwareVolumeInstance (
443 IN OUT UINTN
*Instance
,
444 IN EFI_FV_FILETYPE SeachType
,
445 OUT EFI_PEI_FV_HANDLE
*VolumeHandle
,
446 OUT EFI_PEI_FILE_HANDLE
*FileHandle
450 EFI_STATUS VolumeStatus
;
453 VolumeStatus
= PeiServicesFfsFindNextVolume (*Instance
, VolumeHandle
);
454 if (!EFI_ERROR (VolumeStatus
)) {
456 Status
= PeiServicesFfsFindNextFile (SeachType
, *VolumeHandle
, FileHandle
);
457 if (!EFI_ERROR (Status
)) {
462 } while (!EFI_ERROR (VolumeStatus
));
468 Loads and relocates a PE/COFF image into memory.
470 @param FileHandle The image file handle
471 @param ImageAddress The base address of the relocated PE/COFF image
472 @param ImageSize The size of the relocated PE/COFF image
473 @param EntryPoint The entry point of the relocated PE/COFF image
475 @return EFI_SUCCESS The file was loaded and relocated
476 @return EFI_OUT_OF_RESOURCES There was not enough memory to load and relocate the PE/COFF file
480 IN EFI_PEI_FILE_HANDLE FileHandle
,
481 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
482 OUT UINT64
*ImageSize
,
483 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
488 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
491 // First try to find the PE32 section in this ffs file.
493 Status
= PeiServicesFfsFindSectionData (
499 if (EFI_ERROR (Status
)) {
501 // NO image types we support so exit.
506 ZeroMem (&ImageContext
, sizeof (ImageContext
));
507 ImageContext
.Handle
= Pe32Data
;
508 Status
= GetImageReadFunction (&ImageContext
);
510 ASSERT_EFI_ERROR (Status
);
512 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
513 if (EFI_ERROR (Status
)) {
517 // Allocate Memory for the image
519 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32
) ImageContext
.ImageSize
));
520 ASSERT (ImageContext
.ImageAddress
!= 0);
523 // Load the image to our new buffer
525 Status
= PeCoffLoaderLoadImage (&ImageContext
);
526 if (EFI_ERROR (Status
)) {
530 // Relocate the image in our new buffer
532 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
533 if (EFI_ERROR (Status
)) {
538 // Flush the instruction cache so the image data is written before we execute it
540 InvalidateInstructionCacheRange ((VOID
*)(UINTN
)ImageContext
.ImageAddress
, (UINTN
)ImageContext
.ImageSize
);
542 *ImageAddress
= ImageContext
.ImageAddress
;
543 *ImageSize
= ImageContext
.ImageSize
;
544 *EntryPoint
= ImageContext
.EntryPoint
;
550 The ExtractSection() function processes the input section and
551 returns a pointer to the section contents. If the section being
552 extracted does not require processing (if the section
553 GuidedSectionHeader.Attributes has the
554 EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
555 OutputBuffer is just updated to point to the start of the
556 section's contents. Otherwise, *Buffer must be allocated
557 from PEI permanent memory.
559 @param This Indicates the
560 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
561 Buffer containing the input GUIDed section to be
562 processed. OutputBuffer OutputBuffer is
563 allocated from PEI permanent memory and contains
564 the new section stream.
566 @param OutputSize A pointer to a caller-allocated
567 UINTN in which the size of *OutputBuffer
568 allocation is stored. If the function
569 returns anything other than EFI_SUCCESS,
570 the value of OutputSize is undefined.
572 @param AuthenticationStatus A pointer to a caller-allocated
573 UINT32 that indicates the
574 authentication status of the
575 output buffer. If the input
576 section's GuidedSectionHeader.
577 Attributes field has the
578 EFI_GUIDED_SECTION_AUTH_STATUS_VALID
580 AuthenticationStatus must return
581 zero. These bits reflect the
582 status of the extraction
583 operation. If the function
584 returns anything other than
585 EFI_SUCCESS, the value of
586 AuthenticationStatus is
589 @retval EFI_SUCCESS The InputSection was
590 successfully processed and the
591 section contents were returned.
593 @retval EFI_OUT_OF_RESOURCES The system has insufficient
594 resources to process the request.
596 @reteval EFI_INVALID_PARAMETER The GUID in InputSection does
597 not match this instance of the
598 GUIDed Section Extraction PPI.
601 CustomGuidedSectionExtract (
602 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*This
,
603 IN CONST VOID
*InputSection
,
604 OUT VOID
**OutputBuffer
,
605 OUT UINTN
*OutputSize
,
606 OUT UINT32
*AuthenticationStatus
610 UINT8
*ScratchBuffer
;
611 UINT32 ScratchBufferSize
;
612 UINT32 OutputBufferSize
;
613 UINT16 SectionAttribute
;
616 // Init local variable
618 ScratchBuffer
= NULL
;
621 // Call GetInfo to get the size and attribute of input guided section data.
623 Status
= ExtractGuidedSectionGetInfo (
630 if (EFI_ERROR (Status
)) {
631 DEBUG ((EFI_D_ERROR
, "GetInfo from guided section Failed - %r\n", Status
));
635 if (ScratchBufferSize
!= 0) {
637 // Allocate scratch buffer
639 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
640 if (ScratchBuffer
== NULL
) {
641 return EFI_OUT_OF_RESOURCES
;
645 if ((SectionAttribute
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) && OutputBufferSize
> 0) {
647 // Allocate output buffer
649 *OutputBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize
));
650 if (*OutputBuffer
== NULL
) {
651 return EFI_OUT_OF_RESOURCES
;
655 Status
= ExtractGuidedSectionDecode (
662 if (EFI_ERROR (Status
)) {
666 DEBUG ((EFI_D_ERROR
, "Extract guided section Failed - %r\n", Status
));
670 *OutputSize
= (UINTN
) OutputBufferSize
;
679 IN CONST EFI_PEI_DECOMPRESS_PPI
*This
,
680 IN CONST EFI_COMPRESSION_SECTION
*CompressionSection
,
681 OUT VOID
**OutputBuffer
,
682 OUT UINTN
*OutputSize
687 UINT8
*ScratchBuffer
;
689 UINT32 ScratchBufferSize
;
690 EFI_COMMON_SECTION_HEADER
*Section
;
693 if (CompressionSection
->CommonHeader
.Type
!= EFI_SECTION_COMPRESSION
) {
695 return EFI_INVALID_PARAMETER
;
698 Section
= (EFI_COMMON_SECTION_HEADER
*) CompressionSection
;
699 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
702 // This is a compression set, expand it
704 switch (CompressionSection
->CompressionType
) {
705 case EFI_STANDARD_COMPRESSION
:
707 // Load EFI standard compression.
708 // For compressed data, decompress them to dstbuffer.
710 Status
= UefiDecompressGetInfo (
711 (UINT8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
712 (UINT32
) SectionLength
- sizeof (EFI_COMPRESSION_SECTION
),
713 (UINT32
*) &DstBufferSize
,
716 if (EFI_ERROR (Status
)) {
720 DEBUG ((EFI_D_ERROR
, "Decompress GetInfo Failed - %r\n", Status
));
721 return EFI_NOT_FOUND
;
724 // Allocate scratch buffer
726 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
727 if (ScratchBuffer
== NULL
) {
728 return EFI_OUT_OF_RESOURCES
;
731 // Allocate destination buffer
733 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
));
734 if (DstBuffer
== NULL
) {
735 return EFI_OUT_OF_RESOURCES
;
738 // Call decompress function
740 Status
= UefiDecompress (
741 (CHAR8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
745 if (EFI_ERROR (Status
)) {
749 DEBUG ((EFI_D_ERROR
, "Decompress Failed - %r\n", Status
));
750 return EFI_NOT_FOUND
;
754 // porting note the original branch for customized compress is removed, it should be change to use GUID compress
756 case EFI_NOT_COMPRESSED
:
758 // Allocate destination buffer
760 DstBufferSize
= CompressionSection
->UncompressedLength
;
761 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
));
762 if (DstBuffer
== NULL
) {
763 return EFI_OUT_OF_RESOURCES
;
766 // stream is not actually compressed, just encapsulated. So just copy it.
768 CopyMem (DstBuffer
, CompressionSection
+ 1, DstBufferSize
);
773 // Don't support other unknown compression type.
776 return EFI_NOT_FOUND
;
779 *OutputSize
= DstBufferSize
;
780 *OutputBuffer
= DstBuffer
;
787 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
791 EFI_PEI_HOB_POINTERS Hob
;
793 Hob
.Raw
= GetHobList ();
794 while ((Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION
, Hob
.Raw
)) != NULL
) {
795 if (CompareGuid (&gEfiHobMemoryAllocStackGuid
, &(Hob
.MemoryAllocationStack
->AllocDescriptor
.Name
))) {
797 // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
798 // to be reclaimed by DXE core.
800 BuildMemoryAllocationHob (
801 Hob
.MemoryAllocationStack
->AllocDescriptor
.MemoryBaseAddress
,
802 Hob
.MemoryAllocationStack
->AllocDescriptor
.MemoryLength
,
803 EfiConventionalMemory
806 // Update the BSP Stack Hob to reflect the new stack info.
808 Hob
.MemoryAllocationStack
->AllocDescriptor
.MemoryBaseAddress
= BaseAddress
;
809 Hob
.MemoryAllocationStack
->AllocDescriptor
.MemoryLength
= Length
;
812 Hob
.Raw
= GET_NEXT_HOB (Hob
);