blob: e3944a770dd88107fc3fa3db2f3f8b616053b78c [file] [log] [blame]
/*
* Copyright (c) 2018 Linaro Limited.
* Copyright (c) 2018 Nordic Semiconductor ASA.
* Copyright (c) 2021 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_DEVICE_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 | NON_SHAREABLE_Msk, \
/* Cache-ability */ \
.mair_idx = MPU_MAIR_INDEX_SRAM, \
}
#define REGION_RAM_TEXT_ATTR \
{ \
/* AP, XN, SH */ \
.rbar = P_RO_U_RO_Msk | NON_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 | NON_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 : 5;
/* 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;
#endif /* _ASMLANGUAGE */
#endif /* ZEPHYR_INCLUDE_ARCH_ARM64_CORTEX_R_MPU_ARM_MPU_H_ */