HobLib.c revision a5a3a29c4ce4017c6871bec0f9f627ba520244fc
1/** @file
2 Instance of HOB Library using PEI Services.
3
4 HOB Library implementation that uses PEI Services to retrieve the HOB List.
5 This library instance uses EFI_HOB_TYPE_CV defined in Intel framework HOB specification v0.9
6 to implement HobLib BuildCvHob() API.
7
8Copyright (c) 2007 - 2009, Intel Corporation<BR>
9All rights reserved. This program and the accompanying materials
10are licensed and made available under the terms and conditions of the BSD License
11which accompanies this distribution.  The full text of the license may be found at
12http://opensource.org/licenses/bsd-license.php
13
14THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16
17**/
18
19#include <PiPei.h>
20#include <FrameworkPei.h>
21
22#include <Guid/MemoryAllocationHob.h>
23
24#include <Library/HobLib.h>
25#include <Library/DebugLib.h>
26#include <Library/PeiServicesLib.h>
27#include <Library/BaseMemoryLib.h>
28
29/**
30  Returns the pointer to the HOB list.
31
32  This function returns the pointer to first HOB in the list.
33  For PEI phase, the PEI service GetHobList() can be used to retrieve the pointer
34  to the HOB list.  For the DXE phase, the HOB list pointer can be retrieved through
35  the EFI System Table by looking up theHOB list GUID in the System Configuration Table.
36  Since the System Configuration Table does not exist that the time the DXE Core is
37  launched, the DXE Core uses a global variable from the DXE Core Entry Point Library
38  to manage the pointer to the HOB list.
39
40  If the pointer to the HOB list is NULL, then ASSERT().
41
42  @return The pointer to the HOB list.
43
44**/
45VOID *
46EFIAPI
47GetHobList (
48  VOID
49  )
50{
51  EFI_STATUS            Status;
52  VOID                  *HobList;
53
54  Status = PeiServicesGetHobList (&HobList);
55  ASSERT_EFI_ERROR (Status);
56  ASSERT (HobList != NULL);
57
58  return HobList;
59}
60
61/**
62  Returns the next instance of a HOB type from the starting HOB.
63
64  This function searches the first instance of a HOB type from the starting HOB pointer.
65  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
66  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
67  unconditionally: it returns HobStart back if HobStart itself meets the requirement;
68  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
69
70  If HobStart is NULL, then ASSERT().
71
72  @param  Type          The HOB type to return.
73  @param  HobStart      The starting HOB pointer to search from.
74
75  @return The next instance of a HOB type from the starting HOB.
76
77**/
78VOID *
79EFIAPI
80GetNextHob (
81  IN UINT16                 Type,
82  IN CONST VOID             *HobStart
83  )
84{
85  EFI_PEI_HOB_POINTERS  Hob;
86
87  ASSERT (HobStart != NULL);
88
89  Hob.Raw = (UINT8 *) HobStart;
90  //
91  // Parse the HOB list until end of list or matching type is found.
92  //
93  while (!END_OF_HOB_LIST (Hob)) {
94    if (Hob.Header->HobType == Type) {
95      return Hob.Raw;
96    }
97    Hob.Raw = GET_NEXT_HOB (Hob);
98  }
99  return NULL;
100}
101
102/**
103  Returns the first instance of a HOB type among the whole HOB list.
104
105  This function searches the first instance of a HOB type among the whole HOB list.
106  If there does not exist such HOB type in the HOB list, it will return NULL.
107
108  If the pointer to the HOB list is NULL, then ASSERT().
109
110  @param  Type          The HOB type to return.
111
112  @return The next instance of a HOB type from the starting HOB.
113
114**/
115VOID *
116EFIAPI
117GetFirstHob (
118  IN UINT16                 Type
119  )
120{
121  VOID      *HobList;
122
123  HobList = GetHobList ();
124  return GetNextHob (Type, HobList);
125}
126
127/**
128  Returns the next instance of the matched GUID HOB from the starting HOB.
129
130  This function searches the first instance of a HOB from the starting HOB pointer.
131  Such HOB should satisfy two conditions:
132  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
133  If there does not exist such HOB from the starting HOB pointer, it will return NULL.
134  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
135  to extract the data section and its size info respectively.
136  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
137  unconditionally: it returns HobStart back if HobStart itself meets the requirement;
138  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
139
140  If Guid is NULL, then ASSERT().
141  If HobStart is NULL, then ASSERT().
142
143  @param  Guid          The GUID to match with in the HOB list.
144  @param  HobStart      A pointer to a Guid.
145
146  @return The next instance of the matched GUID HOB from the starting HOB.
147
148**/
149VOID *
150EFIAPI
151GetNextGuidHob (
152  IN CONST EFI_GUID         *Guid,
153  IN CONST VOID             *HobStart
154  )
155{
156  EFI_PEI_HOB_POINTERS  GuidHob;
157
158  GuidHob.Raw = (UINT8 *) HobStart;
159  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
160    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
161      break;
162    }
163    GuidHob.Raw = GET_NEXT_HOB (GuidHob);
164  }
165  return GuidHob.Raw;
166}
167
168/**
169  Returns the first instance of the matched GUID HOB among the whole HOB list.
170
171  This function searches the first instance of a HOB among the whole HOB list.
172  Such HOB should satisfy two conditions:
173  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
174  If there does not exist such HOB from the starting HOB pointer, it will return NULL.
175  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
176  to extract the data section and its size info respectively.
177
178  If the pointer to the HOB list is NULL, then ASSERT().
179  If Guid is NULL, then ASSERT().
180
181  @param  Guid          The GUID to match with in the HOB list.
182
183  @return The first instance of the matched GUID HOB among the whole HOB list.
184
185**/
186VOID *
187EFIAPI
188GetFirstGuidHob (
189  IN CONST EFI_GUID         *Guid
190  )
191{
192  VOID      *HobList;
193
194  HobList = GetHobList ();
195  return GetNextGuidHob (Guid, HobList);
196}
197
198/**
199  Get the system boot mode from the HOB list.
200
201  This function returns the system boot mode information from the
202  PHIT HOB in HOB list.
203
204  If the pointer to the HOB list is NULL, then ASSERT().
205
206  @param  VOID
207
208  @return The Boot Mode.
209
210**/
211EFI_BOOT_MODE
212EFIAPI
213GetBootModeHob (
214  VOID
215  )
216{
217  EFI_STATUS             Status;
218  EFI_BOOT_MODE          BootMode;
219
220  Status = PeiServicesGetBootMode (&BootMode);
221  ASSERT_EFI_ERROR (Status);
222
223  return BootMode;
224}
225
226/**
227  Adds a new HOB to the HOB List.
228
229  This internal function enables PEIMs to create various types of HOBs.
230
231  @param  Type          Type of the new HOB.
232  @param  Length        Length of the new HOB to allocate.
233
234  @return The address of new HOB.
235
236**/
237VOID *
238EFIAPI
239InternalPeiCreateHob (
240  IN UINT16                      Type,
241  IN UINT16                      Length
242  )
243{
244  EFI_STATUS        Status;
245  VOID              *Hob;
246
247  Status = PeiServicesCreateHob (Type, Length, &Hob);
248  //
249  // Assume the process of HOB building is always successful.
250  //
251  ASSERT_EFI_ERROR (Status);
252  return Hob;
253}
254
255/**
256  Builds a HOB for a loaded PE32 module.
257
258  This function builds a HOB for a loaded PE32 module.
259  It can only be invoked during PEI phase;
260  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
261
262  If ModuleName is NULL, then ASSERT().
263  If there is no additional space for HOB creation, then ASSERT().
264
265  @param  ModuleName              The GUID File Name of the module.
266  @param  MemoryAllocationModule  The 64 bit physical address of the module.
267  @param  ModuleLength            The length of the module in bytes.
268  @param  EntryPoint              The 64 bit physical address of the module entry point.
269
270**/
271VOID
272EFIAPI
273BuildModuleHob (
274  IN CONST EFI_GUID         *ModuleName,
275  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,
276  IN UINT64                 ModuleLength,
277  IN EFI_PHYSICAL_ADDRESS   EntryPoint
278  )
279{
280  EFI_HOB_MEMORY_ALLOCATION_MODULE  *Hob;
281
282  ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
283          ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
284
285  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
286
287  CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
288  Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
289  Hob->MemoryAllocationHeader.MemoryLength      = ModuleLength;
290  Hob->MemoryAllocationHeader.MemoryType        = EfiBootServicesCode;
291
292  //
293  // Zero the reserved space to match HOB spec
294  //
295  ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
296
297  CopyGuid (&Hob->ModuleName, ModuleName);
298  Hob->EntryPoint = EntryPoint;
299}
300
301/**
302  Builds a HOB that describes a chunk of system memory.
303
304  This function builds a HOB that describes a chunk of system memory.
305  It can only be invoked during PEI phase;
306  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
307
308  If there is no additional space for HOB creation, then ASSERT().
309
310  @param  ResourceType        The type of resource described by this HOB.
311  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.
312  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.
313  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.
314
315**/
316VOID
317EFIAPI
318BuildResourceDescriptorHob (
319  IN EFI_RESOURCE_TYPE            ResourceType,
320  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
321  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
322  IN UINT64                       NumberOfBytes
323  )
324{
325  EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;
326
327  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
328
329  Hob->ResourceType      = ResourceType;
330  Hob->ResourceAttribute = ResourceAttribute;
331  Hob->PhysicalStart     = PhysicalStart;
332  Hob->ResourceLength    = NumberOfBytes;
333}
334
335/**
336  Builds a customized HOB tagged with a GUID for identification and returns
337  the start address of GUID HOB data.
338
339  This function builds a customized HOB tagged with a GUID for identification
340  and returns the start address of GUID HOB data so that caller can fill the customized data.
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() since PEI HOB is read-only for DXE phase.
344
345  If Guid is NULL, then ASSERT().
346  If there is no additional space for HOB creation, then ASSERT().
347  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
348
349  @param  Guid          The GUID to tag the customized HOB.
350  @param  DataLength    The size of the data payload for the GUID HOB.
351
352  @return The start address of GUID HOB data.
353
354**/
355VOID *
356EFIAPI
357BuildGuidHob (
358  IN CONST EFI_GUID              *Guid,
359  IN UINTN                       DataLength
360  )
361{
362  EFI_HOB_GUID_TYPE *Hob;
363
364  //
365  // Make sure that data length is not too long.
366  //
367  ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
368
369  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
370  CopyGuid (&Hob->Name, Guid);
371  return Hob + 1;
372}
373
374/**
375  Builds a customized HOB tagged with a GUID for identification, copies the input data to the HOB
376  data field, and returns the start address of the GUID HOB data.
377
378  This function builds a customized HOB tagged with a GUID for identification and copies the input
379  data to the HOB data field and returns the start address of the GUID HOB data.  It can only be
380  invoked during PEI phase; for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
381  The HOB Header and Name field is already stripped.
382  It can only be invoked during PEI phase;
383  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
384
385  If Guid is NULL, then ASSERT().
386  If Data is NULL and DataLength > 0, then ASSERT().
387  If there is no additional space for HOB creation, then ASSERT().
388  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
389
390  @param  Guid          The GUID to tag the customized HOB.
391  @param  Data          The data to be copied into the data field of the GUID HOB.
392  @param  DataLength    The size of the data payload for the GUID HOB.
393
394  @return The start address of GUID HOB data.
395
396**/
397VOID *
398EFIAPI
399BuildGuidDataHob (
400  IN CONST EFI_GUID              *Guid,
401  IN VOID                        *Data,
402  IN UINTN                       DataLength
403  )
404{
405  VOID  *HobData;
406
407  ASSERT (Data != NULL || DataLength == 0);
408
409  HobData = BuildGuidHob (Guid, DataLength);
410
411  return CopyMem (HobData, Data, DataLength);
412}
413
414/**
415  Builds a Firmware Volume HOB.
416
417  This function builds a Firmware Volume HOB.
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
421  If there is no additional space for HOB creation, then ASSERT().
422
423  @param  BaseAddress   The base address of the Firmware Volume.
424  @param  Length        The size of the Firmware Volume in bytes.
425
426**/
427VOID
428EFIAPI
429BuildFvHob (
430  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
431  IN UINT64                      Length
432  )
433{
434  EFI_HOB_FIRMWARE_VOLUME  *Hob;
435
436  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
437
438  Hob->BaseAddress = BaseAddress;
439  Hob->Length      = Length;
440}
441
442/**
443  Builds a EFI_HOB_TYPE_FV2 HOB.
444
445  This function builds a EFI_HOB_TYPE_FV2 HOB.
446  It can only be invoked during PEI phase;
447  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
448
449  If there is no additional space for HOB creation, then ASSERT().
450
451  @param  BaseAddress   The base address of the Firmware Volume.
452  @param  Length        The size of the Firmware Volume in bytes.
453  @param  FvName        The name of the Firmware Volume.
454  @param  FileName      The name of the file.
455
456**/
457VOID
458EFIAPI
459BuildFv2Hob (
460  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
461  IN          UINT64                      Length,
462  IN CONST    EFI_GUID                    *FvName,
463  IN CONST    EFI_GUID                    *FileName
464  )
465{
466  EFI_HOB_FIRMWARE_VOLUME2  *Hob;
467
468  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
469
470  Hob->BaseAddress = BaseAddress;
471  Hob->Length      = Length;
472  CopyGuid (&Hob->FvName, FvName);
473  CopyGuid (&Hob->FileName, FileName);
474}
475
476/**
477  Builds a Capsule Volume HOB.
478
479  This function builds a Capsule Volume HOB.
480  It can only be invoked during PEI phase;
481  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
482
483  If the platform does not support Capsule Volume HOBs, then ASSERT().
484  If there is no additional space for HOB creation, then ASSERT().
485
486  @param  BaseAddress   The base address of the Capsule Volume.
487  @param  Length        The size of the Capsule Volume in bytes.
488
489**/
490VOID
491EFIAPI
492BuildCvHob (
493  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
494  IN UINT64                      Length
495  )
496{
497  EFI_HOB_CAPSULE_VOLUME     *Hob;
498
499  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_CV, sizeof (EFI_HOB_CAPSULE_VOLUME));
500
501  Hob->BaseAddress = BaseAddress;
502  Hob->Length      = Length;
503}
504
505/**
506  Builds a HOB for the CPU.
507
508  This function builds a HOB for the CPU.
509  It can only be invoked during PEI phase;
510  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
511
512  If there is no additional space for HOB creation, then ASSERT().
513
514  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.
515  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.
516
517**/
518VOID
519EFIAPI
520BuildCpuHob (
521  IN UINT8                       SizeOfMemorySpace,
522  IN UINT8                       SizeOfIoSpace
523  )
524{
525  EFI_HOB_CPU  *Hob;
526
527  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
528
529  Hob->SizeOfMemorySpace = SizeOfMemorySpace;
530  Hob->SizeOfIoSpace     = SizeOfIoSpace;
531
532  //
533  // Zero the reserved space to match HOB spec
534  //
535  ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
536}
537
538/**
539  Builds a HOB for the Stack.
540
541  This function builds a HOB for the stack.
542  It can only be invoked during PEI phase;
543  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
544
545  If there is no additional space for HOB creation, then ASSERT().
546
547  @param  BaseAddress   The 64 bit physical address of the Stack.
548  @param  Length        The length of the stack in bytes.
549
550**/
551VOID
552EFIAPI
553BuildStackHob (
554  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
555  IN UINT64                      Length
556  )
557{
558  EFI_HOB_MEMORY_ALLOCATION_STACK  *Hob;
559
560  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
561          ((Length & (EFI_PAGE_SIZE - 1)) == 0));
562
563  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));
564
565  CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
566  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
567  Hob->AllocDescriptor.MemoryLength      = Length;
568  Hob->AllocDescriptor.MemoryType        = EfiBootServicesData;
569
570  //
571  // Zero the reserved space to match HOB spec
572  //
573  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
574}
575
576/**
577  Builds a HOB for the BSP store.
578
579  This function builds a HOB for BSP store.
580  It can only be invoked during PEI phase;
581  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
582
583  If there is no additional space for HOB creation, then ASSERT().
584
585  @param  BaseAddress   The 64 bit physical address of the BSP.
586  @param  Length        The length of the BSP store in bytes.
587  @param  MemoryType    Type of memory allocated by this HOB.
588
589**/
590VOID
591EFIAPI
592BuildBspStoreHob (
593  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
594  IN UINT64                      Length,
595  IN EFI_MEMORY_TYPE             MemoryType
596  )
597{
598  EFI_HOB_MEMORY_ALLOCATION_BSP_STORE  *Hob;
599
600  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
601          ((Length & (EFI_PAGE_SIZE - 1)) == 0));
602
603  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_BSP_STORE));
604
605  CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocBspStoreGuid);
606  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
607  Hob->AllocDescriptor.MemoryLength      = Length;
608  Hob->AllocDescriptor.MemoryType        = MemoryType;
609
610  //
611  // Zero the reserved space to match HOB spec
612  //
613  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
614}
615
616/**
617  Builds a HOB for the memory allocation.
618
619  This function builds a HOB for the memory allocation.
620  It can only be invoked during PEI phase;
621  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
622
623  If there is no additional space for HOB creation, then ASSERT().
624
625  @param  BaseAddress   The 64 bit physical address of the memory.
626  @param  Length        The length of the memory allocation in bytes.
627  @param  MemoryType    Type of memory allocated by this HOB.
628
629**/
630VOID
631EFIAPI
632BuildMemoryAllocationHob (
633  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
634  IN UINT64                      Length,
635  IN EFI_MEMORY_TYPE             MemoryType
636  )
637{
638  EFI_HOB_MEMORY_ALLOCATION  *Hob;
639
640  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
641          ((Length & (EFI_PAGE_SIZE - 1)) == 0));
642
643  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
644
645  ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
646  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
647  Hob->AllocDescriptor.MemoryLength      = Length;
648  Hob->AllocDescriptor.MemoryType        = MemoryType;
649  //
650  // Zero the reserved space to match HOB spec
651  //
652  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
653}
654