Line data Source code
1 0 : /*
2 : * Copyright 2019 Broadcom
3 : * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
4 : *
5 : * SPDX-License-Identifier: Apache-2.0
6 : */
7 : #ifndef ZEPHYR_INCLUDE_ARCH_ARM64_ARM_MMU_H_
8 : #define ZEPHYR_INCLUDE_ARCH_ARM64_ARM_MMU_H_
9 :
10 : #ifndef _ASMLANGUAGE
11 : #include <stdint.h>
12 : #include <stdlib.h>
13 : #endif
14 :
15 : /* Following Memory types supported through MAIR encodings can be passed
16 : * by user through "attrs"(attributes) field of specified memory region.
17 : * As MAIR supports such 8 encodings, we will reserve attrs[2:0];
18 : * so that we can provide encodings upto 7 if needed in future.
19 : */
20 0 : #define MT_TYPE_MASK 0x7U
21 0 : #define MT_TYPE(attr) (attr & MT_TYPE_MASK)
22 0 : #define MT_DEVICE_nGnRnE 0U
23 0 : #define MT_DEVICE_nGnRE 1U
24 0 : #define MT_DEVICE_GRE 2U
25 0 : #define MT_NORMAL_NC 3U
26 0 : #define MT_NORMAL 4U
27 0 : #define MT_NORMAL_WT 5U
28 :
29 0 : #define MEMORY_ATTRIBUTES ((0x00 << (MT_DEVICE_nGnRnE * 8)) | \
30 : (0x04 << (MT_DEVICE_nGnRE * 8)) | \
31 : (0x0c << (MT_DEVICE_GRE * 8)) | \
32 : (0x44 << (MT_NORMAL_NC * 8)) | \
33 : (0xffUL << (MT_NORMAL * 8)) | \
34 : (0xbbUL << (MT_NORMAL_WT * 8)))
35 :
36 : /* More flags from user's perspective are supported using remaining bits
37 : * of "attrs" field, i.e. attrs[31:3], underlying code will take care
38 : * of setting PTE fields correctly.
39 : *
40 : * current usage of attrs[31:3] is:
41 : * attrs[3] : Access Permissions
42 : * attrs[4] : Memory access from secure/ns state
43 : * attrs[5] : Execute Permissions privileged mode (PXN)
44 : * attrs[6] : Execute Permissions unprivileged mode (UXN)
45 : * attrs[7] : Mirror RO/RW permissions to EL0
46 : * attrs[8] : Overwrite existing mapping if any
47 : * attrs[9] : non-Global mapping (nG)
48 : * attrs[10]: Paged-out mapping
49 : *
50 : */
51 0 : #define MT_PERM_SHIFT 3U
52 0 : #define MT_SEC_SHIFT 4U
53 0 : #define MT_P_EXECUTE_SHIFT 5U
54 0 : #define MT_U_EXECUTE_SHIFT 6U
55 0 : #define MT_RW_AP_SHIFT 7U
56 0 : #define MT_NO_OVERWRITE_SHIFT 8U
57 0 : #define MT_NON_GLOBAL_SHIFT 9U
58 0 : #define MT_PAGED_OUT_SHIFT 10U
59 :
60 0 : #define MT_RO (0U << MT_PERM_SHIFT)
61 0 : #define MT_RW (1U << MT_PERM_SHIFT)
62 :
63 0 : #define MT_RW_AP_ELx (1U << MT_RW_AP_SHIFT)
64 0 : #define MT_RW_AP_EL_HIGHER (0U << MT_RW_AP_SHIFT)
65 :
66 0 : #define MT_SECURE (0U << MT_SEC_SHIFT)
67 0 : #define MT_NS (1U << MT_SEC_SHIFT)
68 :
69 0 : #define MT_P_EXECUTE (0U << MT_P_EXECUTE_SHIFT)
70 0 : #define MT_P_EXECUTE_NEVER (1U << MT_P_EXECUTE_SHIFT)
71 :
72 0 : #define MT_U_EXECUTE (0U << MT_U_EXECUTE_SHIFT)
73 0 : #define MT_U_EXECUTE_NEVER (1U << MT_U_EXECUTE_SHIFT)
74 :
75 0 : #define MT_NO_OVERWRITE (1U << MT_NO_OVERWRITE_SHIFT)
76 :
77 0 : #define MT_G (0U << MT_NON_GLOBAL_SHIFT)
78 0 : #define MT_NG (1U << MT_NON_GLOBAL_SHIFT)
79 :
80 0 : #define MT_PAGED_OUT (1U << MT_PAGED_OUT_SHIFT)
81 :
82 0 : #define MT_P_RW_U_RW (MT_RW | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
83 0 : #define MT_P_RW_U_NA (MT_RW | MT_RW_AP_EL_HIGHER | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
84 0 : #define MT_P_RO_U_RO (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
85 0 : #define MT_P_RO_U_NA (MT_RO | MT_RW_AP_EL_HIGHER | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
86 0 : #define MT_P_RO_U_RX (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE)
87 0 : #define MT_P_RX_U_RX (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE | MT_U_EXECUTE)
88 0 : #define MT_P_RX_U_NA (MT_RO | MT_RW_AP_EL_HIGHER | MT_P_EXECUTE | MT_U_EXECUTE_NEVER)
89 :
90 : #ifdef CONFIG_ARMV8_A_NS
91 : #define MT_DEFAULT_SECURE_STATE MT_NS
92 : #else
93 0 : #define MT_DEFAULT_SECURE_STATE MT_SECURE
94 : #endif
95 :
96 : /* Definitions used by arch_page_info_get() */
97 0 : #define ARCH_DATA_PAGE_LOADED BIT(0)
98 0 : #define ARCH_DATA_PAGE_ACCESSED BIT(1)
99 0 : #define ARCH_DATA_PAGE_DIRTY BIT(2)
100 0 : #define ARCH_DATA_PAGE_NOT_MAPPED BIT(3)
101 :
102 : /*
103 : * Special unpaged "location" tags (highest possible descriptor physical
104 : * address values unlikely to conflict with backing store locations)
105 : */
106 0 : #define ARCH_UNPAGED_ANON_ZERO 0x0000fffffffff000
107 0 : #define ARCH_UNPAGED_ANON_UNINIT 0x0000ffffffffe000
108 :
109 : #ifndef _ASMLANGUAGE
110 :
111 : /* Region definition data structure */
112 : struct arm_mmu_region {
113 : /* Region Base Physical Address */
114 : uintptr_t base_pa;
115 : /* Region Base Virtual Address */
116 : uintptr_t base_va;
117 : /* Region size */
118 : size_t size;
119 : /* Region Name */
120 : const char *name;
121 : /* Region Attributes */
122 : uint32_t attrs;
123 : };
124 :
125 : /* MMU configuration data structure */
126 : struct arm_mmu_config {
127 : /* Number of regions */
128 0 : unsigned int num_regions;
129 : /* Regions */
130 : const struct arm_mmu_region *mmu_regions;
131 : };
132 :
133 0 : struct arm_mmu_ptables {
134 0 : uint64_t *base_xlat_table;
135 0 : uint64_t ttbr0;
136 : };
137 :
138 : /* Convenience macros to represent the ARMv8-A-specific
139 : * configuration for memory access permission and
140 : * cache-ability attribution.
141 : */
142 :
143 0 : #define MMU_REGION_ENTRY(_name, _base_pa, _base_va, _size, _attrs) \
144 : {\
145 : .name = _name, \
146 : .base_pa = _base_pa, \
147 : .base_va = _base_va, \
148 : .size = _size, \
149 : .attrs = _attrs, \
150 : }
151 :
152 0 : #define MMU_REGION_FLAT_ENTRY(name, adr, sz, attrs) \
153 : MMU_REGION_ENTRY(name, adr, adr, sz, attrs)
154 :
155 : /*
156 : * @brief Auto generate mmu region entry for node_id
157 : *
158 : * Example usage:
159 : *
160 : * @code{.c}
161 : * DT_FOREACH_STATUS_OKAY_VARGS(nxp_imx_gpio,
162 : * MMU_REGION_DT_FLAT_ENTRY,
163 : * (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS))
164 : * @endcode
165 : *
166 : * @note Since devicetree_generated.h does not include
167 : * node_id##_P_reg_FOREACH_PROP_ELEM* definitions,
168 : * we can't automate dts node with multiple reg
169 : * entries.
170 : */
171 0 : #define MMU_REGION_DT_FLAT_ENTRY(node_id, attrs) \
172 : MMU_REGION_FLAT_ENTRY(DT_NODE_FULL_NAME(node_id), \
173 : DT_REG_ADDR(node_id), \
174 : DT_REG_SIZE(node_id), \
175 : attrs),
176 :
177 : /*
178 : * @brief Auto generate mmu region entry for status = "okay"
179 : * nodes compatible to a driver
180 : *
181 : * Example usage:
182 : *
183 : * @code{.c}
184 : * MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(nxp_imx_gpio,
185 : * (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS))
186 : * @endcode
187 : *
188 : * @note This is a wrapper of @ref MMU_REGION_DT_FLAT_ENTRY
189 : */
190 0 : #define MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(compat, attr) \
191 : DT_FOREACH_STATUS_OKAY_VARGS(compat, \
192 : MMU_REGION_DT_FLAT_ENTRY, attr)
193 :
194 : /* Kernel macros for memory attribution
195 : * (access permissions and cache-ability).
196 : *
197 : * The macros are to be stored in k_mem_partition_attr_t
198 : * objects. The format of a k_mem_partition_attr_t object
199 : * is an uint32_t composed by permission and attribute flags
200 : * located in include/arch/arm64/arm_mmu.h
201 : */
202 :
203 : /* Read-Write access permission attributes */
204 0 : #define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \
205 : {MT_P_RW_U_RW})
206 0 : #define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \
207 : {MT_P_RW_U_NA})
208 0 : #define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \
209 : {MT_P_RO_U_RO})
210 0 : #define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \
211 : {MT_P_RO_U_NA})
212 : /* Execution-allowed attributes */
213 0 : #define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \
214 : {MT_P_RX_U_RX})
215 : /* Typedef for the k_mem_partition attribute */
216 0 : typedef struct { uint32_t attrs; } k_mem_partition_attr_t;
217 :
218 : /* Reference to the MMU configuration.
219 : *
220 : * This struct is defined and populated for each SoC (in the SoC definition),
221 : * and holds the build-time configuration information for the fixed MMU
222 : * regions enabled during kernel initialization.
223 : */
224 0 : extern const struct arm_mmu_config mmu_config;
225 :
226 : #endif /* _ASMLANGUAGE */
227 :
228 : #endif /* ZEPHYR_INCLUDE_ARCH_ARM64_ARM_MMU_H_ */
|