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