1 /** @file
2   HOB Library implementation for Dxe Phase with DebugLib dependency removed
3 
4 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 
10 #define ASSERT(Expression)      \
11   do {                          \
12     if (!(Expression)) {        \
13       CpuDeadLoop ();           \
14     }                           \
15   } while (FALSE)
16 
17 #include <PiDxe.h>
18 
19 #include <Guid/HobList.h>
20 
21 #include <Library/HobLib.h>
22 #include <Library/UefiLib.h>
23 #include <Library/BaseMemoryLib.h>
24 
25 VOID  *mHobList = NULL;
26 
27 /**
28   The constructor function caches the pointer to HOB list.
29 
30   The constructor function gets the start address of HOB list from system configuration table.
31 
32   @param  ImageHandle   The firmware allocated handle for the EFI image.
33   @param  SystemTable   A pointer to the EFI System Table.
34 
35   @retval EFI_SUCCESS   The constructor successfully gets HobList.
36   @retval Other value   The constructor can't get HobList.
37 
38 **/
39 EFI_STATUS
40 EFIAPI
HobLibConstructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)41 HobLibConstructor (
42   IN EFI_HANDLE        ImageHandle,
43   IN EFI_SYSTEM_TABLE  *SystemTable
44   )
45 {
46   UINTN             Index;
47 
48   for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {
49     if (CompareGuid (&gEfiHobListGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) {
50       mHobList = SystemTable->ConfigurationTable[Index].VendorTable;
51       return EFI_SUCCESS;
52     }
53   }
54 
55   return EFI_NOT_FOUND;
56 }
57 
58 /**
59   Returns the pointer to the HOB list.
60 
61   This function returns the pointer to first HOB in the list.
62   For PEI phase, the PEI service GetHobList() can be used to retrieve the pointer
63   to the HOB list.  For the DXE phase, the HOB list pointer can be retrieved through
64   the EFI System Table by looking up theHOB list GUID in the System Configuration Table.
65   Since the System Configuration Table does not exist that the time the DXE Core is
66   launched, the DXE Core uses a global variable from the DXE Core Entry Point Library
67   to manage the pointer to the HOB list.
68 
69   If the pointer to the HOB list is NULL, then ASSERT().
70 
71   @return The pointer to the HOB list.
72 
73 **/
74 VOID *
75 EFIAPI
GetHobList(VOID)76 GetHobList (
77   VOID
78   )
79 {
80   ASSERT (mHobList != NULL);
81   return mHobList;
82 }
83 
84 /**
85   Returns the next instance of a HOB type from the starting HOB.
86 
87   This function searches the first instance of a HOB type from the starting HOB pointer.
88   If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
89   In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
90   unconditionally: it returns HobStart back if HobStart itself meets the requirement;
91   caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
92 
93   If HobStart is NULL, then ASSERT().
94 
95   @param  Type          The HOB type to return.
96   @param  HobStart      The starting HOB pointer to search from.
97 
98   @return The next instance of a HOB type from the starting HOB.
99 
100 **/
101 VOID *
102 EFIAPI
GetNextHob(IN UINT16 Type,IN CONST VOID * HobStart)103 GetNextHob (
104   IN UINT16                 Type,
105   IN CONST VOID             *HobStart
106   )
107 {
108   EFI_PEI_HOB_POINTERS  Hob;
109 
110   ASSERT (HobStart != NULL);
111 
112   Hob.Raw = (UINT8 *) HobStart;
113   //
114   // Parse the HOB list until end of list or matching type is found.
115   //
116   while (!END_OF_HOB_LIST (Hob)) {
117     if (Hob.Header->HobType == Type) {
118       return Hob.Raw;
119     }
120     Hob.Raw = GET_NEXT_HOB (Hob);
121   }
122   return NULL;
123 }
124 
125 /**
126   Returns the first instance of a HOB type among the whole HOB list.
127 
128   This function searches the first instance of a HOB type among the whole HOB list.
129   If there does not exist such HOB type in the HOB list, it will return NULL.
130 
131   If the pointer to the HOB list is NULL, then ASSERT().
132 
133   @param  Type          The HOB type to return.
134 
135   @return The next instance of a HOB type from the starting HOB.
136 
137 **/
138 VOID *
139 EFIAPI
GetFirstHob(IN UINT16 Type)140 GetFirstHob (
141   IN UINT16                 Type
142   )
143 {
144   VOID      *HobList;
145 
146   HobList = GetHobList ();
147   return GetNextHob (Type, HobList);
148 }
149 
150 /**
151   Returns the next instance of the matched GUID HOB from the starting HOB.
152 
153   This function searches the first instance of a HOB from the starting HOB pointer.
154   Such HOB should satisfy two conditions:
155   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
156   If there does not exist such HOB from the starting HOB pointer, it will return NULL.
157   Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
158   to extract the data section and its size information, respectively.
159   In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
160   unconditionally: it returns HobStart back if HobStart itself meets the requirement;
161   caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
162 
163   If Guid is NULL, then ASSERT().
164   If HobStart is NULL, then ASSERT().
165 
166   @param  Guid          The GUID to match with in the HOB list.
167   @param  HobStart      A pointer to a Guid.
168 
169   @return The next instance of the matched GUID HOB from the starting HOB.
170 
171 **/
172 VOID *
173 EFIAPI
GetNextGuidHob(IN CONST EFI_GUID * Guid,IN CONST VOID * HobStart)174 GetNextGuidHob (
175   IN CONST EFI_GUID         *Guid,
176   IN CONST VOID             *HobStart
177   )
178 {
179   EFI_PEI_HOB_POINTERS  GuidHob;
180 
181   GuidHob.Raw = (UINT8 *) HobStart;
182   while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
183     if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
184       break;
185     }
186     GuidHob.Raw = GET_NEXT_HOB (GuidHob);
187   }
188   return GuidHob.Raw;
189 }
190 
191 /**
192   Returns the first instance of the matched GUID HOB among the whole HOB list.
193 
194   This function searches the first instance of a HOB among the whole HOB list.
195   Such HOB should satisfy two conditions:
196   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
197   If there does not exist such HOB from the starting HOB pointer, it will return NULL.
198   Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
199   to extract the data section and its size information, respectively.
200 
201   If the pointer to the HOB list is NULL, then ASSERT().
202   If Guid is NULL, then ASSERT().
203 
204   @param  Guid          The GUID to match with in the HOB list.
205 
206   @return The first instance of the matched GUID HOB among the whole HOB list.
207 
208 **/
209 VOID *
210 EFIAPI
GetFirstGuidHob(IN CONST EFI_GUID * Guid)211 GetFirstGuidHob (
212   IN CONST EFI_GUID         *Guid
213   )
214 {
215   VOID      *HobList;
216 
217   HobList = GetHobList ();
218   return GetNextGuidHob (Guid, HobList);
219 }
220 
221 /**
222   Get the system boot mode from the HOB list.
223 
224   This function returns the system boot mode information from the
225   PHIT HOB in HOB list.
226 
227   If the pointer to the HOB list is NULL, then ASSERT().
228 
229   @param  VOID
230 
231   @return The Boot Mode.
232 
233 **/
234 EFI_BOOT_MODE
235 EFIAPI
GetBootModeHob(VOID)236 GetBootModeHob (
237   VOID
238   )
239 {
240   EFI_HOB_HANDOFF_INFO_TABLE    *HandOffHob;
241 
242   HandOffHob = (EFI_HOB_HANDOFF_INFO_TABLE *) GetHobList ();
243 
244   return  HandOffHob->BootMode;
245 }
246 
247 /**
248   Builds a HOB for a loaded PE32 module.
249 
250   This function builds a HOB for a loaded PE32 module.
251   It can only be invoked during PEI phase;
252   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
253 
254   If ModuleName is NULL, then ASSERT().
255   If there is no additional space for HOB creation, then ASSERT().
256 
257   @param  ModuleName              The GUID File Name of the module.
258   @param  MemoryAllocationModule  The 64 bit physical address of the module.
259   @param  ModuleLength            The length of the module in bytes.
260   @param  EntryPoint              The 64 bit physical address of the module entry point.
261 
262 **/
263 VOID
264 EFIAPI
BuildModuleHob(IN CONST EFI_GUID * ModuleName,IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,IN UINT64 ModuleLength,IN EFI_PHYSICAL_ADDRESS EntryPoint)265 BuildModuleHob (
266   IN CONST EFI_GUID         *ModuleName,
267   IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,
268   IN UINT64                 ModuleLength,
269   IN EFI_PHYSICAL_ADDRESS   EntryPoint
270   )
271 {
272   //
273   // PEI HOB is read only for DXE phase
274   //
275   ASSERT (FALSE);
276 }
277 
278 /**
279   Builds a HOB that describes a chunk of system memory.
280 
281   This function builds a HOB that describes a chunk of system memory.
282   It can only be invoked during PEI phase;
283   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
284 
285   If there is no additional space for HOB creation, then ASSERT().
286 
287   @param  ResourceType        The type of resource described by this HOB.
288   @param  ResourceAttribute   The resource attributes of the memory described by this HOB.
289   @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.
290   @param  NumberOfBytes       The length of the memory described by this HOB in bytes.
291 
292 **/
293 VOID
294 EFIAPI
BuildResourceDescriptorHob(IN EFI_RESOURCE_TYPE ResourceType,IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,IN EFI_PHYSICAL_ADDRESS PhysicalStart,IN UINT64 NumberOfBytes)295 BuildResourceDescriptorHob (
296   IN EFI_RESOURCE_TYPE            ResourceType,
297   IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
298   IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
299   IN UINT64                       NumberOfBytes
300   )
301 {
302   //
303   // PEI HOB is read only for DXE phase
304   //
305   ASSERT (FALSE);
306 }
307 
308 /**
309   Builds a customized HOB tagged with a GUID for identification and returns
310   the start address of GUID HOB data.
311 
312   This function builds a customized HOB tagged with a GUID for identification
313   and returns the start address of GUID HOB data so that caller can fill the customized data.
314   The HOB Header and Name field is already stripped.
315   It can only be invoked during PEI phase;
316   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
317 
318   If Guid is NULL, then ASSERT().
319   If there is no additional space for HOB creation, then ASSERT().
320   If DataLength > (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
321   HobLength is UINT16 and multiples of 8 bytes, so the max HobLength is 0xFFF8.
322 
323   @param  Guid          The GUID to tag the customized HOB.
324   @param  DataLength    The size of the data payload for the GUID HOB.
325 
326   @retval  NULL         The GUID HOB could not be allocated.
327   @retval  others       The start address of GUID HOB data.
328 
329 **/
330 VOID *
331 EFIAPI
BuildGuidHob(IN CONST EFI_GUID * Guid,IN UINTN DataLength)332 BuildGuidHob (
333   IN CONST EFI_GUID              *Guid,
334   IN UINTN                       DataLength
335   )
336 {
337   //
338   // PEI HOB is read only for DXE phase
339   //
340   ASSERT (FALSE);
341   return NULL;
342 }
343 
344 /**
345   Builds a customized HOB tagged with a GUID for identification, copies the input data to the HOB
346   data field, and returns the start address of the GUID HOB data.
347 
348   This function builds a customized HOB tagged with a GUID for identification and copies the input
349   data to the HOB data field and returns the start address of the GUID HOB data.  It can only be
350   invoked during PEI phase; for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
351   The HOB Header and Name field is already stripped.
352   It can only be invoked during PEI phase;
353   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
354 
355   If Guid is NULL, then ASSERT().
356   If Data is NULL and DataLength > 0, then ASSERT().
357   If there is no additional space for HOB creation, then ASSERT().
358   If DataLength > (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
359   HobLength is UINT16 and multiples of 8 bytes, so the max HobLength is 0xFFF8.
360 
361   @param  Guid          The GUID to tag the customized HOB.
362   @param  Data          The data to be copied into the data field of the GUID HOB.
363   @param  DataLength    The size of the data payload for the GUID HOB.
364 
365   @retval  NULL         The GUID HOB could not be allocated.
366   @retval  others       The start address of GUID HOB data.
367 
368 **/
369 VOID *
370 EFIAPI
BuildGuidDataHob(IN CONST EFI_GUID * Guid,IN VOID * Data,IN UINTN DataLength)371 BuildGuidDataHob (
372   IN CONST EFI_GUID              *Guid,
373   IN VOID                        *Data,
374   IN UINTN                       DataLength
375   )
376 {
377   //
378   // PEI HOB is read only for DXE phase
379   //
380   ASSERT (FALSE);
381   return NULL;
382 }
383 
384 /**
385   Builds a Firmware Volume HOB.
386 
387   This function builds a Firmware Volume HOB.
388   It can only be invoked during PEI phase;
389   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
390 
391   If there is no additional space for HOB creation, then ASSERT().
392   If the FvImage buffer is not at its required alignment, then ASSERT().
393 
394   @param  BaseAddress   The base address of the Firmware Volume.
395   @param  Length        The size of the Firmware Volume in bytes.
396 
397 **/
398 VOID
399 EFIAPI
BuildFvHob(IN EFI_PHYSICAL_ADDRESS BaseAddress,IN UINT64 Length)400 BuildFvHob (
401   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
402   IN UINT64                      Length
403   )
404 {
405   //
406   // PEI HOB is read only for DXE phase
407   //
408   ASSERT (FALSE);
409 }
410 
411 /**
412   Builds a EFI_HOB_TYPE_FV2 HOB.
413 
414   This function builds a EFI_HOB_TYPE_FV2 HOB.
415   It can only be invoked during PEI phase;
416   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
417 
418   If there is no additional space for HOB creation, then ASSERT().
419   If the FvImage buffer is not at its required alignment, then ASSERT().
420 
421   @param  BaseAddress   The base address of the Firmware Volume.
422   @param  Length        The size of the Firmware Volume in bytes.
423   @param  FvName        The name of the Firmware Volume.
424   @param  FileName      The name of the file.
425 
426 **/
427 VOID
428 EFIAPI
BuildFv2Hob(IN EFI_PHYSICAL_ADDRESS BaseAddress,IN UINT64 Length,IN CONST EFI_GUID * FvName,IN CONST EFI_GUID * FileName)429 BuildFv2Hob (
430   IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
431   IN          UINT64                      Length,
432   IN CONST    EFI_GUID                    *FvName,
433   IN CONST    EFI_GUID                    *FileName
434   )
435 {
436   ASSERT (FALSE);
437 }
438 
439 /**
440   Builds a EFI_HOB_TYPE_FV3 HOB.
441 
442   This function builds a EFI_HOB_TYPE_FV3 HOB.
443   It can only be invoked during PEI phase;
444   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
445 
446   If there is no additional space for HOB creation, then ASSERT().
447   If the FvImage buffer is not at its required alignment, then ASSERT().
448 
449   @param BaseAddress            The base address of the Firmware Volume.
450   @param Length                 The size of the Firmware Volume in bytes.
451   @param AuthenticationStatus   The authentication status.
452   @param ExtractedFv            TRUE if the FV was extracted as a file within
453                                 another firmware volume. FALSE otherwise.
454   @param FvName                 The name of the Firmware Volume.
455                                 Valid only if IsExtractedFv is TRUE.
456   @param FileName               The name of the file.
457                                 Valid only if IsExtractedFv is TRUE.
458 
459 **/
460 VOID
461 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)462 BuildFv3Hob (
463   IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
464   IN          UINT64                      Length,
465   IN          UINT32                      AuthenticationStatus,
466   IN          BOOLEAN                     ExtractedFv,
467   IN CONST    EFI_GUID                    *FvName, OPTIONAL
468   IN CONST    EFI_GUID                    *FileName OPTIONAL
469   )
470 {
471   ASSERT (FALSE);
472 }
473 
474 /**
475   Builds a Capsule Volume HOB.
476 
477   This function builds a Capsule Volume HOB.
478   It can only be invoked during PEI phase;
479   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
480 
481   If the platform does not support Capsule Volume HOBs, then ASSERT().
482   If there is no additional space for HOB creation, then ASSERT().
483 
484   @param  BaseAddress   The base address of the Capsule Volume.
485   @param  Length        The size of the Capsule Volume in bytes.
486 
487 **/
488 VOID
489 EFIAPI
BuildCvHob(IN EFI_PHYSICAL_ADDRESS BaseAddress,IN UINT64 Length)490 BuildCvHob (
491   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
492   IN UINT64                      Length
493   )
494 {
495   //
496   // PEI HOB is read only for DXE phase
497   //
498   ASSERT (FALSE);
499 }
500 
501 /**
502   Builds a HOB for the CPU.
503 
504   This function builds a HOB for the CPU.
505   It can only be invoked during PEI phase;
506   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
507 
508   If there is no additional space for HOB creation, then ASSERT().
509 
510   @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.
511   @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.
512 
513 **/
514 VOID
515 EFIAPI
BuildCpuHob(IN UINT8 SizeOfMemorySpace,IN UINT8 SizeOfIoSpace)516 BuildCpuHob (
517   IN UINT8                       SizeOfMemorySpace,
518   IN UINT8                       SizeOfIoSpace
519   )
520 {
521   //
522   // PEI HOB is read only for DXE phase
523   //
524   ASSERT (FALSE);
525 }
526 
527 /**
528   Builds a HOB for the Stack.
529 
530   This function builds a HOB for the stack.
531   It can only be invoked during PEI phase;
532   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
533 
534   If there is no additional space for HOB creation, then ASSERT().
535 
536   @param  BaseAddress   The 64 bit physical address of the Stack.
537   @param  Length        The length of the stack in bytes.
538 
539 **/
540 VOID
541 EFIAPI
BuildStackHob(IN EFI_PHYSICAL_ADDRESS BaseAddress,IN UINT64 Length)542 BuildStackHob (
543   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
544   IN UINT64                      Length
545   )
546 {
547   //
548   // PEI HOB is read only for DXE phase
549   //
550   ASSERT (FALSE);
551 }
552 
553 /**
554   Builds a HOB for the BSP store.
555 
556   This function builds a HOB for BSP store.
557   It can only be invoked during PEI phase;
558   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
559 
560   If there is no additional space for HOB creation, then ASSERT().
561 
562   @param  BaseAddress   The 64 bit physical address of the BSP.
563   @param  Length        The length of the BSP store in bytes.
564   @param  MemoryType    Type of memory allocated by this HOB.
565 
566 **/
567 VOID
568 EFIAPI
BuildBspStoreHob(IN EFI_PHYSICAL_ADDRESS BaseAddress,IN UINT64 Length,IN EFI_MEMORY_TYPE MemoryType)569 BuildBspStoreHob (
570   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
571   IN UINT64                      Length,
572   IN EFI_MEMORY_TYPE             MemoryType
573   )
574 {
575   //
576   // PEI HOB is read only for DXE phase
577   //
578   ASSERT (FALSE);
579 }
580 
581 /**
582   Builds a HOB for the memory allocation.
583 
584   This function builds a HOB for the memory allocation.
585   It can only be invoked during PEI phase;
586   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
587 
588   If there is no additional space for HOB creation, then ASSERT().
589 
590   @param  BaseAddress   The 64 bit physical address of the memory.
591   @param  Length        The length of the memory allocation in bytes.
592   @param  MemoryType    Type of memory allocated by this HOB.
593 
594 **/
595 VOID
596 EFIAPI
BuildMemoryAllocationHob(IN EFI_PHYSICAL_ADDRESS BaseAddress,IN UINT64 Length,IN EFI_MEMORY_TYPE MemoryType)597 BuildMemoryAllocationHob (
598   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
599   IN UINT64                      Length,
600   IN EFI_MEMORY_TYPE             MemoryType
601   )
602 {
603   //
604   // PEI HOB is read only for DXE phase
605   //
606   ASSERT (FALSE);
607 }
608