TianoCore EDK2 master
Loading...
Searching...
No Matches
ArmMmuStandaloneMmLib.c
Go to the documentation of this file.
1
16#include <Uefi.h>
19
20#include <Library/ArmLib.h>
21#include <Library/ArmMmuLib.h>
22#include <Library/ArmSvcLib.h>
23#include <Library/BaseLib.h>
25#include <Library/DebugLib.h>
26#include <Library/PcdLib.h>
27
48 IN OUT ARM_SVC_ARGS *SvcArgs,
49 OUT INT32 *RetVal
50 )
51{
52 if ((SvcArgs == NULL) || (RetVal == NULL)) {
53 return EFI_INVALID_PARAMETER;
54 }
55
56 ArmCallSvc (SvcArgs);
57 if (FeaturePcdGet (PcdFfaEnable)) {
58 // Get/Set memory attributes is an atomic call, with
59 // StandaloneMm at S-EL0 being the caller and the SPM
60 // core being the callee. Thus there won't be a
61 // FFA_INTERRUPT or FFA_SUCCESS response to the Direct
62 // Request sent above. This will have to be considered
63 // for other Direct Request calls which are not atomic
64 // We therefore check only for Direct Response by the
65 // callee.
66 if (SvcArgs->Arg0 == ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP) {
67 // A Direct Response means FF-A success
68 // Now check the payload for errors
69 // The callee sends back the return value
70 // in Arg3
71 *RetVal = SvcArgs->Arg3;
72 } else {
73 // If Arg0 is not a Direct Response, that means we
74 // have an FF-A error. We need to check Arg2 for the
75 // FF-A error code.
76 // See [2], Table 10.8: FFA_ERROR encoding.
77 *RetVal = SvcArgs->Arg2;
78 switch (*RetVal) {
79 case ARM_FFA_SPM_RET_INVALID_PARAMETERS:
80 return EFI_INVALID_PARAMETER;
81
82 case ARM_FFA_SPM_RET_DENIED:
83 return EFI_ACCESS_DENIED;
84
85 case ARM_FFA_SPM_RET_NOT_SUPPORTED:
86 return EFI_UNSUPPORTED;
87
88 case ARM_FFA_SPM_RET_BUSY:
89 return EFI_NOT_READY;
90
91 case ARM_FFA_SPM_RET_ABORTED:
92 return EFI_ABORTED;
93
94 default:
95 // Undefined error code received.
96 ASSERT (0);
97 return EFI_INVALID_PARAMETER;
98 }
99 }
100 } else {
101 *RetVal = SvcArgs->Arg0;
102 }
103
104 // Check error response from Callee.
105 if ((*RetVal & BIT31) != 0) {
106 // Bit 31 set means there is an error returned
107 // See [1], Section 13.5.5.1 MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64 and
108 // Section 13.5.5.2 MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64.
109 switch (*RetVal) {
110 case ARM_SVC_SPM_RET_NOT_SUPPORTED:
111 return EFI_UNSUPPORTED;
112
113 case ARM_SVC_SPM_RET_INVALID_PARAMS:
114 return EFI_INVALID_PARAMETER;
115
116 case ARM_SVC_SPM_RET_DENIED:
117 return EFI_ACCESS_DENIED;
118
119 case ARM_SVC_SPM_RET_NO_MEMORY:
120 return EFI_OUT_OF_RESOURCES;
121
122 default:
123 // Undefined error code received.
124 ASSERT (0);
125 return EFI_INVALID_PARAMETER;
126 }
127 }
128
129 return EFI_SUCCESS;
130}
131
148STATIC
151 IN EFI_PHYSICAL_ADDRESS BaseAddress,
152 OUT UINT32 *MemoryAttributes
153 )
154{
155 EFI_STATUS Status;
156 INT32 Ret;
157 ARM_SVC_ARGS SvcArgs;
158
159 if (MemoryAttributes == NULL) {
160 return EFI_INVALID_PARAMETER;
161 }
162
163 // Prepare the message parameters.
164 // See [1], Section 13.5.5.1 MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64.
165 ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
166 if (FeaturePcdGet (PcdFfaEnable)) {
167 // See [2], Section 10.2 FFA_MSG_SEND_DIRECT_REQ.
168 SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ;
169 SvcArgs.Arg1 = ARM_FFA_DESTINATION_ENDPOINT_ID;
170 SvcArgs.Arg2 = 0;
171 SvcArgs.Arg3 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES;
172 SvcArgs.Arg4 = BaseAddress;
173 } else {
174 SvcArgs.Arg0 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES;
175 SvcArgs.Arg1 = BaseAddress;
176 SvcArgs.Arg2 = 0;
177 SvcArgs.Arg3 = 0;
178 }
179
180 Status = SendMemoryPermissionRequest (&SvcArgs, &Ret);
181 if (EFI_ERROR (Status)) {
182 *MemoryAttributes = 0;
183 return Status;
184 }
185
186 *MemoryAttributes = Ret;
187 return Status;
188}
189
207STATIC
210 IN EFI_PHYSICAL_ADDRESS BaseAddress,
211 IN UINT64 Length,
212 IN UINT32 Permissions
213 )
214{
215 INT32 Ret;
216 ARM_SVC_ARGS SvcArgs;
217
218 // Prepare the message parameters.
219 // See [1], Section 13.5.5.2 MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64.
220 ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
221 if (FeaturePcdGet (PcdFfaEnable)) {
222 // See [2], Section 10.2 FFA_MSG_SEND_DIRECT_REQ.
223 SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ;
224 SvcArgs.Arg1 = ARM_FFA_DESTINATION_ENDPOINT_ID;
225 SvcArgs.Arg2 = 0;
226 SvcArgs.Arg3 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES;
227 SvcArgs.Arg4 = BaseAddress;
228 SvcArgs.Arg5 = EFI_SIZE_TO_PAGES (Length);
229 SvcArgs.Arg6 = Permissions;
230 } else {
231 SvcArgs.Arg0 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES;
232 SvcArgs.Arg1 = BaseAddress;
233 SvcArgs.Arg2 = EFI_SIZE_TO_PAGES (Length);
234 SvcArgs.Arg3 = Permissions;
235 }
236
237 return SendMemoryPermissionRequest (&SvcArgs, &Ret);
238}
239
241ArmSetMemoryRegionNoExec (
242 IN EFI_PHYSICAL_ADDRESS BaseAddress,
243 IN UINT64 Length
244 )
245{
246 EFI_STATUS Status;
247 UINT32 MemoryAttributes;
248 UINT32 CodePermission;
249
250 Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
251 if (!EFI_ERROR (Status)) {
252 CodePermission = SET_MEM_ATTR_CODE_PERM_XN << SET_MEM_ATTR_CODE_PERM_SHIFT;
254 BaseAddress,
255 Length,
256 MemoryAttributes | CodePermission
257 );
258 }
259
260 return Status;
261}
262
264ArmClearMemoryRegionNoExec (
265 IN EFI_PHYSICAL_ADDRESS BaseAddress,
266 IN UINT64 Length
267 )
268{
269 EFI_STATUS Status;
270 UINT32 MemoryAttributes;
271 UINT32 CodePermission;
272
273 Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
274 if (!EFI_ERROR (Status)) {
275 CodePermission = SET_MEM_ATTR_CODE_PERM_XN << SET_MEM_ATTR_CODE_PERM_SHIFT;
277 BaseAddress,
278 Length,
279 MemoryAttributes & ~CodePermission
280 );
281 }
282
283 return Status;
284}
285
287ArmSetMemoryRegionReadOnly (
288 IN EFI_PHYSICAL_ADDRESS BaseAddress,
289 IN UINT64 Length
290 )
291{
292 EFI_STATUS Status;
293 UINT32 MemoryAttributes;
294 UINT32 DataPermission;
295
296 Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
297 if (!EFI_ERROR (Status)) {
298 DataPermission = SET_MEM_ATTR_DATA_PERM_RO << SET_MEM_ATTR_DATA_PERM_SHIFT;
300 BaseAddress,
301 Length,
302 MemoryAttributes | DataPermission
303 );
304 }
305
306 return Status;
307}
308
310ArmClearMemoryRegionReadOnly (
311 IN EFI_PHYSICAL_ADDRESS BaseAddress,
312 IN UINT64 Length
313 )
314{
315 EFI_STATUS Status;
316 UINT32 MemoryAttributes;
317 UINT32 PermissionRequest;
318
319 Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
320 if (!EFI_ERROR (Status)) {
321 PermissionRequest = SET_MEM_ATTR_MAKE_PERM_REQUEST (
322 SET_MEM_ATTR_DATA_PERM_RW,
323 MemoryAttributes
324 );
326 BaseAddress,
327 Length,
328 PermissionRequest
329 );
330 }
331
332 return Status;
333}
STATIC EFI_STATUS GetMemoryPermissions(IN EFI_PHYSICAL_ADDRESS BaseAddress, OUT UINT32 *MemoryAttributes)
STATIC EFI_STATUS RequestMemoryPermissionChange(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT32 Permissions)
STATIC EFI_STATUS SendMemoryPermissionRequest(IN OUT ARM_SVC_ARGS *SvcArgs, OUT INT32 *RetVal)
VOID ArmCallSvc(IN OUT ARM_SVC_ARGS *Args)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112