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