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