]> git.proxmox.com Git - mirror_edk2.git/blob - UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c
UefiPayloadPkg: Update the function definition of HobConstructor
[mirror_edk2.git] / UefiPayloadPkg / Library / PayloadEntryHobLib / Hob.c
1 /** @file
2
3 Copyright (c) 2010, Apple Inc. All rights reserved.<BR>
4 Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include <PiPei.h>
11
12 #include <Library/BaseLib.h>
13 #include <Library/BaseMemoryLib.h>
14 #include <Library/DebugLib.h>
15 #include <Library/HobLib.h>
16 #include <Library/PcdLib.h>
17
18 VOID *mHobList;
19
20 /**
21 Returns the pointer to the HOB list.
22
23 This function returns the pointer to first HOB in the list.
24
25 @return The pointer to the HOB list.
26
27 **/
28 VOID *
29 EFIAPI
30 GetHobList (
31 VOID
32 )
33 {
34 ASSERT (mHobList != NULL);
35 return mHobList;
36 }
37
38
39 /**
40 Build a Handoff Information Table HOB
41
42 This function initialize a HOB region from EfiMemoryBegin to
43 EfiMemoryTop. And EfiFreeMemoryBottom and EfiFreeMemoryTop should
44 be inside the HOB region.
45
46 @param[in] EfiMemoryBottom Total memory start address
47 @param[in] EfiMemoryTop Total memory end address.
48 @param[in] EfiFreeMemoryBottom Free memory start address
49 @param[in] EfiFreeMemoryTop Free memory end address.
50
51 @return The pointer to the handoff HOB table.
52
53 **/
54 EFI_HOB_HANDOFF_INFO_TABLE*
55 EFIAPI
56 HobConstructor (
57 IN VOID *EfiMemoryBottom,
58 IN VOID *EfiMemoryTop,
59 IN VOID *EfiFreeMemoryBottom,
60 IN VOID *EfiFreeMemoryTop
61 )
62 {
63 EFI_HOB_HANDOFF_INFO_TABLE *Hob;
64 EFI_HOB_GENERIC_HEADER *HobEnd;
65
66 Hob = EfiFreeMemoryBottom;
67 HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
68
69 Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
70 Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
71 Hob->Header.Reserved = 0;
72
73 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
74 HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
75 HobEnd->Reserved = 0;
76
77 Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
78 Hob->BootMode = BOOT_WITH_FULL_CONFIGURATION;
79
80 Hob->EfiMemoryTop = (EFI_PHYSICAL_ADDRESS) EfiMemoryTop;
81 Hob->EfiMemoryBottom = (EFI_PHYSICAL_ADDRESS) EfiMemoryBottom;
82 Hob->EfiFreeMemoryTop = (EFI_PHYSICAL_ADDRESS) EfiFreeMemoryTop;
83 Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) (HobEnd+1);
84 Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
85
86 mHobList = Hob;
87 return Hob;
88 }
89
90 /**
91 Add a new HOB to the HOB List.
92
93 @param HobType Type of the new HOB.
94 @param HobLength Length of the new HOB to allocate.
95
96 @return NULL if there is no space to create a hob.
97 @return The address point to the new created hob.
98
99 **/
100 VOID *
101 EFIAPI
102 CreateHob (
103 IN UINT16 HobType,
104 IN UINT16 HobLength
105 )
106 {
107 EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
108 EFI_HOB_GENERIC_HEADER *HobEnd;
109 EFI_PHYSICAL_ADDRESS FreeMemory;
110 VOID *Hob;
111
112 HandOffHob = GetHobList ();
113
114 HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
115
116 FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
117
118 if (FreeMemory < HobLength) {
119 return NULL;
120 }
121
122 Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
123 ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
124 ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
125 ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
126
127 HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
128 HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
129
130 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
131 HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
132 HobEnd->Reserved = 0;
133 HobEnd++;
134 HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
135
136 return Hob;
137 }
138
139 /**
140 Builds a HOB that describes a chunk of system memory.
141
142 This function builds a HOB that describes a chunk of system memory.
143 If there is no additional space for HOB creation, then ASSERT().
144
145 @param ResourceType The type of resource described by this HOB.
146 @param ResourceAttribute The resource attributes of the memory described by this HOB.
147 @param PhysicalStart The 64 bit physical address of memory described by this HOB.
148 @param NumberOfBytes The length of the memory described by this HOB in bytes.
149
150 **/
151 VOID
152 EFIAPI
153 BuildResourceDescriptorHob (
154 IN EFI_RESOURCE_TYPE ResourceType,
155 IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
156 IN EFI_PHYSICAL_ADDRESS PhysicalStart,
157 IN UINT64 NumberOfBytes
158 )
159 {
160 EFI_HOB_RESOURCE_DESCRIPTOR *Hob;
161
162 Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
163 ASSERT(Hob != NULL);
164
165 Hob->ResourceType = ResourceType;
166 Hob->ResourceAttribute = ResourceAttribute;
167 Hob->PhysicalStart = PhysicalStart;
168 Hob->ResourceLength = NumberOfBytes;
169 }
170
171 VOID
172 EFIAPI
173 BuildFvHobs (
174 IN EFI_PHYSICAL_ADDRESS PhysicalStart,
175 IN UINT64 NumberOfBytes,
176 IN EFI_RESOURCE_ATTRIBUTE_TYPE *ResourceAttribute
177 )
178 {
179
180 EFI_RESOURCE_ATTRIBUTE_TYPE Resource;
181
182 BuildFvHob (PhysicalStart, NumberOfBytes);
183
184 if (ResourceAttribute == NULL) {
185 Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT |
186 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
187 EFI_RESOURCE_ATTRIBUTE_TESTED |
188 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);
189 } else {
190 Resource = *ResourceAttribute;
191 }
192
193 BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes);
194 }
195
196 /**
197 Returns the next instance of a HOB type from the starting HOB.
198
199 This function searches the first instance of a HOB type from the starting HOB pointer.
200 If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
201 In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
202 unconditionally: it returns HobStart back if HobStart itself meets the requirement;
203 caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
204 If HobStart is NULL, then ASSERT().
205
206 @param Type The HOB type to return.
207 @param HobStart The starting HOB pointer to search from.
208
209 @return The next instance of a HOB type from the starting HOB.
210
211 **/
212 VOID *
213 EFIAPI
214 GetNextHob (
215 IN UINT16 Type,
216 IN CONST VOID *HobStart
217 )
218 {
219 EFI_PEI_HOB_POINTERS Hob;
220
221 ASSERT (HobStart != NULL);
222
223 Hob.Raw = (UINT8 *) HobStart;
224 //
225 // Parse the HOB list until end of list or matching type is found.
226 //
227 while (!END_OF_HOB_LIST (Hob)) {
228 if (Hob.Header->HobType == Type) {
229 return Hob.Raw;
230 }
231 Hob.Raw = GET_NEXT_HOB (Hob);
232 }
233 return NULL;
234 }
235
236
237
238 /**
239 Returns the first instance of a HOB type among the whole HOB list.
240
241 This function searches the first instance of a HOB type among the whole HOB list.
242 If there does not exist such HOB type in the HOB list, it will return NULL.
243
244 @param Type The HOB type to return.
245
246 @return The next instance of a HOB type from the starting HOB.
247
248 **/
249 VOID *
250 EFIAPI
251 GetFirstHob (
252 IN UINT16 Type
253 )
254 {
255 VOID *HobList;
256
257 HobList = GetHobList ();
258 return GetNextHob (Type, HobList);
259 }
260
261
262 /**
263 This function searches the first instance of a HOB from the starting HOB pointer.
264 Such HOB should satisfy two conditions:
265 its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
266 If there does not exist such HOB from the starting HOB pointer, it will return NULL.
267 Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
268 to extract the data section and its size info respectively.
269 In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
270 unconditionally: it returns HobStart back if HobStart itself meets the requirement;
271 caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
272 If Guid is NULL, then ASSERT().
273 If HobStart is NULL, then ASSERT().
274
275 @param Guid The GUID to match with in the HOB list.
276 @param HobStart A pointer to a Guid.
277
278 @return The next instance of the matched GUID HOB from the starting HOB.
279
280 **/
281 VOID *
282 EFIAPI
283 GetNextGuidHob (
284 IN CONST EFI_GUID *Guid,
285 IN CONST VOID *HobStart
286 ){
287 EFI_PEI_HOB_POINTERS GuidHob;
288
289 GuidHob.Raw = (UINT8 *) HobStart;
290 while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
291 if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
292 break;
293 }
294 GuidHob.Raw = GET_NEXT_HOB (GuidHob);
295 }
296 return GuidHob.Raw;
297 }
298
299
300 /**
301 This function searches the first instance of a HOB among the whole HOB list.
302 Such HOB should satisfy two conditions:
303 its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
304 If there does not exist such HOB from the starting HOB pointer, it will return NULL.
305 Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
306 to extract the data section and its size info respectively.
307 If Guid is NULL, then ASSERT().
308
309 @param Guid The GUID to match with in the HOB list.
310
311 @return The first instance of the matched GUID HOB among the whole HOB list.
312
313 **/
314 VOID *
315 EFIAPI
316 GetFirstGuidHob (
317 IN CONST EFI_GUID *Guid
318 )
319 {
320 VOID *HobList;
321
322 HobList = GetHobList ();
323 return GetNextGuidHob (Guid, HobList);
324 }
325
326
327
328
329 /**
330 Builds a HOB for a loaded PE32 module.
331
332 This function builds a HOB for a loaded PE32 module.
333 It can only be invoked during PEI phase;
334 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
335 If ModuleName is NULL, then ASSERT().
336 If there is no additional space for HOB creation, then ASSERT().
337
338 @param ModuleName The GUID File Name of the module.
339 @param MemoryAllocationModule The 64 bit physical address of the module.
340 @param ModuleLength The length of the module in bytes.
341 @param EntryPoint The 64 bit physical address of the module entry point.
342
343 **/
344 VOID
345 EFIAPI
346 BuildModuleHob (
347 IN CONST EFI_GUID *ModuleName,
348 IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,
349 IN UINT64 ModuleLength,
350 IN EFI_PHYSICAL_ADDRESS EntryPoint
351 )
352 {
353 EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob;
354
355 ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
356 ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
357
358 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
359
360 CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
361 Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
362 Hob->MemoryAllocationHeader.MemoryLength = ModuleLength;
363 Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode;
364
365 //
366 // Zero the reserved space to match HOB spec
367 //
368 ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
369
370 CopyGuid (&Hob->ModuleName, ModuleName);
371 Hob->EntryPoint = EntryPoint;
372 }
373
374 /**
375 Builds a GUID HOB with a certain data length.
376
377 This function builds a customized HOB tagged with a GUID for identification
378 and returns the start address of GUID HOB data so that caller can fill the customized data.
379 The HOB Header and Name field is already stripped.
380 It can only be invoked during PEI phase;
381 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
382 If Guid is NULL, then ASSERT().
383 If there is no additional space for HOB creation, then ASSERT().
384 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
385
386 @param Guid The GUID to tag the customized HOB.
387 @param DataLength The size of the data payload for the GUID HOB.
388
389 @return The start address of GUID HOB data.
390
391 **/
392 VOID *
393 EFIAPI
394 BuildGuidHob (
395 IN CONST EFI_GUID *Guid,
396 IN UINTN DataLength
397 )
398 {
399 EFI_HOB_GUID_TYPE *Hob;
400
401 //
402 // Make sure that data length is not too long.
403 //
404 ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
405
406 Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
407 CopyGuid (&Hob->Name, Guid);
408 return Hob + 1;
409 }
410
411
412 /**
413 Copies a data buffer to a newly-built HOB.
414
415 This function builds a customized HOB tagged with a GUID for identification,
416 copies the input data to the HOB data field and returns the start address of the GUID HOB data.
417 The HOB Header and Name field is already stripped.
418 It can only be invoked during PEI phase;
419 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
420 If Guid is NULL, then ASSERT().
421 If Data is NULL and DataLength > 0, then ASSERT().
422 If there is no additional space for HOB creation, then ASSERT().
423 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
424
425 @param Guid The GUID to tag the customized HOB.
426 @param Data The data to be copied into the data field of the GUID HOB.
427 @param DataLength The size of the data payload for the GUID HOB.
428
429 @return The start address of GUID HOB data.
430
431 **/
432 VOID *
433 EFIAPI
434 BuildGuidDataHob (
435 IN CONST EFI_GUID *Guid,
436 IN VOID *Data,
437 IN UINTN DataLength
438 )
439 {
440 VOID *HobData;
441
442 ASSERT (Data != NULL || DataLength == 0);
443
444 HobData = BuildGuidHob (Guid, DataLength);
445
446 return CopyMem (HobData, Data, DataLength);
447 }
448
449
450 /**
451 Builds a Firmware Volume HOB.
452
453 This function builds a Firmware Volume HOB.
454 It can only be invoked during PEI phase;
455 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
456 If there is no additional space for HOB creation, then ASSERT().
457
458 @param BaseAddress The base address of the Firmware Volume.
459 @param Length The size of the Firmware Volume in bytes.
460
461 **/
462 VOID
463 EFIAPI
464 BuildFvHob (
465 IN EFI_PHYSICAL_ADDRESS BaseAddress,
466 IN UINT64 Length
467 )
468 {
469 EFI_HOB_FIRMWARE_VOLUME *Hob;
470
471 Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
472
473 Hob->BaseAddress = BaseAddress;
474 Hob->Length = Length;
475 }
476
477
478 /**
479 Builds a EFI_HOB_TYPE_FV2 HOB.
480
481 This function builds a EFI_HOB_TYPE_FV2 HOB.
482 It can only be invoked during PEI phase;
483 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
484 If there is no additional space for HOB creation, then ASSERT().
485
486 @param BaseAddress The base address of the Firmware Volume.
487 @param Length The size of the Firmware Volume in bytes.
488 @param FvName The name of the Firmware Volume.
489 @param FileName The name of the file.
490
491 **/
492 VOID
493 EFIAPI
494 BuildFv2Hob (
495 IN EFI_PHYSICAL_ADDRESS BaseAddress,
496 IN UINT64 Length,
497 IN CONST EFI_GUID *FvName,
498 IN CONST EFI_GUID *FileName
499 )
500 {
501 EFI_HOB_FIRMWARE_VOLUME2 *Hob;
502
503 Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
504
505 Hob->BaseAddress = BaseAddress;
506 Hob->Length = Length;
507 CopyGuid (&Hob->FvName, FvName);
508 CopyGuid (&Hob->FileName, FileName);
509 }
510
511 /**
512 Builds a EFI_HOB_TYPE_FV3 HOB.
513
514 This function builds a EFI_HOB_TYPE_FV3 HOB.
515 It can only be invoked during PEI phase;
516 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
517
518 If there is no additional space for HOB creation, then ASSERT().
519
520 @param BaseAddress The base address of the Firmware Volume.
521 @param Length The size of the Firmware Volume in bytes.
522 @param AuthenticationStatus The authentication status.
523 @param ExtractedFv TRUE if the FV was extracted as a file within
524 another firmware volume. FALSE otherwise.
525 @param FvName The name of the Firmware Volume.
526 Valid only if IsExtractedFv is TRUE.
527 @param FileName The name of the file.
528 Valid only if IsExtractedFv is TRUE.
529
530 **/
531 VOID
532 EFIAPI
533 BuildFv3Hob (
534 IN EFI_PHYSICAL_ADDRESS BaseAddress,
535 IN UINT64 Length,
536 IN UINT32 AuthenticationStatus,
537 IN BOOLEAN ExtractedFv,
538 IN CONST EFI_GUID *FvName, OPTIONAL
539 IN CONST EFI_GUID *FileName OPTIONAL
540 )
541 {
542 EFI_HOB_FIRMWARE_VOLUME3 *Hob;
543
544 Hob = CreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3));
545
546 Hob->BaseAddress = BaseAddress;
547 Hob->Length = Length;
548 Hob->AuthenticationStatus = AuthenticationStatus;
549 Hob->ExtractedFv = ExtractedFv;
550 if (ExtractedFv) {
551 CopyGuid (&Hob->FvName, FvName);
552 CopyGuid (&Hob->FileName, FileName);
553 }
554 }
555
556
557 /**
558 Builds a HOB for the CPU.
559
560 This function builds a HOB for the CPU.
561 It can only be invoked during PEI phase;
562 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
563 If there is no additional space for HOB creation, then ASSERT().
564
565 @param SizeOfMemorySpace The maximum physical memory addressability of the processor.
566 @param SizeOfIoSpace The maximum physical I/O addressability of the processor.
567
568 **/
569 VOID
570 EFIAPI
571 BuildCpuHob (
572 IN UINT8 SizeOfMemorySpace,
573 IN UINT8 SizeOfIoSpace
574 )
575 {
576 EFI_HOB_CPU *Hob;
577
578 Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
579
580 Hob->SizeOfMemorySpace = SizeOfMemorySpace;
581 Hob->SizeOfIoSpace = SizeOfIoSpace;
582
583 //
584 // Zero the reserved space to match HOB spec
585 //
586 ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
587 }
588
589
590 /**
591 Builds a HOB for the Stack.
592
593 This function builds a HOB for the stack.
594 It can only be invoked during PEI phase;
595 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
596 If there is no additional space for HOB creation, then ASSERT().
597
598 @param BaseAddress The 64 bit physical address of the Stack.
599 @param Length The length of the stack in bytes.
600
601 **/
602 VOID
603 EFIAPI
604 BuildStackHob (
605 IN EFI_PHYSICAL_ADDRESS BaseAddress,
606 IN UINT64 Length
607 )
608 {
609 EFI_HOB_MEMORY_ALLOCATION_STACK *Hob;
610
611 ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
612 ((Length & (EFI_PAGE_SIZE - 1)) == 0));
613
614 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));
615
616 CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
617 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
618 Hob->AllocDescriptor.MemoryLength = Length;
619 Hob->AllocDescriptor.MemoryType = EfiBootServicesData;
620
621 //
622 // Zero the reserved space to match HOB spec
623 //
624 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
625 }
626
627
628 /**
629 Update the Stack Hob if the stack has been moved
630
631 @param BaseAddress The 64 bit physical address of the Stack.
632 @param Length The length of the stack in bytes.
633
634 **/
635 VOID
636 EFIAPI
637 UpdateStackHob (
638 IN EFI_PHYSICAL_ADDRESS BaseAddress,
639 IN UINT64 Length
640 )
641 {
642 EFI_PEI_HOB_POINTERS Hob;
643
644 Hob.Raw = GetHobList ();
645 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
646 if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
647 //
648 // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
649 // to be reclaimed by DXE core.
650 //
651 BuildMemoryAllocationHob (
652 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
653 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
654 EfiConventionalMemory
655 );
656 //
657 // Update the BSP Stack Hob to reflect the new stack info.
658 //
659 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
660 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
661 break;
662 }
663 Hob.Raw = GET_NEXT_HOB (Hob);
664 }
665 }
666
667
668
669 /**
670 Builds a HOB for the memory allocation.
671
672 This function builds a HOB for the memory allocation.
673 It can only be invoked during PEI phase;
674 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
675 If there is no additional space for HOB creation, then ASSERT().
676
677 @param BaseAddress The 64 bit physical address of the memory.
678 @param Length The length of the memory allocation in bytes.
679 @param MemoryType Type of memory allocated by this HOB.
680
681 **/
682 VOID
683 EFIAPI
684 BuildMemoryAllocationHob (
685 IN EFI_PHYSICAL_ADDRESS BaseAddress,
686 IN UINT64 Length,
687 IN EFI_MEMORY_TYPE MemoryType
688 )
689 {
690 EFI_HOB_MEMORY_ALLOCATION *Hob;
691
692 ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
693 ((Length & (EFI_PAGE_SIZE - 1)) == 0));
694
695 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
696
697 ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
698 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
699 Hob->AllocDescriptor.MemoryLength = Length;
700 Hob->AllocDescriptor.MemoryType = MemoryType;
701 //
702 // Zero the reserved space to match HOB spec
703 //
704 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
705 }
706