]> git.proxmox.com Git - mirror_edk2.git/blame - UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / UefiPayloadPkg / Library / PayloadEntryHobLib / Hob.c
CommitLineData
7c4ab1c2
GD
1/** @file\r
2\r
3 Copyright (c) 2010, Apple Inc. All rights reserved.<BR>\r
82f727c4 4 Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>\r
7c4ab1c2
GD
5\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
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/HobLib.h>\r
16#include <Library/PcdLib.h>\r
17\r
e5efcf8b 18VOID *mHobList;\r
7c4ab1c2
GD
19\r
20/**\r
21 Returns the pointer to the HOB list.\r
22\r
23 This function returns the pointer to first HOB in the list.\r
24\r
25 @return The pointer to the HOB list.\r
26\r
27**/\r
28VOID *\r
29EFIAPI\r
30GetHobList (\r
31 VOID\r
32 )\r
33{\r
34 ASSERT (mHobList != NULL);\r
35 return mHobList;\r
36}\r
37\r
7c4ab1c2
GD
38/**\r
39 Build a Handoff Information Table HOB\r
40\r
d63595c3
ZL
41 This function initialize a HOB region from EfiMemoryBegin to\r
42 EfiMemoryTop. And EfiFreeMemoryBottom and EfiFreeMemoryTop should\r
7c4ab1c2
GD
43 be inside the HOB region.\r
44\r
d63595c3
ZL
45 @param[in] EfiMemoryBottom Total memory start address\r
46 @param[in] EfiMemoryTop Total memory end address.\r
47 @param[in] EfiFreeMemoryBottom Free memory start address\r
48 @param[in] EfiFreeMemoryTop Free memory end address.\r
7c4ab1c2
GD
49\r
50 @return The pointer to the handoff HOB table.\r
51\r
52**/\r
e5efcf8b 53EFI_HOB_HANDOFF_INFO_TABLE *\r
7c4ab1c2
GD
54EFIAPI\r
55HobConstructor (\r
e5efcf8b
MK
56 IN VOID *EfiMemoryBottom,\r
57 IN VOID *EfiMemoryTop,\r
58 IN VOID *EfiFreeMemoryBottom,\r
59 IN VOID *EfiFreeMemoryTop\r
7c4ab1c2
GD
60 )\r
61{\r
62 EFI_HOB_HANDOFF_INFO_TABLE *Hob;\r
63 EFI_HOB_GENERIC_HEADER *HobEnd;\r
64\r
65 Hob = EfiFreeMemoryBottom;\r
66 HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);\r
67\r
e5efcf8b
MK
68 Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;\r
69 Hob->Header.HobLength = sizeof (EFI_HOB_HANDOFF_INFO_TABLE);\r
70 Hob->Header.Reserved = 0;\r
7c4ab1c2 71\r
e5efcf8b
MK
72 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;\r
73 HobEnd->HobLength = sizeof (EFI_HOB_GENERIC_HEADER);\r
74 HobEnd->Reserved = 0;\r
7c4ab1c2 75\r
e5efcf8b
MK
76 Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;\r
77 Hob->BootMode = BOOT_WITH_FULL_CONFIGURATION;\r
7c4ab1c2 78\r
e5efcf8b
MK
79 Hob->EfiMemoryTop = (EFI_PHYSICAL_ADDRESS)(UINTN)EfiMemoryTop;\r
80 Hob->EfiMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)EfiMemoryBottom;\r
81 Hob->EfiFreeMemoryTop = (EFI_PHYSICAL_ADDRESS)(UINTN)EfiFreeMemoryTop;\r
82 Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);\r
83 Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;\r
7c4ab1c2
GD
84\r
85 mHobList = Hob;\r
86 return Hob;\r
87}\r
88\r
89/**\r
90 Add a new HOB to the HOB List.\r
91\r
92 @param HobType Type of the new HOB.\r
93 @param HobLength Length of the new HOB to allocate.\r
94\r
95 @return NULL if there is no space to create a hob.\r
96 @return The address point to the new created hob.\r
97\r
98**/\r
99VOID *\r
100EFIAPI\r
101CreateHob (\r
e5efcf8b
MK
102 IN UINT16 HobType,\r
103 IN UINT16 HobLength\r
7c4ab1c2
GD
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
e5efcf8b 118 return NULL;\r
7c4ab1c2
GD
119 }\r
120\r
e5efcf8b
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
7c4ab1c2 125\r
e5efcf8b
MK
126 HobEnd = (EFI_HOB_GENERIC_HEADER *)((UINTN)Hob + HobLength);\r
127 HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;\r
7c4ab1c2
GD
128\r
129 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;\r
e5efcf8b 130 HobEnd->HobLength = sizeof (EFI_HOB_GENERIC_HEADER);\r
7c4ab1c2
GD
131 HobEnd->Reserved = 0;\r
132 HobEnd++;\r
e5efcf8b 133 HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;\r
7c4ab1c2
GD
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
e5efcf8b 162 ASSERT (Hob != NULL);\r
7c4ab1c2
GD
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
7c4ab1c2
GD
170/**\r
171 Returns the next instance of a HOB type from the starting HOB.\r
172\r
173 This function searches the first instance of a HOB type from the starting HOB pointer.\r
174 If there does not exist such HOB type from the starting HOB pointer, it will return NULL.\r
175 In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
176 unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
177 caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
178 If HobStart is NULL, then ASSERT().\r
179\r
180 @param Type The HOB type to return.\r
181 @param HobStart The starting HOB pointer to search from.\r
182\r
183 @return The next instance of a HOB type from the starting HOB.\r
184\r
185**/\r
186VOID *\r
187EFIAPI\r
188GetNextHob (\r
e5efcf8b
MK
189 IN UINT16 Type,\r
190 IN CONST VOID *HobStart\r
7c4ab1c2
GD
191 )\r
192{\r
193 EFI_PEI_HOB_POINTERS Hob;\r
194\r
195 ASSERT (HobStart != NULL);\r
196\r
e5efcf8b 197 Hob.Raw = (UINT8 *)HobStart;\r
7c4ab1c2
GD
198 //\r
199 // Parse the HOB list until end of list or matching type is found.\r
200 //\r
201 while (!END_OF_HOB_LIST (Hob)) {\r
202 if (Hob.Header->HobType == Type) {\r
203 return Hob.Raw;\r
204 }\r
e5efcf8b 205\r
7c4ab1c2
GD
206 Hob.Raw = GET_NEXT_HOB (Hob);\r
207 }\r
e5efcf8b 208\r
7c4ab1c2
GD
209 return NULL;\r
210}\r
211\r
7c4ab1c2
GD
212/**\r
213 Returns the first instance of a HOB type among the whole HOB list.\r
214\r
215 This function searches the first instance of a HOB type among the whole HOB list.\r
216 If there does not exist such HOB type in the HOB list, it will return NULL.\r
217\r
218 @param Type The HOB type to return.\r
219\r
220 @return The next instance of a HOB type from the starting HOB.\r
221\r
222**/\r
223VOID *\r
224EFIAPI\r
225GetFirstHob (\r
e5efcf8b 226 IN UINT16 Type\r
7c4ab1c2
GD
227 )\r
228{\r
e5efcf8b 229 VOID *HobList;\r
7c4ab1c2
GD
230\r
231 HobList = GetHobList ();\r
232 return GetNextHob (Type, HobList);\r
233}\r
234\r
7c4ab1c2
GD
235/**\r
236 This function searches the first instance of a HOB from the starting HOB pointer.\r
237 Such HOB should satisfy two conditions:\r
238 its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.\r
239 If there does not exist such HOB from the starting HOB pointer, it will return NULL.\r
240 Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
241 to extract the data section and its size info respectively.\r
242 In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
243 unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
244 caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
245 If Guid is NULL, then ASSERT().\r
246 If HobStart is NULL, then ASSERT().\r
247\r
248 @param Guid The GUID to match with in the HOB list.\r
249 @param HobStart A pointer to a Guid.\r
250\r
251 @return The next instance of the matched GUID HOB from the starting HOB.\r
252\r
253**/\r
254VOID *\r
255EFIAPI\r
256GetNextGuidHob (\r
e5efcf8b
MK
257 IN CONST EFI_GUID *Guid,\r
258 IN CONST VOID *HobStart\r
6ef57974
GD
259 )\r
260{\r
7c4ab1c2
GD
261 EFI_PEI_HOB_POINTERS GuidHob;\r
262\r
e5efcf8b 263 GuidHob.Raw = (UINT8 *)HobStart;\r
7c4ab1c2
GD
264 while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {\r
265 if (CompareGuid (Guid, &GuidHob.Guid->Name)) {\r
266 break;\r
267 }\r
e5efcf8b 268\r
7c4ab1c2
GD
269 GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
270 }\r
e5efcf8b 271\r
7c4ab1c2
GD
272 return GuidHob.Raw;\r
273}\r
274\r
7c4ab1c2
GD
275/**\r
276 This function searches the first instance of a HOB among the whole HOB list.\r
277 Such HOB should satisfy two conditions:\r
278 its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.\r
279 If there does not exist such HOB from the starting HOB pointer, it will return NULL.\r
280 Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
281 to extract the data section and its size info respectively.\r
282 If Guid is NULL, then ASSERT().\r
283\r
284 @param Guid The GUID to match with in the HOB list.\r
285\r
286 @return The first instance of the matched GUID HOB among the whole HOB list.\r
287\r
288**/\r
289VOID *\r
290EFIAPI\r
291GetFirstGuidHob (\r
e5efcf8b 292 IN CONST EFI_GUID *Guid\r
7c4ab1c2
GD
293 )\r
294{\r
e5efcf8b 295 VOID *HobList;\r
7c4ab1c2
GD
296\r
297 HobList = GetHobList ();\r
298 return GetNextGuidHob (Guid, HobList);\r
299}\r
300\r
7c4ab1c2
GD
301/**\r
302 Builds a HOB for a loaded PE32 module.\r
303\r
304 This function builds a HOB for a loaded PE32 module.\r
305 It can only be invoked during PEI phase;\r
306 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
307 If ModuleName is NULL, then ASSERT().\r
308 If there is no additional space for HOB creation, then ASSERT().\r
309\r
310 @param ModuleName The GUID File Name of the module.\r
311 @param MemoryAllocationModule The 64 bit physical address of the module.\r
312 @param ModuleLength The length of the module in bytes.\r
313 @param EntryPoint The 64 bit physical address of the module entry point.\r
314\r
315**/\r
316VOID\r
317EFIAPI\r
318BuildModuleHob (\r
e5efcf8b
MK
319 IN CONST EFI_GUID *ModuleName,\r
320 IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,\r
321 IN UINT64 ModuleLength,\r
322 IN EFI_PHYSICAL_ADDRESS EntryPoint\r
7c4ab1c2
GD
323 )\r
324{\r
325 EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob;\r
326\r
e5efcf8b
MK
327 ASSERT (\r
328 ((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&\r
329 ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0)\r
330 );\r
7c4ab1c2
GD
331\r
332 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));\r
333\r
334 CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);\r
335 Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;\r
336 Hob->MemoryAllocationHeader.MemoryLength = ModuleLength;\r
337 Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode;\r
338\r
339 //\r
340 // Zero the reserved space to match HOB spec\r
341 //\r
342 ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));\r
343\r
344 CopyGuid (&Hob->ModuleName, ModuleName);\r
345 Hob->EntryPoint = EntryPoint;\r
346}\r
347\r
348/**\r
349 Builds a GUID HOB with a certain data length.\r
350\r
351 This function builds a customized HOB tagged with a GUID for identification\r
352 and returns the start address of GUID HOB data so that caller can fill the customized data.\r
353 The HOB Header and Name field is already stripped.\r
354 It can only be invoked during PEI phase;\r
355 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
356 If Guid is NULL, then ASSERT().\r
357 If there is no additional space for HOB creation, then ASSERT().\r
358 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
359\r
360 @param Guid The GUID to tag the customized HOB.\r
361 @param DataLength The size of the data payload for the GUID HOB.\r
362\r
363 @return The start address of GUID HOB data.\r
364\r
365**/\r
366VOID *\r
367EFIAPI\r
368BuildGuidHob (\r
e5efcf8b
MK
369 IN CONST EFI_GUID *Guid,\r
370 IN UINTN DataLength\r
7c4ab1c2
GD
371 )\r
372{\r
e5efcf8b 373 EFI_HOB_GUID_TYPE *Hob;\r
7c4ab1c2
GD
374\r
375 //\r
376 // Make sure that data length is not too long.\r
377 //\r
378 ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));\r
379\r
e5efcf8b 380 Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16)(sizeof (EFI_HOB_GUID_TYPE) + DataLength));\r
7c4ab1c2
GD
381 CopyGuid (&Hob->Name, Guid);\r
382 return Hob + 1;\r
383}\r
384\r
7c4ab1c2
GD
385/**\r
386 Copies a data buffer to a newly-built HOB.\r
387\r
388 This function builds a customized HOB tagged with a GUID for identification,\r
389 copies the input data to the HOB data field and returns the start address of the GUID HOB data.\r
390 The HOB Header and Name field is already stripped.\r
391 It can only be invoked during PEI phase;\r
392 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
393 If Guid is NULL, then ASSERT().\r
394 If Data is NULL and DataLength > 0, then ASSERT().\r
395 If there is no additional space for HOB creation, then ASSERT().\r
396 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
397\r
398 @param Guid The GUID to tag the customized HOB.\r
399 @param Data The data to be copied into the data field of the GUID HOB.\r
400 @param DataLength The size of the data payload for the GUID HOB.\r
401\r
402 @return The start address of GUID HOB data.\r
403\r
404**/\r
405VOID *\r
406EFIAPI\r
407BuildGuidDataHob (\r
e5efcf8b
MK
408 IN CONST EFI_GUID *Guid,\r
409 IN VOID *Data,\r
410 IN UINTN DataLength\r
7c4ab1c2
GD
411 )\r
412{\r
413 VOID *HobData;\r
414\r
415 ASSERT (Data != NULL || DataLength == 0);\r
416\r
417 HobData = BuildGuidHob (Guid, DataLength);\r
418\r
419 return CopyMem (HobData, Data, DataLength);\r
420}\r
421\r
7c4ab1c2
GD
422/**\r
423 Builds a Firmware Volume HOB.\r
424\r
425 This function builds a Firmware Volume HOB.\r
426 It can only be invoked during PEI phase;\r
427 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
428 If there is no additional space for HOB creation, then ASSERT().\r
429\r
430 @param BaseAddress The base address of the Firmware Volume.\r
431 @param Length The size of the Firmware Volume in bytes.\r
432\r
433**/\r
434VOID\r
435EFIAPI\r
436BuildFvHob (\r
e5efcf8b
MK
437 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
438 IN UINT64 Length\r
7c4ab1c2
GD
439 )\r
440{\r
441 EFI_HOB_FIRMWARE_VOLUME *Hob;\r
442\r
443 Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));\r
444\r
445 Hob->BaseAddress = BaseAddress;\r
446 Hob->Length = Length;\r
447}\r
448\r
7c4ab1c2
GD
449/**\r
450 Builds a EFI_HOB_TYPE_FV2 HOB.\r
451\r
452 This function builds a EFI_HOB_TYPE_FV2 HOB.\r
453 It can only be invoked during PEI phase;\r
454 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
455 If there is no additional space for HOB creation, then ASSERT().\r
456\r
457 @param BaseAddress The base address of the Firmware Volume.\r
458 @param Length The size of the Firmware Volume in bytes.\r
459 @param FvName The name of the Firmware Volume.\r
460 @param FileName The name of the file.\r
461\r
462**/\r
463VOID\r
464EFIAPI\r
465BuildFv2Hob (\r
e5efcf8b
MK
466 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
467 IN UINT64 Length,\r
468 IN CONST EFI_GUID *FvName,\r
469 IN CONST EFI_GUID *FileName\r
7c4ab1c2
GD
470 )\r
471{\r
472 EFI_HOB_FIRMWARE_VOLUME2 *Hob;\r
473\r
474 Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));\r
475\r
476 Hob->BaseAddress = BaseAddress;\r
477 Hob->Length = Length;\r
478 CopyGuid (&Hob->FvName, FvName);\r
479 CopyGuid (&Hob->FileName, FileName);\r
480}\r
481\r
482/**\r
483 Builds a EFI_HOB_TYPE_FV3 HOB.\r
484\r
485 This function builds a EFI_HOB_TYPE_FV3 HOB.\r
486 It can only be invoked during PEI phase;\r
487 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
488\r
489 If there is no additional space for HOB creation, then ASSERT().\r
490\r
491 @param BaseAddress The base address of the Firmware Volume.\r
492 @param Length The size of the Firmware Volume in bytes.\r
493 @param AuthenticationStatus The authentication status.\r
494 @param ExtractedFv TRUE if the FV was extracted as a file within\r
495 another firmware volume. FALSE otherwise.\r
496 @param FvName The name of the Firmware Volume.\r
497 Valid only if IsExtractedFv is TRUE.\r
498 @param FileName The name of the file.\r
499 Valid only if IsExtractedFv is TRUE.\r
500\r
501**/\r
502VOID\r
503EFIAPI\r
504BuildFv3Hob (\r
e5efcf8b
MK
505 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
506 IN UINT64 Length,\r
507 IN UINT32 AuthenticationStatus,\r
508 IN BOOLEAN ExtractedFv,\r
509 IN CONST EFI_GUID *FvName OPTIONAL,\r
510 IN CONST EFI_GUID *FileName OPTIONAL\r
7c4ab1c2
GD
511 )\r
512{\r
513 EFI_HOB_FIRMWARE_VOLUME3 *Hob;\r
514\r
515 Hob = CreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3));\r
516\r
517 Hob->BaseAddress = BaseAddress;\r
518 Hob->Length = Length;\r
519 Hob->AuthenticationStatus = AuthenticationStatus;\r
520 Hob->ExtractedFv = ExtractedFv;\r
521 if (ExtractedFv) {\r
522 CopyGuid (&Hob->FvName, FvName);\r
523 CopyGuid (&Hob->FileName, FileName);\r
524 }\r
525}\r
526\r
7c4ab1c2
GD
527/**\r
528 Builds a HOB for the CPU.\r
529\r
530 This function builds a HOB for the CPU.\r
531 It can only be invoked during PEI phase;\r
532 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
533 If there is no additional space for HOB creation, then ASSERT().\r
534\r
535 @param SizeOfMemorySpace The maximum physical memory addressability of the processor.\r
536 @param SizeOfIoSpace The maximum physical I/O addressability of the processor.\r
537\r
538**/\r
539VOID\r
540EFIAPI\r
541BuildCpuHob (\r
e5efcf8b
MK
542 IN UINT8 SizeOfMemorySpace,\r
543 IN UINT8 SizeOfIoSpace\r
7c4ab1c2
GD
544 )\r
545{\r
546 EFI_HOB_CPU *Hob;\r
547\r
548 Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));\r
549\r
550 Hob->SizeOfMemorySpace = SizeOfMemorySpace;\r
551 Hob->SizeOfIoSpace = SizeOfIoSpace;\r
552\r
553 //\r
554 // Zero the reserved space to match HOB spec\r
555 //\r
556 ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));\r
557}\r
558\r
7c4ab1c2
GD
559/**\r
560 Builds a HOB for the Stack.\r
561\r
562 This function builds a HOB for the stack.\r
563 It can only be invoked during PEI phase;\r
564 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
565 If there is no additional space for HOB creation, then ASSERT().\r
566\r
567 @param BaseAddress The 64 bit physical address of the Stack.\r
568 @param Length The length of the stack in bytes.\r
569\r
570**/\r
571VOID\r
572EFIAPI\r
573BuildStackHob (\r
e5efcf8b
MK
574 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
575 IN UINT64 Length\r
7c4ab1c2
GD
576 )\r
577{\r
578 EFI_HOB_MEMORY_ALLOCATION_STACK *Hob;\r
579\r
e5efcf8b
MK
580 ASSERT (\r
581 ((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&\r
582 ((Length & (EFI_PAGE_SIZE - 1)) == 0)\r
583 );\r
7c4ab1c2
GD
584\r
585 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));\r
586\r
587 CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);\r
588 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
589 Hob->AllocDescriptor.MemoryLength = Length;\r
590 Hob->AllocDescriptor.MemoryType = EfiBootServicesData;\r
591\r
592 //\r
593 // Zero the reserved space to match HOB spec\r
594 //\r
595 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));\r
596}\r
597\r
7c4ab1c2
GD
598/**\r
599 Update the Stack Hob if the stack has been moved\r
600\r
601 @param BaseAddress The 64 bit physical address of the Stack.\r
602 @param Length The length of the stack in bytes.\r
603\r
604**/\r
605VOID\r
606EFIAPI\r
607UpdateStackHob (\r
e5efcf8b
MK
608 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
609 IN UINT64 Length\r
7c4ab1c2
GD
610 )\r
611{\r
e5efcf8b 612 EFI_PEI_HOB_POINTERS Hob;\r
7c4ab1c2
GD
613\r
614 Hob.Raw = GetHobList ();\r
615 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {\r
616 if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {\r
617 //\r
618 // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type\r
619 // to be reclaimed by DXE core.\r
620 //\r
621 BuildMemoryAllocationHob (\r
622 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,\r
623 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,\r
624 EfiConventionalMemory\r
625 );\r
626 //\r
627 // Update the BSP Stack Hob to reflect the new stack info.\r
628 //\r
629 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
e5efcf8b 630 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;\r
7c4ab1c2
GD
631 break;\r
632 }\r
e5efcf8b 633\r
7c4ab1c2
GD
634 Hob.Raw = GET_NEXT_HOB (Hob);\r
635 }\r
636}\r
637\r
7c4ab1c2
GD
638/**\r
639 Builds a HOB for the memory allocation.\r
640\r
641 This function builds a HOB for the memory allocation.\r
642 It can only be invoked during PEI phase;\r
643 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
644 If there is no additional space for HOB creation, then ASSERT().\r
645\r
646 @param BaseAddress The 64 bit physical address of the memory.\r
647 @param Length The length of the memory allocation in bytes.\r
648 @param MemoryType Type of memory allocated by this HOB.\r
649\r
650**/\r
651VOID\r
652EFIAPI\r
653BuildMemoryAllocationHob (\r
e5efcf8b
MK
654 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
655 IN UINT64 Length,\r
656 IN EFI_MEMORY_TYPE MemoryType\r
7c4ab1c2
GD
657 )\r
658{\r
659 EFI_HOB_MEMORY_ALLOCATION *Hob;\r
660\r
e5efcf8b
MK
661 ASSERT (\r
662 ((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&\r
663 ((Length & (EFI_PAGE_SIZE - 1)) == 0)\r
664 );\r
7c4ab1c2
GD
665\r
666 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));\r
667\r
668 ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));\r
669 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
670 Hob->AllocDescriptor.MemoryLength = Length;\r
671 Hob->AllocDescriptor.MemoryType = MemoryType;\r
672 //\r
673 // Zero the reserved space to match HOB spec\r
674 //\r
675 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));\r
676}\r