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