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 #include <cmsis_core.h> 11 12 /* Convenience macros to represent the ARMv7-M-specific 13 * configuration for memory access permission and 14 * cache-ability attribution. 15 */ 16 17 /* Privileged No Access, Unprivileged No Access */ 18 #define NO_ACCESS 0x0 19 #define NO_ACCESS_Msk ((NO_ACCESS << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) 20 /* Privileged No Access, Unprivileged No Access */ 21 #define P_NA_U_NA 0x0 22 #define P_NA_U_NA_Msk ((P_NA_U_NA << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) 23 /* Privileged Read Write, Unprivileged No Access */ 24 #define P_RW_U_NA 0x1 25 #define P_RW_U_NA_Msk ((P_RW_U_NA << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) 26 /* Privileged Read Write, Unprivileged Read Only */ 27 #define P_RW_U_RO 0x2 28 #define P_RW_U_RO_Msk ((P_RW_U_RO << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) 29 /* Privileged Read Write, Unprivileged Read Write */ 30 #define P_RW_U_RW 0x3U 31 #define P_RW_U_RW_Msk ((P_RW_U_RW << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) 32 /* Privileged Read Write, Unprivileged Read Write */ 33 #define FULL_ACCESS 0x3 34 #define FULL_ACCESS_Msk ((FULL_ACCESS << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) 35 /* Privileged Read Only, Unprivileged No Access */ 36 #define P_RO_U_NA 0x5 37 #define P_RO_U_NA_Msk ((P_RO_U_NA << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) 38 /* Privileged Read Only, Unprivileged Read Only */ 39 #define P_RO_U_RO 0x6 40 #define P_RO_U_RO_Msk ((P_RO_U_RO << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) 41 /* Privileged Read Only, Unprivileged Read Only */ 42 #define RO 0x7 43 #define RO_Msk ((RO << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) 44 45 /* Attribute flag for not-allowing execution (eXecute Never) */ 46 #define NOT_EXEC MPU_RASR_XN_Msk 47 48 /* The following definitions are for internal use in arm_mpu.h. */ 49 #define STRONGLY_ORDERED_SHAREABLE MPU_RASR_S_Msk 50 #define DEVICE_SHAREABLE (MPU_RASR_B_Msk | MPU_RASR_S_Msk) 51 #define NORMAL_OUTER_INNER_WRITE_THROUGH_SHAREABLE \ 52 (MPU_RASR_C_Msk | MPU_RASR_S_Msk) 53 #define NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE MPU_RASR_C_Msk 54 #define NORMAL_OUTER_INNER_WRITE_BACK_SHAREABLE \ 55 (MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk) 56 #define NORMAL_OUTER_INNER_WRITE_BACK_NON_SHAREABLE \ 57 (MPU_RASR_C_Msk | MPU_RASR_B_Msk) 58 #define NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE \ 59 ((1 << MPU_RASR_TEX_Pos) | MPU_RASR_S_Msk) 60 #define NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE \ 61 (1 << MPU_RASR_TEX_Pos) 62 #define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_SHAREABLE \ 63 ((1 << MPU_RASR_TEX_Pos) |\ 64 MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk) 65 #define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE \ 66 ((1 << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk) 67 #define DEVICE_NON_SHAREABLE (2 << MPU_RASR_TEX_Pos) 68 69 /* Bit-masks to disable sub-regions. */ 70 #define SUB_REGION_0_DISABLED ((0x01 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) 71 #define SUB_REGION_1_DISABLED ((0x02 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) 72 #define SUB_REGION_2_DISABLED ((0x04 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) 73 #define SUB_REGION_3_DISABLED ((0x08 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) 74 #define SUB_REGION_4_DISABLED ((0x10 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) 75 #define SUB_REGION_5_DISABLED ((0x20 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) 76 #define SUB_REGION_6_DISABLED ((0x40 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) 77 #define SUB_REGION_7_DISABLED ((0x80 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) 78 79 80 #define REGION_SIZE(size) ((ARM_MPU_REGION_SIZE_ ## size \ 81 << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) 82 83 #define REGION_32B REGION_SIZE(32B) 84 #define REGION_64B REGION_SIZE(64B) 85 #define REGION_128B REGION_SIZE(128B) 86 #define REGION_256B REGION_SIZE(256B) 87 #define REGION_512B REGION_SIZE(512B) 88 #define REGION_1K REGION_SIZE(1KB) 89 #define REGION_2K REGION_SIZE(2KB) 90 #define REGION_4K REGION_SIZE(4KB) 91 #define REGION_8K REGION_SIZE(8KB) 92 #define REGION_16K REGION_SIZE(16KB) 93 #define REGION_32K REGION_SIZE(32KB) 94 #define REGION_64K REGION_SIZE(64KB) 95 #define REGION_128K REGION_SIZE(128KB) 96 #define REGION_256K REGION_SIZE(256KB) 97 #define REGION_512K REGION_SIZE(512KB) 98 #define REGION_1M REGION_SIZE(1MB) 99 #define REGION_2M REGION_SIZE(2MB) 100 #define REGION_4M REGION_SIZE(4MB) 101 #define REGION_8M REGION_SIZE(8MB) 102 #define REGION_16M REGION_SIZE(16MB) 103 #define REGION_32M REGION_SIZE(32MB) 104 #define REGION_64M REGION_SIZE(64MB) 105 #define REGION_128M REGION_SIZE(128MB) 106 #define REGION_256M REGION_SIZE(256MB) 107 #define REGION_512M REGION_SIZE(512MB) 108 #define REGION_1G REGION_SIZE(1GB) 109 #define REGION_2G REGION_SIZE(2GB) 110 #define REGION_4G REGION_SIZE(4GB) 111 112 #define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ 113 { .name = p_name, \ 114 .base = p_base, \ 115 .attr = p_attr(size_to_mpu_rasr_size(p_size)), \ 116 } 117 118 /* Some helper defines for common regions */ 119 120 /* On Cortex-M, we can only set the XN bit when CONFIG_XIP=y. When 121 * CONFIG_XIP=n, the entire image will be linked to SRAM, so we need to keep 122 * the SRAM region XN bit clear or the application code will not be executable. 123 */ 124 #define REGION_RAM_ATTR(size) \ 125 { \ 126 (NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE | \ 127 IF_ENABLED(CONFIG_XIP, (MPU_RASR_XN_Msk |)) size | P_RW_U_NA_Msk) \ 128 } 129 #define REGION_RAM_NOCACHE_ATTR(size) \ 130 { \ 131 (NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE | \ 132 MPU_RASR_XN_Msk | size | P_RW_U_NA_Msk) \ 133 } 134 #if defined(CONFIG_MPU_ALLOW_FLASH_WRITE) 135 #define REGION_FLASH_ATTR(size) \ 136 { \ 137 (NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | size | \ 138 P_RW_U_RO_Msk) \ 139 } 140 #else 141 #define REGION_FLASH_ATTR(size) \ 142 { \ 143 (NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | size | RO_Msk) \ 144 } 145 #endif 146 #define REGION_PPB_ATTR(size) { (STRONGLY_ORDERED_SHAREABLE | size | \ 147 P_RW_U_NA_Msk) } 148 #define REGION_IO_ATTR(size) { (DEVICE_NON_SHAREABLE | size | P_RW_U_NA_Msk) } 149 #define REGION_EXTMEM_ATTR(size) { (STRONGLY_ORDERED_SHAREABLE | size | \ 150 NO_ACCESS_Msk) } 151 152 struct arm_mpu_region_attr { 153 /* Attributes belonging to RASR (including the encoded region size) */ 154 uint32_t rasr; 155 }; 156 157 typedef struct arm_mpu_region_attr arm_mpu_region_attr_t; 158 159 /* Typedef for the k_mem_partition attribute */ 160 typedef struct { 161 uint32_t rasr_attr; 162 } k_mem_partition_attr_t; 163 164 /* Read-Write access permission attributes */ 165 #define _K_MEM_PARTITION_P_NA_U_NA (NO_ACCESS_Msk | NOT_EXEC) 166 #define _K_MEM_PARTITION_P_RW_U_RW (P_RW_U_RW_Msk | NOT_EXEC) 167 #define _K_MEM_PARTITION_P_RW_U_RO (P_RW_U_RO_Msk | NOT_EXEC) 168 #define _K_MEM_PARTITION_P_RW_U_NA (P_RW_U_NA_Msk | NOT_EXEC) 169 #define _K_MEM_PARTITION_P_RO_U_RO (P_RO_U_RO_Msk | NOT_EXEC) 170 #define _K_MEM_PARTITION_P_RO_U_NA (P_RO_U_NA_Msk | NOT_EXEC) 171 172 /* Execution-allowed attributes */ 173 #define _K_MEM_PARTITION_P_RWX_U_RWX (P_RW_U_RW_Msk) 174 #define _K_MEM_PARTITION_P_RWX_U_RX (P_RW_U_RO_Msk) 175 #define _K_MEM_PARTITION_P_RX_U_RX (P_RO_U_RO_Msk) 176 177 /* Kernel macros for memory attribution 178 * (access permissions and cache-ability). 179 * 180 * The macros are to be stored in k_mem_partition_attr_t 181 * objects. The format of k_mem_partition_attr_t is an 182 * "1-1" mapping of the ARMv7-M MPU RASR attribute register 183 * fields (excluding the <size> and <enable> bit-fields). 184 */ 185 186 /* Read-Write access permission attributes (default cache-ability) */ 187 #define K_MEM_PARTITION_P_NA_U_NA ((k_mem_partition_attr_t) \ 188 { _K_MEM_PARTITION_P_NA_U_NA | \ 189 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) 190 #define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \ 191 { _K_MEM_PARTITION_P_RW_U_RW | \ 192 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) 193 #define K_MEM_PARTITION_P_RW_U_RO ((k_mem_partition_attr_t) \ 194 { _K_MEM_PARTITION_P_RW_U_RO | \ 195 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) 196 #define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \ 197 { _K_MEM_PARTITION_P_RW_U_NA | \ 198 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) 199 #define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \ 200 { _K_MEM_PARTITION_P_RO_U_RO | \ 201 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) 202 #define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \ 203 { _K_MEM_PARTITION_P_RO_U_NA | \ 204 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) 205 206 /* Execution-allowed attributes (default-cacheability) */ 207 #define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t) \ 208 { _K_MEM_PARTITION_P_RWX_U_RWX | \ 209 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) 210 #define K_MEM_PARTITION_P_RWX_U_RX ((k_mem_partition_attr_t) \ 211 { _K_MEM_PARTITION_P_RWX_U_RX | \ 212 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) 213 #define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \ 214 { _K_MEM_PARTITION_P_RX_U_RX | \ 215 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) 216 217 /* 218 * @brief Evaluate Write-ability 219 * 220 * Evaluate whether the access permissions include write-ability. 221 * 222 * @param attr The k_mem_partition_attr_t object holding the 223 * MPU attributes to be checked against write-ability. 224 */ 225 #define K_MEM_PARTITION_IS_WRITABLE(attr) \ 226 ({ \ 227 int __is_writable__; \ 228 switch (attr.rasr_attr & MPU_RASR_AP_Msk) { \ 229 case P_RW_U_RW_Msk: \ 230 case P_RW_U_RO_Msk: \ 231 case P_RW_U_NA_Msk: \ 232 __is_writable__ = 1; \ 233 break; \ 234 default: \ 235 __is_writable__ = 0; \ 236 } \ 237 __is_writable__; \ 238 }) 239 240 /* 241 * @brief Evaluate Execution allowance 242 * 243 * Evaluate whether the access permissions include execution. 244 * 245 * @param attr The k_mem_partition_attr_t object holding the 246 * MPU attributes to be checked against execution 247 * allowance. 248 */ 249 #define K_MEM_PARTITION_IS_EXECUTABLE(attr) \ 250 (!((attr.rasr_attr) & (NOT_EXEC))) 251 252 /* Attributes for no-cache enabling (share-ability is selected by default) */ 253 254 #define K_MEM_PARTITION_P_NA_U_NA_NOCACHE ((k_mem_partition_attr_t) \ 255 {(_K_MEM_PARTITION_P_NA_U_NA \ 256 | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) 257 #define K_MEM_PARTITION_P_RW_U_RW_NOCACHE ((k_mem_partition_attr_t) \ 258 {(_K_MEM_PARTITION_P_RW_U_RW \ 259 | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) 260 #define K_MEM_PARTITION_P_RW_U_RO_NOCACHE ((k_mem_partition_attr_t) \ 261 {(_K_MEM_PARTITION_P_RW_U_RO \ 262 | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) 263 #define K_MEM_PARTITION_P_RW_U_NA_NOCACHE ((k_mem_partition_attr_t) \ 264 {(_K_MEM_PARTITION_P_RW_U_NA \ 265 | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) 266 #define K_MEM_PARTITION_P_RO_U_RO_NOCACHE ((k_mem_partition_attr_t) \ 267 {(_K_MEM_PARTITION_P_RO_U_RO \ 268 | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) 269 #define K_MEM_PARTITION_P_RO_U_NA_NOCACHE ((k_mem_partition_attr_t) \ 270 {(_K_MEM_PARTITION_P_RO_U_NA \ 271 | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) 272 273 #define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE ((k_mem_partition_attr_t) \ 274 {(_K_MEM_PARTITION_P_RWX_U_RWX \ 275 | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) 276 #define K_MEM_PARTITION_P_RWX_U_RX_NOCACHE ((k_mem_partition_attr_t) \ 277 {(_K_MEM_PARTITION_P_RWX_U_RX \ 278 | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) 279 #define K_MEM_PARTITION_P_RX_U_RX_NOCACHE ((k_mem_partition_attr_t) \ 280 {(_K_MEM_PARTITION_P_RX_U_RX \ 281 | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) 282 283 #endif /* _ASMLANGUAGE */ 284 285 #define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ 286 BUILD_ASSERT(!(((size) & ((size) - 1))) && \ 287 (size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \ 288 !((uint32_t)(start) & ((size) - 1)), \ 289 "the size of the partition must be power of 2" \ 290 " and greater than or equal to the minimum MPU region size." \ 291 "start address of the partition must align with size.") 292