1 /* 2 * Copyright (c) 2018 Linaro Limited. 3 * Copyright (c) 2018 Nordic Semiconductor ASA. 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #ifndef _ASMLANGUAGE 9 10 /* Convenience macros to represent the ARMv8-M-specific 11 * configuration for memory access permission and 12 * cache-ability attribution. 13 */ 14 #if defined(CONFIG_AARCH32_ARMV8_R) 15 #define MPU_IR_REGION_Msk (0xFFU) 16 #define MPU_IR_REGION_Pos 8U 17 /* MPU RBAR Register attribute msk Definitions */ 18 #define MPU_RBAR_BASE_Pos 6U 19 #define MPU_RBAR_BASE_Msk (0x3FFFFFFFFFFFFFFUL << MPU_RBAR_BASE_Pos) 20 #define MPU_RBAR_SH_Pos 3U 21 #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) 22 #define MPU_RBAR_AP_Pos 1U 23 #define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) 24 /* RBAR XN */ 25 #define MPU_RBAR_XN_Pos 0U 26 #define MPU_RBAR_XN_Msk (0x1UL << MPU_RBAR_XN_Pos) 27 28 /* MPU PLBAR Register Definitions */ 29 #define MPU_RLAR_LIMIT_Pos 6U 30 #define MPU_RLAR_LIMIT_Msk (0x3FFFFFFFFFFFFFFUL << MPU_RLAR_LIMIT_Pos) 31 #define MPU_RLAR_AttrIndx_Pos 1U 32 #define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) 33 #define MPU_RLAR_EN_Msk (0x1UL) 34 #else 35 #include <cmsis_core.h> 36 #endif 37 38 /* Privileged No Access, Unprivileged No Access */ 39 /*#define NO_ACCESS 0x0 */ 40 /*#define NO_ACCESS_Msk ((NO_ACCESS << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) */ 41 /* Privileged No Access, Unprivileged No Access */ 42 /*#define P_NA_U_NA 0x0 */ 43 /*#define P_NA_U_NA_Msk ((P_NA_U_NA << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) */ 44 /* Privileged Read Write, Unprivileged No Access */ 45 #define P_RW_U_NA 0x0 46 #define P_RW_U_NA_Msk ((P_RW_U_NA << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) 47 /* Privileged Read Write, Unprivileged Read Only */ 48 /*#define P_RW_U_RO 0x2 */ 49 /*#define P_RW_U_RO_Msk ((P_RW_U_RO << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)*/ 50 /* Privileged Read Write, Unprivileged Read Write */ 51 #define P_RW_U_RW 0x1 52 #define P_RW_U_RW_Msk ((P_RW_U_RW << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) 53 /* Privileged Read Write, Unprivileged Read Write */ 54 #define FULL_ACCESS 0x1 55 #define FULL_ACCESS_Msk ((FULL_ACCESS << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) 56 /* Privileged Read Only, Unprivileged No Access */ 57 #define P_RO_U_NA 0x2 58 #define P_RO_U_NA_Msk ((P_RO_U_NA << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) 59 /* Privileged Read Only, Unprivileged Read Only */ 60 #define P_RO_U_RO 0x3 61 #define P_RO_U_RO_Msk ((P_RO_U_RO << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) 62 /* Privileged Read Only, Unprivileged Read Only */ 63 #define RO 0x3 64 #define RO_Msk ((RO << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) 65 66 /* Attribute flag for not-allowing execution (eXecute Never) */ 67 #define NOT_EXEC MPU_RBAR_XN_Msk 68 69 /* Attribute flags for share-ability */ 70 #define NON_SHAREABLE 0x0 71 #define NON_SHAREABLE_Msk \ 72 ((NON_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) 73 #define OUTER_SHAREABLE 0x2 74 #define OUTER_SHAREABLE_Msk \ 75 ((OUTER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) 76 #define INNER_SHAREABLE 0x3 77 #define INNER_SHAREABLE_Msk \ 78 ((INNER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) 79 80 /* Helper define to calculate the region limit address. */ 81 #define REGION_LIMIT_ADDR(base, size) \ 82 (((base & MPU_RBAR_BASE_Msk) + size - 1) & MPU_RLAR_LIMIT_Msk) 83 84 /* Attribute flags for cache-ability */ 85 86 /* Memory Attributes for Device Memory 87 * 1.Gathering (G/nG) 88 * Determines whether multiple accesses can be merged into a single 89 * bus transaction. 90 * nG: Number/size of accesses on the bus = number/size of accesses 91 * in code. 92 * 93 * 2.Reordering (R/nR) 94 * Determines whether accesses to the same device can be reordered. 95 * nR: Accesses to the same IMPLEMENTATION DEFINED block size will 96 * appear on the bus in program order. 97 * 98 * 3 Early Write Acknowledgment (E/nE) 99 * Indicates to the memory system whether a buffer can send 100 * acknowledgements. 101 * nE: The response should come from the end slave, not buffering in 102 * the interconnect. 103 */ 104 #define DEVICE_nGnRnE 0x0U 105 #define DEVICE_nGnRE 0x4U 106 #define DEVICE_nGRE 0x8U 107 #define DEVICE_GRE 0xCU 108 109 /* Read/Write Allocation Configurations for Cacheable Memory */ 110 #define R_NON_W_NON 0x0 /* Do not allocate Read/Write */ 111 #define R_NON_W_ALLOC 0x1 /* Do not allocate Read, Allocate Write */ 112 #define R_ALLOC_W_NON 0x2 /* Allocate Read, Do not allocate Write */ 113 #define R_ALLOC_W_ALLOC 0x3 /* Allocate Read/Write */ 114 115 /* Memory Attributes for Normal Memory */ 116 #define NORMAL_O_WT_NT 0x80 /* Normal, Outer Write-through non-transient */ 117 #define NORMAL_O_WB_NT 0xC0 /* Normal, Outer Write-back non-transient */ 118 #define NORMAL_O_NON_C 0x40 /* Normal, Outer Non-Cacheable */ 119 120 #define NORMAL_I_WT_NT 0x08 /* Normal, Inner Write-through non-transient */ 121 #define NORMAL_I_WB_NT 0x0C /* Normal, Inner Write-back non-transient */ 122 #define NORMAL_I_NON_C 0x04 /* Normal, Inner Non-Cacheable */ 123 124 #define NORMAL_OUTER_INNER_WRITE_THROUGH_READ_ALLOCATE_NON_TRANS \ 125 ((NORMAL_O_WT_NT | (R_ALLOC_W_NON << 4)) \ 126 | \ 127 (NORMAL_I_WT_NT | R_ALLOC_W_NON)) \ 128 129 #define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_TRANS \ 130 ((NORMAL_O_WB_NT | (R_ALLOC_W_ALLOC << 4)) \ 131 | \ 132 (NORMAL_I_WB_NT | R_ALLOC_W_ALLOC)) 133 134 #define NORMAL_OUTER_INNER_NON_CACHEABLE \ 135 ((NORMAL_O_NON_C | (R_NON_W_NON << 4)) \ 136 | \ 137 (NORMAL_I_NON_C | R_NON_W_NON)) 138 139 /* Common cache-ability configuration for Flash, SRAM regions */ 140 #define MPU_CACHE_ATTRIBUTES_FLASH \ 141 NORMAL_OUTER_INNER_WRITE_THROUGH_READ_ALLOCATE_NON_TRANS 142 #define MPU_CACHE_ATTRIBUTES_SRAM \ 143 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_TRANS 144 #define MPU_CACHE_ATTRIBUTES_SRAM_NOCACHE \ 145 NORMAL_OUTER_INNER_NON_CACHEABLE 146 147 /* Global MAIR configurations */ 148 #define MPU_MAIR_ATTR_FLASH MPU_CACHE_ATTRIBUTES_FLASH 149 #define MPU_MAIR_INDEX_FLASH 0 150 #define MPU_MAIR_ATTR_SRAM MPU_CACHE_ATTRIBUTES_SRAM 151 #define MPU_MAIR_INDEX_SRAM 1 152 #define MPU_MAIR_ATTR_SRAM_NOCACHE MPU_CACHE_ATTRIBUTES_SRAM_NOCACHE 153 #define MPU_MAIR_INDEX_SRAM_NOCACHE 2 154 #define MPU_MAIR_ATTR_DEVICE DEVICE_nGnRnE 155 #define MPU_MAIR_INDEX_DEVICE 3 156 /* Flash region(s): Attribute-0 157 * SRAM region(s): Attribute-1 158 * SRAM no cache-able regions(s): Attribute-2 159 * DEVICE no cache-able regions(s): Attribute-3 160 */ 161 #define MPU_MAIR_ATTRS \ 162 ((MPU_MAIR_ATTR_FLASH << (MPU_MAIR_INDEX_FLASH * 8)) | \ 163 (MPU_MAIR_ATTR_SRAM << (MPU_MAIR_INDEX_SRAM * 8)) | \ 164 (MPU_MAIR_ATTR_SRAM_NOCACHE << (MPU_MAIR_INDEX_SRAM_NOCACHE * 8)) | \ 165 (MPU_MAIR_ATTR_DEVICE << (MPU_MAIR_INDEX_DEVICE * 8))) 166 167 /* Some helper defines for common regions. 168 * 169 * Note that the ARMv8-M/R MPU architecture requires that the 170 * enabled MPU regions are non-overlapping. Therefore, it is 171 * recommended to use these helper defines only for configuring 172 * fixed MPU regions at build-time (i.e. regions that are not 173 * expected to be re-programmed or re-adjusted at run-time so 174 * that they do not overlap with other MPU regions). 175 */ 176 #if defined(CONFIG_AARCH32_ARMV8_R) 177 178 #define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ 179 { .name = p_name, \ 180 .base = p_base, \ 181 .attr = p_attr(p_base + p_size), \ 182 } 183 184 #define REGION_RAM_ATTR(limit) \ 185 { \ 186 .rbar = NOT_EXEC | \ 187 P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ 188 /* Cache-ability */ \ 189 .mair_idx = MPU_MAIR_INDEX_SRAM, \ 190 .r_limit = limit - 1, /* Region Limit */ \ 191 } 192 193 #define REGION_RAM_TEXT_ATTR(limit) \ 194 { \ 195 .rbar = P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ 196 /* Cache-ability */ \ 197 .mair_idx = MPU_MAIR_INDEX_SRAM, \ 198 .r_limit = limit - 1, /* Region Limit */ \ 199 } 200 201 #define REGION_RAM_RO_ATTR(limit) \ 202 { \ 203 .rbar = NOT_EXEC | \ 204 P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ 205 /* Cache-ability */ \ 206 .mair_idx = MPU_MAIR_INDEX_SRAM, \ 207 .r_limit = limit - 1, /* Region Limit */ \ 208 } 209 #define REGION_RAM_NOCACHE_ATTR(limit) \ 210 { \ 211 .rbar = NOT_EXEC | \ 212 P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ 213 /* Cache-ability */ \ 214 .mair_idx = MPU_MAIR_INDEX_SRAM_NOCACHE, \ 215 .r_limit = limit - 1, /* Region Limit */ \ 216 } 217 #if defined(CONFIG_MPU_ALLOW_FLASH_WRITE) 218 /* Note that the access permissions allow for un-privileged writes, contrary 219 * to ARMv7-M where un-privileged code has Read-Only permissions. 220 */ 221 #define REGION_FLASH_ATTR(limit) \ 222 { \ 223 .rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ 224 /* Cache-ability */ \ 225 .mair_idx = MPU_MAIR_INDEX_FLASH, \ 226 .r_limit = limit - 1, /* Region Limit */ \ 227 } 228 #else /* CONFIG_MPU_ALLOW_FLASH_WRITE */ 229 #define REGION_FLASH_ATTR(limit) \ 230 { \ 231 .rbar = RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ 232 /* Cache-ability */ \ 233 .mair_idx = MPU_MAIR_INDEX_FLASH, \ 234 .r_limit = limit - 1, /* Region Limit */ \ 235 } 236 #endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */ 237 238 #define REGION_DEVICE_ATTR(limit) \ 239 { \ 240 /* AP, XN, SH */ \ 241 .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, \ 242 /* Cache-ability */ \ 243 .mair_idx = MPU_MAIR_INDEX_DEVICE, \ 244 /* Region Limit */ \ 245 .r_limit = limit - 1, \ 246 } 247 #else 248 249 #define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ 250 { .name = p_name, \ 251 .base = p_base, \ 252 .attr = p_attr(p_base, p_size), \ 253 } 254 255 /* On Cortex-M, we can only set the XN bit when CONFIG_XIP=y. When 256 * CONFIG_XIP=n, the entire image will be linked to SRAM, so we need to keep 257 * the SRAM region XN bit clear or the application code will not be executable. 258 */ 259 #define REGION_RAM_ATTR(base, size) \ 260 {\ 261 .rbar = IF_ENABLED(CONFIG_XIP, (NOT_EXEC |)) \ 262 P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ 263 /* Cache-ability */ \ 264 .mair_idx = MPU_MAIR_INDEX_SRAM, \ 265 .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ 266 } 267 268 #define REGION_RAM_NOCACHE_ATTR(base, size) \ 269 {\ 270 .rbar = NOT_EXEC | \ 271 P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ 272 /* Cache-ability */ \ 273 .mair_idx = MPU_MAIR_INDEX_SRAM_NOCACHE, \ 274 .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ 275 } 276 277 #if defined(CONFIG_MPU_ALLOW_FLASH_WRITE) 278 /* Note that the access permissions allow for un-privileged writes, contrary 279 * to ARMv7-M where un-privileged code has Read-Only permissions. 280 */ 281 #define REGION_FLASH_ATTR(base, size) \ 282 {\ 283 .rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ 284 /* Cache-ability */ \ 285 .mair_idx = MPU_MAIR_INDEX_FLASH, \ 286 .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ 287 } 288 #else /* CONFIG_MPU_ALLOW_FLASH_WRITE */ 289 #define REGION_FLASH_ATTR(base, size) \ 290 {\ 291 .rbar = RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ 292 /* Cache-ability */ \ 293 .mair_idx = MPU_MAIR_INDEX_FLASH, \ 294 .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ 295 } 296 #endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */ 297 298 #define REGION_DEVICE_ATTR(base, size) \ 299 { \ 300 /* AP, XN, SH */ \ 301 .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* Cache-ability */ \ 302 .mair_idx = MPU_MAIR_INDEX_DEVICE, \ 303 .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ 304 } 305 #endif 306 307 struct arm_mpu_region_attr { 308 /* Attributes belonging to RBAR */ 309 uint8_t rbar: 5; 310 /* MAIR index for attribute indirection */ 311 uint8_t mair_idx: 3; 312 /* Region Limit Address value to be written to the RLAR register. */ 313 uint32_t r_limit; 314 }; 315 316 typedef struct arm_mpu_region_attr arm_mpu_region_attr_t; 317 318 /* Typedef for the k_mem_partition attribute */ 319 typedef struct { 320 uint16_t rbar; 321 uint16_t mair_idx; 322 } k_mem_partition_attr_t; 323 324 /* Kernel macros for memory attribution 325 * (access permissions and cache-ability). 326 * 327 * The macros are to be stored in k_mem_partition_attr_t 328 * objects. The format of a k_mem_partition_attr_t object 329 * is as follows: field <rbar> contains a direct mapping 330 * of the <XN> and <AP> bit-fields of the RBAR register; 331 * field <mair_idx> contains a direct mapping of AttrIdx 332 * bit-field, stored in RLAR register. 333 */ 334 335 /* Read-Write access permission attributes */ 336 #define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \ 337 {(P_RW_U_RW_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) 338 #define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \ 339 {(P_RW_U_NA_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) 340 #define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \ 341 {(P_RO_U_RO_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) 342 #define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \ 343 {(P_RO_U_NA_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) 344 345 /* Execution-allowed attributes */ 346 #define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t) \ 347 {(P_RW_U_RW_Msk), MPU_MAIR_INDEX_SRAM}) 348 #define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \ 349 {(P_RO_U_RO_Msk), MPU_MAIR_INDEX_SRAM}) 350 351 /* 352 * @brief Evaluate Write-ability 353 * 354 * Evaluate whether the access permissions include write-ability. 355 * 356 * @param attr The k_mem_partition_attr_t object holding the 357 * MPU attributes to be checked against write-ability. 358 */ 359 #define K_MEM_PARTITION_IS_WRITABLE(attr) \ 360 ({ \ 361 int __is_writable__; \ 362 switch (attr.rbar & MPU_RBAR_AP_Msk) { \ 363 case P_RW_U_RW_Msk: \ 364 case P_RW_U_NA_Msk: \ 365 __is_writable__ = 1; \ 366 break; \ 367 default: \ 368 __is_writable__ = 0; \ 369 } \ 370 __is_writable__; \ 371 }) 372 373 /* 374 * @brief Evaluate Execution allowance 375 * 376 * Evaluate whether the access permissions include execution. 377 * 378 * @param attr The k_mem_partition_attr_t object holding the 379 * MPU attributes to be checked against execution 380 * allowance. 381 */ 382 #define K_MEM_PARTITION_IS_EXECUTABLE(attr) \ 383 (!((attr.rbar) & (NOT_EXEC))) 384 385 /* Attributes for no-cache enabling (share-ability is selected by default) */ 386 387 /* Read-Write access permission attributes */ 388 #define K_MEM_PARTITION_P_RW_U_RW_NOCACHE ((k_mem_partition_attr_t) \ 389 {(P_RW_U_RW_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ 390 MPU_MAIR_INDEX_SRAM_NOCACHE}) 391 #define K_MEM_PARTITION_P_RW_U_NA_NOCACHE ((k_mem_partition_attr_t) \ 392 {(P_RW_U_NA_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ 393 MPU_MAIR_INDEX_SRAM_NOCACHE}) 394 #define K_MEM_PARTITION_P_RO_U_RO_NOCACHE ((k_mem_partition_attr_t) \ 395 {(P_RO_U_RO_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ 396 MPU_MAIR_INDEX_SRAM_NOCACHE}) 397 #define K_MEM_PARTITION_P_RO_U_NA_NOCACHE ((k_mem_partition_attr_t) \ 398 {(P_RO_U_NA_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ 399 MPU_MAIR_INDEX_SRAM_NOCACHE}) 400 401 /* Execution-allowed attributes */ 402 #define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE ((k_mem_partition_attr_t) \ 403 {(P_RW_U_RW_Msk | OUTER_SHAREABLE_Msk), MPU_MAIR_INDEX_SRAM_NOCACHE}) 404 #define K_MEM_PARTITION_P_RX_U_RX_NOCACHE ((k_mem_partition_attr_t) \ 405 {(P_RO_U_RO_Msk | OUTER_SHAREABLE_Msk), MPU_MAIR_INDEX_SRAM_NOCACHE}) 406 407 #endif /* _ASMLANGUAGE */ 408 409 #define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ 410 BUILD_ASSERT((size > 0) && ((uint32_t)start % \ 411 CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0U) && \ 412 ((size) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0), \ 413 " the start and size of the partition must align " \ 414 "with the minimum MPU region size.") 415