diff --git a/arch/arm/core/cortex_m/mpu/arm_mpu.c b/arch/arm/core/cortex_m/mpu/arm_mpu.c index bdaed3e0700..a8c05aa4706 100644 --- a/arch/arm/core/cortex_m/mpu/arm_mpu.c +++ b/arch/arm/core/cortex_m/mpu/arm_mpu.c @@ -243,7 +243,7 @@ void arm_core_mpu_configure_mem_domain(struct k_mem_domain *mem_domain) region_index, pparts->start, pparts->size); region_conf.base = pparts->start; _get_ram_region_attr_by_conf(®ion_conf.attr, - pparts->attr, pparts->start, pparts->size); + &pparts->attr, pparts->start, pparts->size); _region_init(region_index, ®ion_conf); num_partitions--; } else { @@ -273,7 +273,7 @@ void arm_core_mpu_configure_mem_partition(u32_t part_index, LOG_DBG("set region 0x%x 0x%x 0x%x", region_index + part_index, part->start, part->size); _get_ram_region_attr_by_conf(®ion_conf.attr, - part->attr, part->start, part->size); + &part->attr, part->start, part->size); region_conf.base = part->start; _region_init(region_index + part_index, ®ion_conf); } else { diff --git a/arch/arm/core/cortex_m/mpu/arm_mpu_v7_internal.h b/arch/arm/core/cortex_m/mpu/arm_mpu_v7_internal.h index d92fb6d640f..55f474402dd 100644 --- a/arch/arm/core/cortex_m/mpu/arm_mpu_v7_internal.h +++ b/arch/arm/core/cortex_m/mpu/arm_mpu_v7_internal.h @@ -132,14 +132,14 @@ static inline void _get_mpu_ram_nocache_region_attr(arm_mpu_region_attr_t *p_att * parameter set. */ static inline void _get_ram_region_attr_by_conf(arm_mpu_region_attr_t *p_attr, - u32_t attr, u32_t base, u32_t size) + k_mem_partition_attr_t *attr, u32_t base, u32_t size) { /* in ARMv7-M MPU the base address is not required * to determine region attributes */ (void) base; - p_attr->rasr = attr | _size_to_mpu_rasr_size(size); + p_attr->rasr = attr->rasr_attr | _size_to_mpu_rasr_size(size); } /** diff --git a/arch/arm/core/cortex_m/mpu/arm_mpu_v8_internal.h b/arch/arm/core/cortex_m/mpu/arm_mpu_v8_internal.h index 0f7515cc29c..541156a6e36 100644 --- a/arch/arm/core/cortex_m/mpu/arm_mpu_v8_internal.h +++ b/arch/arm/core/cortex_m/mpu/arm_mpu_v8_internal.h @@ -21,13 +21,17 @@ static void _mpu_init(void) /* Flash region(s): Attribute-0 * SRAM region(s): Attribute-1 + * SRAM no cache-able regions(s): Attribute-2 */ MPU->MAIR0 = ((MPU_MAIR_ATTR_FLASH << MPU_MAIR0_Attr0_Pos) & MPU_MAIR0_Attr0_Msk) | ((MPU_MAIR_ATTR_SRAM << MPU_MAIR0_Attr1_Pos) & - MPU_MAIR0_Attr1_Msk); + MPU_MAIR0_Attr1_Msk) + | + ((MPU_MAIR_ATTR_SRAM_NOCACHE << MPU_MAIR0_Attr2_Pos) & + MPU_MAIR0_Attr2_Msk); } /* This internal function performs MPU region initialization. @@ -79,10 +83,10 @@ static inline void _get_mpu_ram_region_attr(arm_mpu_region_attr_t *p_attr, * the correct parameter set. */ static inline void _get_ram_region_attr_by_conf(arm_mpu_region_attr_t *p_attr, - u32_t ap_attr, u32_t base, u32_t size) + k_mem_partition_attr_t *attr, u32_t base, u32_t size) { - p_attr->rbar = ap_attr & (MPU_RBAR_XN_Msk | MPU_RBAR_AP_Msk); - p_attr->mair_idx = MPU_MAIR_INDEX_SRAM; + p_attr->rbar = attr->rbar & (MPU_RBAR_XN_Msk | MPU_RBAR_AP_Msk); + p_attr->mair_idx = attr->mair_idx; p_attr->r_limit = REGION_LIMIT_ADDR(base, size); } diff --git a/include/app_memory/app_memdomain.h b/include/app_memory/app_memdomain.h index 62a8eaba36b..aa202822c10 100644 --- a/include/app_memory/app_memdomain.h +++ b/include/app_memory/app_memdomain.h @@ -68,7 +68,7 @@ struct app_region { /* * Declares a partition and provides a function to add the - * partition to the linke dlist and initialize the partition. + * partition to the linked list and initialize the partition. */ #ifdef CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT /* For power of 2 MPUs linker provides support to help us diff --git a/include/arch/arm/arch.h b/include/arch/arm/arch.h index 29d30ec984f..aefe22b5882 100644 --- a/include/arch/arm/arch.h +++ b/include/arch/arm/arch.h @@ -254,83 +254,13 @@ extern "C" { #ifdef CONFIG_ARM_MPU #ifdef CONFIG_CPU_HAS_ARM_MPU -#ifndef _ASMLANGUAGE #include -#endif /* _ASMLANGUAGE */ -#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ - BUILD_ASSERT_MSG(!(((size) & ((size) - 1))) && \ - (size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \ - !((u32_t)(start) & ((size) - 1)), \ - "the size of the partition must be power of 2" \ - " and greater than or equal to the minimum MPU region size." \ - "start address of the partition must align with size.") #endif /* CONFIG_CPU_HAS_ARM_MPU */ #ifdef CONFIG_CPU_HAS_NXP_MPU -#ifndef _ASMLANGUAGE #include - -#define K_MEM_PARTITION_P_NA_U_NA (MPU_REGION_SU) -#define K_MEM_PARTITION_P_RW_U_RW (MPU_REGION_READ | MPU_REGION_WRITE | \ - MPU_REGION_SU) -#define K_MEM_PARTITION_P_RW_U_RO (MPU_REGION_READ | MPU_REGION_SU_RW) -#define K_MEM_PARTITION_P_RW_U_NA (MPU_REGION_SU_RW) -#define K_MEM_PARTITION_P_RO_U_RO (MPU_REGION_READ | MPU_REGION_SU) -#define K_MEM_PARTITION_P_RO_U_NA (MPU_REGION_SU_RX) - -/* Execution-allowed attributes */ -#define K_MEM_PARTITION_P_RWX_U_RWX (MPU_REGION_READ | MPU_REGION_WRITE | \ - MPU_REGION_EXEC | MPU_REGION_SU) -#define K_MEM_PARTITION_P_RWX_U_RX (MPU_REGION_READ | MPU_REGION_EXEC | \ - MPU_REGION_SU_RWX) -#define K_MEM_PARTITION_P_RX_U_RX (MPU_REGION_READ | MPU_REGION_EXEC | \ - MPU_REGION_SU) - -#define K_MEM_PARTITION_IS_WRITABLE(attr) \ - ({ \ - int __is_writable__; \ - switch (attr) { \ - case MPU_REGION_WRITE: \ - case MPU_REGION_SU_RW: \ - __is_writable__ = 1; \ - break; \ - default: \ - __is_writable__ = 0; \ - } \ - __is_writable__; \ - }) -#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \ - ({ \ - int __is_executable__; \ - switch (attr) { \ - case MPU_REGION_SU_RX: \ - case MPU_REGION_EXEC: \ - __is_executable__ = 1; \ - break; \ - default: \ - __is_executable__ = 0; \ - } \ - __is_executable__; \ - }) - -#endif /* _ASMLANGUAGE */ -#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ - BUILD_ASSERT_MSG((size) % \ - CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0 && \ - (size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \ - (u32_t)(start) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0, \ - "the size of the partition must align with minimum MPU \ - region size" \ - " and greater than or equal to minimum MPU region size." \ - "start address of the partition must align with minimum MPU \ - region size.") -#endif /* CONFIG_CPU_HAS_NXP_MPU */ +#endif /* CONFIG_CPU_HAS_NXP_MPU */ #endif /* CONFIG_ARM_MPU */ -#ifndef _ASMLANGUAGE -/* Typedef for the k_mem_partition attribute*/ -typedef u32_t k_mem_partition_attr_t; -#endif /* _ASMLANGUAGE */ - #ifdef __cplusplus } #endif diff --git a/include/arch/arm/cortex_m/mpu/arm_mpu.h b/include/arch/arm/cortex_m/mpu/arm_mpu.h index 973c1e1cf40..155fdac0c9c 100644 --- a/include/arch/arm/cortex_m/mpu/arm_mpu.h +++ b/include/arch/arm/cortex_m/mpu/arm_mpu.h @@ -6,9 +6,6 @@ #ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_ARM_MPU_H_ #define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_ARM_MPU_H_ -#include -#include - #if defined(CONFIG_CPU_CORTEX_M0PLUS) || \ defined(CONFIG_CPU_CORTEX_M3) || \ defined(CONFIG_CPU_CORTEX_M4) || \ @@ -21,6 +18,10 @@ #error "Unsupported ARM CPU" #endif +#ifndef _ASMLANGUAGE + +#include + /* Region definition data structure */ struct arm_mpu_region { /* Region Base Address */ @@ -56,4 +57,6 @@ struct arm_mpu_config { */ extern const struct arm_mpu_config mpu_config; +#endif /* _ASMLANGUAGE */ + #endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_ARM_MPU_H_ */ diff --git a/include/arch/arm/cortex_m/mpu/arm_mpu_v7m.h b/include/arch/arm/cortex_m/mpu/arm_mpu_v7m.h index 0f4acdc35c2..cf2fcb7ac8d 100644 --- a/include/arch/arm/cortex_m/mpu/arm_mpu_v7m.h +++ b/include/arch/arm/cortex_m/mpu/arm_mpu_v7m.h @@ -5,6 +5,15 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef _ASMLANGUAGE + +#include + +/* Convenience macros to represent the ARMv7-M-specific + * configuration for memory access permission and + * cache-ability attribution. + */ + /* Privileged No Access, Unprivileged No Access */ #define NO_ACCESS 0x0 #define NO_ACCESS_Msk ((NO_ACCESS << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) @@ -129,24 +138,54 @@ struct arm_mpu_region_attr { typedef struct arm_mpu_region_attr arm_mpu_region_attr_t; -#ifndef _ASMLANGUAGE +/* Typedef for the k_mem_partition attribute */ +typedef struct { + u32_t rasr_attr; +} k_mem_partition_attr_t; + +/* Kernel macros for memory attribution + * (access permissions and cache-ability). + * + * The macros are to be stored in k_mem_partition_attr_t + * objects. The format of k_mem_partition_attr_t is an + * "1-1" mapping of the ARMv7-M MPU RASR attribute register + * fields (excluding the and bit-fields). + */ + /* Read-Write access permission attributes */ -#define K_MEM_PARTITION_P_NA_U_NA (NO_ACCESS_Msk | NOT_EXEC) -#define K_MEM_PARTITION_P_RW_U_RW (P_RW_U_RW_Msk | NOT_EXEC) -#define K_MEM_PARTITION_P_RW_U_RO (P_RW_U_RO_Msk | NOT_EXEC) -#define K_MEM_PARTITION_P_RW_U_NA (P_RW_U_NA_Msk | NOT_EXEC) -#define K_MEM_PARTITION_P_RO_U_RO (P_RO_U_RO_Msk | NOT_EXEC) -#define K_MEM_PARTITION_P_RO_U_NA (P_RO_U_NA_Msk | NOT_EXEC) +#define K_MEM_PARTITION_P_NA_U_NA ((k_mem_partition_attr_t) \ + {(NO_ACCESS_Msk | NOT_EXEC)}) +#define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \ + {(P_RW_U_RW_Msk | NOT_EXEC)}) +#define K_MEM_PARTITION_P_RW_U_RO ((k_mem_partition_attr_t) \ + {(P_RW_U_RO_Msk | NOT_EXEC)}) +#define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \ + {(P_RW_U_NA_Msk | NOT_EXEC)}) +#define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \ + {(P_RO_U_RO_Msk | NOT_EXEC)}) +#define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \ + {(P_RO_U_NA_Msk | NOT_EXEC)}) /* Execution-allowed attributes */ -#define K_MEM_PARTITION_P_RWX_U_RWX (P_RW_U_RW_Msk) -#define K_MEM_PARTITION_P_RWX_U_RX (P_RW_U_RO_Msk) -#define K_MEM_PARTITION_P_RX_U_RX (P_RO_U_RO_Msk) +#define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t) \ + {(P_RW_U_RW_Msk)}) +#define K_MEM_PARTITION_P_RWX_U_RX ((k_mem_partition_attr_t) \ + {(P_RW_U_RO_Msk)}) +#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \ + {(P_RO_U_RO_Msk)}) +/* + * @brief Evaluate Write-ability + * + * Evaluate whether the access permissions include write-ability. + * + * @param attr The k_mem_partition_attr_t object holding the + * MPU attributes to be checked against write-ability. + */ #define K_MEM_PARTITION_IS_WRITABLE(attr) \ ({ \ int __is_writable__; \ - switch (attr & MPU_RASR_AP_Msk) { \ + switch (attr.rasr_attr & MPU_RASR_AP_Msk) { \ case P_RW_U_RW_Msk: \ case P_RW_U_RO_Msk: \ case P_RW_U_NA_Msk: \ @@ -158,6 +197,55 @@ typedef struct arm_mpu_region_attr arm_mpu_region_attr_t; __is_writable__; \ }) +/* + * @brief Evaluate Execution allowance + * + * Evaluate whether the access permissions include execution. + * + * @param attr The k_mem_partition_attr_t object holding the + * MPU attributes to be checked against execution + * allowance. + */ #define K_MEM_PARTITION_IS_EXECUTABLE(attr) \ - (!((attr) & (NOT_EXEC))) + (!((attr.rasr_attr) & (NOT_EXEC))) + +/* Attributes for no-cache enabling (share-ability is selected by default) */ + +#define K_MEM_PARTITION_P_NA_U_NA_NOCACHE ((k_mem_partition_attr_t) \ + {(K_MEM_PARTITION_P_NA_U_NA \ + | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RW_U_RW_NOCACHE ((k_mem_partition_attr_t) \ + {(K_MEM_PARTITION_P_RW_U_RW \ + | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RW_U_RO_NOCACHE ((k_mem_partition_attr_t) \ + {(K_MEM_PARTITION_P_RW_U_RO \ + | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RW_U_NA_NOCACHE ((k_mem_partition_attr_t) \ + {(K_MEM_PARTITION_P_RW_U_NA \ + | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RO_U_RO_NOCACHE ((k_mem_partition_attr_t) \ + {(K_MEM_PARTITION_P_RO_U_RO \ + | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RO_U_NA_NOCACHE ((k_mem_partition_attr_t) \ + {(K_MEM_PARTITION_P_RO_U_NA \ + | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) + +#define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE ((k_mem_partition_attr_t) \ + {(K_MEM_PARTITION_P_RWX_U_RWX \ + | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RWX_U_RX_NOCACHE ((k_mem_partition_attr_t) \ + {(K_MEM_PARTITION_P_RWX_U_RX \ + | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RX_U_RX_NOCACHE ((k_mem_partition_attr_t) \ + {(K_MEM_PARTITION_P_RX_U_RX \ + | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) + #endif /* _ASMLANGUAGE */ + +#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ + BUILD_ASSERT_MSG(!(((size) & ((size) - 1))) && \ + (size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \ + !((u32_t)(start) & ((size) - 1)), \ + "the size of the partition must be power of 2" \ + " and greater than or equal to the minimum MPU region size." \ + "start address of the partition must align with size.") diff --git a/include/arch/arm/cortex_m/mpu/arm_mpu_v8m.h b/include/arch/arm/cortex_m/mpu/arm_mpu_v8m.h index 62d83285f15..2ed01f0cc57 100644 --- a/include/arch/arm/cortex_m/mpu/arm_mpu_v8m.h +++ b/include/arch/arm/cortex_m/mpu/arm_mpu_v8m.h @@ -5,6 +5,15 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef _ASMLANGUAGE + +#include + +/* Convenience macros to represent the ARMv8-M-specific + * configuration for memory access permission and + * cache-ability attribution. + */ + /* Privileged No Access, Unprivileged No Access */ /*#define NO_ACCESS 0x0 */ /*#define NO_ACCESS_Msk ((NO_ACCESS << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) */ @@ -63,9 +72,11 @@ /* Memory Attributes for Normal Memory */ #define NORMAL_O_WT_NT 0x80 /* Normal, Outer Write-through non-transient */ #define NORMAL_O_WB_NT 0xC0 /* Normal, Outer Write-back non-transient */ +#define NORMAL_O_NON_C 0x40 /* Normal, Outer Non-Cacheable */ #define NORMAL_I_WT_NT 0x08 /* Normal, Inner Write-through non-transient */ #define NORMAL_I_WB_NT 0x0C /* Normal, Inner Write-back non-transient */ +#define NORMAL_I_NON_C 0x04 /* Normal, Inner Non-Cacheable */ #define NORMAL_OUTER_INNER_WRITE_THROUGH_READ_ALLOCATE_NON_TRANS \ ((NORMAL_O_WT_NT | (R_ALLOC_W_NON << 4)) \ @@ -77,17 +88,26 @@ | \ (NORMAL_I_WB_NT | R_ALLOC_W_ALLOC)) +#define NORMAL_OUTER_INNER_NON_CACHEABLE \ + ((NORMAL_O_NON_C | (R_NON_W_NON << 4)) \ + | \ + (NORMAL_I_NON_C | R_NON_W_NON)) + /* Common cache-ability configuration for Flash, SRAM regions */ #define MPU_CACHE_ATTRIBUTES_FLASH \ NORMAL_OUTER_INNER_WRITE_THROUGH_READ_ALLOCATE_NON_TRANS #define MPU_CACHE_ATTRIBUTES_SRAM \ NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_TRANS +#define MPU_CACHE_ATTRIBUTES_SRAM_NOCACHE \ + NORMAL_OUTER_INNER_NON_CACHEABLE /* Global MAIR configurations */ -#define MPU_MAIR_ATTR_FLASH MPU_CACHE_ATTRIBUTES_FLASH -#define MPU_MAIR_INDEX_FLASH 0 -#define MPU_MAIR_ATTR_SRAM MPU_CACHE_ATTRIBUTES_SRAM -#define MPU_MAIR_INDEX_SRAM 1 +#define MPU_MAIR_ATTR_FLASH MPU_CACHE_ATTRIBUTES_FLASH +#define MPU_MAIR_INDEX_FLASH 0 +#define MPU_MAIR_ATTR_SRAM MPU_CACHE_ATTRIBUTES_SRAM +#define MPU_MAIR_INDEX_SRAM 1 +#define MPU_MAIR_ATTR_SRAM_NOCACHE MPU_CACHE_ATTRIBUTES_SRAM_NOCACHE +#define MPU_MAIR_INDEX_SRAM_NOCACHE 2 /* Some helper defines for common regions. * @@ -128,6 +148,7 @@ } #endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */ + struct arm_mpu_region_attr { /* Attributes belonging to RBAR */ u8_t rbar: 5; @@ -137,25 +158,55 @@ struct arm_mpu_region_attr { u32_t r_limit; }; - typedef struct arm_mpu_region_attr arm_mpu_region_attr_t; +typedef struct arm_mpu_region_attr arm_mpu_region_attr_t; + +/* Typedef for the k_mem_partition attribute */ +typedef struct { + u16_t rbar; + u16_t mair_idx; +} k_mem_partition_attr_t; + +/* Kernel macros for memory attribution + * (access permissions and cache-ability). + * + * The macros are to be stored in k_mem_partition_attr_t + * objects. The format of a k_mem_partition_attr_t object + * is as follows: field contains a direct mapping + * of the and bit-fields of the RBAR register; + * field contains a direct mapping of AttrIdx + * bit-field, stored in RLAR register. + */ -#ifndef _ASMLANGUAGE /* Read-Write access permission attributes */ -#define K_MEM_PARTITION_P_RW_U_RW (P_RW_U_RW_Msk | NOT_EXEC) -#define K_MEM_PARTITION_P_RW_U_NA (P_RW_U_NA_Msk | NOT_EXEC) -#define K_MEM_PARTITION_P_RO_U_RO (P_RO_U_RO_Msk | NOT_EXEC) -#define K_MEM_PARTITION_P_RO_U_NA (P_RO_U_NA_Msk | NOT_EXEC) +#define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \ + {(P_RW_U_RW_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) +#define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \ + {(P_RW_U_NA_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) +#define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \ + {(P_RO_U_RO_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) +#define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \ + {(P_RO_U_NA_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) /* Execution-allowed attributes */ -#define K_MEM_PARTITION_P_RWX_U_RWX (P_RW_U_RW_Msk) -#define K_MEM_PARTITION_P_RX_U_RX (P_RO_U_RO_Msk) +#define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t) \ + {(P_RW_U_RW_Msk), MPU_MAIR_INDEX_SRAM}) +#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \ + {(P_RO_U_RO_Msk), MPU_MAIR_INDEX_SRAM}) +/* + * @brief Evaluate Write-ability + * + * Evaluate whether the access permissions include write-ability. + * + * @param attr The k_mem_partition_attr_t object holding the + * MPU attributes to be checked against write-ability. + */ #define K_MEM_PARTITION_IS_WRITABLE(attr) \ ({ \ int __is_writable__; \ - switch (attr) { \ - case P_RW_U_RW: \ - case P_RW_U_NA: \ + switch (attr.rbar & MPU_RBAR_AP_Msk) { \ + case P_RW_U_RW_Msk: \ + case P_RW_U_NA_Msk: \ __is_writable__ = 1; \ break; \ default: \ @@ -164,6 +215,44 @@ struct arm_mpu_region_attr { __is_writable__; \ }) +/* + * @brief Evaluate Execution allowance + * + * Evaluate whether the access permissions include execution. + * + * @param attr The k_mem_partition_attr_t object holding the + * MPU attributes to be checked against execution + * allowance. + */ #define K_MEM_PARTITION_IS_EXECUTABLE(attr) \ - (!((attr) & (NOT_EXEC))) + (!((attr.rbar) & (NOT_EXEC))) + +/* Attributes for no-cache enabling (share-ability is selected by default) */ + +/* Read-Write access permission attributes */ +#define K_MEM_PARTITION_P_RW_U_RW_NOCACHE ((k_mem_partition_attr_t) \ + {(P_RW_U_RW_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ + MPU_MAIR_INDEX_SRAM_NOCACHE}) +#define K_MEM_PARTITION_P_RW_U_NA_NOCACHE ((k_mem_partition_attr_t) \ + {(P_RW_U_NA_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ + MPU_MAIR_INDEX_SRAM_NOCACHE}) +#define K_MEM_PARTITION_P_RO_U_RO_NOCACHE ((k_mem_partition_attr_t) \ + {(P_RO_U_RO_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ + MPU_MAIR_INDEX_SRAM_NOCACHE}) +#define K_MEM_PARTITION_P_RO_U_NA_NOCACHE ((k_mem_partition_attr_t) \ + {(P_RO_U_NA_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ + MPU_MAIR_INDEX_SRAM_NOCACHE}) + +/* Execution-allowed attributes */ +#define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE ((k_mem_partition_attr_t) \ + {(P_RW_U_RW_Msk | OUTER_SHAREABLE_Msk), MPU_MAIR_INDEX_SRAM_NOCACHE}) +#define K_MEM_PARTITION_P_RX_U_RX_NOCACHE ((k_mem_partition_attr_t) \ + {(P_RO_U_RO_Msk | OUTER_SHAREABLE_Msk), MPU_MAIR_INDEX_SRAM_NOCACHE}) + #endif /* _ASMLANGUAGE */ + +#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ + BUILD_ASSERT_MSG((size > 0) && \ + ((size) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0), \ + " the size of the partition must align " \ + "with the minimum MPU region size.") diff --git a/include/arch/arm/cortex_m/mpu/nxp_mpu.h b/include/arch/arm/cortex_m/mpu/nxp_mpu.h index 6607d59c27a..75a2f05df32 100644 --- a/include/arch/arm/cortex_m/mpu/nxp_mpu.h +++ b/include/arch/arm/cortex_m/mpu/nxp_mpu.h @@ -6,6 +6,8 @@ #ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_NXP_MPU_H_ #define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_NXP_MPU_H_ +#ifndef _ASMLANGUAGE + #include #include @@ -121,6 +123,77 @@ #define REGION_BACKGROUND_ATTR MPU_REGION_SU_RW + +/* Typedef for the k_mem_partition attribute*/ +typedef u32_t k_mem_partition_attr_t; + +/* Kernel macros for memory attribution + * (access permissions and cache-ability). + */ + +/* Read-Write access permission attributes */ +#define K_MEM_PARTITION_P_NA_U_NA (MPU_REGION_SU) +#define K_MEM_PARTITION_P_RW_U_RW (MPU_REGION_READ | MPU_REGION_WRITE | \ + MPU_REGION_SU) +#define K_MEM_PARTITION_P_RW_U_RO (MPU_REGION_READ | MPU_REGION_SU_RW) +#define K_MEM_PARTITION_P_RW_U_NA (MPU_REGION_SU_RW) +#define K_MEM_PARTITION_P_RO_U_RO (MPU_REGION_READ | MPU_REGION_SU) +#define K_MEM_PARTITION_P_RO_U_NA (MPU_REGION_SU_RX) + +/* Execution-allowed attributes */ +#define K_MEM_PARTITION_P_RWX_U_RWX (MPU_REGION_READ | MPU_REGION_WRITE | \ + MPU_REGION_EXEC | MPU_REGION_SU) +#define K_MEM_PARTITION_P_RWX_U_RX (MPU_REGION_READ | MPU_REGION_EXEC | \ + MPU_REGION_SU_RWX) +#define K_MEM_PARTITION_P_RX_U_RX (MPU_REGION_READ | MPU_REGION_EXEC | \ + MPU_REGION_SU) + +/* + * @brief Evaluate Write-ability + * + * Evaluate whether the access permissions include write-ability. + * + * @param attr The k_mem_partition_attr_t object holding the + * MPU attributes to be checked against write-ability. + */ +#define K_MEM_PARTITION_IS_WRITABLE(attr) \ + ({ \ + int __is_writable__; \ + switch (attr) { \ + case MPU_REGION_WRITE: \ + case MPU_REGION_SU_RW: \ + __is_writable__ = 1; \ + break; \ + default: \ + __is_writable__ = 0; \ + } \ + __is_writable__; \ + }) + +/* + * @brief Evaluate Execution allowance + * + * Evaluate whether the access permissions include execution. + * + * @param attr The k_mem_partition_attr_t object holding the + * MPU attributes to be checked against execution + * allowance. + */ +#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \ + ({ \ + int __is_executable__; \ + switch (attr) { \ + case MPU_REGION_SU_RX: \ + case MPU_REGION_EXEC: \ + __is_executable__ = 1; \ + break; \ + default: \ + __is_executable__ = 0; \ + } \ + __is_executable__; \ + }) + + /* Region definition data structure */ struct nxp_mpu_region { /* Region Base Address */ @@ -161,4 +234,17 @@ struct nxp_mpu_config { */ extern const struct nxp_mpu_config mpu_config; +#endif /* _ASMLANGUAGE */ + +#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ + BUILD_ASSERT_MSG((size) % \ + CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0 && \ + (size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \ + (u32_t)(start) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0, \ + "the size of the partition must align with minimum MPU \ + region size" \ + " and greater than or equal to minimum MPU region size." \ + "start address of the partition must align with minimum MPU \ + region size.") + #endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_NXP_MPU_H_ */