]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
d0baf2eb9120ee6d84680583769af094b0602029
[mirror_edk2.git] / MdeModulePkg / Core / DxeIplPeim / DxeLoad.c
1 /** @file
2 Last PEIM.
3 Responsibility of this module is to load the DXE Core from a Firmware Volume.
4
5 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
6 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
10
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.
13
14 **/
15
16 #include "DxeIpl.h"
17
18
19 //
20 // Module Globals used in the DXE to PEI hand off
21 // These must be module globals, so the stack can be switched
22 //
23 CONST EFI_DXE_IPL_PPI mDxeIplPpi = {
24 DxeLoadCore
25 };
26
27 CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {
28 CustomGuidedSectionExtract
29 };
30
31 CONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {
32 Decompress
33 };
34
35 CONST EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
36 {
37 EFI_PEI_PPI_DESCRIPTOR_PPI,
38 &gEfiDxeIplPpiGuid,
39 (VOID *) &mDxeIplPpi
40 },
41 {
42 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
43 &gEfiPeiDecompressPpiGuid,
44 (VOID *) &mDecompressPpi
45 }
46 };
47
48 CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {
49 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
50 &gEfiEndOfPeiSignalPpiGuid,
51 NULL
52 };
53
54 /**
55 Entry point of DXE IPL PEIM.
56
57 This function installs DXE IPL PPI and Decompress PPI. It also reloads
58 itself to memory on non-S3 resume boot path.
59
60 @param FileHandle Handle of the file being invoked.
61 @param PeiServices Describes the list of possible PEI Services.
62
63 @retval EFI_SUCESS The entry point of DXE IPL PEIM executes successfully.
64 @retval Others Some error occurs during the execution of this function.
65
66 **/
67 EFI_STATUS
68 EFIAPI
69 PeimInitializeDxeIpl (
70 IN EFI_PEI_FILE_HANDLE FileHandle,
71 IN CONST EFI_PEI_SERVICES **PeiServices
72 )
73 {
74 EFI_STATUS Status;
75 EFI_BOOT_MODE BootMode;
76 EFI_GUID *ExtractHandlerGuidTable;
77 UINTN ExtractHandlerNumber;
78 EFI_PEI_PPI_DESCRIPTOR *GuidPpi;
79
80 BootMode = GetBootModeHob ();
81
82 if (BootMode != BOOT_ON_S3_RESUME) {
83 Status = PeiServicesRegisterForShadow (FileHandle);
84 if (Status == EFI_SUCCESS) {
85 //
86 // EFI_SUCESS means it is the first time to call register for shadow.
87 //
88 return Status;
89 }
90
91 //
92 // Ensure that DXE IPL is shadowed to permanent memory.
93 //
94 ASSERT (Status == EFI_ALREADY_STARTED);
95
96 //
97 // Get custom extract guided section method guid list
98 //
99 ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
100
101 //
102 // Install custom extraction guid PPI
103 //
104 if (ExtractHandlerNumber > 0) {
105 GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
106 ASSERT (GuidPpi != NULL);
107 while (ExtractHandlerNumber-- > 0) {
108 GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
109 GuidPpi->Ppi = (VOID *) &mCustomGuidedSectionExtractionPpi;
110 GuidPpi->Guid = &ExtractHandlerGuidTable[ExtractHandlerNumber];
111 Status = PeiServicesInstallPpi (GuidPpi++);
112 ASSERT_EFI_ERROR(Status);
113 }
114 }
115
116 }
117
118 //
119 // Install DxeIpl and Decompress PPIs.
120 //
121 Status = PeiServicesInstallPpi (mPpiList);
122 ASSERT_EFI_ERROR(Status);
123
124 return Status;
125 }
126
127 /**
128 Main entry point to last PEIM.
129
130 This function finds DXE Core in the firmware volume and transfer the control to
131 DXE core.
132
133 @param This Entry point for DXE IPL PPI.
134 @param PeiServices General purpose services available to every PEIM.
135 @param HobList Address to the Pei HOB list.
136
137 @return EFI_SUCCESS DXE core was successfully loaded.
138 @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core.
139
140 **/
141 EFI_STATUS
142 EFIAPI
143 DxeLoadCore (
144 IN CONST EFI_DXE_IPL_PPI *This,
145 IN EFI_PEI_SERVICES **PeiServices,
146 IN EFI_PEI_HOB_POINTERS HobList
147 )
148 {
149 EFI_STATUS Status;
150 EFI_FV_FILE_INFO DxeCoreFileInfo;
151 EFI_PHYSICAL_ADDRESS DxeCoreAddress;
152 UINT64 DxeCoreSize;
153 EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;
154 EFI_BOOT_MODE BootMode;
155 EFI_PEI_FILE_HANDLE FileHandle;
156 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
157 EFI_PEI_LOAD_FILE_PPI *LoadFile;
158 UINTN Instance;
159 UINT32 AuthenticationState;
160 UINTN DataSize;
161 EFI_PEI_S3_RESUME2_PPI *S3Resume;
162 EFI_PEI_RECOVERY_MODULE_PPI *PeiRecovery;
163 EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1];
164
165 //
166 // if in S3 Resume, restore configure
167 //
168 BootMode = GetBootModeHob ();
169
170 if (BootMode == BOOT_ON_S3_RESUME) {
171 Status = PeiServicesLocatePpi (
172 &gEfiPeiS3Resume2PpiGuid,
173 0,
174 NULL,
175 (VOID **) &S3Resume
176 );
177 ASSERT_EFI_ERROR (Status);
178
179 Status = S3Resume->S3RestoreConfig2 (S3Resume);
180 ASSERT_EFI_ERROR (Status);
181 } else if (BootMode == BOOT_IN_RECOVERY_MODE) {
182 Status = PeiServicesLocatePpi (
183 &gEfiPeiRecoveryModulePpiGuid,
184 0,
185 NULL,
186 (VOID **) &PeiRecovery
187 );
188 ASSERT_EFI_ERROR (Status);
189
190 Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);
191 if (EFI_ERROR (Status)) {
192 DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));
193 CpuDeadLoop ();
194 }
195
196 //
197 // Now should have a HOB with the DXE core
198 //
199 }
200
201 Status = PeiServicesLocatePpi (
202 &gEfiPeiReadOnlyVariable2PpiGuid,
203 0,
204 NULL,
205 (VOID **)&Variable
206 );
207 if (!EFI_ERROR (Status)) {
208 DataSize = sizeof (MemoryData);
209 Status = Variable->GetVariable (
210 Variable,
211 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
212 &gEfiMemoryTypeInformationGuid,
213 NULL,
214 &DataSize,
215 &MemoryData
216 );
217 if (!EFI_ERROR (Status)) {
218 //
219 // Build the GUID'd HOB for DXE
220 //
221 BuildGuidDataHob (
222 &gEfiMemoryTypeInformationGuid,
223 MemoryData,
224 DataSize
225 );
226 }
227 }
228
229 //
230 // Look in all the FVs present in PEI and find the DXE Core FileHandle
231 //
232 FileHandle = DxeIplFindDxeCore ();
233
234 //
235 // Load the DXE Core from a Firmware Volume.
236 //
237 Instance = 0;
238 do {
239 Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **) &LoadFile);
240 //
241 // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully.
242 //
243 ASSERT_EFI_ERROR (Status);
244
245 Status = LoadFile->LoadFile (
246 LoadFile,
247 FileHandle,
248 &DxeCoreAddress,
249 &DxeCoreSize,
250 &DxeCoreEntryPoint,
251 &AuthenticationState
252 );
253 } while (EFI_ERROR (Status));
254
255 //
256 // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name.
257 //
258 Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo);
259 ASSERT_EFI_ERROR (Status);
260
261 //
262 // Add HOB for the DXE Core
263 //
264 BuildModuleHob (
265 &DxeCoreFileInfo.FileName,
266 DxeCoreAddress,
267 ALIGN_VALUE (DxeCoreSize, EFI_PAGE_SIZE),
268 DxeCoreEntryPoint
269 );
270
271 //
272 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
273 //
274 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT));
275
276 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint)));
277
278 //
279 // Transfer control to the DXE Core
280 // The hand off state is simply a pointer to the HOB list
281 //
282 HandOffToDxeCore (DxeCoreEntryPoint, HobList);
283 //
284 // If we get here, then the DXE Core returned. This is an error
285 // DxeCore should not return.
286 //
287 ASSERT (FALSE);
288 CpuDeadLoop ();
289
290 return EFI_OUT_OF_RESOURCES;
291 }
292
293
294 /**
295 Searches DxeCore in all firmware Volumes and loads the first
296 instance that contains DxeCore.
297
298 @return FileHandle of DxeCore to load DxeCore.
299
300 **/
301 EFI_PEI_FILE_HANDLE
302 DxeIplFindDxeCore (
303 VOID
304 )
305 {
306 EFI_STATUS Status;
307 UINTN Instance;
308 EFI_PEI_FV_HANDLE VolumeHandle;
309 EFI_PEI_FILE_HANDLE FileHandle;
310
311 Instance = 0;
312 while (TRUE) {
313 //
314 // Traverse all firmware volume instances
315 //
316 Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);
317 //
318 // If some error occurs here, then we cannot find any firmware
319 // volume that may contain DxeCore.
320 //
321 if (EFI_ERROR (Status)) {
322 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT));
323 }
324 ASSERT_EFI_ERROR (Status);
325
326 //
327 // Find the DxeCore file type from the beginning in this firmware volume.
328 //
329 FileHandle = NULL;
330 Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);
331 if (!EFI_ERROR (Status)) {
332 //
333 // Find DxeCore FileHandle in this volume, then we skip other firmware volume and
334 // return the FileHandle.
335 //
336 return FileHandle;
337 }
338 //
339 // We cannot find DxeCore in this firmware volume, then search the next volume.
340 //
341 Instance++;
342 }
343 }
344
345
346
347 /**
348 The ExtractSection() function processes the input section and
349 returns a pointer to the section contents. If the section being
350 extracted does not require processing (if the section
351 GuidedSectionHeader.Attributes has the
352 EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
353 OutputBuffer is just updated to point to the start of the
354 section's contents. Otherwise, *Buffer must be allocated
355 from PEI permanent memory.
356
357 @param This Indicates the
358 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
359 Buffer containing the input GUIDed section to be
360 processed. OutputBuffer OutputBuffer is
361 allocated from PEI permanent memory and contains
362 the new section stream.
363 @param InputSection A pointer to the input buffer, which contains
364 the input section to be processed.
365 @param OutputBuffer A pointer to a caller-allocated buffer, whose
366 size is specified by the contents of OutputSize.
367 @param OutputSize A pointer to a caller-allocated
368 UINTN in which the size of *OutputBuffer
369 allocation is stored. If the function
370 returns anything other than EFI_SUCCESS,
371 the value of OutputSize is undefined.
372 @param AuthenticationStatus A pointer to a caller-allocated
373 UINT32 that indicates the
374 authentication status of the
375 output buffer. If the input
376 section's GuidedSectionHeader.
377 Attributes field has the
378 EFI_GUIDED_SECTION_AUTH_STATUS_VALID
379 bit as clear,
380 AuthenticationStatus must return
381 zero. These bits reflect the
382 status of the extraction
383 operation. If the function
384 returns anything other than
385 EFI_SUCCESS, the value of
386 AuthenticationStatus is
387 undefined.
388
389 @retval EFI_SUCCESS The InputSection was
390 successfully processed and the
391 section contents were returned.
392
393 @retval EFI_OUT_OF_RESOURCES The system has insufficient
394 resources to process the request.
395
396 @retval EFI_INVALID_PARAMETER The GUID in InputSection does
397 not match this instance of the
398 GUIDed Section Extraction PPI.
399
400 **/
401 EFI_STATUS
402 EFIAPI
403 CustomGuidedSectionExtract (
404 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
405 IN CONST VOID *InputSection,
406 OUT VOID **OutputBuffer,
407 OUT UINTN *OutputSize,
408 OUT UINT32 *AuthenticationStatus
409 )
410 {
411 EFI_STATUS Status;
412 UINT8 *ScratchBuffer;
413 UINT32 ScratchBufferSize;
414 UINT32 OutputBufferSize;
415 UINT16 SectionAttribute;
416
417 //
418 // Init local variable
419 //
420 ScratchBuffer = NULL;
421
422 //
423 // Call GetInfo to get the size and attribute of input guided section data.
424 //
425 Status = ExtractGuidedSectionGetInfo (
426 InputSection,
427 &OutputBufferSize,
428 &ScratchBufferSize,
429 &SectionAttribute
430 );
431
432 if (EFI_ERROR (Status)) {
433 DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));
434 return Status;
435 }
436
437 if (ScratchBufferSize != 0) {
438 //
439 // Allocate scratch buffer
440 //
441 ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
442 if (ScratchBuffer == NULL) {
443 return EFI_OUT_OF_RESOURCES;
444 }
445 }
446
447 if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {
448 //
449 // Allocate output buffer
450 //
451 *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);
452 if (*OutputBuffer == NULL) {
453 return EFI_OUT_OF_RESOURCES;
454 }
455 DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
456 //
457 // *OutputBuffer still is one section. Adjust *OutputBuffer offset,
458 // skip EFI section header to make section data at page alignment.
459 //
460 *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));
461 }
462
463 Status = ExtractGuidedSectionDecode (
464 InputSection,
465 OutputBuffer,
466 ScratchBuffer,
467 AuthenticationStatus
468 );
469 if (EFI_ERROR (Status)) {
470 //
471 // Decode failed
472 //
473 DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));
474 return Status;
475 }
476
477 *OutputSize = (UINTN) OutputBufferSize;
478
479 return EFI_SUCCESS;
480 }
481
482
483
484 /**
485 Decompresses a section to the output buffer.
486
487 This function looks up the compression type field in the input section and
488 applies the appropriate compression algorithm to compress the section to a
489 callee allocated buffer.
490
491 @param This Points to this instance of the
492 EFI_PEI_DECOMPRESS_PEI PPI.
493 @param CompressionSection Points to the compressed section.
494 @param OutputBuffer Holds the returned pointer to the decompressed
495 sections.
496 @param OutputSize Holds the returned size of the decompress
497 section streams.
498
499 @retval EFI_SUCCESS The section was decompressed successfully.
500 OutputBuffer contains the resulting data and
501 OutputSize contains the resulting size.
502
503 **/
504 EFI_STATUS
505 EFIAPI
506 Decompress (
507 IN CONST EFI_PEI_DECOMPRESS_PPI *This,
508 IN CONST EFI_COMPRESSION_SECTION *CompressionSection,
509 OUT VOID **OutputBuffer,
510 OUT UINTN *OutputSize
511 )
512 {
513 EFI_STATUS Status;
514 UINT8 *DstBuffer;
515 UINT8 *ScratchBuffer;
516 UINT32 DstBufferSize;
517 UINT32 ScratchBufferSize;
518 VOID *CompressionSource;
519 UINT32 CompressionSourceSize;
520 UINT32 UncompressedLength;
521 UINT8 CompressionType;
522
523 if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {
524 ASSERT (FALSE);
525 return EFI_INVALID_PARAMETER;
526 }
527
528 if (IS_SECTION2 (CompressionSection)) {
529 CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION2));
530 CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION2));
531 UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->UncompressedLength;
532 CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->CompressionType;
533 } else {
534 CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION));
535 CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION));
536 UncompressedLength = CompressionSection->UncompressedLength;
537 CompressionType = CompressionSection->CompressionType;
538 }
539
540 //
541 // This is a compression set, expand it
542 //
543 switch (CompressionType) {
544 case EFI_STANDARD_COMPRESSION:
545 if (FeaturePcdGet(PcdDxeIplSupportUefiDecompress)) {
546 //
547 // Load EFI standard compression.
548 // For compressed data, decompress them to destination buffer.
549 //
550 Status = UefiDecompressGetInfo (
551 CompressionSource,
552 CompressionSourceSize,
553 &DstBufferSize,
554 &ScratchBufferSize
555 );
556 if (EFI_ERROR (Status)) {
557 //
558 // GetInfo failed
559 //
560 DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));
561 return EFI_NOT_FOUND;
562 }
563 //
564 // Allocate scratch buffer
565 //
566 ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
567 if (ScratchBuffer == NULL) {
568 return EFI_OUT_OF_RESOURCES;
569 }
570 //
571 // Allocate destination buffer, extra one page for adjustment
572 //
573 DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
574 if (DstBuffer == NULL) {
575 return EFI_OUT_OF_RESOURCES;
576 }
577 //
578 // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
579 // to make section data at page alignment.
580 //
581 DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
582 //
583 // Call decompress function
584 //
585 Status = UefiDecompress (
586 CompressionSource,
587 DstBuffer,
588 ScratchBuffer
589 );
590 if (EFI_ERROR (Status)) {
591 //
592 // Decompress failed
593 //
594 DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));
595 return EFI_NOT_FOUND;
596 }
597 break;
598 } else {
599 //
600 // PcdDxeIplSupportUefiDecompress is FALSE
601 // Don't support UEFI decompression algorithm.
602 //
603 ASSERT (FALSE);
604 return EFI_NOT_FOUND;
605 }
606
607 case EFI_NOT_COMPRESSED:
608 //
609 // Allocate destination buffer
610 //
611 DstBufferSize = UncompressedLength;
612 DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
613 if (DstBuffer == NULL) {
614 return EFI_OUT_OF_RESOURCES;
615 }
616 //
617 // Adjust DstBuffer offset, skip EFI section header
618 // to make section data at page alignment.
619 //
620 DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
621 //
622 // stream is not actually compressed, just encapsulated. So just copy it.
623 //
624 CopyMem (DstBuffer, CompressionSource, DstBufferSize);
625 break;
626
627 default:
628 //
629 // Don't support other unknown compression type.
630 //
631 ASSERT (FALSE);
632 return EFI_NOT_FOUND;
633 }
634
635 *OutputSize = DstBufferSize;
636 *OutputBuffer = DstBuffer;
637
638 return EFI_SUCCESS;
639 }
640
641
642 /**
643 Updates the Stack HOB passed to DXE phase.
644
645 This function traverses the whole HOB list and update the stack HOB to
646 reflect the real stack that is used by DXE core.
647
648 @param BaseAddress The lower address of stack used by DxeCore.
649 @param Length The length of stack used by DxeCore.
650
651 **/
652 VOID
653 UpdateStackHob (
654 IN EFI_PHYSICAL_ADDRESS BaseAddress,
655 IN UINT64 Length
656 )
657 {
658 EFI_PEI_HOB_POINTERS Hob;
659
660 Hob.Raw = GetHobList ();
661 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
662 if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
663 //
664 // Build a new memory allocation HOB with old stack info with EfiBootServicesData type. Need to
665 // avoid this region be reclaimed by DXE core as the IDT built in SEC might be on stack, and some
666 // PEIMs may also keep key information on stack
667 //
668 BuildMemoryAllocationHob (
669 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
670 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
671 EfiBootServicesData
672 );
673 //
674 // Update the BSP Stack Hob to reflect the new stack info.
675 //
676 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
677 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
678 break;
679 }
680 Hob.Raw = GET_NEXT_HOB (Hob);
681 }
682 }