1 /* 2 * Copyright (c) 2018 Linaro Limited. 3 * Copyright (c) 2018 Nordic Semiconductor ASA. 4 * Copyright (c) 2021-2023 Arm Limited (or its affiliates). All rights reserved. 5 * 6 * SPDX-License-Identifier: Apache-2.0 7 */ 8 #ifndef ZEPHYR_INCLUDE_ARCH_ARM64_CORTEX_R_MPU_ARM_MPU_H_ 9 #define ZEPHYR_INCLUDE_ARCH_ARM64_CORTEX_R_MPU_ARM_MPU_H_ 10 11 /* 12 * Convenience macros to represent the ARMv8-R64-specific configuration 13 * for memory access permission and cache-ability attribution. 14 */ 15 /* MPU MPUIR Register Definitions */ 16 #define MPU_IR_REGION_Msk (0xFFU) 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 4U 21 #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) 22 #define MPU_RBAR_AP_Pos 2U 23 #define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) 24 /* RBAR_EL1 XN */ 25 #define MPU_RBAR_XN_Pos 1U 26 #define MPU_RBAR_XN_Msk (0x1UL << MPU_RBAR_XN_Pos) 27 28 /* MPU PLBAR_ELx 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 35 /* PRBAR_ELx: Attribute flag for not-allowing execution (eXecute Never) */ 36 #define NOT_EXEC MPU_RBAR_XN_Msk /* PRBAR_EL1 */ 37 38 /* PRBAR_ELx: Attribute flag for access permissions */ 39 /* Privileged Read Write, Unprivileged No Access */ 40 #define P_RW_U_NA 0x0U 41 #define P_RW_U_NA_Msk ((P_RW_U_NA << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) 42 /* Privileged Read Write, Unprivileged Read Write */ 43 #define P_RW_U_RW 0x1U 44 #define P_RW_U_RW_Msk ((P_RW_U_RW << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) 45 /* Privileged Read Only, Unprivileged No Access */ 46 #define P_RO_U_NA 0x2U 47 #define P_RO_U_NA_Msk ((P_RO_U_NA << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) 48 /* Privileged Read Only, Unprivileged Read Only */ 49 #define P_RO_U_RO 0x3U 50 #define P_RO_U_RO_Msk ((P_RO_U_RO << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) 51 52 /* PRBAR_ELx: Attribute flags for share-ability */ 53 #define NON_SHAREABLE 0x0U 54 #define NON_SHAREABLE_Msk \ 55 ((NON_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) 56 #define OUTER_SHAREABLE 0x2U 57 #define OUTER_SHAREABLE_Msk \ 58 ((OUTER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) 59 #define INNER_SHAREABLE 0x3U 60 #define INNER_SHAREABLE_Msk \ 61 ((INNER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) 62 63 /* MPIR_ELx Attribute flags for cache-ability */ 64 65 /* Memory Attributes for Device Memory 66 * 1.Gathering (G/nG) 67 * Determines whether multiple accesses can be merged into a single 68 * bus transaction. 69 * nG: Number/size of accesses on the bus = number/size of accesses 70 * in code. 71 * 72 * 2.Reordering (R/nR) 73 * Determines whether accesses to the same device can be reordered. 74 * nR: Accesses to the same IMPLEMENTATION DEFINED block size will 75 * appear on the bus in program order. 76 * 77 * 3 Early Write Acknowledgment (E/nE) 78 * Indicates to the memory system whether a buffer can send 79 * acknowledgements. 80 * nE: The response should come from the end slave, not buffering in 81 * the interconnect. 82 */ 83 #define DEVICE_nGnRnE 0x0U 84 #define DEVICE_nGnRE 0x4U 85 #define DEVICE_nGRE 0x8U 86 #define DEVICE_GRE 0xCU 87 88 /* Read/Write Allocation Configurations for Cacheable Memory */ 89 #define R_NON_W_NON 0x0U /* Do not allocate Read/Write */ 90 #define R_NON_W_ALLOC 0x1U /* Do not allocate Read, Allocate Write */ 91 #define R_ALLOC_W_NON 0x2U /* Allocate Read, Do not allocate Write */ 92 #define R_ALLOC_W_ALLOC 0x3U /* Allocate Read/Write */ 93 94 /* Memory Attributes for Normal Memory */ 95 #define NORMAL_O_WT_NT 0x80U /* Normal, Outer Write-through non-transient */ 96 #define NORMAL_O_WB_NT 0xC0U /* Normal, Outer Write-back non-transient */ 97 #define NORMAL_O_NON_C 0x40U /* Normal, Outer Non-Cacheable */ 98 99 #define NORMAL_I_WT_NT 0x08U /* Normal, Inner Write-through non-transient */ 100 #define NORMAL_I_WB_NT 0x0CU /* Normal, Inner Write-back non-transient */ 101 #define NORMAL_I_NON_C 0x04U /* Normal, Inner Non-Cacheable */ 102 103 /* Global MAIR configurations */ 104 #define MPU_MAIR_INDEX_DEVICE 0U 105 #define MPU_MAIR_ATTR_DEVICE (DEVICE_nGnRnE) 106 107 #define MPU_MAIR_INDEX_FLASH 1U 108 #define MPU_MAIR_ATTR_FLASH \ 109 ((NORMAL_O_WT_NT | (R_ALLOC_W_NON << 4)) | \ 110 (NORMAL_I_WT_NT | R_ALLOC_W_NON)) 111 112 #define MPU_MAIR_INDEX_SRAM 2U 113 #define MPU_MAIR_ATTR_SRAM \ 114 ((NORMAL_O_WB_NT | (R_ALLOC_W_ALLOC << 4)) | \ 115 (NORMAL_I_WB_NT | R_ALLOC_W_ALLOC)) 116 117 #define MPU_MAIR_INDEX_SRAM_NOCACHE 3U 118 #define MPU_MAIR_ATTR_SRAM_NOCACHE \ 119 ((NORMAL_O_NON_C | (R_NON_W_NON << 4)) | \ 120 (NORMAL_I_NON_C | R_NON_W_NON)) 121 122 #define MPU_MAIR_ATTRS \ 123 ((MPU_MAIR_ATTR_DEVICE << (MPU_MAIR_INDEX_DEVICE * 8)) | \ 124 (MPU_MAIR_ATTR_FLASH << (MPU_MAIR_INDEX_FLASH * 8)) | \ 125 (MPU_MAIR_ATTR_SRAM << (MPU_MAIR_INDEX_SRAM * 8)) | \ 126 (MPU_MAIR_ATTR_SRAM_NOCACHE << (MPU_MAIR_INDEX_SRAM_NOCACHE * 8))) 127 128 /* Some helper defines for common regions. 129 * 130 * Note that the ARMv8-R MPU architecture requires that the 131 * enabled MPU regions are non-overlapping. Therefore, it is 132 * recommended to use these helper defines only for configuring 133 * fixed MPU regions at build-time. 134 */ 135 #define REGION_IO_ATTR \ 136 { \ 137 /* AP, XN, SH */ \ 138 .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, \ 139 /* Cache-ability */ \ 140 .mair_idx = MPU_MAIR_INDEX_DEVICE, \ 141 } 142 143 #define REGION_RAM_ATTR \ 144 { \ 145 /* AP, XN, SH */ \ 146 .rbar = NOT_EXEC | P_RW_U_NA_Msk | OUTER_SHAREABLE_Msk, \ 147 /* Cache-ability */ \ 148 .mair_idx = MPU_MAIR_INDEX_SRAM, \ 149 } 150 151 #define REGION_RAM_NOCACHE_ATTR \ 152 { \ 153 /* AP, XN, SH */ \ 154 .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, \ 155 /* Cache-ability */ \ 156 .mair_idx = MPU_MAIR_INDEX_SRAM_NOCACHE, \ 157 } 158 159 #define REGION_RAM_TEXT_ATTR \ 160 { \ 161 /* AP, XN, SH */ \ 162 .rbar = P_RO_U_RO_Msk | INNER_SHAREABLE_Msk, \ 163 /* Cache-ability */ \ 164 .mair_idx = MPU_MAIR_INDEX_SRAM, \ 165 } 166 167 #define REGION_RAM_RO_ATTR \ 168 { \ 169 /* AP, XN, SH */ \ 170 .rbar = NOT_EXEC | P_RO_U_RO_Msk | INNER_SHAREABLE_Msk, \ 171 /* Cache-ability */ \ 172 .mair_idx = MPU_MAIR_INDEX_SRAM, \ 173 } 174 175 #if defined(CONFIG_MPU_ALLOW_FLASH_WRITE) 176 /* Note that the access permissions allow for un-privileged writes 177 */ 178 #define REGION_FLASH_ATTR \ 179 { \ 180 .rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ 181 /* Cache-ability */ \ 182 .mair_idx = MPU_MAIR_INDEX_FLASH, \ 183 } 184 #else /* CONFIG_MPU_ALLOW_FLASH_WRITE */ 185 #define REGION_FLASH_ATTR \ 186 { \ 187 .rbar = P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ 188 /* Cache-ability */ \ 189 .mair_idx = MPU_MAIR_INDEX_FLASH, \ 190 } 191 #endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */ 192 193 #ifndef _ASMLANGUAGE 194 195 struct arm_mpu_region_attr { 196 /* Attributes belonging to PRBAR */ 197 uint8_t rbar : 6; 198 /* MAIR index for attribute indirection */ 199 uint8_t mair_idx : 3; 200 }; 201 202 /* Region definition data structure */ 203 struct arm_mpu_region { 204 /* Region Base Address */ 205 uint64_t base; 206 /* Region limit Address */ 207 uint64_t limit; 208 /* Region Name */ 209 const char *name; 210 /* Region Attributes */ 211 struct arm_mpu_region_attr attr; 212 }; 213 214 /* MPU configuration data structure */ 215 struct arm_mpu_config { 216 /* Number of regions */ 217 uint32_t num_regions; 218 /* Regions */ 219 const struct arm_mpu_region *mpu_regions; 220 }; 221 222 #define MPU_REGION_ENTRY(_name, _base, _limit, _attr) \ 223 { \ 224 .name = _name, \ 225 .base = _base, \ 226 .limit = _limit, \ 227 .attr = _attr, \ 228 } 229 230 #define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \ 231 {(P_RW_U_RW_Msk), MPU_MAIR_INDEX_SRAM}) 232 #define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \ 233 {(P_RW_U_NA_Msk), MPU_MAIR_INDEX_SRAM}) 234 #define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \ 235 {(P_RO_U_RO_Msk), MPU_MAIR_INDEX_SRAM}) 236 #define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \ 237 {(P_RO_U_NA_Msk), MPU_MAIR_INDEX_SRAM}) 238 239 typedef struct arm_mpu_region_attr k_mem_partition_attr_t; 240 241 /* Reference to the MPU configuration. 242 * 243 * This struct is defined and populated for each SoC (in the SoC definition), 244 * and holds the build-time configuration information for the fixed MPU 245 * regions enabled during kernel initialization. Dynamic MPU regions (e.g. 246 * for Thread Stack, Stack Guards, etc.) are programmed during runtime, thus, 247 * not kept here. 248 */ 249 extern const struct arm_mpu_config mpu_config; 250 251 struct dynamic_region_info { 252 int index; 253 struct arm_mpu_region region_conf; 254 }; 255 256 #define ARM64_MPU_MAX_DYNAMIC_REGIONS \ 257 1 + /* data section */ \ 258 (CONFIG_MAX_DOMAIN_PARTITIONS + 2) + \ 259 (IS_ENABLED(CONFIG_ARM64_STACK_PROTECTION) ? 2 : 0) + \ 260 (IS_ENABLED(CONFIG_USERSPACE) ? 2 : 0) 261 262 #endif /* _ASMLANGUAGE */ 263 264 #endif /* ZEPHYR_INCLUDE_ARCH_ARM64_CORTEX_R_MPU_ARM_MPU_H_ */ 265