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