]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/Arm/StandaloneMmCoreEntryPoint.c
StandaloneMmPkg: Fix issue about SpPcpuSharedBufSize field
[mirror_edk2.git] / StandaloneMmPkg / Library / StandaloneMmCoreEntryPoint / Arm / StandaloneMmCoreEntryPoint.c
... / ...
CommitLineData
1/** @file\r
2 Entry point to the Standalone MM Foundation when initialized during the SEC\r
3 phase on ARM platforms\r
4\r
5Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>\r
6SPDX-License-Identifier: BSD-2-Clause-Patent\r
7\r
8**/\r
9\r
10#include <PiMm.h>\r
11\r
12#include <Library/Arm/StandaloneMmCoreEntryPoint.h>\r
13\r
14#include <PiPei.h>\r
15#include <Guid/MmramMemoryReserve.h>\r
16#include <Guid/MpInformation.h>\r
17\r
18#include <Library/ArmMmuLib.h>\r
19#include <Library/ArmSvcLib.h>\r
20#include <Library/DebugLib.h>\r
21#include <Library/HobLib.h>\r
22#include <Library/BaseLib.h>\r
23#include <Library/BaseMemoryLib.h>\r
24#include <Library/SerialPortLib.h>\r
25#include <Library/PcdLib.h>\r
26\r
27#include <IndustryStandard/ArmStdSmc.h>\r
28#include <IndustryStandard/ArmMmSvc.h>\r
29#include <IndustryStandard/ArmFfaSvc.h>\r
30\r
31#define SPM_MAJOR_VER_MASK 0xFFFF0000\r
32#define SPM_MINOR_VER_MASK 0x0000FFFF\r
33#define SPM_MAJOR_VER_SHIFT 16\r
34#define FFA_NOT_SUPPORTED -1\r
35\r
36STATIC CONST UINT32 mSpmMajorVer = SPM_MAJOR_VERSION;\r
37STATIC CONST UINT32 mSpmMinorVer = SPM_MINOR_VERSION;\r
38\r
39STATIC CONST UINT32 mSpmMajorVerFfa = SPM_MAJOR_VERSION_FFA;\r
40STATIC CONST UINT32 mSpmMinorVerFfa = SPM_MINOR_VERSION_FFA;\r
41\r
42#define BOOT_PAYLOAD_VERSION 1\r
43\r
44PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint = NULL;\r
45\r
46/**\r
47 Retrieve a pointer to and print the boot information passed by privileged\r
48 secure firmware.\r
49\r
50 @param [in] SharedBufAddress The pointer memory shared with privileged\r
51 firmware.\r
52\r
53**/\r
54EFI_SECURE_PARTITION_BOOT_INFO *\r
55GetAndPrintBootinformation (\r
56 IN VOID *SharedBufAddress\r
57 )\r
58{\r
59 EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;\r
60 EFI_SECURE_PARTITION_CPU_INFO *PayloadCpuInfo;\r
61 UINTN Index;\r
62\r
63 PayloadBootInfo = (EFI_SECURE_PARTITION_BOOT_INFO *)SharedBufAddress;\r
64\r
65 if (PayloadBootInfo == NULL) {\r
66 DEBUG ((DEBUG_ERROR, "PayloadBootInfo NULL\n"));\r
67 return NULL;\r
68 }\r
69\r
70 if (PayloadBootInfo->Header.Version != BOOT_PAYLOAD_VERSION) {\r
71 DEBUG ((\r
72 DEBUG_ERROR,\r
73 "Boot Information Version Mismatch. Current=0x%x, Expected=0x%x.\n",\r
74 PayloadBootInfo->Header.Version,\r
75 BOOT_PAYLOAD_VERSION\r
76 ));\r
77 return NULL;\r
78 }\r
79\r
80 DEBUG ((DEBUG_INFO, "NumSpMemRegions - 0x%x\n", PayloadBootInfo->NumSpMemRegions));\r
81 DEBUG ((DEBUG_INFO, "SpMemBase - 0x%lx\n", PayloadBootInfo->SpMemBase));\r
82 DEBUG ((DEBUG_INFO, "SpMemLimit - 0x%lx\n", PayloadBootInfo->SpMemLimit));\r
83 DEBUG ((DEBUG_INFO, "SpImageBase - 0x%lx\n", PayloadBootInfo->SpImageBase));\r
84 DEBUG ((DEBUG_INFO, "SpStackBase - 0x%lx\n", PayloadBootInfo->SpStackBase));\r
85 DEBUG ((DEBUG_INFO, "SpHeapBase - 0x%lx\n", PayloadBootInfo->SpHeapBase));\r
86 DEBUG ((DEBUG_INFO, "SpNsCommBufBase - 0x%lx\n", PayloadBootInfo->SpNsCommBufBase));\r
87 DEBUG ((DEBUG_INFO, "SpSharedBufBase - 0x%lx\n", PayloadBootInfo->SpSharedBufBase));\r
88\r
89 DEBUG ((DEBUG_INFO, "SpImageSize - 0x%x\n", PayloadBootInfo->SpImageSize));\r
90 DEBUG ((DEBUG_INFO, "SpPcpuStackSize - 0x%x\n", PayloadBootInfo->SpPcpuStackSize));\r
91 DEBUG ((DEBUG_INFO, "SpHeapSize - 0x%x\n", PayloadBootInfo->SpHeapSize));\r
92 DEBUG ((DEBUG_INFO, "SpNsCommBufSize - 0x%x\n", PayloadBootInfo->SpNsCommBufSize));\r
93 DEBUG ((DEBUG_INFO, "SpSharedBufSize - 0x%x\n", PayloadBootInfo->SpSharedBufSize));\r
94\r
95 DEBUG ((DEBUG_INFO, "NumCpus - 0x%x\n", PayloadBootInfo->NumCpus));\r
96 DEBUG ((DEBUG_INFO, "CpuInfo - 0x%p\n", PayloadBootInfo->CpuInfo));\r
97\r
98 PayloadCpuInfo = (EFI_SECURE_PARTITION_CPU_INFO *)PayloadBootInfo->CpuInfo;\r
99\r
100 if (PayloadCpuInfo == NULL) {\r
101 DEBUG ((DEBUG_ERROR, "PayloadCpuInfo NULL\n"));\r
102 return NULL;\r
103 }\r
104\r
105 for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) {\r
106 DEBUG ((DEBUG_INFO, "Mpidr - 0x%lx\n", PayloadCpuInfo[Index].Mpidr));\r
107 DEBUG ((DEBUG_INFO, "LinearId - 0x%x\n", PayloadCpuInfo[Index].LinearId));\r
108 DEBUG ((DEBUG_INFO, "Flags - 0x%x\n", PayloadCpuInfo[Index].Flags));\r
109 }\r
110\r
111 return PayloadBootInfo;\r
112}\r
113\r
114/**\r
115 A loop to delegated events.\r
116\r
117 @param [in] EventCompleteSvcArgs Pointer to the event completion arguments.\r
118\r
119**/\r
120VOID\r
121EFIAPI\r
122DelegatedEventLoop (\r
123 IN ARM_SVC_ARGS *EventCompleteSvcArgs\r
124 )\r
125{\r
126 BOOLEAN FfaEnabled;\r
127 EFI_STATUS Status;\r
128 UINTN SvcStatus;\r
129\r
130 while (TRUE) {\r
131 ArmCallSvc (EventCompleteSvcArgs);\r
132\r
133 DEBUG ((DEBUG_INFO, "Received delegated event\n"));\r
134 DEBUG ((DEBUG_INFO, "X0 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg0));\r
135 DEBUG ((DEBUG_INFO, "X1 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg1));\r
136 DEBUG ((DEBUG_INFO, "X2 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg2));\r
137 DEBUG ((DEBUG_INFO, "X3 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg3));\r
138 DEBUG ((DEBUG_INFO, "X4 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg4));\r
139 DEBUG ((DEBUG_INFO, "X5 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg5));\r
140 DEBUG ((DEBUG_INFO, "X6 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg6));\r
141 DEBUG ((DEBUG_INFO, "X7 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg7));\r
142\r
143 FfaEnabled = FeaturePcdGet (PcdFfaEnable);\r
144 if (FfaEnabled) {\r
145 Status = CpuDriverEntryPoint (\r
146 EventCompleteSvcArgs->Arg0,\r
147 EventCompleteSvcArgs->Arg6,\r
148 EventCompleteSvcArgs->Arg3\r
149 );\r
150 if (EFI_ERROR (Status)) {\r
151 DEBUG ((\r
152 DEBUG_ERROR,\r
153 "Failed delegated event 0x%x, Status 0x%x\n",\r
154 EventCompleteSvcArgs->Arg3,\r
155 Status\r
156 ));\r
157 }\r
158 } else {\r
159 Status = CpuDriverEntryPoint (\r
160 EventCompleteSvcArgs->Arg0,\r
161 EventCompleteSvcArgs->Arg3,\r
162 EventCompleteSvcArgs->Arg1\r
163 );\r
164 if (EFI_ERROR (Status)) {\r
165 DEBUG ((\r
166 DEBUG_ERROR,\r
167 "Failed delegated event 0x%x, Status 0x%x\n",\r
168 EventCompleteSvcArgs->Arg0,\r
169 Status\r
170 ));\r
171 }\r
172 }\r
173\r
174 switch (Status) {\r
175 case EFI_SUCCESS:\r
176 SvcStatus = ARM_SVC_SPM_RET_SUCCESS;\r
177 break;\r
178 case EFI_INVALID_PARAMETER:\r
179 SvcStatus = ARM_SVC_SPM_RET_INVALID_PARAMS;\r
180 break;\r
181 case EFI_ACCESS_DENIED:\r
182 SvcStatus = ARM_SVC_SPM_RET_DENIED;\r
183 break;\r
184 case EFI_OUT_OF_RESOURCES:\r
185 SvcStatus = ARM_SVC_SPM_RET_NO_MEMORY;\r
186 break;\r
187 case EFI_UNSUPPORTED:\r
188 SvcStatus = ARM_SVC_SPM_RET_NOT_SUPPORTED;\r
189 break;\r
190 default:\r
191 SvcStatus = ARM_SVC_SPM_RET_NOT_SUPPORTED;\r
192 break;\r
193 }\r
194\r
195 if (FfaEnabled) {\r
196 EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP;\r
197 EventCompleteSvcArgs->Arg1 = 0;\r
198 EventCompleteSvcArgs->Arg2 = 0;\r
199 EventCompleteSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE;\r
200 EventCompleteSvcArgs->Arg4 = SvcStatus;\r
201 } else {\r
202 EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE;\r
203 EventCompleteSvcArgs->Arg1 = SvcStatus;\r
204 }\r
205 }\r
206}\r
207\r
208/**\r
209 Query the SPM version, check compatibility and return success if compatible.\r
210\r
211 @retval EFI_SUCCESS SPM versions compatible.\r
212 @retval EFI_UNSUPPORTED SPM versions not compatible.\r
213**/\r
214STATIC\r
215EFI_STATUS\r
216GetSpmVersion (\r
217 VOID\r
218 )\r
219{\r
220 EFI_STATUS Status;\r
221 UINT16 CalleeSpmMajorVer;\r
222 UINT16 CallerSpmMajorVer;\r
223 UINT16 CalleeSpmMinorVer;\r
224 UINT16 CallerSpmMinorVer;\r
225 UINT32 SpmVersion;\r
226 ARM_SVC_ARGS SpmVersionArgs;\r
227\r
228 if (FeaturePcdGet (PcdFfaEnable)) {\r
229 SpmVersionArgs.Arg0 = ARM_SVC_ID_FFA_VERSION_AARCH32;\r
230 SpmVersionArgs.Arg1 = mSpmMajorVerFfa << SPM_MAJOR_VER_SHIFT;\r
231 SpmVersionArgs.Arg1 |= mSpmMinorVerFfa;\r
232 CallerSpmMajorVer = mSpmMajorVerFfa;\r
233 CallerSpmMinorVer = mSpmMinorVerFfa;\r
234 } else {\r
235 SpmVersionArgs.Arg0 = ARM_SVC_ID_SPM_VERSION_AARCH32;\r
236 CallerSpmMajorVer = mSpmMajorVer;\r
237 CallerSpmMinorVer = mSpmMinorVer;\r
238 }\r
239\r
240 ArmCallSvc (&SpmVersionArgs);\r
241\r
242 SpmVersion = SpmVersionArgs.Arg0;\r
243 if (SpmVersion == FFA_NOT_SUPPORTED) {\r
244 return EFI_UNSUPPORTED;\r
245 }\r
246\r
247 CalleeSpmMajorVer = ((SpmVersion & SPM_MAJOR_VER_MASK) >> SPM_MAJOR_VER_SHIFT);\r
248 CalleeSpmMinorVer = ((SpmVersion & SPM_MINOR_VER_MASK) >> 0);\r
249\r
250 // Different major revision values indicate possibly incompatible functions.\r
251 // For two revisions, A and B, for which the major revision values are\r
252 // identical, if the minor revision value of revision B is greater than\r
253 // the minor revision value of revision A, then every function in\r
254 // revision A must work in a compatible way with revision B.\r
255 // However, it is possible for revision B to have a higher\r
256 // function count than revision A.\r
257 if ((CalleeSpmMajorVer == CallerSpmMajorVer) &&\r
258 (CalleeSpmMinorVer >= CallerSpmMinorVer))\r
259 {\r
260 DEBUG ((\r
261 DEBUG_INFO,\r
262 "SPM Version: Major=0x%x, Minor=0x%x\n",\r
263 CalleeSpmMajorVer,\r
264 CalleeSpmMinorVer\r
265 ));\r
266 Status = EFI_SUCCESS;\r
267 } else {\r
268 DEBUG ((\r
269 DEBUG_INFO,\r
270 "Incompatible SPM Versions.\n Callee Version: Major=0x%x, Minor=0x%x.\n Caller: Major=0x%x, Minor>=0x%x.\n",\r
271 CalleeSpmMajorVer,\r
272 CalleeSpmMinorVer,\r
273 CallerSpmMajorVer,\r
274 CallerSpmMinorVer\r
275 ));\r
276 Status = EFI_UNSUPPORTED;\r
277 }\r
278\r
279 return Status;\r
280}\r
281\r
282/**\r
283 Initialize parameters to be sent via SVC call.\r
284\r
285 @param[out] InitMmFoundationSvcArgs Args structure\r
286 @param[out] Ret Return Code\r
287\r
288**/\r
289STATIC\r
290VOID\r
291InitArmSvcArgs (\r
292 OUT ARM_SVC_ARGS *InitMmFoundationSvcArgs,\r
293 OUT INT32 *Ret\r
294 )\r
295{\r
296 if (FeaturePcdGet (PcdFfaEnable)) {\r
297 InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP;\r
298 InitMmFoundationSvcArgs->Arg1 = 0;\r
299 InitMmFoundationSvcArgs->Arg2 = 0;\r
300 InitMmFoundationSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE;\r
301 InitMmFoundationSvcArgs->Arg4 = *Ret;\r
302 } else {\r
303 InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE;\r
304 InitMmFoundationSvcArgs->Arg1 = *Ret;\r
305 }\r
306}\r
307\r
308/**\r
309 The entry point of Standalone MM Foundation.\r
310\r
311 @param [in] SharedBufAddress Pointer to the Buffer between SPM and SP.\r
312 @param [in] SharedBufSize Size of the shared buffer.\r
313 @param [in] cookie1 Cookie 1\r
314 @param [in] cookie2 Cookie 2\r
315\r
316**/\r
317VOID\r
318EFIAPI\r
319_ModuleEntryPoint (\r
320 IN VOID *SharedBufAddress,\r
321 IN UINT64 SharedBufSize,\r
322 IN UINT64 cookie1,\r
323 IN UINT64 cookie2\r
324 )\r
325{\r
326 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
327 EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;\r
328 ARM_SVC_ARGS InitMmFoundationSvcArgs;\r
329 EFI_STATUS Status;\r
330 INT32 Ret;\r
331 UINT32 SectionHeaderOffset;\r
332 UINT16 NumberOfSections;\r
333 VOID *HobStart;\r
334 VOID *TeData;\r
335 UINTN TeDataSize;\r
336 EFI_PHYSICAL_ADDRESS ImageBase;\r
337\r
338 // Get Secure Partition Manager Version Information\r
339 Status = GetSpmVersion ();\r
340 if (EFI_ERROR (Status)) {\r
341 goto finish;\r
342 }\r
343\r
344 PayloadBootInfo = GetAndPrintBootinformation (SharedBufAddress);\r
345 if (PayloadBootInfo == NULL) {\r
346 Status = EFI_UNSUPPORTED;\r
347 goto finish;\r
348 }\r
349\r
350 // Locate PE/COFF File information for the Standalone MM core module\r
351 Status = LocateStandaloneMmCorePeCoffData (\r
352 (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PayloadBootInfo->SpImageBase,\r
353 &TeData,\r
354 &TeDataSize\r
355 );\r
356\r
357 if (EFI_ERROR (Status)) {\r
358 goto finish;\r
359 }\r
360\r
361 // Obtain the PE/COFF Section information for the Standalone MM core module\r
362 Status = GetStandaloneMmCorePeCoffSections (\r
363 TeData,\r
364 &ImageContext,\r
365 &ImageBase,\r
366 &SectionHeaderOffset,\r
367 &NumberOfSections\r
368 );\r
369\r
370 if (EFI_ERROR (Status)) {\r
371 goto finish;\r
372 }\r
373\r
374 //\r
375 // ImageBase may deviate from ImageContext.ImageAddress if we are dealing\r
376 // with a TE image, in which case the latter points to the actual offset\r
377 // of the image, whereas ImageBase refers to the address where the image\r
378 // would start if the stripped PE headers were still in place. In either\r
379 // case, we need to fix up ImageBase so it refers to the actual current\r
380 // load address.\r
381 //\r
382 ImageBase += (UINTN)TeData - ImageContext.ImageAddress;\r
383\r
384 // Update the memory access permissions of individual sections in the\r
385 // Standalone MM core module\r
386 Status = UpdateMmFoundationPeCoffPermissions (\r
387 &ImageContext,\r
388 ImageBase,\r
389 SectionHeaderOffset,\r
390 NumberOfSections,\r
391 ArmSetMemoryRegionNoExec,\r
392 ArmSetMemoryRegionReadOnly,\r
393 ArmClearMemoryRegionReadOnly\r
394 );\r
395\r
396 if (EFI_ERROR (Status)) {\r
397 goto finish;\r
398 }\r
399\r
400 if (ImageContext.ImageAddress != (UINTN)TeData) {\r
401 ImageContext.ImageAddress = (UINTN)TeData;\r
402 ArmSetMemoryRegionNoExec (ImageBase, SIZE_4KB);\r
403 ArmClearMemoryRegionReadOnly (ImageBase, SIZE_4KB);\r
404\r
405 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
406 ASSERT_EFI_ERROR (Status);\r
407 }\r
408\r
409 //\r
410 // Create Hoblist based upon boot information passed by privileged software\r
411 //\r
412 HobStart = CreateHobListFromBootInfo (&CpuDriverEntryPoint, PayloadBootInfo);\r
413\r
414 //\r
415 // Call the MM Core entry point\r
416 //\r
417 ProcessModuleEntryPointList (HobStart);\r
418\r
419 DEBUG ((DEBUG_INFO, "Shared Cpu Driver EP %p\n", (VOID *)CpuDriverEntryPoint));\r
420\r
421finish:\r
422 if (Status == RETURN_UNSUPPORTED) {\r
423 Ret = -1;\r
424 } else if (Status == RETURN_INVALID_PARAMETER) {\r
425 Ret = -2;\r
426 } else if (Status == EFI_NOT_FOUND) {\r
427 Ret = -7;\r
428 } else {\r
429 Ret = 0;\r
430 }\r
431\r
432 ZeroMem (&InitMmFoundationSvcArgs, sizeof (InitMmFoundationSvcArgs));\r
433 InitArmSvcArgs (&InitMmFoundationSvcArgs, &Ret);\r
434 DelegatedEventLoop (&InitMmFoundationSvcArgs);\r
435}\r