]> git.proxmox.com Git - mirror_edk2.git/blame - StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/Arm/StandaloneMmCoreEntryPoint.c
StandaloneMmPkg: Fix issue about SpPcpuSharedBufSize field
[mirror_edk2.git] / StandaloneMmPkg / Library / StandaloneMmCoreEntryPoint / Arm / StandaloneMmCoreEntryPoint.c
CommitLineData
184558d0
SV
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
764942a2 5Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>\r
86094561 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
184558d0
SV
7\r
8**/\r
9\r
184558d0
SV
10#include <PiMm.h>\r
11\r
a776bbab 12#include <Library/Arm/StandaloneMmCoreEntryPoint.h>\r
184558d0
SV
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
cb4267d4 25#include <Library/PcdLib.h>\r
184558d0
SV
26\r
27#include <IndustryStandard/ArmStdSmc.h>\r
28#include <IndustryStandard/ArmMmSvc.h>\r
82abb8f9 29#include <IndustryStandard/ArmFfaSvc.h>\r
184558d0 30\r
91415a36
MK
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
184558d0 35\r
91415a36
MK
36STATIC CONST UINT32 mSpmMajorVer = SPM_MAJOR_VERSION;\r
37STATIC CONST UINT32 mSpmMinorVer = SPM_MINOR_VERSION;\r
184558d0 38\r
91415a36
MK
39STATIC CONST UINT32 mSpmMajorVerFfa = SPM_MAJOR_VERSION_FFA;\r
40STATIC CONST UINT32 mSpmMinorVerFfa = SPM_MINOR_VERSION_FFA;\r
cb4267d4 41\r
91415a36 42#define BOOT_PAYLOAD_VERSION 1\r
184558d0 43\r
91415a36 44PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint = NULL;\r
184558d0
SV
45\r
46/**\r
47 Retrieve a pointer to and print the boot information passed by privileged\r
561c3630 48 secure firmware.\r
184558d0 49\r
561c3630
SM
50 @param [in] SharedBufAddress The pointer memory shared with privileged\r
51 firmware.\r
184558d0
SV
52\r
53**/\r
54EFI_SECURE_PARTITION_BOOT_INFO *\r
55GetAndPrintBootinformation (\r
91415a36
MK
56 IN VOID *SharedBufAddress\r
57 )\r
184558d0 58{\r
91415a36
MK
59 EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;\r
60 EFI_SECURE_PARTITION_CPU_INFO *PayloadCpuInfo;\r
61 UINTN Index;\r
184558d0 62\r
91415a36 63 PayloadBootInfo = (EFI_SECURE_PARTITION_BOOT_INFO *)SharedBufAddress;\r
184558d0
SV
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
91415a36
MK
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
184558d0
SV
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
9ab18fec 93 DEBUG ((DEBUG_INFO, "SpSharedBufSize - 0x%x\n", PayloadBootInfo->SpSharedBufSize));\r
184558d0
SV
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
91415a36 98 PayloadCpuInfo = (EFI_SECURE_PARTITION_CPU_INFO *)PayloadBootInfo->CpuInfo;\r
184558d0
SV
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
764942a2
SM
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
184558d0
SV
120VOID\r
121EFIAPI\r
122DelegatedEventLoop (\r
91415a36 123 IN ARM_SVC_ARGS *EventCompleteSvcArgs\r
184558d0
SV
124 )\r
125{\r
91415a36
MK
126 BOOLEAN FfaEnabled;\r
127 EFI_STATUS Status;\r
128 UINTN SvcStatus;\r
184558d0
SV
129\r
130 while (TRUE) {\r
131 ArmCallSvc (EventCompleteSvcArgs);\r
132\r
133 DEBUG ((DEBUG_INFO, "Received delegated event\n"));\r
91415a36
MK
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
388dfe02
AG
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
91415a36
MK
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
388dfe02
AG
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
91415a36
MK
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
388dfe02 171 }\r
184558d0
SV
172 }\r
173\r
174 switch (Status) {\r
91415a36
MK
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
184558d0
SV
193 }\r
194\r
388dfe02 195 if (FfaEnabled) {\r
a776bbab 196 EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP;\r
388dfe02
AG
197 EventCompleteSvcArgs->Arg1 = 0;\r
198 EventCompleteSvcArgs->Arg2 = 0;\r
a776bbab 199 EventCompleteSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE;\r
388dfe02
AG
200 EventCompleteSvcArgs->Arg4 = SvcStatus;\r
201 } else {\r
a776bbab 202 EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE;\r
388dfe02
AG
203 EventCompleteSvcArgs->Arg1 = SvcStatus;\r
204 }\r
184558d0
SV
205 }\r
206}\r
207\r
764942a2
SM
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
184558d0
SV
214STATIC\r
215EFI_STATUS\r
91415a36
MK
216GetSpmVersion (\r
217 VOID\r
218 )\r
184558d0 219{\r
91415a36
MK
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
184558d0 227\r
cb4267d4 228 if (FeaturePcdGet (PcdFfaEnable)) {\r
91415a36
MK
229 SpmVersionArgs.Arg0 = ARM_SVC_ID_FFA_VERSION_AARCH32;\r
230 SpmVersionArgs.Arg1 = mSpmMajorVerFfa << SPM_MAJOR_VER_SHIFT;\r
cb4267d4 231 SpmVersionArgs.Arg1 |= mSpmMinorVerFfa;\r
91415a36
MK
232 CallerSpmMajorVer = mSpmMajorVerFfa;\r
233 CallerSpmMinorVer = mSpmMinorVerFfa;\r
cb4267d4
SG
234 } else {\r
235 SpmVersionArgs.Arg0 = ARM_SVC_ID_SPM_VERSION_AARCH32;\r
91415a36
MK
236 CallerSpmMajorVer = mSpmMajorVer;\r
237 CallerSpmMinorVer = mSpmMinorVer;\r
cb4267d4 238 }\r
184558d0
SV
239\r
240 ArmCallSvc (&SpmVersionArgs);\r
241\r
242 SpmVersion = SpmVersionArgs.Arg0;\r
cb4267d4
SG
243 if (SpmVersion == FFA_NOT_SUPPORTED) {\r
244 return EFI_UNSUPPORTED;\r
245 }\r
184558d0 246\r
cb4267d4
SG
247 CalleeSpmMajorVer = ((SpmVersion & SPM_MAJOR_VER_MASK) >> SPM_MAJOR_VER_SHIFT);\r
248 CalleeSpmMinorVer = ((SpmVersion & SPM_MINOR_VER_MASK) >> 0);\r
184558d0
SV
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
cb4267d4
SG
257 if ((CalleeSpmMajorVer == CallerSpmMajorVer) &&\r
258 (CalleeSpmMinorVer >= CallerSpmMinorVer))\r
184558d0 259 {\r
91415a36
MK
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
184558d0 266 Status = EFI_SUCCESS;\r
91415a36
MK
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
184558d0
SV
276 Status = EFI_UNSUPPORTED;\r
277 }\r
278\r
279 return Status;\r
280}\r
281\r
388dfe02
AG
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
91415a36
MK
292 OUT ARM_SVC_ARGS *InitMmFoundationSvcArgs,\r
293 OUT INT32 *Ret\r
388dfe02
AG
294 )\r
295{\r
296 if (FeaturePcdGet (PcdFfaEnable)) {\r
a776bbab 297 InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP;\r
388dfe02
AG
298 InitMmFoundationSvcArgs->Arg1 = 0;\r
299 InitMmFoundationSvcArgs->Arg2 = 0;\r
a776bbab 300 InitMmFoundationSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE;\r
388dfe02
AG
301 InitMmFoundationSvcArgs->Arg4 = *Ret;\r
302 } else {\r
a776bbab 303 InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE;\r
388dfe02
AG
304 InitMmFoundationSvcArgs->Arg1 = *Ret;\r
305 }\r
306}\r
307\r
184558d0
SV
308/**\r
309 The entry point of Standalone MM Foundation.\r
310\r
4779bc6c
SM
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
184558d0
SV
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
91415a36
MK
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
184558d0 337\r
184558d0
SV
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
91415a36 352 (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PayloadBootInfo->SpImageBase,\r
184558d0
SV
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
493f2c69 365 &ImageBase,\r
184558d0
SV
366 &SectionHeaderOffset,\r
367 &NumberOfSections\r
368 );\r
369\r
370 if (EFI_ERROR (Status)) {\r
371 goto finish;\r
372 }\r
373\r
493f2c69
AB
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
184558d0
SV
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
493f2c69 388 ImageBase,\r
184558d0
SV
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
493f2c69
AB
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
184558d0
SV
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
91415a36 419 DEBUG ((DEBUG_INFO, "Shared Cpu Driver EP %p\n", (VOID *)CpuDriverEntryPoint));\r
184558d0
SV
420\r
421finish:\r
388dfe02
AG
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
91415a36
MK
431\r
432 ZeroMem (&InitMmFoundationSvcArgs, sizeof (InitMmFoundationSvcArgs));\r
388dfe02 433 InitArmSvcArgs (&InitMmFoundationSvcArgs, &Ret);\r
184558d0 434 DelegatedEventLoop (&InitMmFoundationSvcArgs);\r
184558d0 435}\r