Line data Source code
1 0 : /*
2 : * Copyright (c) 2023 Intel Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #include <stdint.h>
8 :
9 : #include <zephyr/toolchain.h>
10 : #include <zephyr/sys/util_macro.h>
11 :
12 : #include <xtensa/config/core-isa.h>
13 :
14 : #ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_MPU_H
15 : #define ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_MPU_H
16 :
17 : /**
18 : * @defgroup xtensa_mpu_apis Xtensa Memory Protection Unit (MPU) APIs
19 : * @ingroup xtensa_apis
20 : * @{
21 : */
22 :
23 : /** Number of available entries in the MPU table. */
24 1 : #define XTENSA_MPU_NUM_ENTRIES XCHAL_MPU_ENTRIES
25 :
26 : /**
27 : * @name MPU memory region access rights.
28 : *
29 : * @note These are NOT bit masks, and must be used as whole value.
30 : *
31 : * @{
32 : */
33 :
34 : /** Kernel and user modes no access. */
35 1 : #define XTENSA_MPU_ACCESS_P_NA_U_NA (0)
36 :
37 : /** Kernel mode execution only. */
38 1 : #define XTENSA_MPU_ACCESS_P_X_U_NA (2)
39 :
40 : /** User mode execution only. */
41 1 : #define XTENSA_MPU_ACCESS_P_NA_U_X (3)
42 :
43 : /** Kernel mode read only. */
44 1 : #define XTENSA_MPU_ACCESS_P_RO_U_NA (4)
45 :
46 : /** Kernel mode read and execution. */
47 1 : #define XTENSA_MPU_ACCESS_P_RX_U_NA (5)
48 :
49 : /** Kernel mode read and write. */
50 1 : #define XTENSA_MPU_ACCESS_P_RW_U_NA (6)
51 :
52 : /** Kernel mode read, write and execution. */
53 1 : #define XTENSA_MPU_ACCESS_P_RWX_U_NA (7)
54 :
55 : /** Kernel and user modes write only. */
56 1 : #define XTENSA_MPU_ACCESS_P_WO_U_WO (8)
57 :
58 : /** Kernel mode read, write. User mode read, write and execution. */
59 1 : #define XTENSA_MPU_ACCESS_P_RW_U_RWX (9)
60 :
61 : /** Kernel mode read and write. User mode read only. */
62 1 : #define XTENSA_MPU_ACCESS_P_RW_U_RO (10)
63 :
64 : /** Kernel mode read, write and execution. User mode read and execution. */
65 1 : #define XTENSA_MPU_ACCESS_P_RWX_U_RX (11)
66 :
67 : /** Kernel and user modes read only. */
68 1 : #define XTENSA_MPU_ACCESS_P_RO_U_RO (12)
69 :
70 : /** Kernel and user modes read and execution. */
71 1 : #define XTENSA_MPU_ACCESS_P_RX_U_RX (13)
72 :
73 : /** Kernel and user modes read and write. */
74 1 : #define XTENSA_MPU_ACCESS_P_RW_U_RW (14)
75 :
76 : /** Kernel and user modes read, write and execution. */
77 1 : #define XTENSA_MPU_ACCESS_P_RWX_U_RWX (15)
78 :
79 : /**
80 : * @}
81 : */
82 :
83 : /**
84 : * @brief Foreground MPU Entry.
85 : *
86 : * This holds the as, at register values for one MPU entry which can be
87 : * used directly by WPTLB.
88 : */
89 1 : struct xtensa_mpu_entry {
90 : /**
91 : * Content of as register for WPTLB.
92 : *
93 : * This contains the start address, the enable bit, and the lock bit.
94 : */
95 : union {
96 : /** Raw value. */
97 1 : uint32_t raw;
98 :
99 : /** Individual parts. */
100 : struct {
101 : /**
102 : * Enable bit for this entry.
103 : *
104 : * Modifying this will also modify the corresponding bit of
105 : * the MPUENB register.
106 : */
107 1 : uint32_t enable:1;
108 :
109 : /**
110 : * Lock bit for this entry.
111 : *
112 : * Usable only if MPULOCKABLE parameter is enabled in
113 : * processor configuration.
114 : *
115 : * Once set:
116 : * - This cannot be cleared until reset.
117 : * - This entry can no longer be modified.
118 : * - The start address of the next entry also
119 : * cannot be modified.
120 : */
121 1 : uint32_t lock:1;
122 :
123 : /** Must be zero. */
124 1 : uint32_t mbz:3;
125 :
126 : /**
127 : * Start address of this MPU entry.
128 : *
129 : * Effective bits in this portion are affected by the minimum
130 : * segment size of each MPU entry, ranging from 32 bytes to 4GB.
131 : */
132 1 : uint32_t start_addr:27;
133 1 : } p;
134 1 : } as;
135 :
136 : /**
137 : * Content of at register for WPTLB.
138 : *
139 : * This contains the memory type, access rights, and the segment number.
140 : */
141 : union {
142 : /** Raw value. */
143 : uint32_t raw;
144 :
145 : /** Individual parts. */
146 : struct {
147 : /** The segment number of this MPU entry. */
148 1 : uint32_t segment:5;
149 :
150 : /** Must be zero (part 1). */
151 1 : uint32_t mbz1:3;
152 :
153 : /**
154 : * Access rights associated with this MPU entry.
155 : *
156 : * This dictates the access right from the start address of
157 : * this entry, to the start address of next entry.
158 : *
159 : * Refer to XTENSA_MPU_ACCESS_* macros for available rights.
160 : */
161 1 : uint32_t access_rights:4;
162 :
163 : /**
164 : * Memory type associated with this MPU entry.
165 : *
166 : * This dictates the memory type from the start address of
167 : * this entry, to the start address of next entry.
168 : *
169 : * This affects how the hardware treats the memory, for example,
170 : * cacheable vs non-cacheable, shareable vs non-shareable.
171 : * Refer to the Xtensa Instruction Set Architecture (ISA) manual
172 : * for general description, and the processor manual for processor
173 : * specific information.
174 : */
175 1 : uint32_t memory_type:9;
176 :
177 : /** Must be zero (part 2). */
178 1 : uint32_t mbz2:11;
179 1 : } p;
180 1 : } at;
181 : };
182 :
183 : /**
184 : * @brief Struct to hold foreground MPU map and its entries.
185 : */
186 1 : struct xtensa_mpu_map {
187 : /**
188 : * Array of MPU entries.
189 : */
190 1 : struct xtensa_mpu_entry entries[XTENSA_MPU_NUM_ENTRIES];
191 : };
192 :
193 : /**
194 : * @name Memory domain and partitions
195 : * @{
196 : */
197 :
198 : typedef uint32_t k_mem_partition_attr_t;
199 :
200 0 : static inline bool xtensa_mem_partition_is_executable(k_mem_partition_attr_t access_rights)
201 : {
202 : bool is_exec;
203 :
204 : switch (access_rights) {
205 : case XTENSA_MPU_ACCESS_P_X_U_NA:
206 : case XTENSA_MPU_ACCESS_P_NA_U_X:
207 : case XTENSA_MPU_ACCESS_P_RX_U_NA:
208 : case XTENSA_MPU_ACCESS_P_RWX_U_NA:
209 : case XTENSA_MPU_ACCESS_P_RW_U_RWX:
210 : case XTENSA_MPU_ACCESS_P_RWX_U_RX:
211 : case XTENSA_MPU_ACCESS_P_RX_U_RX:
212 : case XTENSA_MPU_ACCESS_P_RWX_U_RWX:
213 : is_exec = true;
214 : break;
215 : default:
216 : is_exec = false;
217 : break;
218 : };
219 :
220 : return is_exec;
221 : }
222 :
223 0 : static inline bool xtensa_mem_partition_is_writable(k_mem_partition_attr_t access_rights)
224 : {
225 : bool is_writable;
226 :
227 : switch (access_rights) {
228 : case XTENSA_MPU_ACCESS_P_RW_U_NA:
229 : case XTENSA_MPU_ACCESS_P_RWX_U_NA:
230 : case XTENSA_MPU_ACCESS_P_WO_U_WO:
231 : case XTENSA_MPU_ACCESS_P_RW_U_RWX:
232 : case XTENSA_MPU_ACCESS_P_RW_U_RO:
233 : case XTENSA_MPU_ACCESS_P_RWX_U_RX:
234 : case XTENSA_MPU_ACCESS_P_RW_U_RW:
235 : case XTENSA_MPU_ACCESS_P_RWX_U_RWX:
236 : is_writable = true;
237 : break;
238 : default:
239 : is_writable = false;
240 : break;
241 : };
242 :
243 : return is_writable;
244 : }
245 :
246 0 : #define K_MEM_PARTITION_IS_EXECUTABLE(access_rights) \
247 : (xtensa_mem_partition_is_executable(access_rights))
248 :
249 0 : #define K_MEM_PARTITION_IS_WRITABLE(access_rights) \
250 : (xtensa_mem_partition_is_writable(access_rights))
251 :
252 : /* Read-Write access permission attributes */
253 0 : #define K_MEM_PARTITION_P_RW_U_RW \
254 : ((k_mem_partition_attr_t) {XTENSA_MPU_ACCESS_P_RW_U_RW})
255 0 : #define K_MEM_PARTITION_P_RW_U_NA \
256 : ((k_mem_partition_attr_t) {XTENSA_MPU_ACCESS_P_RW_U_NA})
257 0 : #define K_MEM_PARTITION_P_RO_U_RO \
258 : ((k_mem_partition_attr_t) {XTENSA_MPU_ACCESS_P_RO_U_RO})
259 0 : #define K_MEM_PARTITION_P_RO_U_NA \
260 : ((k_mem_partition_attr_t) {XTENSA_MPU_ACCESS_P_RO_U_NA})
261 0 : #define K_MEM_PARTITION_P_NA_U_NA \
262 : ((k_mem_partition_attr_t) {XTENSA_MPU_ACCESS_P_NA_U_NA})
263 :
264 : /* Execution-allowed attributes */
265 0 : #define K_MEM_PARTITION_P_RX_U_RX \
266 : ((k_mem_partition_attr_t) {XTENSA_MPU_ACCESS_P_RX_U_RX})
267 :
268 : /**
269 : * @}
270 : */
271 :
272 : /**
273 : * Struct to describe a memory region [start, end).
274 : */
275 1 : struct xtensa_mpu_range {
276 : /** Start address (inclusive) of the memory region. */
277 1 : const uintptr_t start;
278 :
279 : /**
280 : * End address (exclusive) of the memory region.
281 : *
282 : * Use 0xFFFFFFFF for the end of memory.
283 : */
284 1 : const uintptr_t end;
285 :
286 : /** Access rights for the memory region. */
287 1 : const uint8_t access_rights:4;
288 :
289 : /**
290 : * Memory type for the region.
291 : *
292 : * Refer to the Xtensa Instruction Set Architecture (ISA) manual
293 : * for general description, and the processor manual for processor
294 : * specific information.
295 : */
296 1 : const uint16_t memory_type:9;
297 : } __packed;
298 :
299 : /**
300 : * @brief Additional memory regions required by SoC.
301 : *
302 : * These memory regions will be setup by MPU initialization code at boot.
303 : *
304 : * Must be defined in the SoC layer.
305 : */
306 1 : extern const struct xtensa_mpu_range xtensa_soc_mpu_ranges[];
307 :
308 : /**
309 : * @brief Number of SoC additional memory regions.
310 : *
311 : * Must be defined in the SoC layer.
312 : */
313 1 : extern const int xtensa_soc_mpu_ranges_num;
314 :
315 : /**
316 : * @brief Initialize hardware MPU.
317 : *
318 : * This initializes the MPU hardware and setup the memory regions at boot.
319 : */
320 1 : void xtensa_mpu_init(void);
321 :
322 : /**
323 : * @}
324 : */
325 :
326 : #endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_MPU_H */
|