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