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