]> git.proxmox.com Git - mirror_edk2.git/blob - StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.c
d8bfba263ae26b6da683d4297ab41d0142db7547
[mirror_edk2.git] / StandaloneMmPkg / Drivers / StandaloneMmCpu / StandaloneMmCpu.c
1 /** @file
2
3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
4 Copyright (c) 2016 HP Development Company, L.P.
5 Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include <Base.h>
12 #include <Pi/PiMmCis.h>
13 #include <Library/Arm/StandaloneMmCoreEntryPoint.h>
14 #include <Library/DebugLib.h>
15 #include <Library/ArmSvcLib.h>
16 #include <Library/ArmLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/HobLib.h>
19
20 #include <Protocol/DebugSupport.h> // for EFI_SYSTEM_CONTEXT
21
22 #include <Guid/ZeroGuid.h>
23 #include <Guid/MmramMemoryReserve.h>
24
25 #include "StandaloneMmCpu.h"
26
27 // GUID to identify HOB with whereabouts of communication buffer with Normal
28 // World
29 extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;
30
31 // GUID to identify HOB where the entry point of this CPU driver will be
32 // populated to allow the entry point driver to invoke it upon receipt of an
33 // event
34 extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid;
35
36 //
37 // Private copy of the MM system table for future use
38 //
39 EFI_MM_SYSTEM_TABLE *mMmst = NULL;
40
41 //
42 // Globals used to initialize the protocol
43 //
44 STATIC EFI_HANDLE mMmCpuHandle = NULL;
45
46 /** Returns the HOB data for the matching HOB GUID.
47
48 @param [in] HobList Pointer to the HOB list.
49 @param [in] HobGuid The GUID for the HOB.
50 @param [out] HobData Pointer to the HOB data.
51
52 @retval EFI_SUCCESS The function completed successfully.
53 @retval EFI_INVALID_PARAMETER Invalid parameter.
54 @retval EFI_NOT_FOUND Could not find HOB with matching GUID.
55 **/
56 EFI_STATUS
57 GetGuidedHobData (
58 IN VOID *HobList,
59 IN CONST EFI_GUID *HobGuid,
60 OUT VOID **HobData
61 )
62 {
63 EFI_HOB_GUID_TYPE *Hob;
64
65 if ((HobList == NULL) || (HobGuid == NULL) || (HobData == NULL)) {
66 return EFI_INVALID_PARAMETER;
67 }
68
69 Hob = GetNextGuidHob (HobGuid, HobList);
70 if (Hob == NULL) {
71 return EFI_NOT_FOUND;
72 }
73
74 *HobData = GET_GUID_HOB_DATA (Hob);
75 if (*HobData == NULL) {
76 return EFI_NOT_FOUND;
77 }
78
79 return EFI_SUCCESS;
80 }
81
82 /** Entry point for the Standalone MM CPU driver.
83
84 @param [in] ImageHandle Unused. Not actual image handle.
85 @param [in] SystemTable Pointer to MM System table.
86
87 @retval EFI_SUCCESS The function completed successfully.
88 @retval EFI_INVALID_PARAMETER Invalid parameter.
89 @retval EFI_OUT_OF_RESOURCES Out of resources.
90 @retval EFI_NOT_FOUND Failed to find the HOB for the CPU
91 driver endpoint descriptor.
92 **/
93 EFI_STATUS
94 StandaloneMmCpuInitialize (
95 IN EFI_HANDLE ImageHandle, // not actual imagehandle
96 IN EFI_MM_SYSTEM_TABLE *SystemTable // not actual systemtable
97 )
98 {
99 ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;
100 EFI_CONFIGURATION_TABLE *ConfigurationTable;
101 MP_INFORMATION_HOB_DATA *MpInformationHobData;
102 EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;
103 EFI_STATUS Status;
104 EFI_HANDLE DispatchHandle;
105 UINT32 MpInfoSize;
106 UINTN Index;
107 UINTN ArraySize;
108 VOID *HobStart;
109
110 ASSERT (SystemTable != NULL);
111 mMmst = SystemTable;
112
113 // publish the MM config protocol so the MM core can register its entry point
114 Status = mMmst->MmInstallProtocolInterface (
115 &mMmCpuHandle,
116 &gEfiMmConfigurationProtocolGuid,
117 EFI_NATIVE_INTERFACE,
118 &mMmConfig
119 );
120 if (EFI_ERROR (Status)) {
121 return Status;
122 }
123
124 // register the root MMI handler
125 Status = mMmst->MmiHandlerRegister (
126 PiMmCpuTpFwRootMmiHandler,
127 NULL,
128 &DispatchHandle
129 );
130 if (EFI_ERROR (Status)) {
131 return Status;
132 }
133
134 // Retrieve the Hoblist from the MMST to extract the details of the NS
135 // communication buffer that has been reserved by S-EL1/EL3
136 ConfigurationTable = mMmst->MmConfigurationTable;
137 for (Index = 0; Index < mMmst->NumberOfTableEntries; Index++) {
138 if (CompareGuid (&gEfiHobListGuid, &(ConfigurationTable[Index].VendorGuid))) {
139 break;
140 }
141 }
142
143 // Bail out if the Hoblist could not be found
144 if (Index >= mMmst->NumberOfTableEntries) {
145 DEBUG ((DEBUG_ERROR, "Hoblist not found - 0x%x\n", Index));
146 return EFI_OUT_OF_RESOURCES;
147 }
148
149 HobStart = ConfigurationTable[Index].VendorTable;
150
151 //
152 // Locate the HOB with the buffer to populate the entry point of this driver
153 //
154 Status = GetGuidedHobData (
155 HobStart,
156 &gEfiArmTfCpuDriverEpDescriptorGuid,
157 (VOID **)&CpuDriverEntryPointDesc
158 );
159 if (EFI_ERROR (Status)) {
160 DEBUG ((DEBUG_ERROR, "ArmTfCpuDriverEpDesc HOB data extraction failed - 0x%x\n", Status));
161 return Status;
162 }
163
164 // Share the entry point of the CPU driver
165 DEBUG ((
166 DEBUG_INFO,
167 "Sharing Cpu Driver EP *0x%lx = 0x%lx\n",
168 (UINTN)CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr,
169 (UINTN)PiMmStandaloneArmTfCpuDriverEntry
170 ));
171 *(CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr) = PiMmStandaloneArmTfCpuDriverEntry;
172
173 // Find the descriptor that contains the whereabouts of the buffer for
174 // communication with the Normal world.
175 Status = GetGuidedHobData (
176 HobStart,
177 &gEfiStandaloneMmNonSecureBufferGuid,
178 (VOID **)&NsCommBufMmramRange
179 );
180 if (EFI_ERROR (Status)) {
181 DEBUG ((DEBUG_ERROR, "NsCommBufMmramRange HOB data extraction failed - 0x%x\n", Status));
182 return Status;
183 }
184
185 DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalStart - 0x%lx\n", (UINTN)NsCommBufMmramRange->PhysicalStart));
186 DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalSize - 0x%lx\n", (UINTN)NsCommBufMmramRange->PhysicalSize));
187
188 CopyMem (&mNsCommBuffer, NsCommBufMmramRange, sizeof (EFI_MMRAM_DESCRIPTOR));
189 DEBUG ((DEBUG_INFO, "mNsCommBuffer: 0x%016lx - 0x%lx\n", mNsCommBuffer.CpuStart, mNsCommBuffer.PhysicalSize));
190
191 //
192 // Extract the MP information from the Hoblist
193 //
194 Status = GetGuidedHobData (
195 HobStart,
196 &gMpInformationHobGuid,
197 (VOID **)&MpInformationHobData
198 );
199 if (EFI_ERROR (Status)) {
200 DEBUG ((DEBUG_ERROR, "MpInformationHob extraction failed - 0x%x\n", Status));
201 return Status;
202 }
203
204 //
205 // Allocate memory for the MP information and copy over the MP information
206 // passed by Trusted Firmware. Use the number of processors passed in the HOB
207 // to copy the processor information
208 //
209 MpInfoSize = sizeof (MP_INFORMATION_HOB_DATA) +
210 (sizeof (EFI_PROCESSOR_INFORMATION) *
211 MpInformationHobData->NumberOfProcessors);
212 Status = mMmst->MmAllocatePool (
213 EfiRuntimeServicesData,
214 MpInfoSize,
215 (VOID **)&mMpInformationHobData
216 );
217 if (EFI_ERROR (Status)) {
218 DEBUG ((DEBUG_ERROR, "mMpInformationHobData mem alloc failed - 0x%x\n", Status));
219 return Status;
220 }
221
222 CopyMem (mMpInformationHobData, MpInformationHobData, MpInfoSize);
223
224 // Print MP information
225 DEBUG ((
226 DEBUG_INFO,
227 "mMpInformationHobData: 0x%016lx - 0x%lx\n",
228 mMpInformationHobData->NumberOfProcessors,
229 mMpInformationHobData->NumberOfEnabledProcessors
230 ));
231 for (Index = 0; Index < mMpInformationHobData->NumberOfProcessors; Index++) {
232 DEBUG ((
233 DEBUG_INFO,
234 "mMpInformationHobData[0x%lx]: %d, %d, %d\n",
235 mMpInformationHobData->ProcessorInfoBuffer[Index].ProcessorId,
236 mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Package,
237 mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Core,
238 mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Thread
239 ));
240 }
241
242 //
243 // Allocate memory for a table to hold pointers to a
244 // EFI_MM_COMMUNICATE_HEADER for each CPU
245 //
246 ArraySize = sizeof (EFI_MM_COMMUNICATE_HEADER *) *
247 mMpInformationHobData->NumberOfEnabledProcessors;
248 Status = mMmst->MmAllocatePool (
249 EfiRuntimeServicesData,
250 ArraySize,
251 (VOID **)&PerCpuGuidedEventContext
252 );
253 if (EFI_ERROR (Status)) {
254 DEBUG ((DEBUG_ERROR, "PerCpuGuidedEventContext mem alloc failed - 0x%x\n", Status));
255 return Status;
256 }
257
258 return Status;
259 }