]> git.proxmox.com Git - mirror_edk2.git/blob - StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
cc1a0816647071a545261bf1c30e4e955661cc0f
[mirror_edk2.git] / StandaloneMmPkg / Library / StandaloneMmHobLib / StandaloneMmHobLib.c
1 /** @file
2 HOB Library implementation for Standalone MM Core.
3
4 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>
6 Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
7
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php.
12
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15
16 **/
17
18 #include <PiMm.h>
19
20 #include <Library/HobLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/BaseMemoryLib.h>
23 #include <Library/MmServicesTableLib.h>
24
25 //
26 // Cache copy of HobList pointer.
27 //
28 STATIC VOID *gHobList = NULL;
29
30 /**
31 The constructor function caches the pointer to HOB list.
32
33 The constructor function gets the start address of HOB list from system configuration table.
34 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
35
36 @param ImageHandle The firmware allocated handle for the image.
37 @param MmSystemTable A pointer to the MM System Table.
38
39 @retval EFI_SUCCESS The constructor successfully gets HobList.
40 @retval Other value The constructor can't get HobList.
41
42 **/
43 EFI_STATUS
44 EFIAPI
45 HobLibConstructor (
46 IN EFI_HANDLE ImageHandle,
47 IN EFI_MM_SYSTEM_TABLE *MmSystemTable
48 )
49 {
50 UINTN Index;
51
52 for (Index = 0; Index < gMmst->NumberOfTableEntries; Index++) {
53 if (CompareGuid (&gEfiHobListGuid, &gMmst->MmConfigurationTable[Index].VendorGuid)) {
54 gHobList = gMmst->MmConfigurationTable[Index].VendorTable;
55 break;
56 }
57 }
58 return EFI_SUCCESS;
59 }
60
61 /**
62 Returns the pointer to the HOB list.
63
64 This function returns the pointer to first HOB in the list.
65 If the pointer to the HOB list is NULL, then ASSERT().
66
67 @return The pointer to the HOB list.
68
69 **/
70 VOID *
71 EFIAPI
72 GetHobList (
73 VOID
74 )
75 {
76 UINTN Index;
77
78 if (gHobList == NULL) {
79 for (Index = 0; Index < gMmst->NumberOfTableEntries; Index++) {
80 if (CompareGuid (&gEfiHobListGuid, &gMmst->MmConfigurationTable[Index].VendorGuid)) {
81 gHobList = gMmst->MmConfigurationTable[Index].VendorTable;
82 break;
83 }
84 }
85 }
86 ASSERT (gHobList != NULL);
87 return gHobList;
88 }
89
90 /**
91 Returns the next instance of a HOB type from the starting HOB.
92
93 This function searches the first instance of a HOB type from the starting HOB pointer.
94 If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
95 In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
96 unconditionally: it returns HobStart back if HobStart itself meets the requirement;
97 caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
98
99 If HobStart is NULL, then ASSERT().
100
101 @param Type The HOB type to return.
102 @param HobStart The starting HOB pointer to search from.
103
104 @return The next instance of a HOB type from the starting HOB.
105
106 **/
107 VOID *
108 EFIAPI
109 GetNextHob (
110 IN UINT16 Type,
111 IN CONST VOID *HobStart
112 )
113 {
114 EFI_PEI_HOB_POINTERS Hob;
115
116 ASSERT (HobStart != NULL);
117
118 Hob.Raw = (UINT8 *) HobStart;
119 //
120 // Parse the HOB list until end of list or matching type is found.
121 //
122 while (!END_OF_HOB_LIST (Hob)) {
123 if (Hob.Header->HobType == Type) {
124 return Hob.Raw;
125 }
126 Hob.Raw = GET_NEXT_HOB (Hob);
127 }
128 return NULL;
129 }
130
131 /**
132 Returns the first instance of a HOB type among the whole HOB list.
133
134 This function searches the first instance of a HOB type among the whole HOB list.
135 If there does not exist such HOB type in the HOB list, it will return NULL.
136
137 If the pointer to the HOB list is NULL, then ASSERT().
138
139 @param Type The HOB type to return.
140
141 @return The next instance of a HOB type from the starting HOB.
142
143 **/
144 VOID *
145 EFIAPI
146 GetFirstHob (
147 IN UINT16 Type
148 )
149 {
150 VOID *HobList;
151
152 HobList = GetHobList ();
153 return GetNextHob (Type, HobList);
154 }
155
156 /**
157 Returns the next instance of the matched GUID HOB from the starting HOB.
158
159 This function searches the first instance of a HOB from the starting HOB pointer.
160 Such HOB should satisfy two conditions:
161 its HOB type is EFI_HOB_TYPE_GUID_EXTENSION, and its GUID Name equals to the input Guid.
162 If such a HOB from the starting HOB pointer does not exist, it will return NULL.
163 Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
164 to extract the data section and its size information, respectively.
165 In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
166 unconditionally: it returns HobStart back if HobStart itself meets the requirement;
167 caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
168
169 If Guid is NULL, then ASSERT().
170 If HobStart is NULL, then ASSERT().
171
172 @param Guid The GUID to match with in the HOB list.
173 @param HobStart A pointer to a Guid.
174
175 @return The next instance of the matched GUID HOB from the starting HOB.
176
177 **/
178 VOID *
179 EFIAPI
180 GetNextGuidHob (
181 IN CONST EFI_GUID *Guid,
182 IN CONST VOID *HobStart
183 )
184 {
185 EFI_PEI_HOB_POINTERS GuidHob;
186
187 GuidHob.Raw = (UINT8 *) HobStart;
188 while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
189 if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
190 break;
191 }
192 GuidHob.Raw = GET_NEXT_HOB (GuidHob);
193 }
194 return GuidHob.Raw;
195 }
196
197 /**
198 Returns the first instance of the matched GUID HOB among the whole HOB list.
199
200 This function searches the first instance of a HOB among the whole HOB list.
201 Such HOB should satisfy two conditions:
202 its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
203 If such a HOB from the starting HOB pointer does not exist, it will return NULL.
204 Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
205 to extract the data section and its size information, respectively.
206
207 If the pointer to the HOB list is NULL, then ASSERT().
208 If Guid is NULL, then ASSERT().
209
210 @param Guid The GUID to match with in the HOB list.
211
212 @return The first instance of the matched GUID HOB among the whole HOB list.
213
214 **/
215 VOID *
216 EFIAPI
217 GetFirstGuidHob (
218 IN CONST EFI_GUID *Guid
219 )
220 {
221 VOID *HobList;
222
223 HobList = GetHobList ();
224 return GetNextGuidHob (Guid, HobList);
225 }
226
227 /**
228 Get the system boot mode from the HOB list.
229
230 This function returns the system boot mode information from the
231 PHIT HOB in HOB list.
232
233 If the pointer to the HOB list is NULL, then ASSERT().
234
235 @param VOID
236
237 @return The Boot Mode.
238
239 **/
240 EFI_BOOT_MODE
241 EFIAPI
242 GetBootModeHob (
243 VOID
244 )
245 {
246 EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
247
248 HandOffHob = (EFI_HOB_HANDOFF_INFO_TABLE *) GetHobList ();
249
250 return HandOffHob->BootMode;
251 }
252
253 VOID *
254 CreateHob (
255 IN UINT16 HobType,
256 IN UINT16 HobLength
257 )
258 {
259 EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
260 EFI_HOB_GENERIC_HEADER *HobEnd;
261 EFI_PHYSICAL_ADDRESS FreeMemory;
262 VOID *Hob;
263
264 HandOffHob = GetHobList ();
265
266 HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
267
268 FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
269
270 if (FreeMemory < HobLength) {
271 return NULL;
272 }
273
274 Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
275 ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
276 ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
277 ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
278
279 HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
280 HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
281
282 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
283 HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
284 HobEnd->Reserved = 0;
285 HobEnd++;
286 HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
287
288 return Hob;
289 }
290
291 /**
292 Builds a HOB for a loaded PE32 module.
293
294 This function builds a HOB for a loaded PE32 module.
295 If ModuleName is NULL, then ASSERT().
296 If there is no additional space for HOB creation, then ASSERT().
297
298 @param ModuleName The GUID File Name of the module.
299 @param MemoryAllocationModule The 64 bit physical address of the module.
300 @param ModuleLength The length of the module in bytes.
301 @param EntryPoint The 64 bit physical address of the module entry point.
302
303 **/
304 VOID
305 EFIAPI
306 BuildModuleHob (
307 IN CONST EFI_GUID *ModuleName,
308 IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,
309 IN UINT64 ModuleLength,
310 IN EFI_PHYSICAL_ADDRESS EntryPoint
311 )
312 {
313 EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob;
314
315 ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
316 ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
317
318 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
319
320 CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
321 Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
322 Hob->MemoryAllocationHeader.MemoryLength = ModuleLength;
323 Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode;
324
325 //
326 // Zero the reserved space to match HOB spec
327 //
328 ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
329
330 CopyGuid (&Hob->ModuleName, ModuleName);
331 Hob->EntryPoint = EntryPoint;
332 }
333
334 /**
335 Builds a HOB that describes a chunk of system memory.
336
337 This function builds a HOB that describes a chunk of system memory.
338 If there is no additional space for HOB creation, then ASSERT().
339
340 @param ResourceType The type of resource described by this HOB.
341 @param ResourceAttribute The resource attributes of the memory described by this HOB.
342 @param PhysicalStart The 64 bit physical address of memory described by this HOB.
343 @param NumberOfBytes The length of the memory described by this HOB in bytes.
344
345 **/
346 VOID
347 EFIAPI
348 BuildResourceDescriptorHob (
349 IN EFI_RESOURCE_TYPE ResourceType,
350 IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
351 IN EFI_PHYSICAL_ADDRESS PhysicalStart,
352 IN UINT64 NumberOfBytes
353 )
354 {
355 EFI_HOB_RESOURCE_DESCRIPTOR *Hob;
356
357 Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
358 ASSERT(Hob != NULL);
359
360 Hob->ResourceType = ResourceType;
361 Hob->ResourceAttribute = ResourceAttribute;
362 Hob->PhysicalStart = PhysicalStart;
363 Hob->ResourceLength = NumberOfBytes;
364 }
365
366 /**
367 Builds a GUID HOB with a certain data length.
368
369 This function builds a customized HOB tagged with a GUID for identification
370 and returns the start address of GUID HOB data so that caller can fill the customized data.
371 The HOB Header and Name field is already stripped.
372 If Guid is NULL, then ASSERT().
373 If there is no additional space for HOB creation, then ASSERT().
374 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
375
376 @param Guid The GUID to tag the customized HOB.
377 @param DataLength The size of the data payload for the GUID HOB.
378
379 @return The start address of GUID HOB data.
380
381 **/
382 VOID *
383 EFIAPI
384 BuildGuidHob (
385 IN CONST EFI_GUID *Guid,
386 IN UINTN DataLength
387 )
388 {
389 EFI_HOB_GUID_TYPE *Hob;
390
391 //
392 // Make sure that data length is not too long.
393 //
394 ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
395
396 Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
397 CopyGuid (&Hob->Name, Guid);
398 return Hob + 1;
399 }
400
401
402 /**
403 Copies a data buffer to a newly-built HOB.
404
405 This function builds a customized HOB tagged with a GUID for identification,
406 copies the input data to the HOB data field and returns the start address of the GUID HOB data.
407 The HOB Header and Name field is already stripped.
408 If Guid is NULL, then ASSERT().
409 If Data is NULL and DataLength > 0, then ASSERT().
410 If there is no additional space for HOB creation, then ASSERT().
411 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
412
413 @param Guid The GUID to tag the customized HOB.
414 @param Data The data to be copied into the data field of the GUID HOB.
415 @param DataLength The size of the data payload for the GUID HOB.
416
417 @return The start address of GUID HOB data.
418
419 **/
420 VOID *
421 EFIAPI
422 BuildGuidDataHob (
423 IN CONST EFI_GUID *Guid,
424 IN VOID *Data,
425 IN UINTN DataLength
426 )
427 {
428 VOID *HobData;
429
430 ASSERT (Data != NULL || DataLength == 0);
431
432 HobData = BuildGuidHob (Guid, DataLength);
433
434 return CopyMem (HobData, Data, DataLength);
435 }
436
437 /**
438 Builds a Firmware Volume HOB.
439
440 This function builds a Firmware Volume HOB.
441 If there is no additional space for HOB creation, then ASSERT().
442
443 @param BaseAddress The base address of the Firmware Volume.
444 @param Length The size of the Firmware Volume in bytes.
445
446 **/
447 VOID
448 EFIAPI
449 BuildFvHob (
450 IN EFI_PHYSICAL_ADDRESS BaseAddress,
451 IN UINT64 Length
452 )
453 {
454 EFI_HOB_FIRMWARE_VOLUME *Hob;
455
456 Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
457
458 Hob->BaseAddress = BaseAddress;
459 Hob->Length = Length;
460 }
461
462
463 /**
464 Builds a EFI_HOB_TYPE_FV2 HOB.
465
466 This function builds a EFI_HOB_TYPE_FV2 HOB.
467 If there is no additional space for HOB creation, then ASSERT().
468
469 @param BaseAddress The base address of the Firmware Volume.
470 @param Length The size of the Firmware Volume in bytes.
471 @param FvName The name of the Firmware Volume.
472 @param FileName The name of the file.
473
474 **/
475 VOID
476 EFIAPI
477 BuildFv2Hob (
478 IN EFI_PHYSICAL_ADDRESS BaseAddress,
479 IN UINT64 Length,
480 IN CONST EFI_GUID *FvName,
481 IN CONST EFI_GUID *FileName
482 )
483 {
484 EFI_HOB_FIRMWARE_VOLUME2 *Hob;
485
486 Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
487
488 Hob->BaseAddress = BaseAddress;
489 Hob->Length = Length;
490 CopyGuid (&Hob->FvName, FvName);
491 CopyGuid (&Hob->FileName, FileName);
492 }
493
494
495 /**
496 Builds a HOB for the CPU.
497
498 This function builds a HOB for the CPU.
499 If there is no additional space for HOB creation, then ASSERT().
500
501 @param SizeOfMemorySpace The maximum physical memory addressability of the processor.
502 @param SizeOfIoSpace The maximum physical I/O addressability of the processor.
503
504 **/
505 VOID
506 EFIAPI
507 BuildCpuHob (
508 IN UINT8 SizeOfMemorySpace,
509 IN UINT8 SizeOfIoSpace
510 )
511 {
512 EFI_HOB_CPU *Hob;
513
514 Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
515
516 Hob->SizeOfMemorySpace = SizeOfMemorySpace;
517 Hob->SizeOfIoSpace = SizeOfIoSpace;
518
519 //
520 // Zero the reserved space to match HOB spec
521 //
522 ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
523 }
524
525 /**
526 Builds a HOB for the memory allocation.
527
528 This function builds a HOB for the memory allocation.
529 If there is no additional space for HOB creation, then ASSERT().
530
531 @param BaseAddress The 64 bit physical address of the memory.
532 @param Length The length of the memory allocation in bytes.
533 @param MemoryType Type of memory allocated by this HOB.
534
535 **/
536 VOID
537 EFIAPI
538 BuildMemoryAllocationHob (
539 IN EFI_PHYSICAL_ADDRESS BaseAddress,
540 IN UINT64 Length,
541 IN EFI_MEMORY_TYPE MemoryType
542 )
543 {
544 EFI_HOB_MEMORY_ALLOCATION *Hob;
545
546 ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
547 ((Length & (EFI_PAGE_SIZE - 1)) == 0));
548
549 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
550
551 ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
552 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
553 Hob->AllocDescriptor.MemoryLength = Length;
554 Hob->AllocDescriptor.MemoryType = MemoryType;
555 //
556 // Zero the reserved space to match HOB spec
557 //
558 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
559 }
560
561 /**
562 Builds a HOB that describes a chunk of system memory with Owner GUID.
563
564 This function builds a HOB that describes a chunk of system memory.
565 If there is no additional space for HOB creation, then ASSERT().
566
567 @param ResourceType The type of resource described by this HOB.
568 @param ResourceAttribute The resource attributes of the memory described by this HOB.
569 @param PhysicalStart The 64 bit physical address of memory described by this HOB.
570 @param NumberOfBytes The length of the memory described by this HOB in bytes.
571 @param OwnerGUID GUID for the owner of this resource.
572
573 **/
574 VOID
575 EFIAPI
576 BuildResourceDescriptorWithOwnerHob (
577 IN EFI_RESOURCE_TYPE ResourceType,
578 IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
579 IN EFI_PHYSICAL_ADDRESS PhysicalStart,
580 IN UINT64 NumberOfBytes,
581 IN EFI_GUID *OwnerGUID
582 )
583 {
584 ASSERT (FALSE);
585 }
586
587 /**
588 Builds a Capsule Volume HOB.
589
590 This function builds a Capsule Volume HOB.
591 If the platform does not support Capsule Volume HOBs, then ASSERT().
592 If there is no additional space for HOB creation, then ASSERT().
593
594 @param BaseAddress The base address of the Capsule Volume.
595 @param Length The size of the Capsule Volume in bytes.
596
597 **/
598 VOID
599 EFIAPI
600 BuildCvHob (
601 IN EFI_PHYSICAL_ADDRESS BaseAddress,
602 IN UINT64 Length
603 )
604 {
605 ASSERT (FALSE);
606 }
607
608
609 /**
610 Builds a HOB for the BSP store.
611
612 This function builds a HOB for BSP store.
613 If there is no additional space for HOB creation, then ASSERT().
614
615 @param BaseAddress The 64 bit physical address of the BSP.
616 @param Length The length of the BSP store in bytes.
617 @param MemoryType Type of memory allocated by this HOB.
618
619 **/
620 VOID
621 EFIAPI
622 BuildBspStoreHob (
623 IN EFI_PHYSICAL_ADDRESS BaseAddress,
624 IN UINT64 Length,
625 IN EFI_MEMORY_TYPE MemoryType
626 )
627 {
628 ASSERT (FALSE);
629 }
630
631 /**
632 Builds a HOB for the Stack.
633
634 This function builds a HOB for the stack.
635 If there is no additional space for HOB creation, then ASSERT().
636
637 @param BaseAddress The 64 bit physical address of the Stack.
638 @param Length The length of the stack in bytes.
639
640 **/
641 VOID
642 EFIAPI
643 BuildStackHob (
644 IN EFI_PHYSICAL_ADDRESS BaseAddress,
645 IN UINT64 Length
646 )
647 {
648 ASSERT (FALSE);
649 }