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