1 /**************************************************************************//**
2  * @file     mmu_armv8a.h
3  * @brief    CMSIS Cortex-Axx MMU API header file
4  * @version  V1.0.0
5  * @date     20. october 2021
6  ******************************************************************************/
7 /*
8  * Copyright 2019 Broadcom
9  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
10  * Copyright (c) 2021 Arm Limited. All rights reserved.
11  * Copyright 2021 NXP
12  *
13  * SPDX-License-Identifier: Apache-2.0
14  *
15  * Licensed under the Apache License, Version 2.0 (the License); you may
16  * not use this file except in compliance with the License.
17  * You may obtain a copy of the License at
18  *
19  * www.apache.org/licenses/LICENSE-2.0
20  *
21  * Unless required by applicable law or agreed to in writing, software
22  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
23  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24  * See the License for the specific language governing permissions and
25  * limitations under the License.
26  */
27 
28 #if   defined ( __ICCARM__ )
29  #pragma system_include         /* treat file as system include file for MISRA check */
30 #elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
31   #pragma clang system_header   /* treat file as system include file */
32 #endif
33 
34 #ifndef __MMU_ARMV8A_H
35 #define __MMU_ARMV8A_H
36 
37 #include <stdbool.h>
38 #include <stddef.h>
39 
40 #ifdef __cplusplus
41  extern "C" {
42 #endif
43 
44 /******************************************************************************/
45 
46 /* Following Memory types supported through MAIR encodings can be passed
47  * by user through "attrs"(attributes) field of specified memory region.
48  * As MAIR supports such 8 encodings, we will reserve attrs[2:0];
49  * so that we can provide encodings upto 7 if needed in future.
50  */
51 #define MT_TYPE_MASK                            0x7U
52 #define MT_TYPE(attr)                           (attr & MT_TYPE_MASK)
53 #define MT_DEVICE_nGnRnE                        0U
54 #define MT_DEVICE_nGnRE                         1U
55 #define MT_DEVICE_GRE                           2U
56 #define MT_NORMAL_NC                            3U
57 #define MT_NORMAL                               4U
58 #define MT_NORMAL_WT                            5U
59 
60 #define MEMORY_ATTRIBUTES                       ((0x00 << (MT_DEVICE_nGnRnE * 8)) | \
61                                                 (0x04 << (MT_DEVICE_nGnRE * 8))   | \
62                                                 (0x0c << (MT_DEVICE_GRE * 8))     | \
63                                                 (0x44 << (MT_NORMAL_NC * 8))      | \
64                                                 (0xffUL << (MT_NORMAL * 8))       | \
65                                                 (0xbbUL << (MT_NORMAL_WT * 8)))
66 
67 /* More flags from user's perpective are supported using remaining bits
68  * of "attrs" field, i.e. attrs[31:3], underlying code will take care
69  * of setting PTE fields correctly.
70  *
71  * current usage of attrs[31:3] is:
72  * attrs[3] : Access Permissions
73  * attrs[4] : Memory access from secure/ns state
74  * attrs[5] : Execute Permissions privileged mode (PXN)
75  * attrs[6] : Execute Permissions unprivileged mode (UXN)
76  * attrs[7] : Mirror RO/RW permissions to EL0
77  * attrs[8] : Overwrite existing mapping if any
78  *
79  */
80 #define MT_PERM_SHIFT                          3U
81 #define MT_SEC_SHIFT                           4U
82 #define MT_P_EXECUTE_SHIFT                     5U
83 #define MT_U_EXECUTE_SHIFT                     6U
84 #define MT_RW_AP_SHIFT                         7U
85 #define MT_NO_OVERWRITE_SHIFT                  8U
86 
87 #define MT_RO                                  (0U << MT_PERM_SHIFT)
88 #define MT_RW                                  (1U << MT_PERM_SHIFT)
89 
90 #define MT_RW_AP_ELx                           (1U << MT_RW_AP_SHIFT)
91 #define MT_RW_AP_EL_HIGHER                     (0U << MT_RW_AP_SHIFT)
92 
93 #define MT_SECURE                              (0U << MT_SEC_SHIFT)
94 #define MT_NS                                  (1U << MT_SEC_SHIFT)
95 
96 #define MT_P_EXECUTE                           (0U << MT_P_EXECUTE_SHIFT)
97 #define MT_P_EXECUTE_NEVER                     (1U << MT_P_EXECUTE_SHIFT)
98 
99 #define MT_U_EXECUTE                           (0U << MT_U_EXECUTE_SHIFT)
100 #define MT_U_EXECUTE_NEVER                     (1U << MT_U_EXECUTE_SHIFT)
101 
102 #define MT_NO_OVERWRITE                        (1U << MT_NO_OVERWRITE_SHIFT)
103 
104 #define MT_P_RW_U_RW                           (MT_RW | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
105 #define MT_P_RW_U_NA                           (MT_RW | MT_RW_AP_EL_HIGHER  | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
106 #define MT_P_RO_U_RO                           (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
107 #define MT_P_RO_U_NA                           (MT_RO | MT_RW_AP_EL_HIGHER  | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
108 #define MT_P_RO_U_RX                           (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE)
109 #define MT_P_RX_U_RX                           (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE | MT_U_EXECUTE)
110 #define MT_P_RX_U_NA                           (MT_RO | MT_RW_AP_EL_HIGHER  | MT_P_EXECUTE | MT_U_EXECUTE_NEVER)
111 
112 #ifdef CONFIG_ARMV8_A_NS
113 #define MT_DEFAULT_SECURE_STATE                MT_NS
114 #else
115 #define MT_DEFAULT_SECURE_STATE                MT_SECURE
116 #endif
117 #ifndef CONFIG_ARM64_PA_BITS
118 #define CONFIG_ARM64_PA_BITS                   48
119 #endif
120 #ifndef CONFIG_ARM64_VA_BITS
121 #define CONFIG_ARM64_VA_BITS                   48
122 #endif
123 
124 /*
125  * PTE descriptor can be Block descriptor or Table descriptor
126  * or Page descriptor.
127  */
128 #define PTE_DESC_TYPE_MASK                     3U
129 #define PTE_BLOCK_DESC                         1U
130 #define PTE_TABLE_DESC                         3U
131 #define PTE_PAGE_DESC                          3U
132 #define PTE_INVALID_DESC                       0U
133 
134 /*
135  * Block and Page descriptor attributes fields
136  */
137 #define PTE_BLOCK_DESC_MEMTYPE(x)              (x << 2)
138 #define PTE_BLOCK_DESC_NS                      (1ULL << 5)
139 #define PTE_BLOCK_DESC_AP_ELx                  (1ULL << 6)
140 #define PTE_BLOCK_DESC_AP_EL_HIGHER            (0ULL << 6)
141 #define PTE_BLOCK_DESC_AP_RO                   (1ULL << 7)
142 #define PTE_BLOCK_DESC_AP_RW                   (0ULL << 7)
143 #define PTE_BLOCK_DESC_NON_SHARE               (0ULL << 8)
144 #define PTE_BLOCK_DESC_OUTER_SHARE             (2ULL << 8)
145 #define PTE_BLOCK_DESC_INNER_SHARE             (3ULL << 8)
146 #define PTE_BLOCK_DESC_AF                      (1ULL << 10)
147 #define PTE_BLOCK_DESC_NG                      (1ULL << 11)
148 #define PTE_BLOCK_DESC_PXN                     (1ULL << 53)
149 #define PTE_BLOCK_DESC_UXN                     (1ULL << 54)
150 
151 /*
152  * TCR definitions.
153  */
154 #define TCR_EL1_IPS_SHIFT                      32U
155 #define TCR_EL2_PS_SHIFT                       16U
156 #define TCR_EL3_PS_SHIFT                       16U
157 
158 #define TCR_T0SZ_SHIFT                         0U
159 #define TCR_T0SZ(x)                            ((64 - (x)) << TCR_T0SZ_SHIFT)
160 
161 #define TCR_IRGN_NC                            (0ULL << 8)
162 #define TCR_IRGN_WBWA                          (1ULL << 8)
163 #define TCR_IRGN_WT                            (2ULL << 8)
164 #define TCR_IRGN_WBNWA                         (3ULL << 8)
165 #define TCR_IRGN_MASK                          (3ULL << 8)
166 #define TCR_ORGN_NC                            (0ULL << 10)
167 #define TCR_ORGN_WBWA                          (1ULL << 10)
168 #define TCR_ORGN_WT                            (2ULL << 10)
169 #define TCR_ORGN_WBNWA                         (3ULL << 10)
170 #define TCR_ORGN_MASK                          (3ULL << 10)
171 #define TCR_SHARED_NON                         (0ULL << 12)
172 #define TCR_SHARED_OUTER                       (2ULL << 12)
173 #define TCR_SHARED_INNER                       (3ULL << 12)
174 #define TCR_TG0_4K                             (0ULL << 14)
175 #define TCR_TG0_64K                            (1ULL << 14)
176 #define TCR_TG0_16K                            (2ULL << 14)
177 #define TCR_EPD1_DISABLE                       (1ULL << 23)
178 
179 #define TCR_PS_BITS_4GB                        0x0ULL
180 #define TCR_PS_BITS_64GB                       0x1ULL
181 #define TCR_PS_BITS_1TB                        0x2ULL
182 #define TCR_PS_BITS_4TB                        0x3ULL
183 #define TCR_PS_BITS_16TB                       0x4ULL
184 #define TCR_PS_BITS_256TB                      0x5ULL
185 
186 /* Region definition data structure */
187 struct ARM_MMU_region {
188                                  /* Region BasePhysical Address */
189   uintptr_t base_pa;
190   /* Region Base Virtual Address */
191   uintptr_t base_va;
192   /* Region size */
193   size_t size;
194   /* Region Name */
195   const char *name;
196   /* Region Attributes */
197   uint32_t attrs;
198 };
199 
200 /* MMU configuration data structure */
201 struct ARM_MMU_config {
202   /* Number of regions */
203   unsigned int num_regions;
204   /* Regions */
205   const struct ARM_MMU_region *mmu_regions;
206   /* Number of OS memory regions */
207   unsigned int num_os_ranges;
208   /* OS memory regions */
209   const struct ARM_MMU_flat_range *mmu_os_ranges;
210 };
211 
212 struct ARM_MMU_flat_range {
213   char *name;
214   void *start;
215   void *end;
216   uint32_t attrs;
217 };
218 
219 struct ARM_MMU_ptables {
220   uint64_t *base_xlat_table;
221 };
222 
223 /* Convenience macros to represent the ARMv8-A-specific
224  * configuration for memory access permission and
225  * cache-ability attribution.
226  */
227 
228 #define MMU_REGION_ENTRY(_name, _base_pa, _base_va, _size, _attrs) \
229   {\
230     .name = _name, \
231     .base_pa = _base_pa, \
232     .base_va = _base_va, \
233     .size = _size, \
234     .attrs = _attrs, \
235   }
236 
237 #define MMU_REGION_FLAT_ENTRY(name, adr, sz, attrs) \
238         MMU_REGION_ENTRY(name, adr, adr, sz, attrs)
239 
240 void ARM_MMU_Initialize(const struct ARM_MMU_config *MMU_config, bool is_primary_core);
241 int ARM_MMU_AddMap(const char *name, uintptr_t phys, uintptr_t virt, size_t size, uint32_t attrs);
242 void ARM_MMU_InvalidateTLB(void);
243 
244 #ifdef __cplusplus
245 }
246 #endif
247 
248 #endif /* __MMU_ARMV8A_H */
249