1 /** @file
2 
3   Copyright (c) 2010, Apple Inc. All rights reserved.<BR>
4   Copyright (c) 2017 - 2020, 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/HobLib.h>
16 #include <Library/PcdLib.h>
17 
18 VOID      *mHobList;
19 
20 /**
21   Returns the pointer to the HOB list.
22 
23   This function returns the pointer to first HOB in the list.
24 
25   @return The pointer to the HOB list.
26 
27 **/
28 VOID *
29 EFIAPI
GetHobList(VOID)30 GetHobList (
31   VOID
32   )
33 {
34   ASSERT (mHobList != NULL);
35   return mHobList;
36 }
37 
38 
39 /**
40   Build a Handoff Information Table HOB
41 
42   This function initialize a HOB region from EfiMemoryBegin with length
43   EfiMemoryLength. And EfiFreeMemoryBottom and EfiFreeMemoryTop should
44   be inside the HOB region.
45 
46   @param[in] EfiMemoryBegin       Total memory start address
47   @param[in] EfiMemoryLength      Total memory length reported in handoff HOB.
48   @param[in] EfiFreeMemoryBottom  Free memory start address
49   @param[in] EfiFreeMemoryTop     Free memory end address.
50 
51   @return   The pointer to the handoff HOB table.
52 
53 **/
54 EFI_HOB_HANDOFF_INFO_TABLE*
55 EFIAPI
HobConstructor(IN VOID * EfiMemoryBegin,IN UINTN EfiMemoryLength,IN VOID * EfiFreeMemoryBottom,IN VOID * EfiFreeMemoryTop)56 HobConstructor (
57   IN VOID   *EfiMemoryBegin,
58   IN UINTN  EfiMemoryLength,
59   IN VOID   *EfiFreeMemoryBottom,
60   IN VOID   *EfiFreeMemoryTop
61   )
62 {
63   EFI_HOB_HANDOFF_INFO_TABLE  *Hob;
64   EFI_HOB_GENERIC_HEADER      *HobEnd;
65 
66   Hob    = EfiFreeMemoryBottom;
67   HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
68 
69   Hob->Header.HobType      = EFI_HOB_TYPE_HANDOFF;
70   Hob->Header.HobLength    = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
71   Hob->Header.Reserved     = 0;
72 
73   HobEnd->HobType          = EFI_HOB_TYPE_END_OF_HOB_LIST;
74   HobEnd->HobLength        = sizeof(EFI_HOB_GENERIC_HEADER);
75   HobEnd->Reserved         = 0;
76 
77   Hob->Version             = EFI_HOB_HANDOFF_TABLE_VERSION;
78   Hob->BootMode            = BOOT_WITH_FULL_CONFIGURATION;
79 
80   Hob->EfiMemoryTop        = (UINTN)EfiMemoryBegin + EfiMemoryLength;
81   Hob->EfiMemoryBottom     = (UINTN)EfiMemoryBegin;
82   Hob->EfiFreeMemoryTop    = (UINTN)EfiFreeMemoryTop;
83   Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);
84   Hob->EfiEndOfHobList     = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
85 
86   mHobList = Hob;
87   return Hob;
88 }
89 
90 /**
91   Add a new HOB to the HOB List.
92 
93   @param HobType            Type of the new HOB.
94   @param HobLength          Length of the new HOB to allocate.
95 
96   @return  NULL if there is no space to create a hob.
97   @return  The address point to the new created hob.
98 
99 **/
100 VOID *
101 EFIAPI
CreateHob(IN UINT16 HobType,IN UINT16 HobLength)102 CreateHob (
103   IN  UINT16    HobType,
104   IN  UINT16    HobLength
105   )
106 {
107   EFI_HOB_HANDOFF_INFO_TABLE  *HandOffHob;
108   EFI_HOB_GENERIC_HEADER      *HobEnd;
109   EFI_PHYSICAL_ADDRESS        FreeMemory;
110   VOID                        *Hob;
111 
112   HandOffHob = GetHobList ();
113 
114   HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
115 
116   FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
117 
118   if (FreeMemory < HobLength) {
119       return NULL;
120   }
121 
122   Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
123   ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
124   ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
125   ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
126 
127   HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
128   HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
129 
130   HobEnd->HobType   = EFI_HOB_TYPE_END_OF_HOB_LIST;
131   HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
132   HobEnd->Reserved  = 0;
133   HobEnd++;
134   HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
135 
136   return Hob;
137 }
138 
139 /**
140   Builds a HOB that describes a chunk of system memory.
141 
142   This function builds a HOB that describes a chunk of system memory.
143   If there is no additional space for HOB creation, then ASSERT().
144 
145   @param  ResourceType        The type of resource described by this HOB.
146   @param  ResourceAttribute   The resource attributes of the memory described by this HOB.
147   @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.
148   @param  NumberOfBytes       The length of the memory described by this HOB in bytes.
149 
150 **/
151 VOID
152 EFIAPI
BuildResourceDescriptorHob(IN EFI_RESOURCE_TYPE ResourceType,IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,IN EFI_PHYSICAL_ADDRESS PhysicalStart,IN UINT64 NumberOfBytes)153 BuildResourceDescriptorHob (
154   IN EFI_RESOURCE_TYPE            ResourceType,
155   IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
156   IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
157   IN UINT64                       NumberOfBytes
158   )
159 {
160   EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;
161 
162   Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
163   ASSERT(Hob != NULL);
164 
165   Hob->ResourceType      = ResourceType;
166   Hob->ResourceAttribute = ResourceAttribute;
167   Hob->PhysicalStart     = PhysicalStart;
168   Hob->ResourceLength    = NumberOfBytes;
169 }
170 
171 VOID
172 EFIAPI
BuildFvHobs(IN EFI_PHYSICAL_ADDRESS PhysicalStart,IN UINT64 NumberOfBytes,IN EFI_RESOURCE_ATTRIBUTE_TYPE * ResourceAttribute)173 BuildFvHobs (
174   IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
175   IN UINT64                       NumberOfBytes,
176   IN EFI_RESOURCE_ATTRIBUTE_TYPE  *ResourceAttribute
177   )
178 {
179 
180   EFI_RESOURCE_ATTRIBUTE_TYPE Resource;
181 
182   BuildFvHob (PhysicalStart, NumberOfBytes);
183 
184   if (ResourceAttribute == NULL) {
185     Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
186                 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
187                 EFI_RESOURCE_ATTRIBUTE_TESTED |
188                 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);
189   } else {
190     Resource = *ResourceAttribute;
191   }
192 
193   BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes);
194 }
195 
196 /**
197   Returns the next instance of a HOB type from the starting HOB.
198 
199   This function searches the first instance of a HOB type from the starting HOB pointer.
200   If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
201   In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
202   unconditionally: it returns HobStart back if HobStart itself meets the requirement;
203   caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
204   If HobStart is NULL, then ASSERT().
205 
206   @param  Type          The HOB type to return.
207   @param  HobStart      The starting HOB pointer to search from.
208 
209   @return The next instance of a HOB type from the starting HOB.
210 
211 **/
212 VOID *
213 EFIAPI
GetNextHob(IN UINT16 Type,IN CONST VOID * HobStart)214 GetNextHob (
215   IN UINT16                 Type,
216   IN CONST VOID             *HobStart
217   )
218 {
219   EFI_PEI_HOB_POINTERS  Hob;
220 
221   ASSERT (HobStart != NULL);
222 
223   Hob.Raw = (UINT8 *) HobStart;
224   //
225   // Parse the HOB list until end of list or matching type is found.
226   //
227   while (!END_OF_HOB_LIST (Hob)) {
228     if (Hob.Header->HobType == Type) {
229       return Hob.Raw;
230     }
231     Hob.Raw = GET_NEXT_HOB (Hob);
232   }
233   return NULL;
234 }
235 
236 
237 
238 /**
239   Returns the first instance of a HOB type among the whole HOB list.
240 
241   This function searches the first instance of a HOB type among the whole HOB list.
242   If there does not exist such HOB type in the HOB list, it will return NULL.
243 
244   @param  Type          The HOB type to return.
245 
246   @return The next instance of a HOB type from the starting HOB.
247 
248 **/
249 VOID *
250 EFIAPI
GetFirstHob(IN UINT16 Type)251 GetFirstHob (
252   IN UINT16                 Type
253   )
254 {
255   VOID      *HobList;
256 
257   HobList = GetHobList ();
258   return GetNextHob (Type, HobList);
259 }
260 
261 
262 /**
263   This function searches the first instance of a HOB from the starting HOB pointer.
264   Such HOB should satisfy two conditions:
265   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
266   If there does not exist such HOB from the starting HOB pointer, it will return NULL.
267   Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
268   to extract the data section and its size info respectively.
269   In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
270   unconditionally: it returns HobStart back if HobStart itself meets the requirement;
271   caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
272   If Guid is NULL, then ASSERT().
273   If HobStart is NULL, then ASSERT().
274 
275   @param  Guid          The GUID to match with in the HOB list.
276   @param  HobStart      A pointer to a Guid.
277 
278   @return The next instance of the matched GUID HOB from the starting HOB.
279 
280 **/
281 VOID *
282 EFIAPI
GetNextGuidHob(IN CONST EFI_GUID * Guid,IN CONST VOID * HobStart)283 GetNextGuidHob (
284   IN CONST EFI_GUID         *Guid,
285   IN CONST VOID             *HobStart
286   ){
287   EFI_PEI_HOB_POINTERS  GuidHob;
288 
289   GuidHob.Raw = (UINT8 *) HobStart;
290   while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
291     if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
292       break;
293     }
294     GuidHob.Raw = GET_NEXT_HOB (GuidHob);
295   }
296   return GuidHob.Raw;
297 }
298 
299 
300 /**
301   This function searches the first instance of a HOB among the whole HOB list.
302   Such HOB should satisfy two conditions:
303   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
304   If there does not exist such HOB from the starting HOB pointer, it will return NULL.
305   Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
306   to extract the data section and its size info respectively.
307   If Guid is NULL, then ASSERT().
308 
309   @param  Guid          The GUID to match with in the HOB list.
310 
311   @return The first instance of the matched GUID HOB among the whole HOB list.
312 
313 **/
314 VOID *
315 EFIAPI
GetFirstGuidHob(IN CONST EFI_GUID * Guid)316 GetFirstGuidHob (
317   IN CONST EFI_GUID         *Guid
318   )
319 {
320   VOID      *HobList;
321 
322   HobList = GetHobList ();
323   return GetNextGuidHob (Guid, HobList);
324 }
325 
326 
327 
328 
329 /**
330   Builds a HOB for a loaded PE32 module.
331 
332   This function builds a HOB for a loaded PE32 module.
333   It can only be invoked during PEI phase;
334   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
335   If ModuleName is NULL, then ASSERT().
336   If there is no additional space for HOB creation, then ASSERT().
337 
338   @param  ModuleName              The GUID File Name of the module.
339   @param  MemoryAllocationModule  The 64 bit physical address of the module.
340   @param  ModuleLength            The length of the module in bytes.
341   @param  EntryPoint              The 64 bit physical address of the module entry point.
342 
343 **/
344 VOID
345 EFIAPI
BuildModuleHob(IN CONST EFI_GUID * ModuleName,IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,IN UINT64 ModuleLength,IN EFI_PHYSICAL_ADDRESS EntryPoint)346 BuildModuleHob (
347   IN CONST EFI_GUID         *ModuleName,
348   IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,
349   IN UINT64                 ModuleLength,
350   IN EFI_PHYSICAL_ADDRESS   EntryPoint
351   )
352 {
353   EFI_HOB_MEMORY_ALLOCATION_MODULE  *Hob;
354 
355   ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
356           ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
357 
358   Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
359 
360   CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
361   Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
362   Hob->MemoryAllocationHeader.MemoryLength      = ModuleLength;
363   Hob->MemoryAllocationHeader.MemoryType        = EfiBootServicesCode;
364 
365   //
366   // Zero the reserved space to match HOB spec
367   //
368   ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
369 
370   CopyGuid (&Hob->ModuleName, ModuleName);
371   Hob->EntryPoint = EntryPoint;
372 }
373 
374 /**
375   Builds a GUID HOB with a certain data length.
376 
377   This function builds a customized HOB tagged with a GUID for identification
378   and returns the start address of GUID HOB data so that caller can fill the customized data.
379   The HOB Header and Name field is already stripped.
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 Guid is NULL, then ASSERT().
383   If there is no additional space for HOB creation, then ASSERT().
384   If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
385 
386   @param  Guid          The GUID to tag the customized HOB.
387   @param  DataLength    The size of the data payload for the GUID HOB.
388 
389   @return The start address of GUID HOB data.
390 
391 **/
392 VOID *
393 EFIAPI
BuildGuidHob(IN CONST EFI_GUID * Guid,IN UINTN DataLength)394 BuildGuidHob (
395   IN CONST EFI_GUID              *Guid,
396   IN UINTN                       DataLength
397   )
398 {
399   EFI_HOB_GUID_TYPE *Hob;
400 
401   //
402   // Make sure that data length is not too long.
403   //
404   ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
405 
406   Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
407   CopyGuid (&Hob->Name, Guid);
408   return Hob + 1;
409 }
410 
411 
412 /**
413   Copies a data buffer to a newly-built HOB.
414 
415   This function builds a customized HOB tagged with a GUID for identification,
416   copies the input data to the HOB data field and returns the start address of the GUID HOB data.
417   The HOB Header and Name field is already stripped.
418   It can only be invoked during PEI phase;
419   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
420   If Guid is NULL, then ASSERT().
421   If Data is NULL and DataLength > 0, then ASSERT().
422   If there is no additional space for HOB creation, then ASSERT().
423   If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
424 
425   @param  Guid          The GUID to tag the customized HOB.
426   @param  Data          The data to be copied into the data field of the GUID HOB.
427   @param  DataLength    The size of the data payload for the GUID HOB.
428 
429   @return The start address of GUID HOB data.
430 
431 **/
432 VOID *
433 EFIAPI
BuildGuidDataHob(IN CONST EFI_GUID * Guid,IN VOID * Data,IN UINTN DataLength)434 BuildGuidDataHob (
435   IN CONST EFI_GUID              *Guid,
436   IN VOID                        *Data,
437   IN UINTN                       DataLength
438   )
439 {
440   VOID  *HobData;
441 
442   ASSERT (Data != NULL || DataLength == 0);
443 
444   HobData = BuildGuidHob (Guid, DataLength);
445 
446   return CopyMem (HobData, Data, DataLength);
447 }
448 
449 
450 /**
451   Builds a Firmware Volume HOB.
452 
453   This function builds a Firmware Volume HOB.
454   It can only be invoked during PEI phase;
455   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
456   If there is no additional space for HOB creation, then ASSERT().
457 
458   @param  BaseAddress   The base address of the Firmware Volume.
459   @param  Length        The size of the Firmware Volume in bytes.
460 
461 **/
462 VOID
463 EFIAPI
BuildFvHob(IN EFI_PHYSICAL_ADDRESS BaseAddress,IN UINT64 Length)464 BuildFvHob (
465   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
466   IN UINT64                      Length
467   )
468 {
469   EFI_HOB_FIRMWARE_VOLUME  *Hob;
470 
471   Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
472 
473   Hob->BaseAddress = BaseAddress;
474   Hob->Length      = Length;
475 }
476 
477 
478 /**
479   Builds a EFI_HOB_TYPE_FV2 HOB.
480 
481   This function builds a EFI_HOB_TYPE_FV2 HOB.
482   It can only be invoked during PEI phase;
483   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
484   If there is no additional space for HOB creation, then ASSERT().
485 
486   @param  BaseAddress   The base address of the Firmware Volume.
487   @param  Length        The size of the Firmware Volume in bytes.
488   @param  FvName       The name of the Firmware Volume.
489   @param  FileName      The name of the file.
490 
491 **/
492 VOID
493 EFIAPI
BuildFv2Hob(IN EFI_PHYSICAL_ADDRESS BaseAddress,IN UINT64 Length,IN CONST EFI_GUID * FvName,IN CONST EFI_GUID * FileName)494 BuildFv2Hob (
495   IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
496   IN          UINT64                      Length,
497   IN CONST    EFI_GUID                    *FvName,
498   IN CONST    EFI_GUID                    *FileName
499   )
500 {
501   EFI_HOB_FIRMWARE_VOLUME2  *Hob;
502 
503   Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
504 
505   Hob->BaseAddress = BaseAddress;
506   Hob->Length      = Length;
507   CopyGuid (&Hob->FvName, FvName);
508   CopyGuid (&Hob->FileName, FileName);
509 }
510 
511 /**
512   Builds a EFI_HOB_TYPE_FV3 HOB.
513 
514   This function builds a EFI_HOB_TYPE_FV3 HOB.
515   It can only be invoked during PEI phase;
516   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
517 
518   If there is no additional space for HOB creation, then ASSERT().
519 
520   @param BaseAddress            The base address of the Firmware Volume.
521   @param Length                 The size of the Firmware Volume in bytes.
522   @param AuthenticationStatus   The authentication status.
523   @param ExtractedFv            TRUE if the FV was extracted as a file within
524                                 another firmware volume. FALSE otherwise.
525   @param FvName                 The name of the Firmware Volume.
526                                 Valid only if IsExtractedFv is TRUE.
527   @param FileName               The name of the file.
528                                 Valid only if IsExtractedFv is TRUE.
529 
530 **/
531 VOID
532 EFIAPI
BuildFv3Hob(IN EFI_PHYSICAL_ADDRESS BaseAddress,IN UINT64 Length,IN UINT32 AuthenticationStatus,IN BOOLEAN ExtractedFv,IN CONST EFI_GUID * FvName,OPTIONAL IN CONST EFI_GUID * FileName OPTIONAL)533 BuildFv3Hob (
534   IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
535   IN          UINT64                      Length,
536   IN          UINT32                      AuthenticationStatus,
537   IN          BOOLEAN                     ExtractedFv,
538   IN CONST    EFI_GUID                    *FvName, OPTIONAL
539   IN CONST    EFI_GUID                    *FileName OPTIONAL
540   )
541 {
542   EFI_HOB_FIRMWARE_VOLUME3  *Hob;
543 
544   Hob = CreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3));
545 
546   Hob->BaseAddress          = BaseAddress;
547   Hob->Length               = Length;
548   Hob->AuthenticationStatus = AuthenticationStatus;
549   Hob->ExtractedFv          = ExtractedFv;
550   if (ExtractedFv) {
551     CopyGuid (&Hob->FvName, FvName);
552     CopyGuid (&Hob->FileName, FileName);
553   }
554 }
555 
556 
557 /**
558   Builds a HOB for the CPU.
559 
560   This function builds a HOB for the CPU.
561   It can only be invoked during PEI phase;
562   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
563   If there is no additional space for HOB creation, then ASSERT().
564 
565   @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.
566   @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.
567 
568 **/
569 VOID
570 EFIAPI
BuildCpuHob(IN UINT8 SizeOfMemorySpace,IN UINT8 SizeOfIoSpace)571 BuildCpuHob (
572   IN UINT8                       SizeOfMemorySpace,
573   IN UINT8                       SizeOfIoSpace
574   )
575 {
576   EFI_HOB_CPU  *Hob;
577 
578   Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
579 
580   Hob->SizeOfMemorySpace = SizeOfMemorySpace;
581   Hob->SizeOfIoSpace     = SizeOfIoSpace;
582 
583   //
584   // Zero the reserved space to match HOB spec
585   //
586   ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
587 }
588 
589 
590 /**
591   Builds a HOB for the Stack.
592 
593   This function builds a HOB for the stack.
594   It can only be invoked during PEI phase;
595   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
596   If there is no additional space for HOB creation, then ASSERT().
597 
598   @param  BaseAddress   The 64 bit physical address of the Stack.
599   @param  Length        The length of the stack in bytes.
600 
601 **/
602 VOID
603 EFIAPI
BuildStackHob(IN EFI_PHYSICAL_ADDRESS BaseAddress,IN UINT64 Length)604 BuildStackHob (
605   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
606   IN UINT64                      Length
607   )
608 {
609   EFI_HOB_MEMORY_ALLOCATION_STACK  *Hob;
610 
611   ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
612           ((Length & (EFI_PAGE_SIZE - 1)) == 0));
613 
614   Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));
615 
616   CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
617   Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
618   Hob->AllocDescriptor.MemoryLength      = Length;
619   Hob->AllocDescriptor.MemoryType        = EfiBootServicesData;
620 
621   //
622   // Zero the reserved space to match HOB spec
623   //
624   ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
625 }
626 
627 
628 /**
629   Update the Stack Hob if the stack has been moved
630 
631   @param  BaseAddress   The 64 bit physical address of the Stack.
632   @param  Length        The length of the stack in bytes.
633 
634 **/
635 VOID
636 EFIAPI
UpdateStackHob(IN EFI_PHYSICAL_ADDRESS BaseAddress,IN UINT64 Length)637 UpdateStackHob (
638   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
639   IN UINT64                      Length
640   )
641 {
642   EFI_PEI_HOB_POINTERS           Hob;
643 
644   Hob.Raw = GetHobList ();
645   while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
646     if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
647       //
648       // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
649       // to be reclaimed by DXE core.
650       //
651       BuildMemoryAllocationHob (
652         Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
653         Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
654         EfiConventionalMemory
655         );
656       //
657       // Update the BSP Stack Hob to reflect the new stack info.
658       //
659       Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
660       Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
661       break;
662     }
663     Hob.Raw = GET_NEXT_HOB (Hob);
664   }
665 }
666 
667 
668 
669 /**
670   Builds a HOB for the memory allocation.
671 
672   This function builds a HOB for the memory allocation.
673   It can only be invoked during PEI phase;
674   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
675   If there is no additional space for HOB creation, then ASSERT().
676 
677   @param  BaseAddress   The 64 bit physical address of the memory.
678   @param  Length        The length of the memory allocation in bytes.
679   @param  MemoryType    Type of memory allocated by this HOB.
680 
681 **/
682 VOID
683 EFIAPI
BuildMemoryAllocationHob(IN EFI_PHYSICAL_ADDRESS BaseAddress,IN UINT64 Length,IN EFI_MEMORY_TYPE MemoryType)684 BuildMemoryAllocationHob (
685   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
686   IN UINT64                      Length,
687   IN EFI_MEMORY_TYPE             MemoryType
688   )
689 {
690   EFI_HOB_MEMORY_ALLOCATION  *Hob;
691 
692   ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
693           ((Length & (EFI_PAGE_SIZE - 1)) == 0));
694 
695   Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
696 
697   ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
698   Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
699   Hob->AllocDescriptor.MemoryLength      = Length;
700   Hob->AllocDescriptor.MemoryType        = MemoryType;
701   //
702   // Zero the reserved space to match HOB spec
703   //
704   ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
705 }
706 
707