2 Creates HOB during Standalone MM Foundation entry point
5 Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include <Guid/MmramMemoryReserve.h>
14 #include <Guid/MpInformation.h>
16 #include <Library/Arm/StandaloneMmCoreEntryPoint.h>
17 #include <Library/ArmMmuLib.h>
18 #include <Library/ArmSvcLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/HobLib.h>
21 #include <Library/BaseLib.h>
22 #include <Library/BaseMemoryLib.h>
23 #include <Library/SerialPortLib.h>
25 #include <IndustryStandard/ArmStdSmc.h>
27 extern EFI_HOB_HANDOFF_INFO_TABLE
*
29 IN VOID
*EfiMemoryBegin
,
30 IN UINTN EfiMemoryLength
,
31 IN VOID
*EfiFreeMemoryBottom
,
32 IN VOID
*EfiFreeMemoryTop
35 // GUID to identify HOB with whereabouts of communication buffer with Normal
37 extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid
;
39 // GUID to identify HOB where the entry point of the CPU driver will be
40 // populated to allow this entry point driver to invoke it upon receipt of an
42 extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid
;
45 Use the boot information passed by privileged firmware to populate a HOB list
46 suitable for consumption by the MM Core and drivers.
48 @param [in, out] CpuDriverEntryPoint Address of MM CPU driver entrypoint
49 @param [in] PayloadBootInfo Boot information passed by privileged
54 CreateHobListFromBootInfo (
55 IN OUT PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT
*CpuDriverEntryPoint
,
56 IN EFI_SECURE_PARTITION_BOOT_INFO
*PayloadBootInfo
59 EFI_HOB_HANDOFF_INFO_TABLE
*HobStart
;
60 EFI_RESOURCE_ATTRIBUTE_TYPE Attributes
;
64 EFI_MMRAM_HOB_DESCRIPTOR_BLOCK
*MmramRangesHob
;
65 EFI_MMRAM_DESCRIPTOR
*MmramRanges
;
66 EFI_MMRAM_DESCRIPTOR
*NsCommBufMmramRange
;
67 MP_INFORMATION_HOB_DATA
*MpInformationHobData
;
68 EFI_PROCESSOR_INFORMATION
*ProcInfoBuffer
;
69 EFI_SECURE_PARTITION_CPU_INFO
*CpuInfo
;
70 ARM_TF_CPU_DRIVER_EP_DESCRIPTOR
*CpuDriverEntryPointDesc
;
72 // Create a hoblist with a PHIT and EOH
73 HobStart
= HobConstructor (
74 (VOID
*)(UINTN
)PayloadBootInfo
->SpMemBase
,
75 (UINTN
)PayloadBootInfo
->SpMemLimit
- PayloadBootInfo
->SpMemBase
,
76 (VOID
*)(UINTN
)PayloadBootInfo
->SpHeapBase
,
77 (VOID
*)(UINTN
)(PayloadBootInfo
->SpHeapBase
+ PayloadBootInfo
->SpHeapSize
)
80 // Check that the Hoblist starts at the bottom of the Heap
81 ASSERT (HobStart
== (VOID
*)(UINTN
)PayloadBootInfo
->SpHeapBase
);
83 // Build a Boot Firmware Volume HOB
84 BuildFvHob (PayloadBootInfo
->SpImageBase
, PayloadBootInfo
->SpImageSize
);
86 // Build a resource descriptor Hob that describes the available physical
89 EFI_RESOURCE_ATTRIBUTE_PRESENT
|
90 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
91 EFI_RESOURCE_ATTRIBUTE_TESTED
|
92 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
93 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
94 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
95 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
98 BuildResourceDescriptorHob (
99 EFI_RESOURCE_SYSTEM_MEMORY
,
101 (UINTN
)PayloadBootInfo
->SpMemBase
,
102 PayloadBootInfo
->SpMemLimit
- PayloadBootInfo
->SpMemBase
105 // Find the size of the GUIDed HOB with MP information
106 BufferSize
= sizeof (MP_INFORMATION_HOB_DATA
);
107 BufferSize
+= sizeof (EFI_PROCESSOR_INFORMATION
) * PayloadBootInfo
->NumCpus
;
109 // Create a Guided MP information HOB to enable the ARM TF CPU driver to
110 // perform per-cpu allocations.
111 MpInformationHobData
= BuildGuidHob (&gMpInformationHobGuid
, BufferSize
);
113 // Populate the MP information HOB with the topology information passed by
114 // privileged firmware
115 MpInformationHobData
->NumberOfProcessors
= PayloadBootInfo
->NumCpus
;
116 MpInformationHobData
->NumberOfEnabledProcessors
= PayloadBootInfo
->NumCpus
;
117 ProcInfoBuffer
= MpInformationHobData
->ProcessorInfoBuffer
;
118 CpuInfo
= PayloadBootInfo
->CpuInfo
;
120 for (Index
= 0; Index
< PayloadBootInfo
->NumCpus
; Index
++) {
121 ProcInfoBuffer
[Index
].ProcessorId
= CpuInfo
[Index
].Mpidr
;
122 ProcInfoBuffer
[Index
].Location
.Package
= GET_CLUSTER_ID (CpuInfo
[Index
].Mpidr
);
123 ProcInfoBuffer
[Index
].Location
.Core
= GET_CORE_ID (CpuInfo
[Index
].Mpidr
);
124 ProcInfoBuffer
[Index
].Location
.Thread
= GET_CORE_ID (CpuInfo
[Index
].Mpidr
);
126 Flags
= PROCESSOR_ENABLED_BIT
| PROCESSOR_HEALTH_STATUS_BIT
;
127 if (CpuInfo
[Index
].Flags
& CPU_INFO_FLAG_PRIMARY_CPU
) {
128 Flags
|= PROCESSOR_AS_BSP_BIT
;
131 ProcInfoBuffer
[Index
].StatusFlag
= Flags
;
134 // Create a Guided HOB to tell the ARM TF CPU driver the location and length
135 // of the communication buffer shared with the Normal world.
136 NsCommBufMmramRange
= (EFI_MMRAM_DESCRIPTOR
*)BuildGuidHob (
137 &gEfiStandaloneMmNonSecureBufferGuid
,
138 sizeof (EFI_MMRAM_DESCRIPTOR
)
140 NsCommBufMmramRange
->PhysicalStart
= PayloadBootInfo
->SpNsCommBufBase
;
141 NsCommBufMmramRange
->CpuStart
= PayloadBootInfo
->SpNsCommBufBase
;
142 NsCommBufMmramRange
->PhysicalSize
= PayloadBootInfo
->SpNsCommBufSize
;
143 NsCommBufMmramRange
->RegionState
= EFI_CACHEABLE
| EFI_ALLOCATED
;
145 // Create a Guided HOB to enable the ARM TF CPU driver to share its entry
146 // point and populate it with the address of the shared buffer
147 CpuDriverEntryPointDesc
= (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR
*)BuildGuidHob (
148 &gEfiArmTfCpuDriverEpDescriptorGuid
,
149 sizeof (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR
)
152 *CpuDriverEntryPoint
= NULL
;
153 CpuDriverEntryPointDesc
->ArmTfCpuDriverEpPtr
= CpuDriverEntryPoint
;
155 // Find the size of the GUIDed HOB with SRAM ranges
156 BufferSize
= sizeof (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK
);
157 BufferSize
+= PayloadBootInfo
->NumSpMemRegions
* sizeof (EFI_MMRAM_DESCRIPTOR
);
159 // Create a GUIDed HOB with SRAM ranges
160 MmramRangesHob
= BuildGuidHob (&gEfiMmPeiMmramMemoryReserveGuid
, BufferSize
);
162 // Fill up the number of MMRAM memory regions
163 MmramRangesHob
->NumberOfMmReservedRegions
= PayloadBootInfo
->NumSpMemRegions
;
164 // Fill up the MMRAM ranges
165 MmramRanges
= &MmramRangesHob
->Descriptor
[0];
167 // Base and size of memory occupied by the Standalone MM image
168 MmramRanges
[0].PhysicalStart
= PayloadBootInfo
->SpImageBase
;
169 MmramRanges
[0].CpuStart
= PayloadBootInfo
->SpImageBase
;
170 MmramRanges
[0].PhysicalSize
= PayloadBootInfo
->SpImageSize
;
171 MmramRanges
[0].RegionState
= EFI_CACHEABLE
| EFI_ALLOCATED
;
173 // Base and size of buffer shared with privileged Secure world software
174 MmramRanges
[1].PhysicalStart
= PayloadBootInfo
->SpSharedBufBase
;
175 MmramRanges
[1].CpuStart
= PayloadBootInfo
->SpSharedBufBase
;
176 MmramRanges
[1].PhysicalSize
= PayloadBootInfo
->SpPcpuSharedBufSize
* PayloadBootInfo
->NumCpus
;
177 MmramRanges
[1].RegionState
= EFI_CACHEABLE
| EFI_ALLOCATED
;
179 // Base and size of buffer used for synchronous communication with Normal
181 MmramRanges
[2].PhysicalStart
= PayloadBootInfo
->SpNsCommBufBase
;
182 MmramRanges
[2].CpuStart
= PayloadBootInfo
->SpNsCommBufBase
;
183 MmramRanges
[2].PhysicalSize
= PayloadBootInfo
->SpNsCommBufSize
;
184 MmramRanges
[2].RegionState
= EFI_CACHEABLE
| EFI_ALLOCATED
;
186 // Base and size of memory allocated for stacks for all cpus
187 MmramRanges
[3].PhysicalStart
= PayloadBootInfo
->SpStackBase
;
188 MmramRanges
[3].CpuStart
= PayloadBootInfo
->SpStackBase
;
189 MmramRanges
[3].PhysicalSize
= PayloadBootInfo
->SpPcpuStackSize
* PayloadBootInfo
->NumCpus
;
190 MmramRanges
[3].RegionState
= EFI_CACHEABLE
| EFI_ALLOCATED
;
192 // Base and size of heap memory shared by all cpus
193 MmramRanges
[4].PhysicalStart
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)HobStart
;
194 MmramRanges
[4].CpuStart
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)HobStart
;
195 MmramRanges
[4].PhysicalSize
= HobStart
->EfiFreeMemoryBottom
- (EFI_PHYSICAL_ADDRESS
)(UINTN
)HobStart
;
196 MmramRanges
[4].RegionState
= EFI_CACHEABLE
| EFI_ALLOCATED
;
198 // Base and size of heap memory shared by all cpus
199 MmramRanges
[5].PhysicalStart
= HobStart
->EfiFreeMemoryBottom
;
200 MmramRanges
[5].CpuStart
= HobStart
->EfiFreeMemoryBottom
;
201 MmramRanges
[5].PhysicalSize
= HobStart
->EfiFreeMemoryTop
- HobStart
->EfiFreeMemoryBottom
;
202 MmramRanges
[5].RegionState
= EFI_CACHEABLE
;