]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Library/PrePiHobLib/Hob.c
EmbeddedPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / EmbeddedPkg / Library / PrePiHobLib / Hob.c
CommitLineData
1e57a462 1/** @file\r
2\r
3 Copyright (c) 2010, Apple Inc. All rights reserved.<BR>\r
e39e40ca 4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
3402aac7 5\r
878b807a 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
1e57a462 7\r
8**/\r
9\r
10#include <PiPei.h>\r
11\r
12#include <Library/BaseLib.h>\r
13#include <Library/BaseMemoryLib.h>\r
14#include <Library/DebugLib.h>\r
15#include <Library/PeCoffLib.h>\r
16#include <Library/HobLib.h>\r
17#include <Library/PcdLib.h>\r
18#include <Library/PrePiHobListPointerLib.h>\r
19\r
20#include <Protocol/PeCoffLoader.h>\r
21#include <Guid/ExtractSection.h>\r
22#include <Guid/MemoryTypeInformation.h>\r
23#include <Guid/MemoryAllocationHob.h>\r
24\r
25VOID\r
26BuildMemoryTypeInformationHob (\r
27 VOID\r
28 );\r
29\r
30/**\r
31 Returns the pointer to the HOB list.\r
32\r
33 This function returns the pointer to first HOB in the list.\r
34\r
35 @return The pointer to the HOB list.\r
36\r
37**/\r
38VOID *\r
39EFIAPI\r
40GetHobList (\r
41 VOID\r
42 )\r
43{\r
44 return PrePeiGetHobList ();\r
45}\r
46\r
47\r
48\r
49/**\r
50 Updates the pointer to the HOB list.\r
51\r
52 @param HobList Hob list pointer to store\r
53\r
54**/\r
55EFI_STATUS\r
56EFIAPI\r
57SetHobList (\r
58 IN VOID *HobList\r
59 )\r
60{\r
61 return PrePeiSetHobList (HobList);\r
62}\r
63\r
64/**\r
65\r
66\r
67**/\r
68EFI_HOB_HANDOFF_INFO_TABLE*\r
69HobConstructor (\r
70 IN VOID *EfiMemoryBegin,\r
71 IN UINTN EfiMemoryLength,\r
72 IN VOID *EfiFreeMemoryBottom,\r
73 IN VOID *EfiFreeMemoryTop\r
74 )\r
75{\r
76 EFI_HOB_HANDOFF_INFO_TABLE *Hob;\r
77 EFI_HOB_GENERIC_HEADER *HobEnd;\r
78\r
79 Hob = EfiFreeMemoryBottom;\r
80 HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);\r
81\r
82 Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;\r
83 Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);\r
84 Hob->Header.Reserved = 0;\r
85\r
86 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;\r
87 HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);\r
88 HobEnd->Reserved = 0;\r
89\r
90 Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;\r
91 Hob->BootMode = BOOT_WITH_FULL_CONFIGURATION;\r
92\r
93 Hob->EfiMemoryTop = (UINTN)EfiMemoryBegin + EfiMemoryLength;\r
94 Hob->EfiMemoryBottom = (UINTN)EfiMemoryBegin;\r
95 Hob->EfiFreeMemoryTop = (UINTN)EfiFreeMemoryTop;\r
96 Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);\r
97 Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;\r
98\r
99 return Hob;\r
100}\r
101\r
102VOID *\r
103CreateHob (\r
104 IN UINT16 HobType,\r
105 IN UINT16 HobLength\r
106 )\r
107{\r
108 EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;\r
109 EFI_HOB_GENERIC_HEADER *HobEnd;\r
110 EFI_PHYSICAL_ADDRESS FreeMemory;\r
111 VOID *Hob;\r
112\r
113 HandOffHob = GetHobList ();\r
114\r
115 HobLength = (UINT16)((HobLength + 0x7) & (~0x7));\r
116\r
117 FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;\r
118\r
119 if (FreeMemory < HobLength) {\r
120 return NULL;\r
121 }\r
122\r
123 Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;\r
124 ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;\r
125 ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;\r
126 ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;\r
127\r
128 HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);\r
129 HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;\r
130\r
131 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;\r
132 HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);\r
133 HobEnd->Reserved = 0;\r
134 HobEnd++;\r
135 HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;\r
136\r
137 return Hob;\r
138}\r
139\r
140/**\r
141 Builds a HOB that describes a chunk of system memory.\r
142\r
143 This function builds a HOB that describes a chunk of system memory.\r
144 If there is no additional space for HOB creation, then ASSERT().\r
145\r
146 @param ResourceType The type of resource described by this HOB.\r
147 @param ResourceAttribute The resource attributes of the memory described by this HOB.\r
148 @param PhysicalStart The 64 bit physical address of memory described by this HOB.\r
149 @param NumberOfBytes The length of the memory described by this HOB in bytes.\r
150\r
151**/\r
152VOID\r
153EFIAPI\r
154BuildResourceDescriptorHob (\r
155 IN EFI_RESOURCE_TYPE ResourceType,\r
156 IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,\r
157 IN EFI_PHYSICAL_ADDRESS PhysicalStart,\r
158 IN UINT64 NumberOfBytes\r
159 )\r
160{\r
161 EFI_HOB_RESOURCE_DESCRIPTOR *Hob;\r
162\r
163 Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));\r
164 ASSERT(Hob != NULL);\r
165\r
166 Hob->ResourceType = ResourceType;\r
167 Hob->ResourceAttribute = ResourceAttribute;\r
168 Hob->PhysicalStart = PhysicalStart;\r
169 Hob->ResourceLength = NumberOfBytes;\r
170}\r
171\r
1e57a462 172VOID\r
173EFIAPI\r
3402aac7 174BuildFvHobs (\r
1e57a462 175 IN EFI_PHYSICAL_ADDRESS PhysicalStart,\r
176 IN UINT64 NumberOfBytes,\r
177 IN EFI_RESOURCE_ATTRIBUTE_TYPE *ResourceAttribute\r
3402aac7 178 )\r
1e57a462 179{\r
180\r
181 EFI_RESOURCE_ATTRIBUTE_TYPE Resource;\r
3402aac7 182\r
1e57a462 183 BuildFvHob (PhysicalStart, NumberOfBytes);\r
3402aac7 184\r
1e57a462 185 if (ResourceAttribute == NULL) {\r
186 Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
187 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
188 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
189 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);\r
190 } else {\r
191 Resource = *ResourceAttribute;\r
192 }\r
3402aac7 193\r
1e57a462 194 BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes);\r
195}\r
196\r
197/**\r
198 Returns the next instance of a HOB type from the starting HOB.\r
199\r
3402aac7 200 This function searches the first instance of a HOB type from the starting HOB pointer.\r
1e57a462 201 If there does not exist such HOB type from the starting HOB pointer, it will return NULL.\r
202 In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
203 unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
204 caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
205 If HobStart is NULL, then ASSERT().\r
206\r
207 @param Type The HOB type to return.\r
208 @param HobStart The starting HOB pointer to search from.\r
209\r
210 @return The next instance of a HOB type from the starting HOB.\r
211\r
212**/\r
213VOID *\r
214EFIAPI\r
215GetNextHob (\r
216 IN UINT16 Type,\r
217 IN CONST VOID *HobStart\r
218 )\r
219{\r
220 EFI_PEI_HOB_POINTERS Hob;\r
221\r
222 ASSERT (HobStart != NULL);\r
3402aac7 223\r
1e57a462 224 Hob.Raw = (UINT8 *) HobStart;\r
225 //\r
226 // Parse the HOB list until end of list or matching type is found.\r
227 //\r
228 while (!END_OF_HOB_LIST (Hob)) {\r
229 if (Hob.Header->HobType == Type) {\r
230 return Hob.Raw;\r
231 }\r
232 Hob.Raw = GET_NEXT_HOB (Hob);\r
233 }\r
234 return NULL;\r
235}\r
3402aac7
RC
236\r
237\r
1e57a462 238\r
239/**\r
240 Returns the first instance of a HOB type among the whole HOB list.\r
241\r
3402aac7
RC
242 This function searches the first instance of a HOB type among the whole HOB list.\r
243 If there does not exist such HOB type in the HOB list, it will return NULL.\r
1e57a462 244\r
245 @param Type The HOB type to return.\r
246\r
247 @return The next instance of a HOB type from the starting HOB.\r
248\r
249**/\r
250VOID *\r
251EFIAPI\r
252GetFirstHob (\r
253 IN UINT16 Type\r
254 )\r
255{\r
256 VOID *HobList;\r
257\r
258 HobList = GetHobList ();\r
259 return GetNextHob (Type, HobList);\r
260}\r
261\r
262\r
263/**\r
3402aac7
RC
264 This function searches the first instance of a HOB from the starting HOB pointer.\r
265 Such HOB should satisfy two conditions:\r
266 its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.\r
267 If there does not exist such HOB from the starting HOB pointer, it will return NULL.\r
1e57a462 268 Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
269 to extract the data section and its size info respectively.\r
270 In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
271 unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
272 caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
273 If Guid is NULL, then ASSERT().\r
274 If HobStart is NULL, then ASSERT().\r
275\r
276 @param Guid The GUID to match with in the HOB list.\r
277 @param HobStart A pointer to a Guid.\r
278\r
279 @return The next instance of the matched GUID HOB from the starting HOB.\r
280\r
281**/\r
282VOID *\r
283EFIAPI\r
284GetNextGuidHob (\r
285 IN CONST EFI_GUID *Guid,\r
286 IN CONST VOID *HobStart\r
287 ){\r
288 EFI_PEI_HOB_POINTERS GuidHob;\r
289\r
290 GuidHob.Raw = (UINT8 *) HobStart;\r
291 while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {\r
292 if (CompareGuid (Guid, &GuidHob.Guid->Name)) {\r
293 break;\r
294 }\r
295 GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
296 }\r
297 return GuidHob.Raw;\r
298}\r
299\r
300\r
301/**\r
3402aac7 302 This function searches the first instance of a HOB among the whole HOB list.\r
1e57a462 303 Such HOB should satisfy two conditions:\r
304 its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.\r
305 If there does not exist such HOB from the starting HOB pointer, it will return NULL.\r
306 Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
307 to extract the data section and its size info respectively.\r
308 If Guid is NULL, then ASSERT().\r
309\r
310 @param Guid The GUID to match with in the HOB list.\r
311\r
312 @return The first instance of the matched GUID HOB among the whole HOB list.\r
313\r
314**/\r
315VOID *\r
316EFIAPI\r
317GetFirstGuidHob (\r
318 IN CONST EFI_GUID *Guid\r
319 )\r
320{\r
321 VOID *HobList;\r
322\r
323 HobList = GetHobList ();\r
324 return GetNextGuidHob (Guid, HobList);\r
325}\r
326\r
327\r
328/**\r
329 Get the Boot Mode from the HOB list.\r
330\r
3402aac7 331 This function returns the system boot mode information from the\r
1e57a462 332 PHIT HOB in HOB list.\r
333\r
334 @param VOID\r
335\r
336 @return The Boot Mode.\r
337\r
338**/\r
339EFI_BOOT_MODE\r
340EFIAPI\r
341GetBootMode (\r
342 VOID\r
343 )\r
344{\r
345 EFI_PEI_HOB_POINTERS Hob;\r
346\r
347 Hob.Raw = GetHobList ();\r
348 return Hob.HandoffInformationTable->BootMode;\r
349}\r
350\r
351\r
352/**\r
353 Get the Boot Mode from the HOB list.\r
354\r
3402aac7 355 This function returns the system boot mode information from the\r
1e57a462 356 PHIT HOB in HOB list.\r
357\r
358 @param VOID\r
359\r
360 @return The Boot Mode.\r
361\r
362**/\r
363EFI_STATUS\r
364EFIAPI\r
365SetBootMode (\r
366 IN EFI_BOOT_MODE BootMode\r
367 )\r
368{\r
369 EFI_PEI_HOB_POINTERS Hob;\r
370\r
371 Hob.Raw = GetHobList ();\r
372 Hob.HandoffInformationTable->BootMode = BootMode;\r
373 return BootMode;\r
374}\r
375\r
376/**\r
377 Builds a HOB for a loaded PE32 module.\r
378\r
379 This function builds a HOB for a loaded PE32 module.\r
380 It can only be invoked during PEI phase;\r
381 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
382 If ModuleName is NULL, then ASSERT().\r
383 If there is no additional space for HOB creation, then ASSERT().\r
384\r
385 @param ModuleName The GUID File Name of the module.\r
386 @param MemoryAllocationModule The 64 bit physical address of the module.\r
387 @param ModuleLength The length of the module in bytes.\r
388 @param EntryPoint The 64 bit physical address of the module entry point.\r
389\r
390**/\r
391VOID\r
392EFIAPI\r
393BuildModuleHob (\r
394 IN CONST EFI_GUID *ModuleName,\r
395 IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,\r
396 IN UINT64 ModuleLength,\r
397 IN EFI_PHYSICAL_ADDRESS EntryPoint\r
398 )\r
399{\r
400 EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob;\r
401\r
402 ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&\r
403 ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));\r
404\r
405 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));\r
406\r
407 CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);\r
408 Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;\r
409 Hob->MemoryAllocationHeader.MemoryLength = ModuleLength;\r
410 Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode;\r
411\r
412 //\r
413 // Zero the reserved space to match HOB spec\r
414 //\r
415 ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));\r
3402aac7 416\r
1e57a462 417 CopyGuid (&Hob->ModuleName, ModuleName);\r
418 Hob->EntryPoint = EntryPoint;\r
419}\r
420\r
421/**\r
422 Builds a GUID HOB with a certain data length.\r
423\r
3402aac7
RC
424 This function builds a customized HOB tagged with a GUID for identification\r
425 and returns the start address of GUID HOB data so that caller can fill the customized data.\r
1e57a462 426 The HOB Header and Name field is already stripped.\r
427 It can only be invoked during PEI phase;\r
428 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
429 If Guid is NULL, then ASSERT().\r
430 If there is no additional space for HOB creation, then ASSERT().\r
431 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
432\r
433 @param Guid The GUID to tag the customized HOB.\r
434 @param DataLength The size of the data payload for the GUID HOB.\r
435\r
436 @return The start address of GUID HOB data.\r
437\r
438**/\r
439VOID *\r
440EFIAPI\r
441BuildGuidHob (\r
442 IN CONST EFI_GUID *Guid,\r
443 IN UINTN DataLength\r
444 )\r
445{\r
446 EFI_HOB_GUID_TYPE *Hob;\r
447\r
448 //\r
449 // Make sure that data length is not too long.\r
450 //\r
451 ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));\r
452\r
453 Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));\r
454 CopyGuid (&Hob->Name, Guid);\r
455 return Hob + 1;\r
456}\r
457\r
458\r
459/**\r
460 Copies a data buffer to a newly-built HOB.\r
461\r
462 This function builds a customized HOB tagged with a GUID for identification,\r
463 copies the input data to the HOB data field and returns the start address of the GUID HOB data.\r
464 The HOB Header and Name field is already stripped.\r
465 It can only be invoked during PEI phase;\r
466 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
467 If Guid is NULL, then ASSERT().\r
468 If Data is NULL and DataLength > 0, then ASSERT().\r
469 If there is no additional space for HOB creation, then ASSERT().\r
470 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
471\r
472 @param Guid The GUID to tag the customized HOB.\r
473 @param Data The data to be copied into the data field of the GUID HOB.\r
474 @param DataLength The size of the data payload for the GUID HOB.\r
475\r
476 @return The start address of GUID HOB data.\r
477\r
478**/\r
479VOID *\r
480EFIAPI\r
481BuildGuidDataHob (\r
482 IN CONST EFI_GUID *Guid,\r
483 IN VOID *Data,\r
484 IN UINTN DataLength\r
485 )\r
486{\r
487 VOID *HobData;\r
488\r
489 ASSERT (Data != NULL || DataLength == 0);\r
490\r
491 HobData = BuildGuidHob (Guid, DataLength);\r
492\r
493 return CopyMem (HobData, Data, DataLength);\r
494}\r
495\r
496\r
497/**\r
498 Builds a Firmware Volume HOB.\r
499\r
500 This function builds a Firmware Volume HOB.\r
501 It can only be invoked during PEI phase;\r
502 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
503 If there is no additional space for HOB creation, then ASSERT().\r
504\r
505 @param BaseAddress The base address of the Firmware Volume.\r
506 @param Length The size of the Firmware Volume in bytes.\r
507\r
508**/\r
509VOID\r
510EFIAPI\r
511BuildFvHob (\r
512 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
513 IN UINT64 Length\r
514 )\r
515{\r
516 EFI_HOB_FIRMWARE_VOLUME *Hob;\r
517\r
518 Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));\r
519\r
520 Hob->BaseAddress = BaseAddress;\r
521 Hob->Length = Length;\r
522}\r
523\r
524\r
525/**\r
526 Builds a EFI_HOB_TYPE_FV2 HOB.\r
527\r
528 This function builds a EFI_HOB_TYPE_FV2 HOB.\r
529 It can only be invoked during PEI phase;\r
530 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
531 If there is no additional space for HOB creation, then ASSERT().\r
532\r
533 @param BaseAddress The base address of the Firmware Volume.\r
534 @param Length The size of the Firmware Volume in bytes.\r
535 @param FvName The name of the Firmware Volume.\r
536 @param FileName The name of the file.\r
3402aac7 537\r
1e57a462 538**/\r
539VOID\r
540EFIAPI\r
541BuildFv2Hob (\r
542 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
543 IN UINT64 Length,\r
544 IN CONST EFI_GUID *FvName,\r
545 IN CONST EFI_GUID *FileName\r
546 )\r
547{\r
548 EFI_HOB_FIRMWARE_VOLUME2 *Hob;\r
549\r
550 Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));\r
551\r
552 Hob->BaseAddress = BaseAddress;\r
553 Hob->Length = Length;\r
554 CopyGuid (&Hob->FvName, FvName);\r
555 CopyGuid (&Hob->FileName, FileName);\r
556}\r
557\r
e39e40ca
SZ
558/**\r
559 Builds a EFI_HOB_TYPE_FV3 HOB.\r
560\r
561 This function builds a EFI_HOB_TYPE_FV3 HOB.\r
562 It can only be invoked during PEI phase;\r
563 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
564\r
565 If there is no additional space for HOB creation, then ASSERT().\r
566\r
567 @param BaseAddress The base address of the Firmware Volume.\r
568 @param Length The size of the Firmware Volume in bytes.\r
569 @param AuthenticationStatus The authentication status.\r
570 @param ExtractedFv TRUE if the FV was extracted as a file within\r
571 another firmware volume. FALSE otherwise.\r
572 @param FvName The name of the Firmware Volume.\r
573 Valid only if IsExtractedFv is TRUE.\r
574 @param FileName The name of the file.\r
575 Valid only if IsExtractedFv is TRUE.\r
576\r
577**/\r
578VOID\r
579EFIAPI\r
580BuildFv3Hob (\r
581 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
582 IN UINT64 Length,\r
583 IN UINT32 AuthenticationStatus,\r
584 IN BOOLEAN ExtractedFv,\r
585 IN CONST EFI_GUID *FvName, OPTIONAL\r
586 IN CONST EFI_GUID *FileName OPTIONAL\r
587 )\r
588{\r
589 EFI_HOB_FIRMWARE_VOLUME3 *Hob;\r
590\r
591 Hob = CreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3));\r
1e57a462 592\r
e39e40ca
SZ
593 Hob->BaseAddress = BaseAddress;\r
594 Hob->Length = Length;\r
595 Hob->AuthenticationStatus = AuthenticationStatus;\r
596 Hob->ExtractedFv = ExtractedFv;\r
597 if (ExtractedFv) {\r
598 CopyGuid (&Hob->FvName, FvName);\r
599 CopyGuid (&Hob->FileName, FileName);\r
600 }\r
601}\r
1e57a462 602\r
603/**\r
604 Builds a Capsule Volume HOB.\r
605\r
606 This function builds a Capsule Volume HOB.\r
607 It can only be invoked during PEI phase;\r
608 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
609 If there is no additional space for HOB creation, then ASSERT().\r
610\r
611 @param BaseAddress The base address of the Capsule Volume.\r
612 @param Length The size of the Capsule Volume in bytes.\r
613\r
614**/\r
615VOID\r
616EFIAPI\r
617BuildCvHob (\r
618 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
619 IN UINT64 Length\r
620 )\r
621{\r
622 ASSERT (FALSE);\r
623}\r
624\r
625\r
626/**\r
627 Builds a HOB for the CPU.\r
628\r
629 This function builds a HOB for the CPU.\r
630 It can only be invoked during PEI phase;\r
631 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
632 If there is no additional space for HOB creation, then ASSERT().\r
633\r
634 @param SizeOfMemorySpace The maximum physical memory addressability of the processor.\r
635 @param SizeOfIoSpace The maximum physical I/O addressability of the processor.\r
636\r
637**/\r
638VOID\r
639EFIAPI\r
640BuildCpuHob (\r
641 IN UINT8 SizeOfMemorySpace,\r
642 IN UINT8 SizeOfIoSpace\r
643 )\r
644{\r
645 EFI_HOB_CPU *Hob;\r
646\r
647 Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));\r
648\r
649 Hob->SizeOfMemorySpace = SizeOfMemorySpace;\r
650 Hob->SizeOfIoSpace = SizeOfIoSpace;\r
651\r
652 //\r
653 // Zero the reserved space to match HOB spec\r
654 //\r
3402aac7 655 ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));\r
1e57a462 656}\r
657\r
658\r
659/**\r
660 Builds a HOB for the Stack.\r
661\r
662 This function builds a HOB for the stack.\r
663 It can only be invoked during PEI phase;\r
664 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
665 If there is no additional space for HOB creation, then ASSERT().\r
666\r
667 @param BaseAddress The 64 bit physical address of the Stack.\r
668 @param Length The length of the stack in bytes.\r
669\r
670**/\r
671VOID\r
672EFIAPI\r
673BuildStackHob (\r
674 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
675 IN UINT64 Length\r
676 )\r
677{\r
678 EFI_HOB_MEMORY_ALLOCATION_STACK *Hob;\r
679\r
680 ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&\r
681 ((Length & (EFI_PAGE_SIZE - 1)) == 0));\r
682\r
683 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));\r
684\r
685 CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);\r
686 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
687 Hob->AllocDescriptor.MemoryLength = Length;\r
688 Hob->AllocDescriptor.MemoryType = EfiBootServicesData;\r
689\r
690 //\r
691 // Zero the reserved space to match HOB spec\r
692 //\r
693 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));\r
694}\r
695\r
696\r
697/**\r
698 Update the Stack Hob if the stack has been moved\r
699\r
700 @param BaseAddress The 64 bit physical address of the Stack.\r
701 @param Length The length of the stack in bytes.\r
702\r
703**/\r
704VOID\r
705UpdateStackHob (\r
706 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
707 IN UINT64 Length\r
708 )\r
709{\r
710 EFI_PEI_HOB_POINTERS Hob;\r
711\r
712 Hob.Raw = GetHobList ();\r
713 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {\r
714 if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {\r
715 //\r
716 // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type\r
717 // to be reclaimed by DXE core.\r
718 //\r
719 BuildMemoryAllocationHob (\r
720 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,\r
721 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,\r
722 EfiConventionalMemory\r
723 );\r
724 //\r
725 // Update the BSP Stack Hob to reflect the new stack info.\r
726 //\r
727 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
728 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;\r
729 break;\r
730 }\r
731 Hob.Raw = GET_NEXT_HOB (Hob);\r
732 }\r
733}\r
734\r
735\r
736\r
737/**\r
738 Builds a HOB for the memory allocation.\r
739\r
740 This function builds a HOB for the memory allocation.\r
741 It can only be invoked during PEI phase;\r
742 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
743 If there is no additional space for HOB creation, then ASSERT().\r
744\r
745 @param BaseAddress The 64 bit physical address of the memory.\r
746 @param Length The length of the memory allocation in bytes.\r
747 @param MemoryType Type of memory allocated by this HOB.\r
748\r
749**/\r
750VOID\r
751EFIAPI\r
752BuildMemoryAllocationHob (\r
753 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
754 IN UINT64 Length,\r
755 IN EFI_MEMORY_TYPE MemoryType\r
756 )\r
757{\r
758 EFI_HOB_MEMORY_ALLOCATION *Hob;\r
759\r
760 ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&\r
761 ((Length & (EFI_PAGE_SIZE - 1)) == 0));\r
3402aac7 762\r
1e57a462 763 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));\r
3402aac7 764\r
1e57a462 765 ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));\r
766 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
767 Hob->AllocDescriptor.MemoryLength = Length;\r
768 Hob->AllocDescriptor.MemoryType = MemoryType;\r
769 //\r
770 // Zero the reserved space to match HOB spec\r
771 //\r
772 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));\r
773}\r
774\r
775\r
776\r
777VOID\r
778EFIAPI\r
779BuildExtractSectionHob (\r
780 IN EFI_GUID *Guid,\r
781 IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER SectionGetInfo,\r
782 IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER SectionExtraction\r
783 )\r
784{\r
785 EXTRACT_SECTION_DATA Data;\r
3402aac7 786\r
1e57a462 787 Data.SectionGetInfo = SectionGetInfo;\r
788 Data.SectionExtraction = SectionExtraction;\r
789 BuildGuidDataHob (Guid, &Data, sizeof (Data));\r
790}\r
791\r
792PE_COFF_LOADER_PROTOCOL gPeCoffProtocol = {\r
793 PeCoffLoaderGetImageInfo,\r
794 PeCoffLoaderLoadImage,\r
795 PeCoffLoaderRelocateImage,\r
796 PeCoffLoaderImageReadFromMemory,\r
797 PeCoffLoaderRelocateImageForRuntime,\r
798 PeCoffLoaderUnloadImage\r
799};\r
800\r
801\r
802\r
803VOID\r
804EFIAPI\r
805BuildPeCoffLoaderHob (\r
806 VOID\r
807 )\r
808{\r
3402aac7
RC
809 VOID *Ptr;\r
810\r
1e57a462 811 Ptr = &gPeCoffProtocol;\r
3402aac7 812 BuildGuidDataHob (&gPeCoffLoaderProtocolGuid, &Ptr, sizeof (VOID *));\r
1e57a462 813}\r
814\r
815// May want to put this into a library so you only need the PCD setings if you are using the feature?\r
816VOID\r
817BuildMemoryTypeInformationHob (\r
818 VOID\r
819 )\r
820{\r
821 EFI_MEMORY_TYPE_INFORMATION Info[10];\r
822\r
823 Info[0].Type = EfiACPIReclaimMemory;\r
824 Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);\r
825 Info[1].Type = EfiACPIMemoryNVS;\r
826 Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);\r
827 Info[2].Type = EfiReservedMemoryType;\r
828 Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);\r
829 Info[3].Type = EfiRuntimeServicesData;\r
830 Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);\r
831 Info[4].Type = EfiRuntimeServicesCode;\r
832 Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);\r
833 Info[5].Type = EfiBootServicesCode;\r
834 Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);\r
835 Info[6].Type = EfiBootServicesData;\r
836 Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);\r
837 Info[7].Type = EfiLoaderCode;\r
838 Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);\r
839 Info[8].Type = EfiLoaderData;\r
840 Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);\r
841\r
842 // Terminator for the list\r
843 Info[9].Type = EfiMaxMemoryType;\r
844 Info[9].NumberOfPages = 0;\r
845\r
846\r
847 BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));\r
848}\r
849\r