Zephyr API Documentation  3.6.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
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#define MT_TYPE_MASK 0x7U
21#define MT_TYPE(attr) (attr & MT_TYPE_MASK)
22#define MT_DEVICE_nGnRnE 0U
23#define MT_DEVICE_nGnRE 1U
24#define MT_DEVICE_GRE 2U
25#define MT_NORMAL_NC 3U
26#define MT_NORMAL 4U
27#define MT_NORMAL_WT 5U
28
29#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 *
49 */
50#define MT_PERM_SHIFT 3U
51#define MT_SEC_SHIFT 4U
52#define MT_P_EXECUTE_SHIFT 5U
53#define MT_U_EXECUTE_SHIFT 6U
54#define MT_RW_AP_SHIFT 7U
55#define MT_NO_OVERWRITE_SHIFT 8U
56#define MT_NON_GLOBAL_SHIFT 9U
57
58#define MT_RO (0U << MT_PERM_SHIFT)
59#define MT_RW (1U << MT_PERM_SHIFT)
60
61#define MT_RW_AP_ELx (1U << MT_RW_AP_SHIFT)
62#define MT_RW_AP_EL_HIGHER (0U << MT_RW_AP_SHIFT)
63
64#define MT_SECURE (0U << MT_SEC_SHIFT)
65#define MT_NS (1U << MT_SEC_SHIFT)
66
67#define MT_P_EXECUTE (0U << MT_P_EXECUTE_SHIFT)
68#define MT_P_EXECUTE_NEVER (1U << MT_P_EXECUTE_SHIFT)
69
70#define MT_U_EXECUTE (0U << MT_U_EXECUTE_SHIFT)
71#define MT_U_EXECUTE_NEVER (1U << MT_U_EXECUTE_SHIFT)
72
73#define MT_NO_OVERWRITE (1U << MT_NO_OVERWRITE_SHIFT)
74
75#define MT_G (0U << MT_NON_GLOBAL_SHIFT)
76#define MT_NG (1U << MT_NON_GLOBAL_SHIFT)
77
78#define MT_P_RW_U_RW (MT_RW | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
79#define MT_P_RW_U_NA (MT_RW | MT_RW_AP_EL_HIGHER | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
80#define MT_P_RO_U_RO (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
81#define MT_P_RO_U_NA (MT_RO | MT_RW_AP_EL_HIGHER | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER)
82#define MT_P_RO_U_RX (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE)
83#define MT_P_RX_U_RX (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE | MT_U_EXECUTE)
84#define MT_P_RX_U_NA (MT_RO | MT_RW_AP_EL_HIGHER | MT_P_EXECUTE | MT_U_EXECUTE_NEVER)
85
86#ifdef CONFIG_ARMV8_A_NS
87#define MT_DEFAULT_SECURE_STATE MT_NS
88#else
89#define MT_DEFAULT_SECURE_STATE MT_SECURE
90#endif
91
92/*
93 * ARM guarantees at least 8 ASID bits.
94 * We may have more available, but do not make use of them for the time being.
95 */
96#define VM_ASID_BITS 8
97#define TTBR_ASID_SHIFT 48
98
99/*
100 * PTE descriptor can be Block descriptor or Table descriptor
101 * or Page descriptor.
102 */
103#define PTE_DESC_TYPE_MASK 3U
104#define PTE_BLOCK_DESC 1U
105#define PTE_TABLE_DESC 3U
106#define PTE_PAGE_DESC 3U
107#define PTE_INVALID_DESC 0U
108
109/*
110 * Block and Page descriptor attributes fields
111 */
112#define PTE_BLOCK_DESC_MEMTYPE(x) (x << 2)
113#define PTE_BLOCK_DESC_NS (1ULL << 5)
114#define PTE_BLOCK_DESC_AP_ELx (1ULL << 6)
115#define PTE_BLOCK_DESC_AP_EL_HIGHER (0ULL << 6)
116#define PTE_BLOCK_DESC_AP_RO (1ULL << 7)
117#define PTE_BLOCK_DESC_AP_RW (0ULL << 7)
118#define PTE_BLOCK_DESC_NON_SHARE (0ULL << 8)
119#define PTE_BLOCK_DESC_OUTER_SHARE (2ULL << 8)
120#define PTE_BLOCK_DESC_INNER_SHARE (3ULL << 8)
121#define PTE_BLOCK_DESC_AF (1ULL << 10)
122#define PTE_BLOCK_DESC_NG (1ULL << 11)
123#define PTE_BLOCK_DESC_PXN (1ULL << 53)
124#define PTE_BLOCK_DESC_UXN (1ULL << 54)
125
126/*
127 * TCR definitions.
128 */
129#define TCR_EL1_IPS_SHIFT 32U
130#define TCR_EL2_PS_SHIFT 16U
131#define TCR_EL3_PS_SHIFT 16U
132
133#define TCR_T0SZ_SHIFT 0U
134#define TCR_T0SZ(x) ((64 - (x)) << TCR_T0SZ_SHIFT)
135
136#define TCR_IRGN_NC (0ULL << 8)
137#define TCR_IRGN_WBWA (1ULL << 8)
138#define TCR_IRGN_WT (2ULL << 8)
139#define TCR_IRGN_WBNWA (3ULL << 8)
140#define TCR_IRGN_MASK (3ULL << 8)
141#define TCR_ORGN_NC (0ULL << 10)
142#define TCR_ORGN_WBWA (1ULL << 10)
143#define TCR_ORGN_WT (2ULL << 10)
144#define TCR_ORGN_WBNWA (3ULL << 10)
145#define TCR_ORGN_MASK (3ULL << 10)
146#define TCR_SHARED_NON (0ULL << 12)
147#define TCR_SHARED_OUTER (2ULL << 12)
148#define TCR_SHARED_INNER (3ULL << 12)
149#define TCR_TG0_4K (0ULL << 14)
150#define TCR_TG0_64K (1ULL << 14)
151#define TCR_TG0_16K (2ULL << 14)
152#define TCR_EPD1_DISABLE (1ULL << 23)
153#define TCR_TG1_16K (1ULL << 30)
154#define TCR_TG1_4K (2ULL << 30)
155#define TCR_TG1_64K (3ULL << 30)
156
157#define TCR_PS_BITS_4GB 0x0ULL
158#define TCR_PS_BITS_64GB 0x1ULL
159#define TCR_PS_BITS_1TB 0x2ULL
160#define TCR_PS_BITS_4TB 0x3ULL
161#define TCR_PS_BITS_16TB 0x4ULL
162#define TCR_PS_BITS_256TB 0x5ULL
163
164#ifndef _ASMLANGUAGE
165
166/* Region definition data structure */
167struct arm_mmu_region {
168 /* Region Base Physical Address */
170 /* Region Base Virtual Address */
172 /* Region size */
173 size_t size;
174 /* Region Name */
175 const char *name;
176 /* Region Attributes */
178};
179
180/* MMU configuration data structure */
181struct arm_mmu_config {
182 /* Number of regions */
183 unsigned int num_regions;
184 /* Regions */
185 const struct arm_mmu_region *mmu_regions;
186};
187
191};
192
193/* Convenience macros to represent the ARMv8-A-specific
194 * configuration for memory access permission and
195 * cache-ability attribution.
196 */
197
198#define MMU_REGION_ENTRY(_name, _base_pa, _base_va, _size, _attrs) \
199 {\
200 .name = _name, \
201 .base_pa = _base_pa, \
202 .base_va = _base_va, \
203 .size = _size, \
204 .attrs = _attrs, \
205 }
206
207#define MMU_REGION_FLAT_ENTRY(name, adr, sz, attrs) \
208 MMU_REGION_ENTRY(name, adr, adr, sz, attrs)
209
210/*
211 * @brief Auto generate mmu region entry for node_id
212 *
213 * Example usage:
214 *
215 * @code{.c}
216 * DT_FOREACH_STATUS_OKAY_VARGS(nxp_imx_gpio,
217 * MMU_REGION_DT_FLAT_ENTRY,
218 * (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS))
219 * @endcode
220 *
221 * @note Since devicetree_generated.h does not include
222 * node_id##_P_reg_FOREACH_PROP_ELEM* definitions,
223 * we can't automate dts node with multiple reg
224 * entries.
225 */
226#define MMU_REGION_DT_FLAT_ENTRY(node_id, attrs) \
227 MMU_REGION_FLAT_ENTRY(DT_NODE_FULL_NAME(node_id), \
228 DT_REG_ADDR(node_id), \
229 DT_REG_SIZE(node_id), \
230 attrs),
231
232/*
233 * @brief Auto generate mmu region entry for status = "okay"
234 * nodes compatible to a driver
235 *
236 * Example usage:
237 *
238 * @code{.c}
239 * MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(nxp_imx_gpio,
240 * (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS))
241 * @endcode
242 *
243 * @note This is a wrapper of @ref MMU_REGION_DT_FLAT_ENTRY
244 */
245#define MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(compat, attr) \
246 DT_FOREACH_STATUS_OKAY_VARGS(compat, \
247 MMU_REGION_DT_FLAT_ENTRY, attr)
248
249/* Kernel macros for memory attribution
250 * (access permissions and cache-ability).
251 *
252 * The macros are to be stored in k_mem_partition_attr_t
253 * objects. The format of a k_mem_partition_attr_t object
254 * is an uint32_t composed by permission and attribute flags
255 * located in include/arch/arm64/arm_mmu.h
256 */
257
258/* Read-Write access permission attributes */
259#define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \
260 {MT_P_RW_U_RW})
261#define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \
262 {MT_P_RW_U_NA})
263#define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \
264 {MT_P_RO_U_RO})
265#define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \
266 {MT_P_RO_U_NA})
267/* Execution-allowed attributes */
268#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \
269 {MT_P_RX_U_RX})
270/* Typedef for the k_mem_partition attribute */
272
273/* Reference to the MMU configuration.
274 *
275 * This struct is defined and populated for each SoC (in the SoC definition),
276 * and holds the build-time configuration information for the fixed MMU
277 * regions enabled during kernel initialization.
278 */
279extern const struct arm_mmu_config mmu_config;
280
281#endif /* _ASMLANGUAGE */
282
283#endif /* ZEPHYR_INCLUDE_ARCH_ARM64_ARM_MMU_H_ */
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:124
const struct arm_mmu_region * mmu_regions
Definition: arm_mmu.h:128
unsigned int num_regions
Definition: arm_mmu.h:183
Definition: arm_mmu.h:188
uint64_t ttbr0
Definition: arm_mmu.h:190
uint64_t * base_xlat_table
Definition: arm_mmu.h:189
Definition: arm_mmu.h:110
uintptr_t base_va
Definition: arm_mmu.h:114
size_t size
Definition: arm_mmu.h:116
uintptr_t base_pa
Definition: arm_mmu.h:112
const char * name
Definition: arm_mmu.h:118
uint32_t attrs
Definition: arm_mmu.h:120
Definition: arm_mpu_v7m.h:160
uint32_t attrs
Definition: arm_mmu.h:271