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