3 Responsibility of this module is to load the DXE Core from a Firmware Volume.
5 Copyright (c) 2006 - 2008, Intel Corporation. <BR>
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>
22 The ExtractSection() function processes the input section and
23 returns a pointer to the section contents. If the section being
24 extracted does not require processing (if the section
25 GuidedSectionHeader.Attributes has the
26 EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
27 OutputBuffer is just updated to point to the start of the
28 section's contents. Otherwise, *Buffer must be allocated
29 from PEI permanent memory.
31 @param This Indicates the
32 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
33 Buffer containing the input GUIDed section to be
34 processed. OutputBuffer OutputBuffer is
35 allocated from PEI permanent memory and contains
36 the new section stream.
37 @param CompressionSection A pointer to the input buffer, which contains
38 the input section to be processed.
39 @param OutputBuffer A pointer to a caller-allocated buffer, whose
40 size is specified by the contents of OutputSize.
41 @param OutputSize A pointer to a caller-allocated
42 UINTN in which the size of *OutputBuffer
43 allocation is stored. If the function
44 returns anything other than EFI_SUCCESS,
45 the value of OutputSize is undefined.
46 @param AuthenticationStatus A pointer to a caller-allocated
47 UINT32 that indicates the
48 authentication status of the
49 output buffer. If the input
50 section's GuidedSectionHeader.
51 Attributes field has the
52 EFI_GUIDED_SECTION_AUTH_STATUS_VALID
54 AuthenticationStatus must return
55 zero. These bits reflect the
56 status of the extraction
57 operation. If the function
58 returns anything other than
59 EFI_SUCCESS, the value of
60 AuthenticationStatus is
63 @retval EFI_SUCCESS The InputSection was
64 successfully processed and the
65 section contents were returned.
67 @retval EFI_OUT_OF_RESOURCES The system has insufficient
68 resources to process the request.
70 @retval EFI_INVALID_PARAMETER The GUID in InputSection does
71 not match this instance of the
72 GUIDed Section Extraction PPI.
76 CustomGuidedSectionExtract (
77 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*This
,
78 IN CONST VOID
*CompressionSection
,
79 OUT VOID
**OutputBuffer
,
80 OUT UINTN
*OutputSize
,
81 OUT UINT32
*AuthenticationStatus
86 Decompresses a section to the output buffer.
88 This function lookes up the compression type field in the input section and
89 applies the appropriate compression algorithm to compress the section to a
90 callee allocated buffer.
92 @param This Points to this instance of the
93 EFI_PEI_DECOMPRESS_PEI PPI.
94 @param CompressionSection Points to the compressed section.
95 @param OutputBuffer Holds the returned pointer to the decompressed
97 @param OutputSize Holds the returned size of the decompress
100 @retval EFI_SUCCESS The section was decompressed successfully.
101 OutputBuffer contains the resulting data and
102 OutputSize contains the resulting size.
108 IN CONST EFI_PEI_DECOMPRESS_PPI
*This
,
109 IN CONST EFI_COMPRESSION_SECTION
*CompressionSection
,
110 OUT VOID
**OutputBuffer
,
111 OUT UINTN
*OutputSize
115 BOOLEAN gInMemory
= FALSE
;
118 // Module Globals used in the DXE to PEI handoff
119 // These must be module globals, so the stack can be switched
121 STATIC EFI_DXE_IPL_PPI mDxeIplPpi
= {
125 STATIC EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi
= {
126 CustomGuidedSectionExtract
129 STATIC EFI_PEI_DECOMPRESS_PPI mDecompressPpi
= {
133 STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList
[] = {
135 EFI_PEI_PPI_DESCRIPTOR_PPI
,
140 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
141 &gEfiPeiDecompressPpiGuid
,
146 STATIC EFI_PEI_PPI_DESCRIPTOR mPpiSignal
= {
147 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
148 &gEfiEndOfPeiSignalPpiGuid
,
153 Initializes the Dxe Ipl PPI
155 @param FfsHandle The handle of FFS file.
156 @param PeiServices General purpose services available to
163 PeimInitializeDxeIpl (
164 IN EFI_PEI_FILE_HANDLE FfsHandle
,
165 IN EFI_PEI_SERVICES
**PeiServices
169 EFI_BOOT_MODE BootMode
;
170 EFI_GUID
*ExtractHandlerGuidTable
;
171 UINTN ExtractHandlerNumber
;
172 EFI_PEI_PPI_DESCRIPTOR
*GuidPpi
;
174 Status
= PeiServicesGetBootMode (&BootMode
);
175 ASSERT_EFI_ERROR (Status
);
177 if (BootMode
!= BOOT_ON_S3_RESUME
) {
178 Status
= PeiServicesRegisterForShadow (FfsHandle
);
179 if (Status
== EFI_SUCCESS
) {
181 // EFI_SUCESS means the first time call register for shadow
184 } else if (Status
== EFI_ALREADY_STARTED
) {
189 // Get custom extract guided section method guid list
191 ExtractHandlerNumber
= ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable
);
194 // Install custom extraction guid ppi
196 if (ExtractHandlerNumber
> 0) {
198 GuidPpi
= (EFI_PEI_PPI_DESCRIPTOR
*) AllocatePool (ExtractHandlerNumber
* sizeof (EFI_PEI_PPI_DESCRIPTOR
));
199 ASSERT (GuidPpi
!= NULL
);
200 while (ExtractHandlerNumber
-- > 0) {
201 GuidPpi
->Flags
= EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
;
202 GuidPpi
->Ppi
= &mCustomGuidedSectionExtractionPpi
;
203 GuidPpi
->Guid
= &(ExtractHandlerGuidTable
[ExtractHandlerNumber
]);
204 Status
= PeiServicesInstallPpi (GuidPpi
++);
205 ASSERT_EFI_ERROR(Status
);
214 // Install DxeIpl and Decompress PPIs.
216 Status
= PeiServicesInstallPpi (mPpiList
);
217 ASSERT_EFI_ERROR(Status
);
223 Main entry point to last PEIM
225 @param This Entry point for DXE IPL PPI
226 @param PeiServices General purpose services available to every PEIM.
227 @param HobList Address to the Pei HOB list
229 @return EFI_SUCCESS DXE core was successfully loaded.
230 @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core.
236 IN EFI_DXE_IPL_PPI
*This
,
237 IN EFI_PEI_SERVICES
**PeiServices
,
238 IN EFI_PEI_HOB_POINTERS HobList
242 EFI_GUID DxeCoreFileName
;
243 EFI_PHYSICAL_ADDRESS DxeCoreAddress
;
245 EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint
;
246 EFI_BOOT_MODE BootMode
;
247 EFI_PEI_FILE_HANDLE FileHandle
;
248 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
;
250 EFI_MEMORY_TYPE_INFORMATION MemoryData
[EfiMaxMemoryType
+ 1];
253 // if in S3 Resume, restore configure
255 Status
= PeiServicesGetBootMode (&BootMode
);
256 ASSERT_EFI_ERROR(Status
);
258 if (BootMode
== BOOT_ON_S3_RESUME
) {
259 Status
= AcpiS3ResumeOs();
260 ASSERT_EFI_ERROR (Status
);
261 } else if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
262 Status
= PeiRecoverFirmware ();
263 if (EFI_ERROR (Status
)) {
264 DEBUG ((DEBUG_ERROR
, "Load Recovery Capsule Failed.(Status = %r)\n", Status
));
269 // Now should have a HOB with the DXE core w/ the old HOB destroyed
273 Status
= PeiServicesLocatePpi (
274 &gEfiPeiReadOnlyVariable2PpiGuid
,
279 ASSERT_EFI_ERROR (Status
);
281 DataSize
= sizeof (MemoryData
);
282 Status
= Variable
->GetVariable (
284 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME
,
285 &gEfiMemoryTypeInformationGuid
,
291 if (!EFI_ERROR (Status
)) {
293 // Build the GUID'd HOB for DXE
296 &gEfiMemoryTypeInformationGuid
,
303 // Look in all the FVs present in PEI and find the DXE Core
306 Status
= DxeIplFindDxeCore (&FileHandle
);
307 ASSERT_EFI_ERROR (Status
);
309 CopyMem(&DxeCoreFileName
, &(((EFI_FFS_FILE_HEADER
*)FileHandle
)->Name
), sizeof (EFI_GUID
));
312 // Load the DXE Core from a Firmware Volume, may use LoadFile ppi to do this for save code size.
314 Status
= PeiLoadFile (
321 ASSERT_EFI_ERROR (Status
);
324 // Add HOB for the DXE Core
329 EFI_SIZE_TO_PAGES ((UINT32
) DxeCoreSize
) * EFI_PAGE_SIZE
,
334 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
338 PcdGet32(PcdStatusCodeValuePeiHandoffToDxe
)
343 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION PtrPeImage
;
344 PtrPeImage
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) ((UINTN
) DxeCoreAddress
+ ((EFI_IMAGE_DOS_HEADER
*) (UINTN
) DxeCoreAddress
)->e_lfanew
);
346 if (PtrPeImage
.Pe32
->FileHeader
.Machine
!= IMAGE_FILE_MACHINE_IA64
) {
347 DEBUG ((DEBUG_INFO
| DEBUG_LOAD
, "Loading DXE CORE at 0x%10p EntryPoint=0x%10p\n", (VOID
*)(UINTN
)DxeCoreAddress
, (VOID
*)(UINTN
)DxeCoreEntryPoint
));
350 // For IPF Image, the real entry point should be print.
352 DEBUG ((DEBUG_INFO
| DEBUG_LOAD
, "Loading DXE CORE at 0x%10p EntryPoint=0x%10p\n", (VOID
*)(UINTN
)DxeCoreAddress
, (VOID
*)(UINTN
)(*(UINT64
*)(UINTN
)DxeCoreEntryPoint
)));
357 // Transfer control to the DXE Core
358 // The handoff state is simply a pointer to the HOB list
360 HandOffToDxeCore (DxeCoreEntryPoint
, HobList
, &mPpiSignal
);
362 // If we get here, then the DXE Core returned. This is an error
363 // Dxe Core should not return.
368 return EFI_OUT_OF_RESOURCES
;
375 Find DxeCore driver from all First Volumes.
377 @param FileHandle Pointer to FFS file to search.
379 @return EFI_SUCESS Success to find the FFS in specificed FV
380 @return others Fail to find the FFS in specificed FV
385 OUT EFI_PEI_FILE_HANDLE
*FileHandle
389 EFI_STATUS FileStatus
;
391 EFI_PEI_FV_HANDLE VolumeHandle
;
397 Status
= PeiServicesFfsFindNextVolume (Instance
++, &VolumeHandle
);
398 if (!EFI_ERROR (Status
)) {
399 FileStatus
= PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE
, VolumeHandle
, FileHandle
);
400 if (!EFI_ERROR (FileStatus
)) {
404 } while (!EFI_ERROR (Status
));
406 return EFI_NOT_FOUND
;
413 Loads and relocates a PE/COFF image into memory.
415 @param FileHandle The image file handle
416 @param ImageAddress The base address of the relocated PE/COFF image
417 @param ImageSize The size of the relocated PE/COFF image
418 @param EntryPoint The entry point of the relocated PE/COFF image
420 @return EFI_SUCCESS The file was loaded and relocated
421 @return EFI_OUT_OF_RESOURCES There was not enough memory to load and relocate the PE/COFF file
426 IN EFI_PEI_FILE_HANDLE FileHandle
,
427 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
428 OUT UINT64
*ImageSize
,
429 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
434 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
437 // First try to find the PE32 section in this ffs file.
439 Status
= PeiServicesFfsFindSectionData (
445 if (EFI_ERROR (Status
)) {
447 // NO image types we support so exit.
452 ZeroMem (&ImageContext
, sizeof (ImageContext
));
453 ImageContext
.Handle
= Pe32Data
;
454 Status
= GetImageReadFunction (&ImageContext
);
456 ASSERT_EFI_ERROR (Status
);
458 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
459 if (EFI_ERROR (Status
)) {
463 // Allocate Memory for the image
465 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32
) ImageContext
.ImageSize
));
466 ASSERT (ImageContext
.ImageAddress
!= 0);
469 // Load the image to our new buffer
471 Status
= PeCoffLoaderLoadImage (&ImageContext
);
472 if (EFI_ERROR (Status
)) {
476 // Relocate the image in our new buffer
478 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
479 if (EFI_ERROR (Status
)) {
484 // Flush the instruction cache so the image data is written before we execute it
486 InvalidateInstructionCacheRange ((VOID
*)(UINTN
)ImageContext
.ImageAddress
, (UINTN
)ImageContext
.ImageSize
);
488 *ImageAddress
= ImageContext
.ImageAddress
;
489 *ImageSize
= ImageContext
.ImageSize
;
490 *EntryPoint
= ImageContext
.EntryPoint
;
499 The ExtractSection() function processes the input section and
500 returns a pointer to the section contents. If the section being
501 extracted does not require processing (if the section
502 GuidedSectionHeader.Attributes has the
503 EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
504 OutputBuffer is just updated to point to the start of the
505 section's contents. Otherwise, *Buffer must be allocated
506 from PEI permanent memory.
508 @param This Indicates the
509 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
510 Buffer containing the input GUIDed section to be
511 processed. OutputBuffer OutputBuffer is
512 allocated from PEI permanent memory and contains
513 the new section stream.
514 @param InputSection A pointer to the input buffer, which contains
515 the input section to be processed.
516 @param OutputBuffer A pointer to a caller-allocated buffer, whose
517 size is specified by the contents of OutputSize.
518 @param OutputSize A pointer to a caller-allocated
519 UINTN in which the size of *OutputBuffer
520 allocation is stored. If the function
521 returns anything other than EFI_SUCCESS,
522 the value of OutputSize is undefined.
523 @param AuthenticationStatus A pointer to a caller-allocated
524 UINT32 that indicates the
525 authentication status of the
526 output buffer. If the input
527 section's GuidedSectionHeader.
528 Attributes field has the
529 EFI_GUIDED_SECTION_AUTH_STATUS_VALID
531 AuthenticationStatus must return
532 zero. These bits reflect the
533 status of the extraction
534 operation. If the function
535 returns anything other than
536 EFI_SUCCESS, the value of
537 AuthenticationStatus is
540 @retval EFI_SUCCESS The InputSection was
541 successfully processed and the
542 section contents were returned.
544 @retval EFI_OUT_OF_RESOURCES The system has insufficient
545 resources to process the request.
547 @retval EFI_INVALID_PARAMETER The GUID in InputSection does
548 not match this instance of the
549 GUIDed Section Extraction PPI.
553 CustomGuidedSectionExtract (
554 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*This
,
555 IN CONST VOID
*InputSection
,
556 OUT VOID
**OutputBuffer
,
557 OUT UINTN
*OutputSize
,
558 OUT UINT32
*AuthenticationStatus
562 UINT8
*ScratchBuffer
;
563 UINT32 ScratchBufferSize
;
564 UINT32 OutputBufferSize
;
565 UINT16 SectionAttribute
;
568 // Init local variable
570 ScratchBuffer
= NULL
;
573 // Call GetInfo to get the size and attribute of input guided section data.
575 Status
= ExtractGuidedSectionGetInfo (
582 if (EFI_ERROR (Status
)) {
583 DEBUG ((DEBUG_ERROR
, "GetInfo from guided section Failed - %r\n", Status
));
587 if (ScratchBufferSize
!= 0) {
589 // Allocate scratch buffer
591 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
592 if (ScratchBuffer
== NULL
) {
593 return EFI_OUT_OF_RESOURCES
;
597 if (((SectionAttribute
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) != 0) && OutputBufferSize
> 0) {
599 // Allocate output buffer
601 *OutputBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize
) + 1);
602 if (*OutputBuffer
== NULL
) {
603 return EFI_OUT_OF_RESOURCES
;
605 DEBUG ((DEBUG_INFO
, "Customed Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize
, *OutputBuffer
));
607 // *OutputBuffer still is one section. Adjust *OutputBuffer offset,
608 // skip EFI section header to make section data at page alignment.
610 *OutputBuffer
= (VOID
*)((UINT8
*) *OutputBuffer
+ EFI_PAGE_SIZE
- sizeof (EFI_COMMON_SECTION_HEADER
));
613 Status
= ExtractGuidedSectionDecode (
620 if (EFI_ERROR (Status
)) {
624 DEBUG ((DEBUG_ERROR
, "Extract guided section Failed - %r\n", Status
));
628 *OutputSize
= (UINTN
) OutputBufferSize
;
636 Decompresses a section to the output buffer.
638 This function lookes up the compression type field in the input section and
639 applies the appropriate compression algorithm to compress the section to a
640 callee allocated buffer.
642 @param This Points to this instance of the
643 EFI_PEI_DECOMPRESS_PEI PPI.
644 @param CompressionSection Points to the compressed section.
645 @param OutputBuffer Holds the returned pointer to the decompressed
647 @param OutputSize Holds the returned size of the decompress
650 @retval EFI_SUCCESS The section was decompressed successfully.
651 OutputBuffer contains the resulting data and
652 OutputSize contains the resulting size.
658 IN CONST EFI_PEI_DECOMPRESS_PPI
*This
,
659 IN CONST EFI_COMPRESSION_SECTION
*CompressionSection
,
660 OUT VOID
**OutputBuffer
,
661 OUT UINTN
*OutputSize
666 UINT8
*ScratchBuffer
;
668 UINT32 ScratchBufferSize
;
669 EFI_COMMON_SECTION_HEADER
*Section
;
672 if (CompressionSection
->CommonHeader
.Type
!= EFI_SECTION_COMPRESSION
) {
674 return EFI_INVALID_PARAMETER
;
677 Section
= (EFI_COMMON_SECTION_HEADER
*) CompressionSection
;
678 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
681 // This is a compression set, expand it
683 switch (CompressionSection
->CompressionType
) {
684 case EFI_STANDARD_COMPRESSION
:
686 // Load EFI standard compression.
687 // For compressed data, decompress them to dstbuffer.
689 Status
= UefiDecompressGetInfo (
690 (UINT8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
691 (UINT32
) SectionLength
- sizeof (EFI_COMPRESSION_SECTION
),
692 (UINT32
*) &DstBufferSize
,
695 if (EFI_ERROR (Status
)) {
699 DEBUG ((DEBUG_ERROR
, "Decompress GetInfo Failed - %r\n", Status
));
700 return EFI_NOT_FOUND
;
703 // Allocate scratch buffer
705 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
706 if (ScratchBuffer
== NULL
) {
707 return EFI_OUT_OF_RESOURCES
;
710 // Allocate destination buffer, extra one page for adjustment
712 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
) + 1);
713 if (DstBuffer
== NULL
) {
714 return EFI_OUT_OF_RESOURCES
;
717 // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
718 // to make section data at page alignment.
720 DstBuffer
= DstBuffer
+ EFI_PAGE_SIZE
- sizeof (EFI_COMMON_SECTION_HEADER
);
722 // Call decompress function
724 Status
= UefiDecompress (
725 (CHAR8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
729 if (EFI_ERROR (Status
)) {
733 DEBUG ((DEBUG_ERROR
, "Decompress Failed - %r\n", Status
));
734 return EFI_NOT_FOUND
;
738 case EFI_NOT_COMPRESSED
:
740 // Allocate destination buffer
742 DstBufferSize
= CompressionSection
->UncompressedLength
;
743 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
) + 1);
744 if (DstBuffer
== NULL
) {
745 return EFI_OUT_OF_RESOURCES
;
748 // Adjust DstBuffer offset, skip EFI section header
749 // to make section data at page alignment.
751 DstBuffer
= DstBuffer
+ EFI_PAGE_SIZE
- sizeof (EFI_COMMON_SECTION_HEADER
);
753 // stream is not actually compressed, just encapsulated. So just copy it.
755 CopyMem (DstBuffer
, CompressionSection
+ 1, DstBufferSize
);
760 // Don't support other unknown compression type.
763 return EFI_NOT_FOUND
;
766 *OutputSize
= DstBufferSize
;
767 *OutputBuffer
= DstBuffer
;
776 Updates the Stack HOB passed to DXE phase.
778 This function traverses the whole HOB list and update the stack HOB to
779 reflect the real stack that is used by DXE core.
781 @param BaseAddress The lower address of stack used by DxeCore.
782 @param Length The length of stack used by DxeCore.
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
);