]> git.proxmox.com Git - mirror_edk2.git/blob - EmbeddedPkg/Library/PrePiHobLib/Hob.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / EmbeddedPkg / Library / PrePiHobLib / Hob.c
1 /** @file
2
3 Copyright (c) 2010, Apple Inc. All rights reserved.<BR>
4 Copyright (c) 2017, 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/PeCoffLib.h>
16 #include <Library/HobLib.h>
17 #include <Library/PcdLib.h>
18 #include <Library/PrePiHobListPointerLib.h>
19
20 #include <Protocol/PeCoffLoader.h>
21 #include <Guid/ExtractSection.h>
22 #include <Guid/MemoryTypeInformation.h>
23 #include <Guid/MemoryAllocationHob.h>
24
25 VOID
26 BuildMemoryTypeInformationHob (
27 VOID
28 );
29
30 /**
31 Returns the pointer to the HOB list.
32
33 This function returns the pointer to first HOB in the list.
34
35 @return The pointer to the HOB list.
36
37 **/
38 VOID *
39 EFIAPI
40 GetHobList (
41 VOID
42 )
43 {
44 return PrePeiGetHobList ();
45 }
46
47 /**
48 Updates the pointer to the HOB list.
49
50 @param HobList Hob list pointer to store
51
52 **/
53 EFI_STATUS
54 EFIAPI
55 SetHobList (
56 IN VOID *HobList
57 )
58 {
59 return PrePeiSetHobList (HobList);
60 }
61
62 /**
63
64
65 **/
66 EFI_HOB_HANDOFF_INFO_TABLE *
67 HobConstructor (
68 IN VOID *EfiMemoryBegin,
69 IN UINTN EfiMemoryLength,
70 IN VOID *EfiFreeMemoryBottom,
71 IN VOID *EfiFreeMemoryTop
72 )
73 {
74 EFI_HOB_HANDOFF_INFO_TABLE *Hob;
75 EFI_HOB_GENERIC_HEADER *HobEnd;
76
77 Hob = EfiFreeMemoryBottom;
78 HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
79
80 Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
81 Hob->Header.HobLength = sizeof (EFI_HOB_HANDOFF_INFO_TABLE);
82 Hob->Header.Reserved = 0;
83
84 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
85 HobEnd->HobLength = sizeof (EFI_HOB_GENERIC_HEADER);
86 HobEnd->Reserved = 0;
87
88 Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
89 Hob->BootMode = BOOT_WITH_FULL_CONFIGURATION;
90
91 Hob->EfiMemoryTop = (UINTN)EfiMemoryBegin + EfiMemoryLength;
92 Hob->EfiMemoryBottom = (UINTN)EfiMemoryBegin;
93 Hob->EfiFreeMemoryTop = (UINTN)EfiFreeMemoryTop;
94 Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);
95 Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
96
97 return Hob;
98 }
99
100 VOID *
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 VOID
171 EFIAPI
172 BuildFvHobs (
173 IN EFI_PHYSICAL_ADDRESS PhysicalStart,
174 IN UINT64 NumberOfBytes,
175 IN EFI_RESOURCE_ATTRIBUTE_TYPE *ResourceAttribute
176 )
177 {
178 EFI_RESOURCE_ATTRIBUTE_TYPE Resource;
179
180 BuildFvHob (PhysicalStart, NumberOfBytes);
181
182 if (ResourceAttribute == NULL) {
183 Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT |
184 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
185 EFI_RESOURCE_ATTRIBUTE_TESTED |
186 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);
187 } else {
188 Resource = *ResourceAttribute;
189 }
190
191 BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes);
192 }
193
194 /**
195 Returns the next instance of a HOB type from the starting HOB.
196
197 This function searches the first instance of a HOB type from the starting HOB pointer.
198 If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
199 In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
200 unconditionally: it returns HobStart back if HobStart itself meets the requirement;
201 caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
202 If HobStart is NULL, then ASSERT().
203
204 @param Type The HOB type to return.
205 @param HobStart The starting HOB pointer to search from.
206
207 @return The next instance of a HOB type from the starting HOB.
208
209 **/
210 VOID *
211 EFIAPI
212 GetNextHob (
213 IN UINT16 Type,
214 IN CONST VOID *HobStart
215 )
216 {
217 EFI_PEI_HOB_POINTERS Hob;
218
219 ASSERT (HobStart != NULL);
220
221 Hob.Raw = (UINT8 *)HobStart;
222 //
223 // Parse the HOB list until end of list or matching type is found.
224 //
225 while (!END_OF_HOB_LIST (Hob)) {
226 if (Hob.Header->HobType == Type) {
227 return Hob.Raw;
228 }
229
230 Hob.Raw = GET_NEXT_HOB (Hob);
231 }
232
233 return NULL;
234 }
235
236 /**
237 Returns the first instance of a HOB type among the whole HOB list.
238
239 This function searches the first instance of a HOB type among the whole HOB list.
240 If there does not exist such HOB type in the HOB list, it will return NULL.
241
242 @param Type The HOB type to return.
243
244 @return The next instance of a HOB type from the starting HOB.
245
246 **/
247 VOID *
248 EFIAPI
249 GetFirstHob (
250 IN UINT16 Type
251 )
252 {
253 VOID *HobList;
254
255 HobList = GetHobList ();
256 return GetNextHob (Type, HobList);
257 }
258
259 /**
260 This function searches the first instance of a HOB from the starting HOB pointer.
261 Such HOB should satisfy two conditions:
262 its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
263 If there does not exist such HOB from the starting HOB pointer, it will return NULL.
264 Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
265 to extract the data section and its size info respectively.
266 In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
267 unconditionally: it returns HobStart back if HobStart itself meets the requirement;
268 caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
269 If Guid is NULL, then ASSERT().
270 If HobStart is NULL, then ASSERT().
271
272 @param Guid The GUID to match with in the HOB list.
273 @param HobStart A pointer to a Guid.
274
275 @return The next instance of the matched GUID HOB from the starting HOB.
276
277 **/
278 VOID *
279 EFIAPI
280 GetNextGuidHob (
281 IN CONST EFI_GUID *Guid,
282 IN CONST VOID *HobStart
283 )
284 {
285 EFI_PEI_HOB_POINTERS GuidHob;
286
287 GuidHob.Raw = (UINT8 *)HobStart;
288 while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
289 if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
290 break;
291 }
292
293 GuidHob.Raw = GET_NEXT_HOB (GuidHob);
294 }
295
296 return GuidHob.Raw;
297 }
298
299 /**
300 This function searches the first instance of a HOB among the whole HOB list.
301 Such HOB should satisfy two conditions:
302 its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
303 If there does not exist such HOB from the starting HOB pointer, it will return NULL.
304 Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
305 to extract the data section and its size info respectively.
306 If Guid is NULL, then ASSERT().
307
308 @param Guid The GUID to match with in the HOB list.
309
310 @return The first instance of the matched GUID HOB among the whole HOB list.
311
312 **/
313 VOID *
314 EFIAPI
315 GetFirstGuidHob (
316 IN CONST EFI_GUID *Guid
317 )
318 {
319 VOID *HobList;
320
321 HobList = GetHobList ();
322 return GetNextGuidHob (Guid, HobList);
323 }
324
325 /**
326 Get the Boot Mode from the HOB list.
327
328 This function returns the system boot mode information from the
329 PHIT HOB in HOB list.
330
331 @param VOID
332
333 @return The Boot Mode.
334
335 **/
336 EFI_BOOT_MODE
337 EFIAPI
338 GetBootMode (
339 VOID
340 )
341 {
342 EFI_PEI_HOB_POINTERS Hob;
343
344 Hob.Raw = GetHobList ();
345 return Hob.HandoffInformationTable->BootMode;
346 }
347
348 /**
349 Get the Boot Mode from the HOB list.
350
351 This function returns the system boot mode information from the
352 PHIT HOB in HOB list.
353
354 @param VOID
355
356 @return The Boot Mode.
357
358 **/
359 EFI_STATUS
360 EFIAPI
361 SetBootMode (
362 IN EFI_BOOT_MODE BootMode
363 )
364 {
365 EFI_PEI_HOB_POINTERS Hob;
366
367 Hob.Raw = GetHobList ();
368 Hob.HandoffInformationTable->BootMode = BootMode;
369 return BootMode;
370 }
371
372 /**
373 Builds a HOB for a loaded PE32 module.
374
375 This function builds a HOB for a loaded PE32 module.
376 It can only be invoked during PEI phase;
377 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
378 If ModuleName is NULL, then ASSERT().
379 If there is no additional space for HOB creation, then ASSERT().
380
381 @param ModuleName The GUID File Name of the module.
382 @param MemoryAllocationModule The 64 bit physical address of the module.
383 @param ModuleLength The length of the module in bytes.
384 @param EntryPoint The 64 bit physical address of the module entry point.
385
386 **/
387 VOID
388 EFIAPI
389 BuildModuleHob (
390 IN CONST EFI_GUID *ModuleName,
391 IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,
392 IN UINT64 ModuleLength,
393 IN EFI_PHYSICAL_ADDRESS EntryPoint
394 )
395 {
396 EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob;
397
398 ASSERT (
399 ((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
400 ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0)
401 );
402
403 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
404
405 CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
406 Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
407 Hob->MemoryAllocationHeader.MemoryLength = ModuleLength;
408 Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode;
409
410 //
411 // Zero the reserved space to match HOB spec
412 //
413 ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
414
415 CopyGuid (&Hob->ModuleName, ModuleName);
416 Hob->EntryPoint = EntryPoint;
417 }
418
419 /**
420 Builds a GUID HOB with a certain data length.
421
422 This function builds a customized HOB tagged with a GUID for identification
423 and returns the start address of GUID HOB data so that caller can fill the customized data.
424 The HOB Header and Name field is already stripped.
425 It can only be invoked during PEI phase;
426 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
427 If Guid is NULL, then ASSERT().
428 If there is no additional space for HOB creation, then ASSERT().
429 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
430
431 @param Guid The GUID to tag the customized HOB.
432 @param DataLength The size of the data payload for the GUID HOB.
433
434 @return The start address of GUID HOB data.
435
436 **/
437 VOID *
438 EFIAPI
439 BuildGuidHob (
440 IN CONST EFI_GUID *Guid,
441 IN UINTN DataLength
442 )
443 {
444 EFI_HOB_GUID_TYPE *Hob;
445
446 //
447 // Make sure that data length is not too long.
448 //
449 ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
450
451 Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16)(sizeof (EFI_HOB_GUID_TYPE) + DataLength));
452 CopyGuid (&Hob->Name, Guid);
453 return Hob + 1;
454 }
455
456 /**
457 Copies a data buffer to a newly-built HOB.
458
459 This function builds a customized HOB tagged with a GUID for identification,
460 copies the input data to the HOB data field and returns the start address of the GUID HOB data.
461 The HOB Header and Name field is already stripped.
462 It can only be invoked during PEI phase;
463 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
464 If Guid is NULL, then ASSERT().
465 If Data is NULL and DataLength > 0, then ASSERT().
466 If there is no additional space for HOB creation, then ASSERT().
467 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
468
469 @param Guid The GUID to tag the customized HOB.
470 @param Data The data to be copied into the data field of the GUID HOB.
471 @param DataLength The size of the data payload for the GUID HOB.
472
473 @return The start address of GUID HOB data.
474
475 **/
476 VOID *
477 EFIAPI
478 BuildGuidDataHob (
479 IN CONST EFI_GUID *Guid,
480 IN VOID *Data,
481 IN UINTN DataLength
482 )
483 {
484 VOID *HobData;
485
486 ASSERT (Data != NULL || DataLength == 0);
487
488 HobData = BuildGuidHob (Guid, DataLength);
489
490 return CopyMem (HobData, Data, DataLength);
491 }
492
493 /**
494 Builds a Firmware Volume HOB.
495
496 This function builds a Firmware Volume HOB.
497 It can only be invoked during PEI phase;
498 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
499 If there is no additional space for HOB creation, then ASSERT().
500
501 @param BaseAddress The base address of the Firmware Volume.
502 @param Length The size of the Firmware Volume in bytes.
503
504 **/
505 VOID
506 EFIAPI
507 BuildFvHob (
508 IN EFI_PHYSICAL_ADDRESS BaseAddress,
509 IN UINT64 Length
510 )
511 {
512 EFI_HOB_FIRMWARE_VOLUME *Hob;
513
514 Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
515
516 Hob->BaseAddress = BaseAddress;
517 Hob->Length = Length;
518 }
519
520 /**
521 Builds a EFI_HOB_TYPE_FV2 HOB.
522
523 This function builds a EFI_HOB_TYPE_FV2 HOB.
524 It can only be invoked during PEI phase;
525 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
526 If there is no additional space for HOB creation, then ASSERT().
527
528 @param BaseAddress The base address of the Firmware Volume.
529 @param Length The size of the Firmware Volume in bytes.
530 @param FvName The name of the Firmware Volume.
531 @param FileName The name of the file.
532
533 **/
534 VOID
535 EFIAPI
536 BuildFv2Hob (
537 IN EFI_PHYSICAL_ADDRESS BaseAddress,
538 IN UINT64 Length,
539 IN CONST EFI_GUID *FvName,
540 IN CONST EFI_GUID *FileName
541 )
542 {
543 EFI_HOB_FIRMWARE_VOLUME2 *Hob;
544
545 Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
546
547 Hob->BaseAddress = BaseAddress;
548 Hob->Length = Length;
549 CopyGuid (&Hob->FvName, FvName);
550 CopyGuid (&Hob->FileName, FileName);
551 }
552
553 /**
554 Builds a EFI_HOB_TYPE_FV3 HOB.
555
556 This function builds a EFI_HOB_TYPE_FV3 HOB.
557 It can only be invoked during PEI phase;
558 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
559
560 If there is no additional space for HOB creation, then ASSERT().
561
562 @param BaseAddress The base address of the Firmware Volume.
563 @param Length The size of the Firmware Volume in bytes.
564 @param AuthenticationStatus The authentication status.
565 @param ExtractedFv TRUE if the FV was extracted as a file within
566 another firmware volume. FALSE otherwise.
567 @param FvName The name of the Firmware Volume.
568 Valid only if IsExtractedFv is TRUE.
569 @param FileName The name of the file.
570 Valid only if IsExtractedFv is TRUE.
571
572 **/
573 VOID
574 EFIAPI
575 BuildFv3Hob (
576 IN EFI_PHYSICAL_ADDRESS BaseAddress,
577 IN UINT64 Length,
578 IN UINT32 AuthenticationStatus,
579 IN BOOLEAN ExtractedFv,
580 IN CONST EFI_GUID *FvName OPTIONAL,
581 IN CONST EFI_GUID *FileName OPTIONAL
582 )
583 {
584 EFI_HOB_FIRMWARE_VOLUME3 *Hob;
585
586 Hob = CreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3));
587
588 Hob->BaseAddress = BaseAddress;
589 Hob->Length = Length;
590 Hob->AuthenticationStatus = AuthenticationStatus;
591 Hob->ExtractedFv = ExtractedFv;
592 if (ExtractedFv) {
593 CopyGuid (&Hob->FvName, FvName);
594 CopyGuid (&Hob->FileName, FileName);
595 }
596 }
597
598 /**
599 Builds a Capsule Volume HOB.
600
601 This function builds a Capsule Volume HOB.
602 It can only be invoked during PEI phase;
603 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
604 If there is no additional space for HOB creation, then ASSERT().
605
606 @param BaseAddress The base address of the Capsule Volume.
607 @param Length The size of the Capsule Volume in bytes.
608
609 **/
610 VOID
611 EFIAPI
612 BuildCvHob (
613 IN EFI_PHYSICAL_ADDRESS BaseAddress,
614 IN UINT64 Length
615 )
616 {
617 ASSERT (FALSE);
618 }
619
620 /**
621 Builds a HOB for the CPU.
622
623 This function builds a HOB for the CPU.
624 It can only be invoked during PEI phase;
625 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
626 If there is no additional space for HOB creation, then ASSERT().
627
628 @param SizeOfMemorySpace The maximum physical memory addressability of the processor.
629 @param SizeOfIoSpace The maximum physical I/O addressability of the processor.
630
631 **/
632 VOID
633 EFIAPI
634 BuildCpuHob (
635 IN UINT8 SizeOfMemorySpace,
636 IN UINT8 SizeOfIoSpace
637 )
638 {
639 EFI_HOB_CPU *Hob;
640
641 Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
642
643 Hob->SizeOfMemorySpace = SizeOfMemorySpace;
644 Hob->SizeOfIoSpace = SizeOfIoSpace;
645
646 //
647 // Zero the reserved space to match HOB spec
648 //
649 ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
650 }
651
652 /**
653 Builds a HOB for the Stack.
654
655 This function builds a HOB for the stack.
656 It can only be invoked during PEI phase;
657 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
658 If there is no additional space for HOB creation, then ASSERT().
659
660 @param BaseAddress The 64 bit physical address of the Stack.
661 @param Length The length of the stack in bytes.
662
663 **/
664 VOID
665 EFIAPI
666 BuildStackHob (
667 IN EFI_PHYSICAL_ADDRESS BaseAddress,
668 IN UINT64 Length
669 )
670 {
671 EFI_HOB_MEMORY_ALLOCATION_STACK *Hob;
672
673 ASSERT (
674 ((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
675 ((Length & (EFI_PAGE_SIZE - 1)) == 0)
676 );
677
678 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));
679
680 CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
681 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
682 Hob->AllocDescriptor.MemoryLength = Length;
683 Hob->AllocDescriptor.MemoryType = EfiBootServicesData;
684
685 //
686 // Zero the reserved space to match HOB spec
687 //
688 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
689 }
690
691 /**
692 Update the Stack Hob if the stack has been moved
693
694 @param BaseAddress The 64 bit physical address of the Stack.
695 @param Length The length of the stack in bytes.
696
697 **/
698 VOID
699 UpdateStackHob (
700 IN EFI_PHYSICAL_ADDRESS BaseAddress,
701 IN UINT64 Length
702 )
703 {
704 EFI_PEI_HOB_POINTERS Hob;
705
706 Hob.Raw = GetHobList ();
707 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
708 if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
709 //
710 // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
711 // to be reclaimed by DXE core.
712 //
713 BuildMemoryAllocationHob (
714 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
715 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
716 EfiConventionalMemory
717 );
718 //
719 // Update the BSP Stack Hob to reflect the new stack info.
720 //
721 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
722 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
723 break;
724 }
725
726 Hob.Raw = GET_NEXT_HOB (Hob);
727 }
728 }
729
730 /**
731 Builds a HOB for the memory allocation.
732
733 This function builds a HOB for the memory allocation.
734 It can only be invoked during PEI phase;
735 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
736 If there is no additional space for HOB creation, then ASSERT().
737
738 @param BaseAddress The 64 bit physical address of the memory.
739 @param Length The length of the memory allocation in bytes.
740 @param MemoryType Type of memory allocated by this HOB.
741
742 **/
743 VOID
744 EFIAPI
745 BuildMemoryAllocationHob (
746 IN EFI_PHYSICAL_ADDRESS BaseAddress,
747 IN UINT64 Length,
748 IN EFI_MEMORY_TYPE MemoryType
749 )
750 {
751 EFI_HOB_MEMORY_ALLOCATION *Hob;
752
753 ASSERT (
754 ((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
755 ((Length & (EFI_PAGE_SIZE - 1)) == 0)
756 );
757
758 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
759
760 ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
761 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
762 Hob->AllocDescriptor.MemoryLength = Length;
763 Hob->AllocDescriptor.MemoryType = MemoryType;
764 //
765 // Zero the reserved space to match HOB spec
766 //
767 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
768 }
769
770 VOID
771 EFIAPI
772 BuildExtractSectionHob (
773 IN EFI_GUID *Guid,
774 IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER SectionGetInfo,
775 IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER SectionExtraction
776 )
777 {
778 EXTRACT_SECTION_DATA Data;
779
780 Data.SectionGetInfo = SectionGetInfo;
781 Data.SectionExtraction = SectionExtraction;
782 BuildGuidDataHob (Guid, &Data, sizeof (Data));
783 }
784
785 PE_COFF_LOADER_PROTOCOL gPeCoffProtocol = {
786 PeCoffLoaderGetImageInfo,
787 PeCoffLoaderLoadImage,
788 PeCoffLoaderRelocateImage,
789 PeCoffLoaderImageReadFromMemory,
790 PeCoffLoaderRelocateImageForRuntime,
791 PeCoffLoaderUnloadImage
792 };
793
794 VOID
795 EFIAPI
796 BuildPeCoffLoaderHob (
797 VOID
798 )
799 {
800 VOID *Ptr;
801
802 Ptr = &gPeCoffProtocol;
803 BuildGuidDataHob (&gPeCoffLoaderProtocolGuid, &Ptr, sizeof (VOID *));
804 }
805
806 // May want to put this into a library so you only need the PCD settings if you are using the feature?
807 VOID
808 BuildMemoryTypeInformationHob (
809 VOID
810 )
811 {
812 EFI_MEMORY_TYPE_INFORMATION Info[10];
813
814 Info[0].Type = EfiACPIReclaimMemory;
815 Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);
816 Info[1].Type = EfiACPIMemoryNVS;
817 Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);
818 Info[2].Type = EfiReservedMemoryType;
819 Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);
820 Info[3].Type = EfiRuntimeServicesData;
821 Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);
822 Info[4].Type = EfiRuntimeServicesCode;
823 Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);
824 Info[5].Type = EfiBootServicesCode;
825 Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);
826 Info[6].Type = EfiBootServicesData;
827 Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);
828 Info[7].Type = EfiLoaderCode;
829 Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);
830 Info[8].Type = EfiLoaderData;
831 Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);
832
833 // Terminator for the list
834 Info[9].Type = EfiMaxMemoryType;
835 Info[9].NumberOfPages = 0;
836
837 BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
838 }