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 */