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