Line data Source code
1 0 : /*
2 : * Copyright (c) 2017 Linaro Limited.
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 : #ifndef ZEPHYR_INCLUDE_ARCH_ARM_MPU_NXP_MPU_H_
7 : #define ZEPHYR_INCLUDE_ARCH_ARM_MPU_NXP_MPU_H_
8 :
9 : #ifndef _ASMLANGUAGE
10 :
11 0 : #define NXP_MPU_REGION_NUMBER 12
12 :
13 : /* Bus Master User Mode Access */
14 0 : #define UM_READ 4
15 0 : #define UM_WRITE 2
16 0 : #define UM_EXEC 1
17 :
18 0 : #define BM0_UM_SHIFT 0
19 0 : #define BM1_UM_SHIFT 6
20 0 : #define BM2_UM_SHIFT 12
21 0 : #define BM3_UM_SHIFT 18
22 :
23 : /* Bus Master Supervisor Mode Access */
24 0 : #define SM_RWX_ALLOW 0
25 0 : #define SM_RX_ALLOW 1
26 0 : #define SM_RW_ALLOW 2
27 0 : #define SM_SAME_AS_UM 3
28 :
29 0 : #define BM0_SM_SHIFT 3
30 0 : #define BM1_SM_SHIFT 9
31 0 : #define BM2_SM_SHIFT 15
32 0 : #define BM3_SM_SHIFT 21
33 :
34 0 : #define BM4_WE_SHIFT 24
35 0 : #define BM4_RE_SHIFT 25
36 :
37 : #if CONFIG_USB_KINETIS || CONFIG_UDC_KINETIS || CONFIG_UHC_NXP_KHCI
38 : #define BM4_PERMISSIONS ((1 << BM4_RE_SHIFT) | (1 << BM4_WE_SHIFT))
39 : #else
40 0 : #define BM4_PERMISSIONS 0
41 : #endif
42 :
43 : /* Read Attribute */
44 0 : #define MPU_REGION_READ \
45 : ((UM_READ << BM0_UM_SHIFT) | (UM_READ << BM1_UM_SHIFT) | (UM_READ << BM2_UM_SHIFT) | \
46 : (UM_READ << BM3_UM_SHIFT))
47 :
48 : /* Write Attribute */
49 0 : #define MPU_REGION_WRITE \
50 : ((UM_WRITE << BM0_UM_SHIFT) | (UM_WRITE << BM1_UM_SHIFT) | (UM_WRITE << BM2_UM_SHIFT) | \
51 : (UM_WRITE << BM3_UM_SHIFT))
52 :
53 : /* Execute Attribute */
54 0 : #define MPU_REGION_EXEC \
55 : ((UM_EXEC << BM0_UM_SHIFT) | (UM_EXEC << BM1_UM_SHIFT) | (UM_EXEC << BM2_UM_SHIFT) | \
56 : (UM_EXEC << BM3_UM_SHIFT))
57 :
58 : /* Super User Attributes */
59 0 : #define MPU_REGION_SU \
60 : ((SM_SAME_AS_UM << BM0_SM_SHIFT) | (SM_SAME_AS_UM << BM1_SM_SHIFT) | \
61 : (SM_SAME_AS_UM << BM2_SM_SHIFT) | (SM_SAME_AS_UM << BM3_SM_SHIFT))
62 :
63 0 : #define MPU_REGION_SU_RX \
64 : ((SM_RX_ALLOW << BM0_SM_SHIFT) | (SM_RX_ALLOW << BM1_SM_SHIFT) | \
65 : (SM_RX_ALLOW << BM2_SM_SHIFT) | (SM_RX_ALLOW << BM3_SM_SHIFT))
66 :
67 0 : #define MPU_REGION_SU_RW \
68 : ((SM_RW_ALLOW << BM0_SM_SHIFT) | (SM_RW_ALLOW << BM1_SM_SHIFT) | \
69 : (SM_RW_ALLOW << BM2_SM_SHIFT) | (SM_RW_ALLOW << BM3_SM_SHIFT))
70 :
71 0 : #define MPU_REGION_SU_RWX \
72 : ((SM_RWX_ALLOW << BM0_SM_SHIFT) | (SM_RWX_ALLOW << BM1_SM_SHIFT) | \
73 : (SM_RWX_ALLOW << BM2_SM_SHIFT) | (SM_RWX_ALLOW << BM3_SM_SHIFT))
74 :
75 : /* The ENDADDR field has the last 5 bit reserved and set to 1 */
76 0 : #define ENDADDR_ROUND(x) (x - 0x1F)
77 :
78 0 : #define REGION_USER_MODE_ATTR {(MPU_REGION_READ | MPU_REGION_WRITE | MPU_REGION_SU)}
79 :
80 : /* Some helper defines for common regions */
81 : #if defined(CONFIG_MPU_ALLOW_FLASH_WRITE)
82 : #define REGION_RAM_ATTR \
83 : {((MPU_REGION_SU_RWX) | ((UM_READ | UM_WRITE | UM_EXEC) << BM3_UM_SHIFT) | \
84 : (BM4_PERMISSIONS))}
85 :
86 : #define REGION_FLASH_ATTR {(MPU_REGION_SU_RWX)}
87 :
88 : #else
89 0 : #define REGION_RAM_ATTR \
90 : {((MPU_REGION_SU_RW) | ((UM_READ | UM_WRITE) << BM3_UM_SHIFT) | (BM4_PERMISSIONS))}
91 :
92 0 : #define REGION_FLASH_ATTR {(MPU_REGION_READ | MPU_REGION_EXEC | MPU_REGION_SU)}
93 : #endif
94 :
95 0 : #define REGION_IO_ATTR {(MPU_REGION_READ | MPU_REGION_WRITE | MPU_REGION_EXEC | MPU_REGION_SU)}
96 :
97 0 : #define REGION_RO_ATTR {(MPU_REGION_READ | MPU_REGION_SU)}
98 :
99 0 : #define REGION_USER_RO_ATTR {(MPU_REGION_READ | MPU_REGION_SU)}
100 :
101 : /* ENET (Master 3) and USB (Master 4) devices will not be able
102 : to access RAM when the region is dynamically disabled in NXP MPU.
103 : DEBUGGER (Master 1) can't be disabled in Region 0. */
104 0 : #define REGION_DEBUGGER_AND_DEVICE_ATTR \
105 : {((MPU_REGION_SU) | ((UM_READ | UM_WRITE) << BM3_UM_SHIFT) | (BM4_PERMISSIONS))}
106 :
107 0 : #define REGION_DEBUG_ATTR {MPU_REGION_SU}
108 :
109 0 : #define REGION_BACKGROUND_ATTR {MPU_REGION_SU_RW}
110 :
111 0 : struct nxp_mpu_region_attr {
112 : /* NXP MPU region access permission attributes */
113 0 : uint32_t attr;
114 : };
115 :
116 0 : typedef struct nxp_mpu_region_attr nxp_mpu_region_attr_t;
117 :
118 : /* Typedef for the k_mem_partition attribute*/
119 : typedef struct {
120 0 : uint32_t ap_attr;
121 : } k_mem_partition_attr_t;
122 :
123 : /* Kernel macros for memory attribution
124 : * (access permissions and cache-ability).
125 : *
126 : * The macros are to be stored in k_mem_partition_attr_t
127 : * objects.
128 : */
129 :
130 : /* Read-Write access permission attributes */
131 0 : #define K_MEM_PARTITION_P_NA_U_NA ((k_mem_partition_attr_t){(MPU_REGION_SU)})
132 0 : #define K_MEM_PARTITION_P_RW_U_RW \
133 : ((k_mem_partition_attr_t){(MPU_REGION_READ | MPU_REGION_WRITE | MPU_REGION_SU)})
134 0 : #define K_MEM_PARTITION_P_RW_U_RO ((k_mem_partition_attr_t){(MPU_REGION_READ | MPU_REGION_SU_RW)})
135 0 : #define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t){(MPU_REGION_SU_RW)})
136 0 : #define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t){(MPU_REGION_READ | MPU_REGION_SU)})
137 0 : #define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t){(MPU_REGION_SU_RX)})
138 :
139 : /* Execution-allowed attributes */
140 0 : #define K_MEM_PARTITION_P_RWX_U_RWX \
141 : ((k_mem_partition_attr_t){ \
142 : (MPU_REGION_READ | MPU_REGION_WRITE | MPU_REGION_EXEC | MPU_REGION_SU)})
143 0 : #define K_MEM_PARTITION_P_RWX_U_RX \
144 : ((k_mem_partition_attr_t){(MPU_REGION_READ | MPU_REGION_EXEC | MPU_REGION_SU_RWX)})
145 0 : #define K_MEM_PARTITION_P_RX_U_RX \
146 : ((k_mem_partition_attr_t){(MPU_REGION_READ | MPU_REGION_EXEC | MPU_REGION_SU)})
147 :
148 : /*
149 : * @brief Evaluate Write-ability
150 : *
151 : * Evaluate whether the access permissions include write-ability.
152 : *
153 : * @param attr The k_mem_partition_attr_t object holding the
154 : * MPU attributes to be checked against write-ability.
155 : */
156 0 : #define K_MEM_PARTITION_IS_WRITABLE(attr) \
157 : ({ \
158 : int __is_writable__; \
159 : switch (attr.ap_attr) { \
160 : case MPU_REGION_WRITE: \
161 : case MPU_REGION_SU_RW: \
162 : __is_writable__ = 1; \
163 : break; \
164 : default: \
165 : __is_writable__ = 0; \
166 : } \
167 : __is_writable__; \
168 : })
169 :
170 : /*
171 : * @brief Evaluate Execution allowance
172 : *
173 : * Evaluate whether the access permissions include execution.
174 : *
175 : * @param attr The k_mem_partition_attr_t object holding the
176 : * MPU attributes to be checked against execution
177 : * allowance.
178 : */
179 0 : #define K_MEM_PARTITION_IS_EXECUTABLE(attr) \
180 : ({ \
181 : int __is_executable__; \
182 : switch (attr.ap_attr) { \
183 : case MPU_REGION_SU_RX: \
184 : case MPU_REGION_EXEC: \
185 : __is_executable__ = 1; \
186 : break; \
187 : default: \
188 : __is_executable__ = 0; \
189 : } \
190 : __is_executable__; \
191 : })
192 :
193 : /* Region definition data structure */
194 0 : struct nxp_mpu_region {
195 : /* Region Base Address */
196 0 : uint32_t base;
197 : /* Region End Address */
198 0 : uint32_t end;
199 : /* Region Name */
200 0 : const char *name;
201 : /* Region Attributes */
202 0 : nxp_mpu_region_attr_t attr;
203 : };
204 :
205 0 : #define MPU_REGION_ENTRY(_name, _base, _end, _attr) \
206 : { \
207 : .name = _name, \
208 : .base = _base, \
209 : .end = _end, \
210 : .attr = _attr, \
211 : }
212 :
213 : /* MPU configuration data structure */
214 0 : struct nxp_mpu_config {
215 : /* Number of regions */
216 0 : uint32_t num_regions;
217 : /* Regions */
218 0 : const struct nxp_mpu_region *mpu_regions;
219 : /* SRAM Region */
220 0 : uint32_t sram_region;
221 : };
222 :
223 : /* Reference to the MPU configuration.
224 : *
225 : * This struct is defined and populated for each SoC (in the SoC definition),
226 : * and holds the build-time configuration information for the fixed MPU
227 : * regions enabled during kernel initialization. Dynamic MPU regions (e.g.
228 : * for Thread Stack, Stack Guards, etc.) are programmed during runtime, thus,
229 : * not kept here.
230 : */
231 0 : extern const struct nxp_mpu_config mpu_config;
232 :
233 : #endif /* _ASMLANGUAGE */
234 :
235 : /* Some compilers do not handle casts on pointers in constant expressions */
236 : #if defined(__IAR_SYSTEMS_ICC__)
237 : #define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
238 : BUILD_ASSERT( \
239 : (size) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0 && \
240 : (size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE, \
241 : "The size of the partition must align with minimum MPU region size" \
242 : " and greater than or equal to minimum MPU region size.\n" \
243 : "The start address of the partition must align with minimum MPU region size.")
244 : #else
245 : #define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
246 : BUILD_ASSERT( \
247 : (size) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0 && \
248 : (size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \
249 : (uint32_t)(start) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0, \
250 : "The size of the partition must align with minimum MPU region size" \
251 : " and greater than or equal to minimum MPU region size.\n" \
252 : "The start address of the partition must align with minimum MPU region size.")
253 : #endif
254 :
255 : #endif /* ZEPHYR_INCLUDE_ARCH_ARM_MPU_NXP_MPU_H_ */
|