1 /*
2  * Copyright (c) 2018 Linaro Limited.
3  * Copyright (c) 2018 Nordic Semiconductor ASA.
4  * Copyright (c) 2021 Arm Limited (or its affiliates). All rights reserved.
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 #ifndef ZEPHYR_INCLUDE_ARCH_ARM64_CORTEX_R_MPU_ARM_MPU_H_
9 #define ZEPHYR_INCLUDE_ARCH_ARM64_CORTEX_R_MPU_ARM_MPU_H_
10 
11 #ifndef _ASMLANGUAGE
12 /*
13  * Convenience macros to represent the ARMv8-R64-specific configuration
14  * for memory access permission and cache-ability attribution.
15  */
16 /* MPU MPUIR Register Definitions */
17 #define MPU_IR_REGION_Msk	(0xFFU)
18 /* MPU RBAR Register attribute msk Definitions */
19 #define MPU_RBAR_BASE_Pos	6U
20 #define MPU_RBAR_BASE_Msk	(0x3FFFFFFFFFFFFFFUL << MPU_RBAR_BASE_Pos)
21 #define MPU_RBAR_SH_Pos		4U
22 #define MPU_RBAR_SH_Msk		(0x3UL << MPU_RBAR_SH_Pos)
23 #define MPU_RBAR_AP_Pos		2U
24 #define MPU_RBAR_AP_Msk		(0x3UL << MPU_RBAR_AP_Pos)
25 /* RBAR_EL1 XN */
26 #define MPU_RBAR_XN_Pos		1U
27 #define MPU_RBAR_XN_Msk		(0x1UL << MPU_RBAR_XN_Pos)
28 
29 /* MPU PLBAR_ELx Register Definitions */
30 #define MPU_RLAR_LIMIT_Pos	6U
31 #define MPU_RLAR_LIMIT_Msk	(0x3FFFFFFFFFFFFFFUL << MPU_RLAR_LIMIT_Pos)
32 #define MPU_RLAR_AttrIndx_Pos	1U
33 #define MPU_RLAR_AttrIndx_Msk	(0x7UL << MPU_RLAR_AttrIndx_Pos)
34 #define MPU_RLAR_EN_Msk		(0x1UL)
35 
36 /* PRBAR_ELx: Attribute flag for not-allowing execution (eXecute Never) */
37 #define NOT_EXEC	MPU_RBAR_XN_Msk /* PRBAR_EL1 */
38 
39 /* PRBAR_ELx: Attribute flag for access permissions */
40 /* Privileged Read Write, Unprivileged No Access */
41 #define P_RW_U_NA	0x0U
42 #define P_RW_U_NA_Msk	((P_RW_U_NA << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
43 /* Privileged Read Write, Unprivileged Read Write */
44 #define P_RW_U_RW	0x1U
45 #define P_RW_U_RW_Msk	((P_RW_U_RW << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
46 /* Privileged Read Only, Unprivileged No Access */
47 #define P_RO_U_NA	0x2U
48 #define P_RO_U_NA_Msk	((P_RO_U_NA << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
49 /* Privileged Read Only, Unprivileged Read Only */
50 #define P_RO_U_RO	0x3U
51 #define P_RO_U_RO_Msk	((P_RO_U_RO << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
52 
53 /* PRBAR_ELx: Attribute flags for share-ability */
54 #define NON_SHAREABLE	0x0U
55 #define NON_SHAREABLE_Msk	\
56 	((NON_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk)
57 #define OUTER_SHAREABLE 0x2U
58 #define OUTER_SHAREABLE_Msk	\
59 	((OUTER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk)
60 #define INNER_SHAREABLE 0x3U
61 #define INNER_SHAREABLE_Msk	\
62 	((INNER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk)
63 
64 /* MPIR_ELx Attribute flags for cache-ability */
65 
66 /* Memory Attributes for Device Memory
67  * 1.Gathering (G/nG)
68  *   Determines whether multiple accesses can be merged into a single
69  *   bus transaction.
70  *   nG: Number/size of accesses on the bus = number/size of accesses
71  *   in code.
72  *
73  * 2.Reordering (R/nR)
74  *   Determines whether accesses to the same device can be reordered.
75  *   nR: Accesses to the same IMPLEMENTATION DEFINED block size will
76  *   appear on the bus in program order.
77  *
78  * 3 Early Write Acknowledgment (E/nE)
79  *   Indicates to the memory system whether a buffer can send
80  *   acknowledgements.
81  *   nE: The response should come from the end slave, not buffering in
82  *   the interconnect.
83  */
84 #define DEVICE_nGnRnE	0x0U
85 #define DEVICE_nGnRE	0x4U
86 #define DEVICE_nGRE	0x8U
87 #define DEVICE_GRE	0xCU
88 
89 /* Read/Write Allocation Configurations for Cacheable Memory */
90 #define R_NON_W_NON	0x0U	/* Do not allocate Read/Write */
91 #define R_NON_W_ALLOC	0x1U	/* Do not allocate Read, Allocate Write */
92 #define R_ALLOC_W_NON	0x2U	/* Allocate Read, Do not allocate Write */
93 #define R_ALLOC_W_ALLOC 0x3U	/* Allocate Read/Write */
94 
95 /* Memory Attributes for Normal Memory */
96 #define NORMAL_O_WT_NT	0x80U	/* Normal, Outer Write-through non-transient */
97 #define NORMAL_O_WB_NT	0xC0U	/* Normal, Outer Write-back non-transient */
98 #define NORMAL_O_NON_C	0x40U	/* Normal, Outer Non-Cacheable	*/
99 
100 #define NORMAL_I_WT_NT	0x08U	/* Normal, Inner Write-through non-transient */
101 #define NORMAL_I_WB_NT	0x0CU	/* Normal, Inner Write-back non-transient */
102 #define NORMAL_I_NON_C	0x04U	/* Normal, Inner Non-Cacheable	*/
103 
104 /* Global MAIR configurations */
105 #define MPU_MAIR_INDEX_DEVICE		0U
106 #define MPU_MAIR_ATTR_DEVICE		(DEVICE_nGnRnE)
107 
108 #define MPU_MAIR_INDEX_FLASH		1U
109 #define MPU_MAIR_ATTR_FLASH				\
110 	((NORMAL_O_WT_NT | (R_ALLOC_W_NON << 4)) |	\
111 	 (NORMAL_I_WT_NT | R_ALLOC_W_NON))
112 
113 #define MPU_MAIR_INDEX_SRAM		2U
114 #define MPU_MAIR_ATTR_SRAM				\
115 	((NORMAL_O_WB_NT | (R_ALLOC_W_ALLOC << 4)) |	\
116 	 (NORMAL_I_WB_NT | R_ALLOC_W_ALLOC))
117 
118 #define MPU_MAIR_INDEX_SRAM_NOCACHE	3U
119 #define MPU_MAIR_ATTR_SRAM_NOCACHE			\
120 	((NORMAL_O_NON_C | (R_NON_W_NON << 4)) |	\
121 	 (NORMAL_I_NON_C | R_NON_W_NON))
122 
123 #define MPU_MAIR_ATTRS						 \
124 	((MPU_MAIR_ATTR_DEVICE << (MPU_MAIR_INDEX_DEVICE * 8)) | \
125 	 (MPU_MAIR_ATTR_FLASH << (MPU_MAIR_INDEX_FLASH * 8)) |	 \
126 	 (MPU_MAIR_ATTR_SRAM << (MPU_MAIR_INDEX_SRAM * 8)) |	 \
127 	 (MPU_MAIR_ATTR_SRAM_NOCACHE << (MPU_MAIR_INDEX_SRAM_NOCACHE * 8)))
128 
129 /* Some helper defines for common regions.
130  *
131  * Note that the ARMv8-R MPU architecture requires that the
132  * enabled MPU regions are non-overlapping. Therefore, it is
133  * recommended to use these helper defines only for configuring
134  * fixed MPU regions at build-time.
135  */
136 #define REGION_DEVICE_ATTR					      \
137 	{							      \
138 		/* AP, XN, SH */				      \
139 		.rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, \
140 		/* Cache-ability */				      \
141 		.mair_idx = MPU_MAIR_INDEX_DEVICE,		      \
142 	}
143 
144 #define REGION_RAM_ATTR						      \
145 	{							      \
146 		/* AP, XN, SH */				      \
147 		.rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, \
148 		/* Cache-ability */				      \
149 		.mair_idx = MPU_MAIR_INDEX_SRAM,		      \
150 	}
151 
152 #define REGION_RAM_TEXT_ATTR				   \
153 	{						   \
154 		/* AP, XN, SH */			   \
155 		.rbar = P_RO_U_NA_Msk | NON_SHAREABLE_Msk, \
156 		/* Cache-ability */			   \
157 		.mair_idx = MPU_MAIR_INDEX_SRAM,	   \
158 	}
159 
160 #define REGION_RAM_RO_ATTR					      \
161 	{							      \
162 		/* AP, XN, SH */				      \
163 		.rbar = NOT_EXEC | P_RO_U_NA_Msk | NON_SHAREABLE_Msk, \
164 		/* Cache-ability */				      \
165 		.mair_idx = MPU_MAIR_INDEX_SRAM,		      \
166 	}
167 
168 #if defined(CONFIG_MPU_ALLOW_FLASH_WRITE)
169 /* Note that the access permissions allow for un-privileged writes
170  */
171 #define REGION_FLASH_ATTR						    \
172 	{								    \
173 		.rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
174 		/* Cache-ability */					    \
175 		.mair_idx = MPU_MAIR_INDEX_FLASH,			    \
176 	}
177 #else /* CONFIG_MPU_ALLOW_FLASH_WRITE */
178 #define REGION_FLASH_ATTR						    \
179 	{								    \
180 		.rbar = P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
181 		/* Cache-ability */					    \
182 		.mair_idx = MPU_MAIR_INDEX_FLASH,			    \
183 	}
184 #endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */
185 
186 struct arm_mpu_region_attr {
187 	/* Attributes belonging to PRBAR */
188 	uint8_t rbar : 5;
189 	/* MAIR index for attribute indirection */
190 	uint8_t mair_idx : 3;
191 };
192 
193 /* Region definition data structure */
194 struct arm_mpu_region {
195 	/* Region Base Address */
196 	uint64_t base;
197 	/* Region limit Address */
198 	uint64_t limit;
199 	/* Region Name */
200 	const char *name;
201 	/* Region Attributes */
202 	struct arm_mpu_region_attr attr;
203 };
204 
205 /* MPU configuration data structure */
206 struct arm_mpu_config {
207 	/* Number of regions */
208 	uint32_t num_regions;
209 	/* Regions */
210 	const struct arm_mpu_region *mpu_regions;
211 };
212 
213 #define MPU_REGION_ENTRY(_name, _base, _limit, _attr) \
214 	{					      \
215 		.name = _name,			      \
216 		.base = _base,			      \
217 		.limit = _limit,		      \
218 		.attr = _attr,			      \
219 	}
220 
221 /* Reference to the MPU configuration.
222  *
223  * This struct is defined and populated for each SoC (in the SoC definition),
224  * and holds the build-time configuration information for the fixed MPU
225  * regions enabled during kernel initialization. Dynamic MPU regions (e.g.
226  * for Thread Stack, Stack Guards, etc.) are programmed during runtime, thus,
227  * not kept here.
228  */
229 extern const struct arm_mpu_config mpu_config;
230 
231 #endif	/* _ASMLANGUAGE */
232 
233 #endif	/* ZEPHYR_INCLUDE_ARCH_ARM64_CORTEX_R_MPU_ARM_MPU_H_ */
234