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