2 * File managing the MMU for ARMv8 architecture in S-EL0
4 * Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
6 * This program and the accompanying materials
7 * are licensed and made available under the terms and conditions of the BSD License
8 * which accompanies this distribution. The full text of the license may be found at
9 * http://opensource.org/licenses/bsd-license.php
11 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <IndustryStandard/ArmMmSvc.h>
19 #include <Library/ArmLib.h>
20 #include <Library/ArmMmuLib.h>
21 #include <Library/ArmSvcLib.h>
22 #include <Library/BaseLib.h>
23 #include <Library/DebugLib.h>
27 GetMemoryPermissions (
28 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
29 OUT UINT32
*MemoryAttributes
32 ARM_SVC_ARGS GetMemoryPermissionsSvcArgs
= {0};
34 GetMemoryPermissionsSvcArgs
.Arg0
= ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64
;
35 GetMemoryPermissionsSvcArgs
.Arg1
= BaseAddress
;
36 GetMemoryPermissionsSvcArgs
.Arg2
= 0;
37 GetMemoryPermissionsSvcArgs
.Arg3
= 0;
39 ArmCallSvc (&GetMemoryPermissionsSvcArgs
);
40 if (GetMemoryPermissionsSvcArgs
.Arg0
== ARM_SVC_SPM_RET_INVALID_PARAMS
) {
41 *MemoryAttributes
= 0;
42 return EFI_INVALID_PARAMETER
;
45 *MemoryAttributes
= GetMemoryPermissionsSvcArgs
.Arg0
;
51 RequestMemoryPermissionChange (
52 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
58 ARM_SVC_ARGS ChangeMemoryPermissionsSvcArgs
= {0};
60 ChangeMemoryPermissionsSvcArgs
.Arg0
= ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64
;
61 ChangeMemoryPermissionsSvcArgs
.Arg1
= BaseAddress
;
62 ChangeMemoryPermissionsSvcArgs
.Arg2
= EFI_SIZE_TO_PAGES(Length
);
63 ChangeMemoryPermissionsSvcArgs
.Arg3
= Permissions
;
65 ArmCallSvc (&ChangeMemoryPermissionsSvcArgs
);
67 Status
= ChangeMemoryPermissionsSvcArgs
.Arg0
;
70 case ARM_SVC_SPM_RET_SUCCESS
:
74 case ARM_SVC_SPM_RET_NOT_SUPPORTED
:
75 Status
= EFI_UNSUPPORTED
;
78 case ARM_SVC_SPM_RET_INVALID_PARAMS
:
79 Status
= EFI_INVALID_PARAMETER
;
82 case ARM_SVC_SPM_RET_DENIED
:
83 Status
= EFI_ACCESS_DENIED
;
86 case ARM_SVC_SPM_RET_NO_MEMORY
:
87 Status
= EFI_BAD_BUFFER_SIZE
;
91 Status
= EFI_ACCESS_DENIED
;
99 ArmSetMemoryRegionNoExec (
100 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
105 UINT32 MemoryAttributes
;
106 UINT32 CodePermission
;
108 Status
= GetMemoryPermissions (BaseAddress
, &MemoryAttributes
);
109 if (Status
!= EFI_INVALID_PARAMETER
) {
110 CodePermission
= SET_MEM_ATTR_CODE_PERM_XN
<< SET_MEM_ATTR_CODE_PERM_SHIFT
;
111 return RequestMemoryPermissionChange (
114 MemoryAttributes
| CodePermission
117 return EFI_INVALID_PARAMETER
;
121 ArmClearMemoryRegionNoExec (
122 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
127 UINT32 MemoryAttributes
;
128 UINT32 CodePermission
;
130 Status
= GetMemoryPermissions (BaseAddress
, &MemoryAttributes
);
131 if (Status
!= EFI_INVALID_PARAMETER
) {
132 CodePermission
= SET_MEM_ATTR_CODE_PERM_XN
<< SET_MEM_ATTR_CODE_PERM_SHIFT
;
133 return RequestMemoryPermissionChange (
136 MemoryAttributes
& ~CodePermission
139 return EFI_INVALID_PARAMETER
;
143 ArmSetMemoryRegionReadOnly (
144 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
149 UINT32 MemoryAttributes
;
150 UINT32 DataPermission
;
152 Status
= GetMemoryPermissions (BaseAddress
, &MemoryAttributes
);
153 if (Status
!= EFI_INVALID_PARAMETER
) {
154 DataPermission
= SET_MEM_ATTR_DATA_PERM_RO
<< SET_MEM_ATTR_DATA_PERM_SHIFT
;
155 return RequestMemoryPermissionChange (
158 MemoryAttributes
| DataPermission
161 return EFI_INVALID_PARAMETER
;
165 ArmClearMemoryRegionReadOnly (
166 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
171 UINT32 MemoryAttributes
;
172 UINT32 PermissionRequest
;
174 Status
= GetMemoryPermissions (BaseAddress
, &MemoryAttributes
);
175 if (Status
!= EFI_INVALID_PARAMETER
) {
176 PermissionRequest
= SET_MEM_ATTR_MAKE_PERM_REQUEST (SET_MEM_ATTR_DATA_PERM_RW
,
178 return RequestMemoryPermissionChange (
184 return EFI_INVALID_PARAMETER
;