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 */
167 struct arm_mmu_region {
168 	/* Region Base Physical Address */
169 	uintptr_t base_pa;
170 	/* Region Base Virtual Address */
171 	uintptr_t base_va;
172 	/* Region size */
173 	size_t size;
174 	/* Region Name */
175 	const char *name;
176 	/* Region Attributes */
177 	uint32_t attrs;
178 };
179 
180 /* MMU configuration data structure */
181 struct arm_mmu_config {
182 	/* Number of regions */
183 	unsigned int num_regions;
184 	/* Regions */
185 	const struct arm_mmu_region *mmu_regions;
186 };
187 
188 struct arm_mmu_ptables {
189 	uint64_t *base_xlat_table;
190 	uint64_t ttbr0;
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 /* Kernel macros for memory attribution
211  * (access permissions and cache-ability).
212  *
213  * The macros are to be stored in k_mem_partition_attr_t
214  * objects. The format of a k_mem_partition_attr_t object
215  * is an uint32_t composed by permission and attribute flags
216  * located in include/arch/arm64/arm_mmu.h
217  */
218 
219 /* Read-Write access permission attributes */
220 #define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \
221 			{MT_P_RW_U_RW})
222 #define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \
223 			{MT_P_RW_U_NA})
224 #define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \
225 			{MT_P_RO_U_RO})
226 #define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \
227 			{MT_P_RO_U_NA})
228 /* Execution-allowed attributes */
229 #define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \
230 			{MT_P_RX_U_RX})
231 /* Typedef for the k_mem_partition attribute */
232 typedef struct { uint32_t attrs; } k_mem_partition_attr_t;
233 
234 /* Reference to the MMU configuration.
235  *
236  * This struct is defined and populated for each SoC (in the SoC definition),
237  * and holds the build-time configuration information for the fixed MMU
238  * regions enabled during kernel initialization.
239  */
240 extern const struct arm_mmu_config mmu_config;
241 
242 #endif /* _ASMLANGUAGE */
243 
244 #endif /* ZEPHYR_INCLUDE_ARCH_ARM64_ARM_MMU_H_ */
245