VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c@ 108793

Last change on this file since 108793 was 105670, checked in by vboxsync, 9 months ago

Devices/EFI/FirmwareNew: Merge edk2-stable-202405 and make it build on aarch64, bugref:4643

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette