TianoCore EDK2 master
Loading...
Searching...
No Matches
MmFoundationHob.c
Go to the documentation of this file.
1
10#include <Guid/MpInformation2.h>
11#include <Guid/AcpiS3Context.h>
12#include <Guid/MmAcpiS3Enable.h>
14#include <Guid/MmProfileData.h>
18
19typedef struct {
21 UINT64 Length;
23
35VOID *
37 IN VOID *Hob,
38 IN UINT16 HobType,
39 IN UINT16 HobLength
40 )
41{
42 //
43 // Check Length to avoid data overflow.
44 //
45 ASSERT (HobLength < MAX_UINT16 - 0x7);
46
47 HobLength = (UINT16)ALIGN_VALUE (HobLength, 8);
48
49 ((EFI_HOB_GENERIC_HEADER *)Hob)->HobType = HobType;
50 ((EFI_HOB_GENERIC_HEADER *)Hob)->HobLength = HobLength;
51 ((EFI_HOB_GENERIC_HEADER *)Hob)->Reserved = 0;
52
53 return Hob;
54}
55
70VOID
73 IN EFI_RESOURCE_TYPE ResourceType,
74 IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
75 IN EFI_PHYSICAL_ADDRESS PhysicalStart,
76 IN UINT64 NumberOfBytes,
77 IN EFI_GUID *Owner
78 )
79{
80 ASSERT (Hob != NULL);
81 MmIplCreateHob (Hob, EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
82
83 Hob->ResourceType = EFI_RESOURCE_SYSTEM_MEMORY;
84 Hob->ResourceAttribute = ResourceAttribute;
85 Hob->PhysicalStart = PhysicalStart;
86 Hob->ResourceLength = NumberOfBytes;
87
88 if (Owner != NULL) {
89 CopyGuid (&Hob->Owner, Owner);
90 } else {
91 ZeroMem (&Hob->Owner, sizeof (EFI_GUID));
92 }
93}
94
109VOID
111 IN UINT8 *Hob,
112 IN OUT UINTN *HobBufferSize,
113 IN EFI_PHYSICAL_ADDRESS BaseAddress,
114 IN UINT64 Length
115 )
116{
118 UINT16 HobLength;
119
120 HobLength = ALIGN_VALUE (sizeof (EFI_HOB_FIRMWARE_VOLUME), 8);
121 if (*HobBufferSize >= HobLength) {
122 ASSERT (Hob != NULL);
123 MmIplCreateHob (Hob, EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
124
125 FvHob = (EFI_HOB_FIRMWARE_VOLUME *)Hob;
126 FvHob->BaseAddress = BaseAddress;
127 FvHob->Length = Length;
128 }
129
130 *HobBufferSize = HobLength;
131}
132
145VOID
147 IN UINT8 *Hob,
148 IN OUT UINTN *HobBufferSize
149 )
150{
151 EFI_HOB_GUID_TYPE *GuidHob;
152 MM_ACPI_S3_ENABLE *MmAcpiS3Enable;
153 UINT16 HobLength;
154
155 HobLength = ALIGN_VALUE (sizeof (EFI_HOB_GUID_TYPE) + sizeof (MM_ACPI_S3_ENABLE), 8);
156 if (*HobBufferSize >= HobLength) {
157 ASSERT (Hob != NULL);
158 MmIplCreateHob (Hob, EFI_HOB_TYPE_GUID_EXTENSION, HobLength);
159
160 GuidHob = (EFI_HOB_GUID_TYPE *)Hob;
161 CopyGuid (&GuidHob->Name, &gMmAcpiS3EnableHobGuid);
162
163 MmAcpiS3Enable = (MM_ACPI_S3_ENABLE *)(GuidHob + 1);
164 MmAcpiS3Enable->AcpiS3Enable = PcdGetBool (PcdAcpiS3Enable);
165 }
166
167 *HobBufferSize = HobLength;
168}
169
182VOID
184 IN UINT8 *Hob,
185 IN OUT UINTN *HobBufferSize
186 )
187{
188 EFI_HOB_GUID_TYPE *GuidHob;
189 MM_CPU_SYNC_CONFIG *MmSyncModeInfoHob;
190 UINT16 HobLength;
191
192 GuidHob = (EFI_HOB_GUID_TYPE *)(UINTN)Hob;
193
194 HobLength = ALIGN_VALUE (sizeof (EFI_HOB_GUID_TYPE) + sizeof (MM_CPU_SYNC_CONFIG), 8);
195 if (*HobBufferSize >= HobLength) {
196 ASSERT (Hob != NULL);
197 MmIplCreateHob (GuidHob, EFI_HOB_TYPE_GUID_EXTENSION, HobLength);
198
199 CopyGuid (&GuidHob->Name, &gMmCpuSyncConfigHobGuid);
200
201 MmSyncModeInfoHob = (MM_CPU_SYNC_CONFIG *)(UINTN)(GuidHob + 1);
202 MmSyncModeInfoHob->RelaxedApMode = (BOOLEAN)(PcdGet8 (PcdCpuSmmSyncMode) == MmCpuSyncModeRelaxedAp);
203 MmSyncModeInfoHob->Timeout = PcdGet64 (PcdCpuSmmApSyncTimeout);
204 MmSyncModeInfoHob->Timeout2 = PcdGet64 (PcdCpuSmmApSyncTimeout2);
205 }
206
207 *HobBufferSize = HobLength;
208}
209
223VOID
225 IN UINT8 *HobBuffer,
226 IN OUT UINTN *HobBufferSize,
227 IN EFI_GUID *Guid,
228 IN BOOLEAN MultiInstances
229 )
230{
231 EFI_HOB_GENERIC_HEADER *GuidHob;
232 UINTN UsedSize;
233
234 UsedSize = 0;
235 GuidHob = GetFirstGuidHob (Guid);
236 ASSERT (GuidHob != NULL);
237
238 while (GuidHob != NULL) {
239 if (*HobBufferSize >= UsedSize + GuidHob->HobLength) {
240 ASSERT (HobBuffer != NULL);
241 CopyMem (HobBuffer + UsedSize, GuidHob, GuidHob->HobLength);
242 }
243
244 UsedSize += GuidHob->HobLength;
245
246 if (!MultiInstances) {
247 break;
248 }
249
250 GuidHob = GetNextGuidHob (Guid, GET_NEXT_HOB (GuidHob));
251 }
252
253 *HobBufferSize = UsedSize;
254}
255
273VOID
275 IN UINT8 *Hob,
276 IN OUT UINTN *HobBufferSize,
277 IN CONST EFI_GUID *ModuleName,
279 IN UINT64 Length,
280 IN EFI_PHYSICAL_ADDRESS EntryPoint
281 )
282{
283 UINT16 HobLength;
284 EFI_HOB_MEMORY_ALLOCATION_MODULE *MmCoreModuleHob;
285
286 ASSERT (ADDRESS_IS_ALIGNED (Base, EFI_PAGE_SIZE));
287 ASSERT (IS_ALIGNED (Length, EFI_PAGE_SIZE));
288 ASSERT (EntryPoint >= Base && EntryPoint < Base + Length);
289
290 HobLength = ALIGN_VALUE (sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE), 8);
291 if (*HobBufferSize >= HobLength) {
292 ASSERT (Hob != NULL);
293 MmIplCreateHob (Hob, EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
294
295 MmCoreModuleHob = (EFI_HOB_MEMORY_ALLOCATION_MODULE *)Hob;
296 CopyGuid (&MmCoreModuleHob->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid);
297 MmCoreModuleHob->MemoryAllocationHeader.MemoryBaseAddress = Base;
298 MmCoreModuleHob->MemoryAllocationHeader.MemoryLength = Length;
300 ZeroMem (MmCoreModuleHob->MemoryAllocationHeader.Reserved, sizeof (MmCoreModuleHob->MemoryAllocationHeader.Reserved));
301
302 CopyGuid (&MmCoreModuleHob->ModuleName, ModuleName);
303 MmCoreModuleHob->EntryPoint = EntryPoint;
304 }
305
306 *HobBufferSize = HobLength;
307}
308
320 VOID
321 )
322{
324 UINTN TotalSize;
325 VOID *Alloc;
326
327 TotalSize = PcdGet32 (PcdCpuSmmProfileSize);
328 Alloc = AllocateReservedPages (EFI_SIZE_TO_PAGES (TotalSize));
329 if (Alloc == NULL) {
330 return NULL;
331 }
332
333 ZeroMem (Alloc, TotalSize);
334
335 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
336 while (Hob.Raw != NULL) {
337 if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)Alloc) {
338 //
339 // Find the HOB just created and change the Name to gMmProfileDataHobGuid in PEI HOB list
340 //
341 CopyGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gMmProfileDataHobGuid);
342 return Hob.MemoryAllocation;
343 }
344
345 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob));
346 }
347
348 return NULL;
349}
350
362VOID
364 IN UINT8 *HobBuffer,
365 IN OUT UINTN *HobBufferSize
366 )
367{
369 UINTN HobLength;
370
371 Hob.MemoryAllocation = NULL;
372 HobLength = ALIGN_VALUE (sizeof (EFI_HOB_MEMORY_ALLOCATION), 8) + ALIGN_VALUE (sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), 8);
373
374 if (*HobBufferSize >= HobLength) {
375 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
376 while (Hob.Raw != NULL) {
377 if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gMmProfileDataHobGuid)) {
378 break;
379 }
380
381 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob));
382 }
383
384 ASSERT (Hob.MemoryAllocation != NULL);
385
386 //
387 // Build memory allocation HOB
388 //
389 ASSERT (Hob.MemoryAllocation->Header.HobLength == ALIGN_VALUE (sizeof (EFI_HOB_MEMORY_ALLOCATION), 8));
390 ASSERT (HobBuffer != NULL);
391 CopyMem (HobBuffer, Hob.Raw, Hob.MemoryAllocation->Header.HobLength);
392
393 //
394 // Build resource HOB
395 //
397 (EFI_HOB_RESOURCE_DESCRIPTOR *)(HobBuffer + Hob.MemoryAllocation->Header.HobLength),
398 EFI_RESOURCE_SYSTEM_MEMORY,
399 0,
400 Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress,
401 Hob.MemoryAllocation->AllocDescriptor.MemoryLength,
402 &gMmProfileDataHobGuid
403 );
404 }
405
406 *HobBufferSize = HobLength;
407}
408
419VOID
421 IN UINT8 *HobBuffer,
422 IN OUT UINTN *HobBufferSize
423 )
424{
425 MM_UNBLOCK_REGION *UnblockRegion;
426 EFI_HOB_GENERIC_HEADER *GuidHob;
427 UINTN UsedSize;
428
429 UsedSize = 0;
430
431 GuidHob = GetFirstGuidHob (&gMmUnblockRegionHobGuid);
432 while (GuidHob != NULL) {
433 if (*HobBufferSize >= UsedSize + sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {
434 UnblockRegion = GET_GUID_HOB_DATA (GuidHob);
436 (EFI_HOB_RESOURCE_DESCRIPTOR *)(HobBuffer + UsedSize),
437 EFI_RESOURCE_SYSTEM_MEMORY,
438 0,
439 UnblockRegion->PhysicalStart,
440 EFI_PAGES_TO_SIZE (UnblockRegion->NumberOfPages),
441 &UnblockRegion->IdentifierGuid
442 );
443 }
444
445 UsedSize += sizeof (EFI_HOB_RESOURCE_DESCRIPTOR);
446 GuidHob = GetNextGuidHob (&gMmUnblockRegionHobGuid, GET_NEXT_HOB (GuidHob));
447 }
448
449 *HobBufferSize = UsedSize;
450}
451
458VOID
460 IN OUT MM_IPL_MEMORY_REGION *MemoryRegion,
461 IN OUT UINTN *MemoryRegionCount
462 )
463{
464 UINTN Index;
465 EFI_HOB_GENERIC_HEADER *GuidHob;
466 MM_UNBLOCK_REGION *UnblockRegion;
467
468 ASSERT (MemoryRegionCount != NULL);
469 ASSERT (*MemoryRegionCount == 0 || MemoryRegion != NULL);
470
471 Index = 0;
472 //
473 // Collect unblock memory ranges
474 //
475 GuidHob = GetFirstGuidHob (&gMmUnblockRegionHobGuid);
476 while (GuidHob != NULL) {
477 if (Index < *MemoryRegionCount) {
478 UnblockRegion = GET_GUID_HOB_DATA (GuidHob);
479 MemoryRegion[Index].Base = UnblockRegion->PhysicalStart;
480 MemoryRegion[Index].Length = EFI_PAGES_TO_SIZE (UnblockRegion->NumberOfPages);
481 }
482
483 Index++;
484 GuidHob = GetNextGuidHob (&gMmUnblockRegionHobGuid, GET_NEXT_HOB (GuidHob));
485 }
486
487 *MemoryRegionCount = Index;
488}
489
498VOID
500 IN UINT8 *PlatformHobList,
501 IN UINTN PlatformHobSize,
502 IN OUT MM_IPL_MEMORY_REGION *MemoryRegion,
503 IN OUT UINTN *MemoryRegionCount
504 )
505{
506 UINTN Index;
508
509 ASSERT (MemoryRegionCount != NULL);
510 ASSERT (*MemoryRegionCount == 0 || MemoryRegion != NULL);
511
512 Index = 0;
513 //
514 // Get the HOB list for processing
515 //
516 Hob.Raw = PlatformHobList;
517
518 //
519 // Collect memory ranges
520 //
521 while (Hob.Raw < PlatformHobList + PlatformHobSize) {
522 if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
523 if ( (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_MAPPED_IO)
524 || (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)
525 || (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_FIRMWARE_DEVICE)
526 || (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED))
527 {
528 if (Index < *MemoryRegionCount) {
529 MemoryRegion[Index].Base = Hob.ResourceDescriptor->PhysicalStart;
530 MemoryRegion[Index].Length = Hob.ResourceDescriptor->ResourceLength;
531 }
532
533 Index++;
534 }
535 }
536
537 Hob.Raw = GET_NEXT_HOB (Hob);
538 }
539
540 *MemoryRegionCount = Index;
541}
542
553INTN
554EFIAPI
556 IN CONST VOID *Buffer1,
557 IN CONST VOID *Buffer2
558 )
559{
560 if (((MM_IPL_MEMORY_REGION *)Buffer1)->Base > ((MM_IPL_MEMORY_REGION *)Buffer2)->Base) {
561 return 1;
562 } else if (((MM_IPL_MEMORY_REGION *)Buffer1)->Base < ((MM_IPL_MEMORY_REGION *)Buffer2)->Base) {
563 return -1;
564 }
565
566 return 0;
567}
568
578BOOLEAN
580 VOID
581 )
582{
583 CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
585 UINT32 MaxExtendedFunctionId;
586
587 AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunctionId, NULL, NULL, NULL);
588 if (MaxExtendedFunctionId >= CPUID_VIR_PHY_ADDRESS_SIZE) {
589 AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL);
590 } else {
591 VirPhyAddressSize.Bits.PhysicalAddressBits = 36;
592 }
593
594 AsmCpuidEx (
597 NULL,
598 NULL,
599 &ExtFeatureEcx.Uint32,
600 NULL
601 );
602
603 if ((VirPhyAddressSize.Bits.PhysicalAddressBits > 4 * 9 + 12) &&
604 (ExtFeatureEcx.Bits.FiveLevelPage == 1))
605 {
606 return TRUE;
607 } else {
608 return FALSE;
609 }
610}
611
617UINT8
619 VOID
620 )
621{
622 UINT32 RegEax;
623 UINT8 PhysicalAddressBits;
624 VOID *Hob;
625
626 //
627 // Get physical address bits supported.
628 //
629 Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
630 if (Hob != NULL) {
631 PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;
632 } else {
633 AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
634 if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
635 AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);
636 PhysicalAddressBits = (UINT8)RegEax;
637 } else {
638 PhysicalAddressBits = 36;
639 }
640 }
641
642 //
643 // 4-level paging supports translating 48-bit linear addresses to 52-bit physical addresses.
644 // Since linear addresses are sign-extended, the linear-address space of 4-level paging is:
645 // [0, 2^47-1] and [0xffff8000_00000000, 0xffffffff_ffffffff].
646 // So only [0, 2^47-1] linear-address range maps to the identical physical-address range when
647 // 5-Level paging is disabled.
648 //
649 ASSERT (PhysicalAddressBits <= 52);
650 if (!MmIplIs5LevelPagingNeeded () && (PhysicalAddressBits > 47)) {
651 PhysicalAddressBits = 47;
652 }
653
654 return PhysicalAddressBits;
655}
656
669VOID
671 IN UINT8 *HobBuffer,
672 IN OUT UINTN *HobBufferSize,
673 IN VOID *PlatformHobList,
674 IN UINTN PlatformHobSize,
676 IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob
677 )
678{
679 UINTN Index;
680 UINTN Count;
681 UINTN PlatformRegionCount;
682 UINTN UsedSize;
683 UINT64 PreviousAddress;
684 UINT64 MaxAddress;
685 MM_IPL_MEMORY_REGION *MemoryRegions;
686 MM_IPL_MEMORY_REGION SortBuffer;
687 UINTN UnblockRegionCount;
688
690
691 //
692 // Get the count of platform memory regions
693 //
694 PlatformRegionCount = 0;
695 if ((PlatformHobList != NULL) && (PlatformHobSize != 0)) {
696 CollectPlatformMemoryRegions (PlatformHobList, PlatformHobSize, NULL, &PlatformRegionCount);
697 }
698
699 //
700 // Get the count of platform memory regions
701 //
702 UnblockRegionCount = 0;
703 CollectUnblockMemoryRegions (NULL, &UnblockRegionCount);
704
705 //
706 // Allocate buffer for platform memory regions, unblock memory regions,
707 // MM Profile data, MMRam ranges, an extra terminator.
708 //
709 Count = PlatformRegionCount + UnblockRegionCount + Block->NumberOfMmReservedRegions + ((MmProfileDataHob != NULL) ? 1 : 0) + 1;
710 MemoryRegions = AllocatePages (EFI_SIZE_TO_PAGES (Count * sizeof (*MemoryRegions)));
711 ASSERT (MemoryRegions != NULL);
712 if (MemoryRegions == NULL) {
713 DEBUG ((DEBUG_ERROR, "%a:%d - No enough memory\n", __func__, __LINE__));
714 CpuDeadLoop ();
715 return;
716 }
717
718 //
719 // The very last region is the terminator
720 //
721 MemoryRegions[Count - 1].Base = MaxAddress;
722 MemoryRegions[Count - 1].Length = 0;
723
724 //
725 // Collect platform memory regions
726 //
727 if (PlatformRegionCount != 0) {
728 CollectPlatformMemoryRegions (PlatformHobList, PlatformHobSize, MemoryRegions, &PlatformRegionCount);
729 }
730
731 //
732 // Collect unblock memory regions
733 //
734 if (UnblockRegionCount != 0) {
735 CollectUnblockMemoryRegions (&MemoryRegions[PlatformRegionCount], &UnblockRegionCount);
736 }
737
738 //
739 // Collect SMRAM regions
740 //
741 for (Index = 0; Index < Block->NumberOfMmReservedRegions; Index++) {
742 MemoryRegions[PlatformRegionCount + UnblockRegionCount + Index].Base = Block->Descriptor[Index].CpuStart;
743 MemoryRegions[PlatformRegionCount + UnblockRegionCount + Index].Length = Block->Descriptor[Index].PhysicalSize;
744 }
745
746 //
747 // Collect MM profile database region
748 //
749 if (MmProfileDataHob != NULL) {
750 MemoryRegions[PlatformRegionCount + UnblockRegionCount + Block->NumberOfMmReservedRegions].Base = MmProfileDataHob->AllocDescriptor.MemoryBaseAddress;
751 MemoryRegions[PlatformRegionCount + UnblockRegionCount + Block->NumberOfMmReservedRegions].Length = MmProfileDataHob->AllocDescriptor.MemoryLength;
752 }
753
754 //
755 // Build system memory resource HOBs excluding platform memory regions, SMRAM regions, MmProfile database, Unblocked memory regions.
756 //
757 QuickSort (MemoryRegions, Count, sizeof (*MemoryRegions), MemoryRegionBaseAddressCompare, &SortBuffer);
758 UsedSize = 0;
759 PreviousAddress = 0;
760 for (Index = 0; Index < Count; Index++) {
761 ASSERT (MaxAddress >= MemoryRegions[Index].Base + MemoryRegions[Index].Length);
762
763 if (MemoryRegions[Index].Base > PreviousAddress) {
764 if (*HobBufferSize >= UsedSize + sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {
766 (EFI_HOB_RESOURCE_DESCRIPTOR *)(HobBuffer + UsedSize),
767 EFI_RESOURCE_SYSTEM_MEMORY,
768 FeaturePcdGet (PcdCpuSmmProfileEnable) ? MM_RESOURCE_ATTRIBUTE_LOGGING : 0,
769 PreviousAddress,
770 MemoryRegions[Index].Base - PreviousAddress,
771 &gEfiCallerIdGuid
772 );
773 }
774
775 UsedSize += sizeof (EFI_HOB_RESOURCE_DESCRIPTOR);
776 }
777
778 PreviousAddress = MemoryRegions[Index].Base + MemoryRegions[Index].Length;
779 }
780
781 *HobBufferSize = UsedSize;
782 FreePages (MemoryRegions, EFI_SIZE_TO_PAGES (Count * sizeof (EFI_MEMORY_DESCRIPTOR)));
783}
784
793UINTN
795 IN UINTN TotalHobSize,
796 IN UINTN UsedSize
797 )
798{
799 if (TotalHobSize > UsedSize) {
800 return TotalHobSize - UsedSize;
801 } else {
802 return 0;
803 }
804}
805
833RETURN_STATUS
835 IN UINT8 *FoundationHobList,
836 IN OUT UINTN *FoundationHobSize,
837 IN UINT8 *PlatformHobList,
838 IN UINTN PlatformHobSize,
839 IN EFI_PHYSICAL_ADDRESS MmFvBase,
840 IN UINT64 MmFvSize,
841 IN EFI_GUID *MmCoreFileName,
842 IN EFI_PHYSICAL_ADDRESS MmCoreImageAddress,
843 IN UINT64 MmCoreImageSize,
844 IN EFI_PHYSICAL_ADDRESS MmCoreEntryPoint,
845 IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob,
847 )
848{
849 UINTN UsedSize;
850 RETURN_STATUS Status;
851 UINTN HobLength;
852
853 ASSERT (FoundationHobSize != NULL);
854
855 ASSERT (
856 ((*FoundationHobSize != 0) && (FoundationHobList != NULL)) ||
857 ((*FoundationHobSize == 0) && (FoundationHobList == NULL))
858 );
859
860 if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
861 //
862 // When SmmProfile is enabled, all DRAM is accessible from SMM drivers' perspective.
863 // However, underline Cpu SMM driver does not map the DRAM so that every access to it triggers #PF.
864 // #PF handler records the access then sets up the mapping in the page table to allow the temporary access by current instruction.
865 // The mapping is revoked before next instruction runs.
866 //
867 ASSERT (!PcdGetBool (PcdCpuSmmRestrictedMemoryAccess));
868 }
869
870 UsedSize = 0;
871
872 //
873 // Build communication buffer HOB in MM HOB list
874 //
875 HobLength = *FoundationHobSize;
876 MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gMmCommBufferHobGuid, FALSE);
877 UsedSize += HobLength;
878
879 //
880 // Build MmCore module HOB in MM HOB list
881 //
882 HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
884 FoundationHobList + UsedSize,
885 &HobLength,
886 MmCoreFileName,
887 MmCoreImageAddress,
888 MmCoreImageSize,
889 MmCoreEntryPoint
890 );
891
892 UsedSize += HobLength;
893
894 //
895 // BFV address for StandaloneMm Core
896 //
897 HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
898 MmIplBuildFvHob (FoundationHobList + UsedSize, &HobLength, MmFvBase, MmFvSize);
899 UsedSize += HobLength;
900
901 //
902 // Build MM ACPI S3 Enable HOB
903 //
904 HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
905 MmIplBuildMmAcpiS3EnableHob (FoundationHobList + UsedSize, &HobLength);
906 UsedSize += HobLength;
907
908 //
909 // Build MM CPU sync configuration HOB
910 //
911 HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
912 MmIplBuildMmCpuSyncConfigHob (FoundationHobList + UsedSize, &HobLength);
913 UsedSize += HobLength;
914
915 //
916 // Build CPU SMM base HOB in MM HOB list
917 //
918 HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
919 MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gSmmBaseHobGuid, TRUE);
920 UsedSize += HobLength;
921
922 //
923 // Build SMRAM memory Hob in MM HOB list
924 //
925 HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
926 MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gEfiSmmSmramMemoryGuid, FALSE);
927 UsedSize += HobLength;
928
929 //
930 // Build Mp Information2 Hob in MM HOB list
931 //
932 HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
933 MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gMpInformation2HobGuid, TRUE);
934 UsedSize += HobLength;
935
936 //
937 // Build ACPI variable HOB
938 //
939 HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
940 MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gEfiAcpiVariableGuid, FALSE);
941 UsedSize += HobLength;
942
943 if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
944 //
945 // Build memory allocation and resource HOB for MM profile data
946 //
947 HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
948 MmIplBuildMmProfileHobs (FoundationHobList + UsedSize, &HobLength);
949 UsedSize += HobLength;
950 }
951
952 //
953 // Build resource HOB for unblocked region
954 //
955 HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
956 MmIplBuildResourceHobForUnblockedRegion (FoundationHobList + UsedSize, &HobLength);
957 UsedSize += HobLength;
958
959 if (!PcdGetBool (PcdCpuSmmRestrictedMemoryAccess)) {
960 //
961 // All system memory (DRAM) is accessible.
962 // When SMM Profile is enabled:
963 // * Access to regions included all Mmram ranges, MM Profile data, Unblock memory ranges and MMIO ranges do not require logging.
964 // * Access to other system memory requires logging.
965 //
966 HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
968 FoundationHobList + UsedSize,
969 &HobLength,
970 PlatformHobList,
971 PlatformHobSize,
972 Block,
973 MmProfileDataHob
974 );
975 UsedSize += HobLength;
976 }
977
978 if (*FoundationHobSize < UsedSize) {
980 } else {
981 Status = RETURN_SUCCESS;
982 }
983
984 *FoundationHobSize = UsedSize;
985 return Status;
986}
UINT64 UINTN
INT64 INTN
VOID *EFIAPI GetFirstHob(IN UINT16 Type)
Definition: HobLib.c:142
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
Definition: HobLib.c:103
VOID *EFIAPI GetNextGuidHob(IN CONST EFI_GUID *Guid, IN CONST VOID *HobStart)
Definition: HobLib.c:176
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
VOID EFIAPI QuickSort(IN OUT VOID *BufferToSort, IN CONST UINTN Count, IN CONST UINTN ElementSize, IN BASE_SORT_COMPARE CompareFunction, OUT VOID *BufferOneElement)
Definition: QuickSort.c:36
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT32 EFIAPI AsmCpuidEx(IN UINT32 Index, IN UINT32 SubIndex, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
Definition: CpuIdEx.c:43
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID *EFIAPI AllocateReservedPages(IN UINTN Pages)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define RETURN_BUFFER_TOO_SMALL
Definition: Base.h:1093
#define ADDRESS_IS_ALIGNED(Address, Alignment)
Definition: Base.h:923
#define IS_ALIGNED(Value, Alignment)
Definition: Base.h:912
#define ALIGN_VALUE(Value, Alignment)
Definition: Base.h:948
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS
Definition: Cpuid.h:1301
#define CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO
Definition: Cpuid.h:1306
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
Definition: CpuId.c:36
VOID * MmIplCreateHob(IN VOID *Hob, IN UINT16 HobType, IN UINT16 HobLength)
VOID MmIplBuildMmCoreModuleHob(IN UINT8 *Hob, IN OUT UINTN *HobBufferSize, IN CONST EFI_GUID *ModuleName, IN EFI_PHYSICAL_ADDRESS Base, IN UINT64 Length, IN EFI_PHYSICAL_ADDRESS EntryPoint)
VOID MmIplCopyGuidHob(IN UINT8 *HobBuffer, IN OUT UINTN *HobBufferSize, IN EFI_GUID *Guid, IN BOOLEAN MultiInstances)
VOID MmIplBuildMmProfileHobs(IN UINT8 *HobBuffer, IN OUT UINTN *HobBufferSize)
INTN EFIAPI MemoryRegionBaseAddressCompare(IN CONST VOID *Buffer1, IN CONST VOID *Buffer2)
VOID CollectPlatformMemoryRegions(IN UINT8 *PlatformHobList, IN UINTN PlatformHobSize, IN OUT MM_IPL_MEMORY_REGION *MemoryRegion, IN OUT UINTN *MemoryRegionCount)
VOID MmIplBuildResourceHobForUnblockedRegion(IN UINT8 *HobBuffer, IN OUT UINTN *HobBufferSize)
VOID MmIplBuildResourceHobForAllSystemMemory(IN UINT8 *HobBuffer, IN OUT UINTN *HobBufferSize, IN VOID *PlatformHobList, IN UINTN PlatformHobSize, IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block, IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob)
BOOLEAN MmIplIs5LevelPagingNeeded(VOID)
VOID MmIplBuildMmCpuSyncConfigHob(IN UINT8 *Hob, IN OUT UINTN *HobBufferSize)
VOID MmIplBuildMmAcpiS3EnableHob(IN UINT8 *Hob, IN OUT UINTN *HobBufferSize)
UINTN GetRemainingHobSize(IN UINTN TotalHobSize, IN UINTN UsedSize)
VOID MmIplBuildFvHob(IN UINT8 *Hob, IN OUT UINTN *HobBufferSize, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
VOID MmIplBuildMemoryResourceHob(IN EFI_HOB_RESOURCE_DESCRIPTOR *Hob, IN EFI_RESOURCE_TYPE ResourceType, IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute, IN EFI_PHYSICAL_ADDRESS PhysicalStart, IN UINT64 NumberOfBytes, IN EFI_GUID *Owner)
UINT8 MmIplCalculateMaximumSupportAddress(VOID)
RETURN_STATUS CreateMmFoundationHobList(IN UINT8 *FoundationHobList, IN OUT UINTN *FoundationHobSize, IN UINT8 *PlatformHobList, IN UINTN PlatformHobSize, IN EFI_PHYSICAL_ADDRESS MmFvBase, IN UINT64 MmFvSize, IN EFI_GUID *MmCoreFileName, IN EFI_PHYSICAL_ADDRESS MmCoreImageAddress, IN UINT64 MmCoreImageSize, IN EFI_PHYSICAL_ADDRESS MmCoreEntryPoint, IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob, IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block)
EFI_HOB_MEMORY_ALLOCATION * BuildMmProfileDataHobInPeiHobList(VOID)
VOID CollectUnblockMemoryRegions(IN OUT MM_IPL_MEMORY_REGION *MemoryRegion, IN OUT UINTN *MemoryRegionCount)
#define MM_RESOURCE_ATTRIBUTE_LOGGING
Definition: MmProfileData.h:31
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGet8(TokenName)
Definition: PcdLib.h:336
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
UINT32 EFI_RESOURCE_TYPE
Definition: PiHob.h:223
UINT32 EFI_RESOURCE_ATTRIBUTE_TYPE
Definition: PiHob.h:241
VOID *EFIAPI AllocatePages(IN UINTN Pages)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
@ EfiReservedMemoryType
EFI_PHYSICAL_ADDRESS BaseAddress
Definition: PiHob.h:364
EFI_GUID Name
Definition: PiHob.h:347
EFI_PHYSICAL_ADDRESS MemoryBaseAddress
Definition: PiHob.h:119
EFI_MEMORY_TYPE MemoryType
Definition: PiHob.h:131
EFI_PHYSICAL_ADDRESS EntryPoint
Definition: PiHob.h:217
EFI_HOB_MEMORY_ALLOCATION_HEADER MemoryAllocationHeader
Definition: PiHob.h:207
EFI_HOB_GENERIC_HEADER Header
Definition: PiHob.h:148
EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor
Definition: PiHob.h:153
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: PiHob.h:328
EFI_RESOURCE_TYPE ResourceType
Definition: PiHob.h:320
Definition: Base.h:213
MM_CPU_SYNC_MODE RelaxedApMode
EFI_PHYSICAL_ADDRESS PhysicalStart
struct CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX::@709 Bits
struct CPUID_VIR_PHY_ADDRESS_SIZE_EAX::@753 Bits