Zephyr API Documentation 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
arm_mmu.h
Go to the documentation of this file.
1/*
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
11
12#ifndef _ASMLANGUAGE
13#include <stdint.h>
14#include <stdlib.h>
15#endif
16
17/* Following Memory types supported through MAIR encodings can be passed
18 * by user through "attrs"(attributes) field of specified memory region.
19 * As MAIR supports such 8 encodings, we will reserve attrs[2:0];
20 * so that we can provide encodings upto 7 if needed in future.
21 */
22#define MT_TYPE_MASK 0x7U
23#define MT_TYPE(attr) (attr & MT_TYPE_MASK)
24#define MT_DEVICE_nGnRnE 0U
25#define MT_DEVICE_nGnRE 1U
26#define MT_DEVICE_GRE 2U
27#define MT_NORMAL_NC 3U
28#define MT_NORMAL 4U
29#define MT_NORMAL_WT 5U
30
31#define MEMORY_ATTRIBUTES ((0x00 << (MT_DEVICE_nGnRnE * 8)) | \
32 (0x04 << (MT_DEVICE_nGnRE * 8)) | \
33 (0x0c << (MT_DEVICE_GRE * 8)) | \
34 (0x44 << (MT_NORMAL_NC * 8)) | \
35 (0xffUL << (MT_NORMAL * 8)) | \
36 (0xbbUL << (MT_NORMAL_WT * 8)))
37
38/* More flags from user's perspective are supported using remaining bits
39 * of "attrs" field, i.e. attrs[31:3], underlying code will take care
40 * of setting PTE fields correctly.
41 *
42 * current usage of attrs[31:3] is:
43 * attrs[3] : Access Permissions
44 * attrs[4] : Memory access from secure/ns state
45 * attrs[5] : Execute Permissions privileged mode (PXN)
46 * attrs[6] : Execute Permissions unprivileged mode (UXN)
47 * attrs[7] : Mirror RO/RW permissions to EL0
48 * attrs[8] : Overwrite existing mapping if any
49 * attrs[9] : non-Global mapping (nG)
50 * attrs[10]: Paged-out mapping
51 *
52 */
53#define MT_PERM_SHIFT 3U
54#define MT_SEC_SHIFT 4U
55#define MT_P_EXECUTE_SHIFT 5U
56#define MT_U_EXECUTE_SHIFT 6U
57#define MT_RW_AP_SHIFT 7U
58#define MT_NO_OVERWRITE_SHIFT 8U
59#define MT_NON_GLOBAL_SHIFT 9U
60#define MT_PAGED_OUT_SHIFT 10U
61
62#define MT_RO (0U << MT_PERM_SHIFT)
63#define MT_RW (1U << MT_PERM_SHIFT)
64
65#define MT_RW_AP_ELx (1U << MT_RW_AP_SHIFT)
66#define MT_RW_AP_EL_HIGHER (0U << MT_RW_AP_SHIFT)
67
68#define MT_SECURE (0U << MT_SEC_SHIFT)
69#define MT_NS (1U << MT_SEC_SHIFT)
70
71#define MT_P_EXECUTE (0U << MT_P_EXECUTE_SHIFT)
72#define MT_P_EXECUTE_NEVER (1U << MT_P_EXECUTE_SHIFT)
73
74#define MT_U_EXECUTE (0U << MT_U_EXECUTE_SHIFT)
75#define MT_U_EXECUTE_NEVER (1U << MT_U_EXECUTE_SHIFT)
76
77#define MT_NO_OVERWRITE (1U << MT_NO_OVERWRITE_SHIFT)
78
79#define MT_G (0U << MT_NON_GLOBAL_SHIFT)
80#define MT_NG (1U << MT_NON_GLOBAL_SHIFT)
81
82#define MT_PAGED_OUT (1U << MT_PAGED_OUT_SHIFT)
83
84#define MT_P_RW_U_RW (MT_RW | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
85#define MT_P_RW_U_NA (MT_RW | MT_RW_AP_EL_HIGHER | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
86#define MT_P_RO_U_RO (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
87#define MT_P_RO_U_NA (MT_RO | MT_RW_AP_EL_HIGHER | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
88#define MT_P_RO_U_RX (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE)
89#define MT_P_RX_U_RX (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE | MT_U_EXECUTE)
90#define MT_P_RX_U_NA (MT_RO | MT_RW_AP_EL_HIGHER | MT_P_EXECUTE | MT_U_EXECUTE_NEVER)
91
92#ifdef CONFIG_ARMV8_A_NS
93#define MT_DEFAULT_SECURE_STATE MT_NS
94#else
95#define MT_DEFAULT_SECURE_STATE MT_SECURE
96#endif
97
98/* Definitions used by arch_page_info_get() */
99#define ARCH_DATA_PAGE_LOADED BIT(0)
100#define ARCH_DATA_PAGE_ACCESSED BIT(1)
101#define ARCH_DATA_PAGE_DIRTY BIT(2)
102#define ARCH_DATA_PAGE_NOT_MAPPED BIT(3)
103
104/*
105 * Special unpaged "location" tags (highest possible descriptor physical
106 * address values unlikely to conflict with backing store locations)
107 */
108#define ARCH_UNPAGED_ANON_ZERO 0x0000fffffffff000
109#define ARCH_UNPAGED_ANON_UNINIT 0x0000ffffffffe000
110
111#ifndef _ASMLANGUAGE
112
113/* Region definition data structure */
114struct arm_mmu_region {
115 /* Region Base Physical Address */
117 /* Region Base Virtual Address */
119 /* Region size */
120 size_t size;
121 /* Region Name */
122 const char *name;
123 /* Region Attributes */
125};
126
127/* MMU configuration data structure */
128struct arm_mmu_config {
129 /* Number of regions */
130 unsigned int num_regions;
131 /* Regions */
132 const struct arm_mmu_region *mmu_regions;
133};
134
139
140/* Convenience macros to represent the ARMv8-A-specific
141 * configuration for memory access permission and
142 * cache-ability attribution.
143 */
144
145#define MMU_REGION_ENTRY(_name, _base_pa, _base_va, _size, _attrs) \
146 {\
147 .name = _name, \
148 .base_pa = _base_pa, \
149 .base_va = _base_va, \
150 .size = _size, \
151 .attrs = _attrs, \
152 }
153
154#define MMU_REGION_FLAT_ENTRY(name, adr, sz, attrs) \
155 MMU_REGION_ENTRY(name, adr, adr, sz, attrs)
156
157/*
158 * @brief Auto generate mmu region entry for node_id
159 *
160 * Example usage:
161 *
162 * @code{.c}
163 * DT_FOREACH_STATUS_OKAY_VARGS(nxp_imx_gpio,
164 * MMU_REGION_DT_FLAT_ENTRY,
165 * (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS))
166 * @endcode
167 *
168 * @note Since devicetree_generated.h does not include
169 * node_id##_P_reg_FOREACH_PROP_ELEM* definitions,
170 * we can't automate dts node with multiple reg
171 * entries.
172 */
173#define MMU_REGION_DT_FLAT_ENTRY(node_id, attrs) \
174 MMU_REGION_FLAT_ENTRY(DT_NODE_FULL_NAME(node_id), \
175 DT_REG_ADDR(node_id), \
176 DT_REG_SIZE(node_id), \
177 attrs),
178
179/*
180 * @brief Auto generate mmu region entry for status = "okay"
181 * nodes compatible to a driver
182 *
183 * Example usage:
184 *
185 * @code{.c}
186 * MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(nxp_imx_gpio,
187 * (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS))
188 * @endcode
189 *
190 * @note This is a wrapper of @ref MMU_REGION_DT_FLAT_ENTRY
191 */
192#define MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(compat, attr) \
193 DT_FOREACH_STATUS_OKAY_VARGS(compat, \
194 MMU_REGION_DT_FLAT_ENTRY, attr)
195
201#define _DT_MEM_ARM64_ARCH_BITS(dt_attr) \
202 (DT_MEM_ARCH_ATTR_GET(dt_attr) >> DT_MEM_ARCH_ATTR_SHIFT)
203
214#define DT_MEM_ATTR_TO_MT(dt_attr) \
215 ((DT_MEM_ATTR_GET(dt_attr) & DT_MEM_CACHEABLE) ? \
216 ((_DT_MEM_ARM64_ARCH_BITS(dt_attr) & ATTR_ARM64_CACHE_WB) ? \
217 (MT_NORMAL | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE) : \
218 (MT_NORMAL_WT | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE)) : \
219 (MT_NORMAL_NC | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE))
220
236#define MMU_REGION_DT_FLAT_ENTRY_FROM_DT(node_id) \
237 IF_ENABLED(DT_NODE_HAS_PROP(node_id, zephyr_memory_attr), \
238 (MMU_REGION_FLAT_ENTRY(DT_NODE_FULL_NAME(node_id), \
239 DT_REG_ADDR(node_id), \
240 DT_REG_SIZE(node_id), \
241 DT_MEM_ATTR_TO_MT( \
242 DT_PROP(node_id, zephyr_memory_attr))),))
243
249#define _DT_MEM_ARM64_SUPPORTED_MASK \
250 (DT_MEM_CACHEABLE | DT_MEM_ARM64(ATTR_ARM64_CACHE_WB))
251
258#define DT_MEM_ARM64_MMU_IS_VALID(dt_attr) \
259 (((dt_attr) & ~_DT_MEM_ARM64_SUPPORTED_MASK) == 0)
260
268#define ARM64_MMU_VALIDATE_DT_REGION(node_id) \
269 IF_ENABLED(DT_NODE_HAS_PROP(node_id, zephyr_memory_attr), \
270 (BUILD_ASSERT(DT_MEM_ARM64_MMU_IS_VALID( \
271 DT_PROP(node_id, zephyr_memory_attr)), \
272 "Unsupported zephyr,memory-attr for ARM64 MMU region " \
273 DT_NODE_FULL_NAME(node_id));))
274
285#define MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY_FROM_DT(compat) \
286 DT_FOREACH_STATUS_OKAY(compat, MMU_REGION_DT_FLAT_ENTRY_FROM_DT)
287
288/* Kernel macros for memory attribution
289 * (access permissions and cache-ability).
290 *
291 * The macros are to be stored in k_mem_partition_attr_t
292 * objects. The format of a k_mem_partition_attr_t object
293 * is an uint32_t composed by permission and attribute flags
294 * located in include/arch/arm64/arm_mmu.h
295 */
296
297/* Read-Write access permission attributes */
298#define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \
299 {MT_P_RW_U_RW})
300#define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \
301 {MT_P_RW_U_NA})
302#define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \
303 {MT_P_RO_U_RO})
304#define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \
305 {MT_P_RO_U_NA})
306/* Execution-allowed attributes */
307#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \
308 {MT_P_RX_U_RX})
309/* Typedef for the k_mem_partition attribute */
311
312/* Reference to the MMU configuration.
313 *
314 * This struct is defined and populated for each SoC (in the SoC definition),
315 * and holds the build-time configuration information for the fixed MMU
316 * regions enabled during kernel initialization.
317 */
318extern const struct arm_mmu_config mmu_config;
319
320#endif /* _ASMLANGUAGE */
321
322#endif /* ZEPHYR_INCLUDE_ARCH_ARM64_ARM_MMU_H_ */
ARM64 specific memory attribute definitions for devicetree.
const struct arm_mmu_config mmu_config
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT64_TYPE__ uint64_t
Definition stdint.h:91
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:105
Definition arm_mmu.h:127
const struct arm_mmu_region * mmu_regions
Definition arm_mmu.h:131
uint32_t num_regions
Definition arm_mmu.h:129
Definition arm_mmu.h:135
uint64_t ttbr0
Definition arm_mmu.h:137
uint64_t * base_xlat_table
Definition arm_mmu.h:136
Definition arm_mmu.h:113
uintptr_t base_va
Definition arm_mmu.h:117
size_t size
Definition arm_mmu.h:119
uintptr_t base_pa
Definition arm_mmu.h:115
const char * name
Definition arm_mmu.h:121
uint32_t attrs
Definition arm_mmu.h:123
Definition arm_mpu_v7m.h:145
uint32_t attrs
Definition arm_mmu.h:310