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