]> git.proxmox.com Git - mirror_edk2.git/blame - StandaloneMmPkg/Drivers/StandaloneMmCpu/EventHandle.c
StandaloneMmPkg: Replace DEBUG_INFO with DEBUG_ERROR
[mirror_edk2.git] / StandaloneMmPkg / Drivers / StandaloneMmCpu / EventHandle.c
CommitLineData
275d4bd4
SV
1/** @file\r
2\r
3 Copyright (c) 2016 HP Development Company, L.P.\r
a9da96ac 4 Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.\r
a776bbab 5 Copyright (c) 2021, Linaro Limited\r
275d4bd4 6\r
86094561 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
275d4bd4
SV
8\r
9**/\r
10\r
11#include <Base.h>\r
12#include <Pi/PiMmCis.h>\r
13\r
275d4bd4
SV
14#include <Library/ArmSvcLib.h>\r
15#include <Library/ArmLib.h>\r
16#include <Library/BaseMemoryLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/HobLib.h>\r
19\r
20#include <Protocol/DebugSupport.h> // for EFI_SYSTEM_CONTEXT\r
21\r
22#include <Guid/ZeroGuid.h>\r
23#include <Guid/MmramMemoryReserve.h>\r
24\r
68e5ecc4 25#include <IndustryStandard/ArmFfaSvc.h>\r
275d4bd4
SV
26#include <IndustryStandard/ArmStdSmc.h>\r
27\r
28#include "StandaloneMmCpu.h"\r
29\r
30EFI_STATUS\r
31EFIAPI\r
32MmFoundationEntryRegister (\r
33 IN CONST EFI_MM_CONFIGURATION_PROTOCOL *This,\r
91415a36 34 IN EFI_MM_ENTRY_POINT MmEntryPoint\r
275d4bd4
SV
35 );\r
36\r
37//\r
38// On ARM platforms every event is expected to have a GUID associated with\r
39// it. It will be used by the MM Entry point to find the handler for the\r
40// event. It will either be populated in a EFI_MM_COMMUNICATE_HEADER by the\r
41// caller of the event (e.g. MM_COMMUNICATE SMC) or by the CPU driver\r
42// (e.g. during an asynchronous event). In either case, this context is\r
43// maintained in an array which has an entry for each CPU. The pointer to this\r
44// array is held in PerCpuGuidedEventContext. Memory is allocated once the\r
45// number of CPUs in the system are made known through the\r
46// MP_INFORMATION_HOB_DATA.\r
47//\r
91415a36 48EFI_MM_COMMUNICATE_HEADER **PerCpuGuidedEventContext = NULL;\r
275d4bd4
SV
49\r
50// Descriptor with whereabouts of memory used for communication with the normal world\r
51EFI_MMRAM_DESCRIPTOR mNsCommBuffer;\r
52\r
91415a36 53MP_INFORMATION_HOB_DATA *mMpInformationHobData;\r
275d4bd4 54\r
91415a36 55EFI_MM_CONFIGURATION_PROTOCOL mMmConfig = {\r
275d4bd4
SV
56 0,\r
57 MmFoundationEntryRegister\r
58};\r
59\r
91415a36 60STATIC EFI_MM_ENTRY_POINT mMmEntryPoint = NULL;\r
275d4bd4 61\r
2da602fa
SM
62/**\r
63 The PI Standalone MM entry point for the TF-A CPU driver.\r
64\r
65 @param [in] EventId The event Id.\r
66 @param [in] CpuNumber The CPU number.\r
67 @param [in] NsCommBufferAddr Address of the NS common buffer.\r
68\r
69 @retval EFI_SUCCESS Success.\r
70 @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
71 @retval EFI_ACCESS_DENIED Access not permitted.\r
72 @retval EFI_OUT_OF_RESOURCES Out of resources.\r
73 @retval EFI_UNSUPPORTED Operation not supported.\r
74**/\r
275d4bd4 75EFI_STATUS\r
c8102727 76PiMmStandaloneArmTfCpuDriverEntry (\r
91415a36
MK
77 IN UINTN EventId,\r
78 IN UINTN CpuNumber,\r
79 IN UINTN NsCommBufferAddr\r
275d4bd4
SV
80 )\r
81{\r
91415a36
MK
82 EFI_MM_COMMUNICATE_HEADER *GuidedEventContext;\r
83 EFI_MM_ENTRY_CONTEXT MmEntryPointContext;\r
84 EFI_STATUS Status;\r
85 UINTN NsCommBufferSize;\r
275d4bd4
SV
86\r
87 DEBUG ((DEBUG_INFO, "Received event - 0x%x on cpu %d\n", EventId, CpuNumber));\r
88\r
89 Status = EFI_SUCCESS;\r
90 //\r
91 // ARM TF passes SMC FID of the MM_COMMUNICATE interface as the Event ID upon\r
92 // receipt of a synchronous MM request. Use the Event ID to distinguish\r
93 // between synchronous and asynchronous events.\r
94 //\r
a776bbab 95 if ((ARM_SMC_ID_MM_COMMUNICATE != EventId) &&\r
91415a36
MK
96 (ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ != EventId))\r
97 {\r
31d3eeb1 98 DEBUG ((DEBUG_ERROR, "UnRecognized Event - 0x%x\n", EventId));\r
275d4bd4
SV
99 return EFI_INVALID_PARAMETER;\r
100 }\r
101\r
102 // Perform parameter validation of NsCommBufferAddr\r
a9da96ac
SM
103 if (NsCommBufferAddr == (UINTN)NULL) {\r
104 return EFI_INVALID_PARAMETER;\r
105 }\r
106\r
107 if (NsCommBufferAddr < mNsCommBuffer.PhysicalStart) {\r
275d4bd4 108 return EFI_ACCESS_DENIED;\r
a9da96ac 109 }\r
275d4bd4
SV
110\r
111 if ((NsCommBufferAddr + sizeof (EFI_MM_COMMUNICATE_HEADER)) >=\r
91415a36
MK
112 (mNsCommBuffer.PhysicalStart + mNsCommBuffer.PhysicalSize))\r
113 {\r
275d4bd4 114 return EFI_INVALID_PARAMETER;\r
a9da96ac 115 }\r
275d4bd4
SV
116\r
117 // Find out the size of the buffer passed\r
91415a36
MK
118 NsCommBufferSize = ((EFI_MM_COMMUNICATE_HEADER *)NsCommBufferAddr)->MessageLength +\r
119 sizeof (EFI_MM_COMMUNICATE_HEADER);\r
275d4bd4
SV
120\r
121 // perform bounds check.\r
122 if (NsCommBufferAddr + NsCommBufferSize >=\r
91415a36
MK
123 mNsCommBuffer.PhysicalStart + mNsCommBuffer.PhysicalSize)\r
124 {\r
275d4bd4 125 return EFI_ACCESS_DENIED;\r
a9da96ac 126 }\r
275d4bd4 127\r
eda1ffac 128 GuidedEventContext = NULL;\r
275d4bd4
SV
129 // Now that the secure world can see the normal world buffer, allocate\r
130 // memory to copy the communication buffer to the secure world.\r
131 Status = mMmst->MmAllocatePool (\r
132 EfiRuntimeServicesData,\r
133 NsCommBufferSize,\r
91415a36 134 (VOID **)&GuidedEventContext\r
275d4bd4
SV
135 );\r
136\r
137 if (Status != EFI_SUCCESS) {\r
31d3eeb1 138 DEBUG ((DEBUG_ERROR, "Mem alloc failed - 0x%x\n", EventId));\r
275d4bd4
SV
139 return EFI_OUT_OF_RESOURCES;\r
140 }\r
141\r
142 // X1 contains the VA of the normal world memory accessible from\r
143 // S-EL0\r
91415a36 144 CopyMem (GuidedEventContext, (CONST VOID *)NsCommBufferAddr, NsCommBufferSize);\r
275d4bd4
SV
145\r
146 // Stash the pointer to the allocated Event Context for this CPU\r
147 PerCpuGuidedEventContext[CpuNumber] = GuidedEventContext;\r
148\r
eda1ffac
SM
149 ZeroMem (&MmEntryPointContext, sizeof (EFI_MM_ENTRY_CONTEXT));\r
150\r
275d4bd4 151 MmEntryPointContext.CurrentlyExecutingCpu = CpuNumber;\r
91415a36 152 MmEntryPointContext.NumberOfCpus = mMpInformationHobData->NumberOfProcessors;\r
275d4bd4
SV
153\r
154 // Populate the MM system table with MP and state information\r
155 mMmst->CurrentlyExecutingCpu = CpuNumber;\r
91415a36
MK
156 mMmst->NumberOfCpus = mMpInformationHobData->NumberOfProcessors;\r
157 mMmst->CpuSaveStateSize = 0;\r
158 mMmst->CpuSaveState = NULL;\r
275d4bd4
SV
159\r
160 if (mMmEntryPoint == NULL) {\r
31d3eeb1 161 DEBUG ((DEBUG_ERROR, "Mm Entry point Not Found\n"));\r
275d4bd4
SV
162 return EFI_UNSUPPORTED;\r
163 }\r
164\r
165 mMmEntryPoint (&MmEntryPointContext);\r
166\r
167 // Free the memory allocation done earlier and reset the per-cpu context\r
168 ASSERT (GuidedEventContext);\r
91415a36 169 CopyMem ((VOID *)NsCommBufferAddr, (CONST VOID *)GuidedEventContext, NsCommBufferSize);\r
275d4bd4 170\r
91415a36 171 Status = mMmst->MmFreePool ((VOID *)GuidedEventContext);\r
275d4bd4
SV
172 if (Status != EFI_SUCCESS) {\r
173 return EFI_OUT_OF_RESOURCES;\r
174 }\r
91415a36 175\r
275d4bd4
SV
176 PerCpuGuidedEventContext[CpuNumber] = NULL;\r
177\r
178 return Status;\r
179}\r
180\r
2da602fa
SM
181/**\r
182 Registers the MM foundation entry point.\r
183\r
184 @param [in] This Pointer to the MM Configuration protocol.\r
185 @param [in] MmEntryPoint Function pointer to the MM Entry point.\r
186\r
187 @retval EFI_SUCCESS Success.\r
188**/\r
275d4bd4
SV
189EFI_STATUS\r
190EFIAPI\r
191MmFoundationEntryRegister (\r
192 IN CONST EFI_MM_CONFIGURATION_PROTOCOL *This,\r
91415a36 193 IN EFI_MM_ENTRY_POINT MmEntryPoint\r
275d4bd4
SV
194 )\r
195{\r
196 // store the entry point in a global\r
197 mMmEntryPoint = MmEntryPoint;\r
198 return EFI_SUCCESS;\r
199}\r
200\r
201/**\r
202 This function is the main entry point for an MM handler dispatch\r
203 or communicate-based callback.\r
204\r
9a0f88b5
SM
205 @param DispatchHandle The unique handle assigned to this handler by\r
206 MmiHandlerRegister().\r
207 @param Context Points to an optional handler context which was\r
208 specified when the handler was registered.\r
275d4bd4 209 @param CommBuffer A pointer to a collection of data in memory that will\r
9a0f88b5
SM
210 be conveyed from a non-MM environment into an\r
211 MM environment.\r
275d4bd4
SV
212 @param CommBufferSize The size of the CommBuffer.\r
213\r
214 @return Status Code\r
215\r
216**/\r
217EFI_STATUS\r
218EFIAPI\r
219PiMmCpuTpFwRootMmiHandler (\r
91415a36
MK
220 IN EFI_HANDLE DispatchHandle,\r
221 IN CONST VOID *Context OPTIONAL,\r
222 IN OUT VOID *CommBuffer OPTIONAL,\r
223 IN OUT UINTN *CommBufferSize OPTIONAL\r
275d4bd4
SV
224 )\r
225{\r
91415a36
MK
226 EFI_STATUS Status;\r
227 UINTN CpuNumber;\r
275d4bd4
SV
228\r
229 ASSERT (Context == NULL);\r
230 ASSERT (CommBuffer == NULL);\r
231 ASSERT (CommBufferSize == NULL);\r
232\r
233 CpuNumber = mMmst->CurrentlyExecutingCpu;\r
a9da96ac 234 if (PerCpuGuidedEventContext[CpuNumber] == NULL) {\r
275d4bd4 235 return EFI_NOT_FOUND;\r
a9da96ac 236 }\r
275d4bd4 237\r
91415a36
MK
238 DEBUG ((\r
239 DEBUG_INFO,\r
240 "CommBuffer - 0x%x, CommBufferSize - 0x%x\n",\r
241 PerCpuGuidedEventContext[CpuNumber],\r
242 PerCpuGuidedEventContext[CpuNumber]->MessageLength\r
243 ));\r
275d4bd4
SV
244\r
245 Status = mMmst->MmiManage (\r
246 &PerCpuGuidedEventContext[CpuNumber]->HeaderGuid,\r
247 NULL,\r
248 PerCpuGuidedEventContext[CpuNumber]->Data,\r
249 &PerCpuGuidedEventContext[CpuNumber]->MessageLength\r
250 );\r
251\r
252 if (Status != EFI_SUCCESS) {\r
253 DEBUG ((DEBUG_WARN, "Unable to manage Guided Event - %d\n", Status));\r
254 }\r
255\r
256 return Status;\r
257}\r