Updated to support passing PE/COFF and LZMA decompress up via HOBS. Currently turned...
[mirror_edk2.git] / EmbeddedPkg / Library / PrePiLib / Hob.c
1 /** @file
2
3 Copyright (c) 2008-2009, Apple Inc. All rights reserved.
4
5 All rights reserved. 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 <PrePi.h>
16 #include <Protocol/PeCoffLoader.h>
17 #include <Guid/ExtractSection.h>
18 #include <Guid/MemoryTypeInformation.h>
19 #include <Library/PeCoffLib.H>
20
21 //
22 // Have to use build system to set the original value in case we are running
23 // from FLASH and globals don't work. So if you do a GetHobList() and gHobList
24 // and gHobList is NULL the PCD default values are used.
25 //
26 VOID *gHobList = NULL;
27
28
29
30
31 // May want to put this into a library so you only need the PCD setings if you are using the feature?
32 VOID
33 BuildMemoryTypeInformationHob (
34 VOID
35 )
36 {
37 EFI_MEMORY_TYPE_INFORMATION Info[10];
38
39 Info[0].Type = EfiACPIReclaimMemory;
40 Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);
41 Info[1].Type = EfiACPIMemoryNVS;
42 Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);
43 Info[2].Type = EfiReservedMemoryType;
44 Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);
45 Info[3].Type = EfiRuntimeServicesData;
46 Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);
47 Info[4].Type = EfiRuntimeServicesCode;
48 Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);
49 Info[5].Type = EfiBootServicesCode;
50 Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);
51 Info[6].Type = EfiBootServicesData;
52 Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);
53 Info[7].Type = EfiLoaderCode;
54 Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);
55 Info[8].Type = EfiLoaderData;
56 Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);
57
58 // Terminator for the list
59 Info[9].Type = EfiMaxMemoryType;
60 Info[9].NumberOfPages = 0;
61
62
63 BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
64 }
65
66 /**
67
68
69 **/
70 VOID
71 CreateHobList (
72 IN VOID *MemoryBegin,
73 IN UINTN MemoryLength,
74 IN VOID *HobBase,
75 IN VOID *StackBase
76 )
77 {
78 EFI_HOB_HANDOFF_INFO_TABLE *Hob;
79 EFI_HOB_GENERIC_HEADER *HobEnd;
80 EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
81
82
83 Hob = HobBase;
84 HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
85
86 Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
87 Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
88 Hob->Header.Reserved = 0;
89
90 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
91 HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
92 HobEnd->Reserved = 0;
93
94 Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
95 Hob->BootMode = BOOT_WITH_FULL_CONFIGURATION;
96
97 Hob->EfiMemoryTop = (UINTN)MemoryBegin + MemoryLength;
98 Hob->EfiMemoryBottom = (UINTN)MemoryBegin;
99 Hob->EfiFreeMemoryTop = (UINTN)StackBase;
100 Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);
101 Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
102
103 SetHobList (Hob);
104
105 BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
106
107 Attributes =(
108 EFI_RESOURCE_ATTRIBUTE_PRESENT |
109 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
110 EFI_RESOURCE_ATTRIBUTE_TESTED |
111 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
112 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
113 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
114 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
115 );
116
117 BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attributes, (UINTN)MemoryBegin, MemoryLength);
118
119
120 BuildStackHob ((UINTN)StackBase, Hob->EfiMemoryTop - (UINTN)StackBase);
121
122 if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
123 // Optional feature that helps prevent EFI memory map fragmentation.
124 BuildMemoryTypeInformationHob ();
125 }
126
127 }
128
129
130 VOID
131 EFIAPI
132 BuildFvHobs (
133 IN EFI_PHYSICAL_ADDRESS PhysicalStart,
134 IN UINT64 NumberOfBytes,
135 IN EFI_RESOURCE_ATTRIBUTE_TYPE *ResourceAttribute
136 )
137 {
138
139 EFI_RESOURCE_ATTRIBUTE_TYPE Resource;
140
141 BuildFvHob (PhysicalStart, NumberOfBytes);
142
143 if (ResourceAttribute == NULL) {
144 Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT |
145 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
146 EFI_RESOURCE_ATTRIBUTE_TESTED |
147 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);
148 } else {
149 Resource = *ResourceAttribute;
150 }
151
152 BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes);
153 }
154
155
156
157
158
159 /**
160 Returns the pointer to the HOB list.
161
162 This function returns the pointer to first HOB in the list.
163
164 @return The pointer to the HOB list.
165
166 **/
167 VOID *
168 EFIAPI
169 GetHobList (
170 VOID
171 )
172 {
173 if (gHobList == NULL) {
174 return (VOID *)(UINTN)PcdGet32 (PcdPrePiHobBase);
175 } else {
176 return gHobList;
177 }
178 }
179
180
181
182 /**
183 Updates the pointer to the HOB list.
184
185 @param HobList Hob list pointer to store
186
187 **/
188 EFI_STATUS
189 EFIAPI
190 SetHobList (
191 IN VOID *HobList
192 )
193 {
194 gHobList = HobList;
195
196 //
197 // If this code is running from ROM this could fail
198 //
199 return (gHobList == HobList) ? EFI_SUCCESS: EFI_UNSUPPORTED;
200 }
201
202
203
204 VOID *
205 CreateHob (
206 IN UINT16 HobType,
207 IN UINT16 HobLength
208 )
209 {
210 EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
211 EFI_HOB_GENERIC_HEADER *HobEnd;
212 EFI_PHYSICAL_ADDRESS FreeMemory;
213 VOID *Hob;
214
215 HandOffHob = GetHobList ();
216
217 HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
218
219 FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
220
221 if (FreeMemory < HobLength) {
222 return NULL;
223 }
224
225 Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
226 ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
227 ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
228 ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
229
230 HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
231 HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
232
233 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
234 HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
235 HobEnd->Reserved = 0;
236 HobEnd++;
237 HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
238
239 return Hob;
240 }
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
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
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
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
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
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
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
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 /**
469 Builds a HOB that describes a chunk of system memory.
470
471 This function builds a HOB that describes a chunk of system memory.
472 If there is no additional space for HOB creation, then ASSERT().
473
474 @param ResourceType The type of resource described by this HOB.
475 @param ResourceAttribute The resource attributes of the memory described by this HOB.
476 @param PhysicalStart The 64 bit physical address of memory described by this HOB.
477 @param NumberOfBytes The length of the memory described by this HOB in bytes.
478
479 **/
480 VOID
481 EFIAPI
482 BuildResourceDescriptorHob (
483 IN EFI_RESOURCE_TYPE ResourceType,
484 IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
485 IN EFI_PHYSICAL_ADDRESS PhysicalStart,
486 IN UINT64 NumberOfBytes
487 )
488 {
489 EFI_HOB_RESOURCE_DESCRIPTOR *Hob;
490
491 Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
492
493 Hob->ResourceType = ResourceType;
494 Hob->ResourceAttribute = ResourceAttribute;
495 Hob->PhysicalStart = PhysicalStart;
496 Hob->ResourceLength = NumberOfBytes;
497 }
498
499
500 /**
501 Builds a GUID HOB with a certain data length.
502
503 This function builds a customized HOB tagged with a GUID for identification
504 and returns the start address of GUID HOB data so that caller can fill the customized data.
505 The HOB Header and Name field is already stripped.
506 It can only be invoked during PEI phase;
507 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
508 If Guid is NULL, then ASSERT().
509 If there is no additional space for HOB creation, then ASSERT().
510 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
511
512 @param Guid The GUID to tag the customized HOB.
513 @param DataLength The size of the data payload for the GUID HOB.
514
515 @return The start address of GUID HOB data.
516
517 **/
518 VOID *
519 EFIAPI
520 BuildGuidHob (
521 IN CONST EFI_GUID *Guid,
522 IN UINTN DataLength
523 )
524 {
525 EFI_HOB_GUID_TYPE *Hob;
526
527 //
528 // Make sure that data length is not too long.
529 //
530 ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
531
532 Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
533 CopyGuid (&Hob->Name, Guid);
534 return Hob + 1;
535 }
536
537
538 /**
539 Copies a data buffer to a newly-built HOB.
540
541 This function builds a customized HOB tagged with a GUID for identification,
542 copies the input data to the HOB data field and returns the start address of the GUID HOB data.
543 The HOB Header and Name field is already stripped.
544 It can only be invoked during PEI phase;
545 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
546 If Guid is NULL, then ASSERT().
547 If Data is NULL and DataLength > 0, then ASSERT().
548 If there is no additional space for HOB creation, then ASSERT().
549 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
550
551 @param Guid The GUID to tag the customized HOB.
552 @param Data The data to be copied into the data field of the GUID HOB.
553 @param DataLength The size of the data payload for the GUID HOB.
554
555 @return The start address of GUID HOB data.
556
557 **/
558 VOID *
559 EFIAPI
560 BuildGuidDataHob (
561 IN CONST EFI_GUID *Guid,
562 IN VOID *Data,
563 IN UINTN DataLength
564 )
565 {
566 VOID *HobData;
567
568 ASSERT (Data != NULL || DataLength == 0);
569
570 HobData = BuildGuidHob (Guid, DataLength);
571
572 return CopyMem (HobData, Data, DataLength);
573 }
574
575
576 /**
577 Builds a Firmware Volume HOB.
578
579 This function builds a Firmware Volume HOB.
580 It can only be invoked during PEI phase;
581 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
582 If there is no additional space for HOB creation, then ASSERT().
583
584 @param BaseAddress The base address of the Firmware Volume.
585 @param Length The size of the Firmware Volume in bytes.
586
587 **/
588 VOID
589 EFIAPI
590 BuildFvHob (
591 IN EFI_PHYSICAL_ADDRESS BaseAddress,
592 IN UINT64 Length
593 )
594 {
595 EFI_HOB_FIRMWARE_VOLUME *Hob;
596
597 Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
598
599 Hob->BaseAddress = BaseAddress;
600 Hob->Length = Length;
601 }
602
603
604 /**
605 Builds a EFI_HOB_TYPE_FV2 HOB.
606
607 This function builds a EFI_HOB_TYPE_FV2 HOB.
608 It can only be invoked during PEI phase;
609 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
610 If there is no additional space for HOB creation, then ASSERT().
611
612 @param BaseAddress The base address of the Firmware Volume.
613 @param Length The size of the Firmware Volume in bytes.
614 @param FvName The name of the Firmware Volume.
615 @param FileName The name of the file.
616
617 **/
618 VOID
619 EFIAPI
620 BuildFv2Hob (
621 IN EFI_PHYSICAL_ADDRESS BaseAddress,
622 IN UINT64 Length,
623 IN CONST EFI_GUID *FvName,
624 IN CONST EFI_GUID *FileName
625 )
626 {
627 EFI_HOB_FIRMWARE_VOLUME2 *Hob;
628
629 Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
630
631 Hob->BaseAddress = BaseAddress;
632 Hob->Length = Length;
633 CopyGuid (&Hob->FvName, FvName);
634 CopyGuid (&Hob->FileName, FileName);
635 }
636
637
638
639 /**
640 Builds a Capsule Volume HOB.
641
642 This function builds a Capsule Volume HOB.
643 It can only be invoked during PEI phase;
644 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
645 If there is no additional space for HOB creation, then ASSERT().
646
647 @param BaseAddress The base address of the Capsule Volume.
648 @param Length The size of the Capsule Volume in bytes.
649
650 **/
651 VOID
652 EFIAPI
653 BuildCvHob (
654 IN EFI_PHYSICAL_ADDRESS BaseAddress,
655 IN UINT64 Length
656 )
657 {
658 ASSERT (FALSE);
659 }
660
661
662 /**
663 Builds a HOB for the CPU.
664
665 This function builds a HOB for the CPU.
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 SizeOfMemorySpace The maximum physical memory addressability of the processor.
671 @param SizeOfIoSpace The maximum physical I/O addressability of the processor.
672
673 **/
674 VOID
675 EFIAPI
676 BuildCpuHob (
677 IN UINT8 SizeOfMemorySpace,
678 IN UINT8 SizeOfIoSpace
679 )
680 {
681 EFI_HOB_CPU *Hob;
682
683 Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
684
685 Hob->SizeOfMemorySpace = SizeOfMemorySpace;
686 Hob->SizeOfIoSpace = SizeOfIoSpace;
687
688 //
689 // Zero the reserved space to match HOB spec
690 //
691 ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
692 }
693
694
695 /**
696 Builds a HOB for the Stack.
697
698 This function builds a HOB for the stack.
699 It can only be invoked during PEI phase;
700 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
701 If there is no additional space for HOB creation, then ASSERT().
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
708 EFIAPI
709 BuildStackHob (
710 IN EFI_PHYSICAL_ADDRESS BaseAddress,
711 IN UINT64 Length
712 )
713 {
714 EFI_HOB_MEMORY_ALLOCATION_STACK *Hob;
715
716 ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
717 ((Length & (EFI_PAGE_SIZE - 1)) == 0));
718
719 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));
720
721 CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
722 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
723 Hob->AllocDescriptor.MemoryLength = Length;
724 Hob->AllocDescriptor.MemoryType = EfiBootServicesData;
725
726 //
727 // Zero the reserved space to match HOB spec
728 //
729 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
730 }
731
732
733 /**
734 Update the Stack Hob if the stack has been moved
735
736 @param BaseAddress The 64 bit physical address of the Stack.
737 @param Length The length of the stack in bytes.
738
739 **/
740 VOID
741 UpdateStackHob (
742 IN EFI_PHYSICAL_ADDRESS BaseAddress,
743 IN UINT64 Length
744 )
745 {
746 EFI_PEI_HOB_POINTERS Hob;
747
748 Hob.Raw = GetHobList ();
749 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
750 if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
751 //
752 // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
753 // to be reclaimed by DXE core.
754 //
755 BuildMemoryAllocationHob (
756 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
757 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
758 EfiConventionalMemory
759 );
760 //
761 // Update the BSP Stack Hob to reflect the new stack info.
762 //
763 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
764 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
765 break;
766 }
767 Hob.Raw = GET_NEXT_HOB (Hob);
768 }
769 }
770
771
772
773 /**
774 Builds a HOB for the memory allocation.
775
776 This function builds a HOB for the memory allocation.
777 It can only be invoked during PEI phase;
778 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
779 If there is no additional space for HOB creation, then ASSERT().
780
781 @param BaseAddress The 64 bit physical address of the memory.
782 @param Length The length of the memory allocation in bytes.
783 @param MemoryType Type of memory allocated by this HOB.
784
785 **/
786 VOID
787 EFIAPI
788 BuildMemoryAllocationHob (
789 IN EFI_PHYSICAL_ADDRESS BaseAddress,
790 IN UINT64 Length,
791 IN EFI_MEMORY_TYPE MemoryType
792 )
793 {
794 EFI_HOB_MEMORY_ALLOCATION *Hob;
795
796 ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
797 ((Length & (EFI_PAGE_SIZE - 1)) == 0));
798
799 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
800
801 ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
802 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
803 Hob->AllocDescriptor.MemoryLength = Length;
804 Hob->AllocDescriptor.MemoryType = MemoryType;
805 //
806 // Zero the reserved space to match HOB spec
807 //
808 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
809 }
810
811
812
813 VOID
814 EFIAPI
815 BuildExtractSectionHob (
816 IN EFI_GUID *Guid,
817 IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER SectionGetInfo,
818 IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER SectionExtraction
819 )
820 {
821 EXTRACT_SECTION_DATA Data;
822
823 Data.SectionGetInfo = SectionGetInfo;
824 Data.SectionExtraction = SectionExtraction;
825 BuildGuidDataHob (Guid, &Data, sizeof (Data));
826 }
827
828 PE_COFF_LOADER_PROTOCOL gPeCoffProtocol = {
829 PeCoffLoaderGetImageInfo,
830 PeCoffLoaderLoadImage,
831 PeCoffLoaderRelocateImage,
832 PeCoffLoaderImageReadFromMemory,
833 PeCoffLoaderRelocateImageForRuntime,
834 PeCoffLoaderUnloadImage
835 };
836
837
838
839 VOID
840 EFIAPI
841 BuildPeCoffLoaderHob (
842 VOID
843 )
844 {
845 VOID *Ptr;
846
847 Ptr = &gPeCoffProtocol;
848 BuildGuidDataHob (&gPeCoffLoaderProtocolGuid, &Ptr, sizeof (VOID *));
849 }
850
851
852