arch: arm: aarch32: add ARMv8-R MPU support
ARMv8-R aarch32 processor has support for ARM PMSAv8-32. To add support for ARMv8-R we reuse the ARMv8-M effort and change access to the different registers such as rbar, rlar, mair, prselr. Signed-off-by: Julien Massot <julien.massot@iot.bzh> Signed-off-by: Manuel Arguelles <manuel.arguelles@nxp.com>
This commit is contained in:
parent
ff54de3e16
commit
ddcc5fb28d
|
@ -12,7 +12,8 @@ config ARM_MPU
|
|||
select THREAD_STACK_INFO
|
||||
select ARCH_HAS_EXECUTABLE_PAGE_BIT
|
||||
select MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT if !(CPU_HAS_NXP_MPU || ARMV8_M_BASELINE || ARMV8_M_MAINLINE)
|
||||
select MPU_REQUIRES_NON_OVERLAPPING_REGIONS if CPU_HAS_ARM_MPU && (ARMV8_M_BASELINE || ARMV8_M_MAINLINE)
|
||||
select MPU_REQUIRES_NON_OVERLAPPING_REGIONS if CPU_HAS_ARM_MPU && (ARMV8_M_BASELINE || ARMV8_M_MAINLINE || AARCH32_ARMV8_R)
|
||||
select MPU_GAP_FILLING if AARCH32_ARMV8_R
|
||||
help
|
||||
MCU implements Memory Protection Unit.
|
||||
|
||||
|
@ -46,6 +47,7 @@ config ARM_MPU
|
|||
config ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
|
||||
int
|
||||
default 256 if ARM_MPU && ARMV6_M_ARMV8_M_BASELINE && !ARMV8_M_BASELINE
|
||||
default 64 if ARM_MPU && AARCH32_ARMV8_R
|
||||
default 32 if ARM_MPU
|
||||
default 4
|
||||
help
|
||||
|
|
|
@ -155,6 +155,8 @@ void z_arm_configure_static_mpu_regions(void)
|
|||
#endif /* CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS */
|
||||
}
|
||||
|
||||
extern void arm_core_mpu_enable(void);
|
||||
extern void arm_core_mpu_disable(void);
|
||||
/**
|
||||
* @brief Use the HW-specific MPU driver to program
|
||||
* the dynamic MPU regions.
|
||||
|
@ -303,8 +305,14 @@ void z_arm_configure_dynamic_mpu_regions(struct k_thread *thread)
|
|||
#endif /* CONFIG_MPU_STACK_GUARD */
|
||||
|
||||
/* Configure the dynamic MPU regions */
|
||||
#ifdef CONFIG_AARCH32_ARMV8_R
|
||||
arm_core_mpu_disable();
|
||||
#endif
|
||||
arm_core_mpu_configure_dynamic_mpu_regions(dynamic_regions,
|
||||
region_num);
|
||||
#ifdef CONFIG_AARCH32_ARMV8_R
|
||||
arm_core_mpu_enable();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CONFIG_USERSPACE)
|
||||
|
|
|
@ -43,11 +43,12 @@ static uint8_t static_regions_num;
|
|||
defined(CONFIG_CPU_CORTEX_M3) || \
|
||||
defined(CONFIG_CPU_CORTEX_M4) || \
|
||||
defined(CONFIG_CPU_CORTEX_M7) || \
|
||||
defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
defined(CONFIG_ARMV7_R)
|
||||
#include "arm_mpu_v7_internal.h"
|
||||
#elif defined(CONFIG_CPU_CORTEX_M23) || \
|
||||
defined(CONFIG_CPU_CORTEX_M33) || \
|
||||
defined(CONFIG_CPU_CORTEX_M55)
|
||||
defined(CONFIG_CPU_CORTEX_M55) || \
|
||||
defined(CONFIG_AARCH32_ARMV8_R)
|
||||
#include "arm_mpu_v8_internal.h"
|
||||
#else
|
||||
#error "Unsupported ARM CPU"
|
||||
|
@ -84,7 +85,7 @@ static int mpu_configure_region(const uint8_t index,
|
|||
|
||||
/* Populate internal ARM MPU region configuration structure. */
|
||||
region_conf.base = new_region->start;
|
||||
#if defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
#if defined(CONFIG_ARMV7_R)
|
||||
region_conf.size = size_to_mpu_rasr_size(new_region->size);
|
||||
#endif
|
||||
get_region_attr_from_mpu_partition_info(®ion_conf.attr,
|
||||
|
|
|
@ -28,7 +28,109 @@ struct dynamic_region_info {
|
|||
* regions may be configured.
|
||||
*/
|
||||
static struct dynamic_region_info dyn_reg_info[MPU_DYNAMIC_REGION_AREAS_NUM];
|
||||
#if defined(CONFIG_CPU_CORTEX_M23) || defined(CONFIG_CPU_CORTEX_M33) || \
|
||||
defined(CONFIG_CPU_CORTEX_M55)
|
||||
static inline void mpu_set_mair0(uint32_t mair0)
|
||||
{
|
||||
MPU->MAIR0 = mair0;
|
||||
}
|
||||
|
||||
static inline void mpu_set_rnr(uint32_t rnr)
|
||||
{
|
||||
MPU->RNR = rnr;
|
||||
}
|
||||
|
||||
static inline void mpu_set_rbar(uint32_t rbar)
|
||||
{
|
||||
MPU->RBAR = rbar;
|
||||
}
|
||||
|
||||
static inline uint32_t mpu_get_rbar(void)
|
||||
{
|
||||
return MPU->RBAR;
|
||||
}
|
||||
|
||||
static inline void mpu_set_rlar(uint32_t rlar)
|
||||
{
|
||||
MPU->RLAR = rlar;
|
||||
}
|
||||
|
||||
static inline uint32_t mpu_get_rlar(void)
|
||||
{
|
||||
return MPU->RLAR;
|
||||
}
|
||||
|
||||
static inline uint8_t mpu_get_num_regions(void)
|
||||
{
|
||||
uint32_t type = MPU->TYPE;
|
||||
|
||||
type = (type & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
|
||||
|
||||
return (uint8_t)type;
|
||||
}
|
||||
|
||||
static inline void mpu_clear_region(uint32_t rnr)
|
||||
{
|
||||
ARM_MPU_ClrRegion(rnr);
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_AARCH32_ARMV8_R)
|
||||
static inline void mpu_set_mair0(uint32_t mair0)
|
||||
{
|
||||
write_mair0(mair0);
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
static inline void mpu_set_rnr(uint32_t rnr)
|
||||
{
|
||||
write_prselr(rnr);
|
||||
__DSB();
|
||||
}
|
||||
|
||||
static inline void mpu_set_rbar(uint32_t rbar)
|
||||
{
|
||||
write_prbar(rbar);
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
static inline uint32_t mpu_get_rbar(void)
|
||||
{
|
||||
return read_prbar();
|
||||
}
|
||||
|
||||
static inline void mpu_set_rlar(uint32_t rlar)
|
||||
{
|
||||
write_prlar(rlar);
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
static inline uint32_t mpu_get_rlar(void)
|
||||
{
|
||||
return read_prlar();
|
||||
}
|
||||
|
||||
static inline uint8_t mpu_get_num_regions(void)
|
||||
{
|
||||
uint32_t type = read_mpuir();
|
||||
|
||||
type = (type >> MPU_IR_REGION_Pos) & MPU_IR_REGION_Msk;
|
||||
|
||||
return (uint8_t)type;
|
||||
}
|
||||
|
||||
static inline void mpu_clear_region(uint32_t rnr)
|
||||
{
|
||||
mpu_set_rnr(rnr);
|
||||
mpu_set_rbar(0);
|
||||
mpu_set_rlar(0);
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Unsupported ARM CPU"
|
||||
#endif
|
||||
|
||||
/* Global MPU configuration at system initialization. */
|
||||
static void mpu_init(void)
|
||||
|
@ -36,20 +138,14 @@ static void mpu_init(void)
|
|||
/* Configure the cache-ability attributes for all the
|
||||
* different types of memory regions.
|
||||
*/
|
||||
mpu_set_mair0(MPU_MAIR_ATTRS);
|
||||
}
|
||||
|
||||
/* 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_MAIR_ATTR_SRAM_NOCACHE << MPU_MAIR0_Attr2_Pos) &
|
||||
MPU_MAIR0_Attr2_Msk);
|
||||
static void mpu_set_region(uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
mpu_set_rnr(rnr);
|
||||
mpu_set_rbar(rbar);
|
||||
mpu_set_rlar(rlar);
|
||||
}
|
||||
|
||||
/* This internal function performs MPU region initialization.
|
||||
|
@ -60,7 +156,7 @@ static void mpu_init(void)
|
|||
static void region_init(const uint32_t index,
|
||||
const struct arm_mpu_region *region_conf)
|
||||
{
|
||||
ARM_MPU_SetRegion(
|
||||
mpu_set_region(
|
||||
/* RNR */
|
||||
index,
|
||||
/* RBAR */
|
||||
|
@ -116,6 +212,21 @@ static int mpu_partition_is_valid(const struct z_arm_mpu_partition *part)
|
|||
* needs to be enabled.
|
||||
*
|
||||
*/
|
||||
#if defined(CONFIG_AARCH32_ARMV8_R)
|
||||
static inline int get_region_index(uint32_t start, uint32_t size)
|
||||
{
|
||||
uint32_t limit = (start + size - 1) & MPU_RLAR_LIMIT_Msk;
|
||||
|
||||
for (uint8_t idx = 0; idx < mpu_get_num_regions(); idx++) {
|
||||
mpu_set_rnr(idx);
|
||||
if (start >= (mpu_get_rbar() & MPU_RBAR_BASE_Msk) &&
|
||||
limit <= (mpu_get_rlar() & MPU_RLAR_LIMIT_Msk)) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
#else
|
||||
static inline int get_region_index(uint32_t start, uint32_t size)
|
||||
{
|
||||
uint32_t region_start_addr = arm_cmse_mpu_region_get(start);
|
||||
|
@ -129,48 +240,49 @@ static inline int get_region_index(uint32_t start, uint32_t size)
|
|||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint32_t mpu_region_get_base(const uint32_t index)
|
||||
{
|
||||
MPU->RNR = index;
|
||||
return MPU->RBAR & MPU_RBAR_BASE_Msk;
|
||||
mpu_set_rnr(index);
|
||||
return mpu_get_rbar() & MPU_RBAR_BASE_Msk;
|
||||
}
|
||||
|
||||
static inline void mpu_region_set_base(const uint32_t index, const uint32_t base)
|
||||
{
|
||||
MPU->RNR = index;
|
||||
MPU->RBAR = (MPU->RBAR & (~MPU_RBAR_BASE_Msk))
|
||||
| (base & MPU_RBAR_BASE_Msk);
|
||||
mpu_set_rnr(index);
|
||||
mpu_set_rbar((mpu_get_rbar() & (~MPU_RBAR_BASE_Msk))
|
||||
| (base & MPU_RBAR_BASE_Msk));
|
||||
}
|
||||
|
||||
static inline uint32_t mpu_region_get_last_addr(const uint32_t index)
|
||||
{
|
||||
MPU->RNR = index;
|
||||
return (MPU->RLAR & MPU_RLAR_LIMIT_Msk) | (~MPU_RLAR_LIMIT_Msk);
|
||||
mpu_set_rnr(index);
|
||||
return (mpu_get_rlar() & MPU_RLAR_LIMIT_Msk) | (~MPU_RLAR_LIMIT_Msk);
|
||||
}
|
||||
|
||||
static inline void mpu_region_set_limit(const uint32_t index, const uint32_t limit)
|
||||
{
|
||||
MPU->RNR = index;
|
||||
MPU->RLAR = (MPU->RLAR & (~MPU_RLAR_LIMIT_Msk))
|
||||
| (limit & MPU_RLAR_LIMIT_Msk);
|
||||
mpu_set_rnr(index);
|
||||
mpu_set_rlar((mpu_get_rlar() & (~MPU_RLAR_LIMIT_Msk))
|
||||
| (limit & MPU_RLAR_LIMIT_Msk));
|
||||
}
|
||||
|
||||
static inline void mpu_region_get_access_attr(const uint32_t index,
|
||||
arm_mpu_region_attr_t *attr)
|
||||
{
|
||||
MPU->RNR = index;
|
||||
mpu_set_rnr(index);
|
||||
|
||||
attr->rbar = MPU->RBAR &
|
||||
attr->rbar = mpu_get_rbar() &
|
||||
(MPU_RBAR_XN_Msk | MPU_RBAR_AP_Msk | MPU_RBAR_SH_Msk);
|
||||
attr->mair_idx = (MPU->RLAR & MPU_RLAR_AttrIndx_Msk) >>
|
||||
attr->mair_idx = (mpu_get_rlar() & MPU_RLAR_AttrIndx_Msk) >>
|
||||
MPU_RLAR_AttrIndx_Pos;
|
||||
}
|
||||
|
||||
static inline void mpu_region_get_conf(const uint32_t index,
|
||||
struct arm_mpu_region *region_conf)
|
||||
{
|
||||
MPU->RNR = index;
|
||||
mpu_set_rnr(index);
|
||||
|
||||
/* Region attribution:
|
||||
* - Cache-ability
|
||||
|
@ -180,10 +292,10 @@ static inline void mpu_region_get_conf(const uint32_t index,
|
|||
mpu_region_get_access_attr(index, ®ion_conf->attr);
|
||||
|
||||
/* Region base address */
|
||||
region_conf->base = (MPU->RBAR & MPU_RBAR_BASE_Msk);
|
||||
region_conf->base = mpu_get_rbar() & MPU_RBAR_BASE_Msk;
|
||||
|
||||
/* Region limit address */
|
||||
region_conf->attr.r_limit = MPU->RLAR & MPU_RLAR_LIMIT_Msk;
|
||||
region_conf->attr.r_limit = mpu_get_rlar() & MPU_RLAR_LIMIT_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,11 +354,76 @@ static inline uint32_t mpu_region_get_size(uint32_t index)
|
|||
*/
|
||||
static inline int is_enabled_region(uint32_t index)
|
||||
{
|
||||
MPU->RNR = index;
|
||||
mpu_set_rnr(index);
|
||||
|
||||
return (MPU->RLAR & MPU_RLAR_EN_Msk) ? 1 : 0;
|
||||
return (mpu_get_rlar() & MPU_RLAR_EN_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_AARCH32_ARMV8_R)
|
||||
/**
|
||||
* This internal function checks if the given buffer is in the region.
|
||||
*
|
||||
* Note:
|
||||
* The caller must provide a valid region number.
|
||||
*/
|
||||
static inline int is_in_region(uint32_t rnr, uint32_t start, uint32_t size)
|
||||
{
|
||||
uint32_t rbar;
|
||||
uint32_t rlar;
|
||||
|
||||
rbar = mpu_region_get_base(rnr);
|
||||
rlar = mpu_region_get_last_addr(rnr);
|
||||
|
||||
if ((start >= rbar) && ((start + size) <= rlar)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int is_user_accessible_region(uint32_t rnr, int write)
|
||||
{
|
||||
uint32_t r_ap;
|
||||
|
||||
mpu_set_rnr(rnr);
|
||||
|
||||
r_ap = (mpu_get_rbar() & MPU_RBAR_AP_Msk) >> MPU_RBAR_AP_Pos;
|
||||
|
||||
if (write != 0) {
|
||||
return r_ap == P_RW_U_RW;
|
||||
}
|
||||
|
||||
return ((r_ap == P_RW_U_RW) || (r_ap == P_RO_U_RO));
|
||||
}
|
||||
|
||||
/**
|
||||
* This internal function validates whether a given memory buffer
|
||||
* is user accessible or not.
|
||||
*/
|
||||
static inline int mpu_buffer_validate(void *addr, size_t size, int write)
|
||||
{
|
||||
int32_t rnr;
|
||||
int rc = -EPERM;
|
||||
|
||||
int key = arch_irq_lock();
|
||||
|
||||
/* Iterate all mpu regions in reversed order */
|
||||
for (rnr = 0; rnr < mpu_get_num_regions(); rnr++) {
|
||||
if (!is_enabled_region(rnr) ||
|
||||
!is_in_region(rnr, (uint32_t)addr, size)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_user_accessible_region(rnr, write)) {
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
arch_irq_unlock(key);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#else
|
||||
/**
|
||||
* This internal function validates whether a given memory buffer
|
||||
* is user accessible or not.
|
||||
|
@ -308,7 +485,7 @@ static inline int mpu_buffer_validate(void *addr, size_t size, int write)
|
|||
#endif /* CONFIG_CPU_HAS_TEE */
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_AARCH32_ARMV8_R */
|
||||
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
||||
|
@ -539,11 +716,7 @@ static inline uint8_t get_num_regions(void)
|
|||
/* Retrieve the number of regions from DTS configuration. */
|
||||
return NUM_MPU_REGIONS;
|
||||
#else
|
||||
uint32_t type = MPU->TYPE;
|
||||
|
||||
type = (type & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
|
||||
|
||||
return (uint8_t)type;
|
||||
return mpu_get_num_regions();
|
||||
#endif /* NUM_MPU_REGIONS */
|
||||
}
|
||||
|
||||
|
@ -562,7 +735,7 @@ static int mpu_configure_dynamic_mpu_regions(const struct z_arm_mpu_partition
|
|||
|
||||
/* Disable all MPU regions except for the static ones. */
|
||||
for (int i = mpu_reg_index; i < get_num_regions(); i++) {
|
||||
ARM_MPU_ClrRegion(i);
|
||||
mpu_clear_region(i);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_MPU_GAP_FILLING)
|
||||
|
@ -587,7 +760,7 @@ static int mpu_configure_dynamic_mpu_regions(const struct z_arm_mpu_partition
|
|||
* may be programmed.
|
||||
*/
|
||||
for (int i = 0; i < MPU_DYNAMIC_REGION_AREAS_NUM; i++) {
|
||||
ARM_MPU_ClrRegion(dyn_reg_info[i].index);
|
||||
mpu_clear_region(dyn_reg_info[i].index);
|
||||
}
|
||||
|
||||
/* The dynamic regions are now programmed on top of
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <zephyr/arch/arm/aarch32/exc.h>
|
||||
|
||||
#if defined(CONFIG_ARMV7_R)
|
||||
#if defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
#include <zephyr/arch/cpu.h>
|
||||
#endif
|
||||
|
||||
|
@ -63,7 +63,7 @@ SECTION_FUNC(TEXT,z_arm_userspace_enter)
|
|||
ldr r0, [r0, #_thread_offset_to_priv_stack_start] /* priv stack ptr */
|
||||
ldr ip, =CONFIG_PRIVILEGED_STACK_SIZE
|
||||
add r0, r0, ip
|
||||
#elif defined(CONFIG_ARMV7_R)
|
||||
#elif defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
ldr r0, [r0, #_thread_offset_to_priv_stack_start] /* priv stack ptr */
|
||||
ldr ip, =CONFIG_PRIVILEGED_STACK_SIZE
|
||||
add r0, r0, ip
|
||||
|
@ -79,7 +79,7 @@ SECTION_FUNC(TEXT,z_arm_userspace_enter)
|
|||
*/
|
||||
mov ip, sp
|
||||
|
||||
#if defined(CONFIG_ARMV7_R)
|
||||
#if defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
mov sp, r0
|
||||
#else
|
||||
/* set stack to privileged stack
|
||||
|
@ -113,7 +113,7 @@ SECTION_FUNC(TEXT,z_arm_userspace_enter)
|
|||
mov r1, ip
|
||||
push {r0,r1}
|
||||
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) \
|
||||
|| defined(CONFIG_ARMV7_R)
|
||||
|| defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
push {r0,ip}
|
||||
#endif
|
||||
|
||||
|
@ -145,7 +145,7 @@ SECTION_FUNC(TEXT,z_arm_userspace_enter)
|
|||
|
||||
push {r0,r3}
|
||||
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) \
|
||||
|| defined(CONFIG_ARMV7_R)
|
||||
|| defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
pop {r0,ip}
|
||||
|
||||
/* load up stack info from user stack */
|
||||
|
@ -169,7 +169,7 @@ SECTION_FUNC(TEXT,z_arm_userspace_enter)
|
|||
pop {r0, r1}
|
||||
mov ip, r1
|
||||
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) \
|
||||
|| defined(CONFIG_ARMV7_R)
|
||||
|| defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
pop {r0,ip}
|
||||
#endif
|
||||
|
||||
|
@ -184,11 +184,11 @@ SECTION_FUNC(TEXT,z_arm_userspace_enter)
|
|||
mov lr, r4
|
||||
mov r4, ip
|
||||
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) \
|
||||
|| defined(CONFIG_ARMV7_R)
|
||||
|| defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
pop {r1,r2,r3,lr}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARMV7_R)
|
||||
#if defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
/*
|
||||
* set stack to user stack. We are in SYSTEM state, so r13 and r14 are
|
||||
* shared with USER state
|
||||
|
@ -244,7 +244,7 @@ SECTION_FUNC(TEXT,z_arm_userspace_enter)
|
|||
/* restore r0 */
|
||||
mov r0, lr
|
||||
|
||||
#if defined(CONFIG_ARMV7_R)
|
||||
#if defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
/* change processor mode to unprivileged, with all interrupts enabled. */
|
||||
msr CPSR_c, #MODE_USR
|
||||
#else
|
||||
|
@ -296,7 +296,7 @@ SECTION_FUNC(TEXT,z_arm_userspace_enter)
|
|||
mov ip, r0
|
||||
pop {r0, r1}
|
||||
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) \
|
||||
|| defined(CONFIG_ARMV7_R)
|
||||
|| defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
ldr ip, =z_thread_entry
|
||||
#endif
|
||||
bx ip
|
||||
|
@ -362,7 +362,7 @@ SECTION_FUNC(TEXT, z_arm_do_syscall)
|
|||
subs ip, #8
|
||||
str sp, [ip, #0]
|
||||
str lr, [ip, #4]
|
||||
#elif defined(CONFIG_ARMV7_R)
|
||||
#elif defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
/*
|
||||
* The SVC handler has already switched to the privileged stack.
|
||||
* Store the user SP and LR at the beginning of the priv stack.
|
||||
|
@ -373,7 +373,7 @@ SECTION_FUNC(TEXT, z_arm_do_syscall)
|
|||
push {ip, lr}
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_ARMV7_R)
|
||||
#if !defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
/* switch to privileged stack */
|
||||
msr PSP, ip
|
||||
#endif
|
||||
|
@ -449,7 +449,7 @@ dispatch_syscall:
|
|||
mov r0, ip
|
||||
|
||||
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) \
|
||||
|| defined(CONFIG_ARMV7_R)
|
||||
|| defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
ldr ip, =K_SYSCALL_BAD
|
||||
cmp r6, ip
|
||||
bne valid_syscall
|
||||
|
@ -551,7 +551,7 @@ dispatch_syscall:
|
|||
msr CONTROL, r2
|
||||
pop {r2, r3}
|
||||
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) \
|
||||
|| defined(CONFIG_ARMV7_R)
|
||||
|| defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
ldr r0, =_kernel
|
||||
ldr r0, [r0, #_kernel_offset_to_current]
|
||||
ldr r1, [r0, #_thread_offset_to_mode]
|
||||
|
@ -615,7 +615,7 @@ dispatch_syscall:
|
|||
*/
|
||||
mov ip, r8
|
||||
orrs ip, ip, #1
|
||||
#elif defined(CONFIG_ARMV7_R)
|
||||
#elif defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
/* Restore user stack pointer */
|
||||
ldr ip, [sp,#12]
|
||||
mov sp, ip
|
||||
|
@ -646,7 +646,7 @@ SECTION_FUNC(TEXT, arch_user_string_nlen)
|
|||
|
||||
/* sp+4 is error value, init to -1 */
|
||||
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) \
|
||||
|| defined(CONFIG_ARMV7_R)
|
||||
|| defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
ldr r3, =-1
|
||||
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
|
||||
mov.w r3, #-1
|
||||
|
@ -662,7 +662,7 @@ z_arm_user_string_nlen_fault_start:
|
|||
ldrb r5, [r0, r3]
|
||||
|
||||
z_arm_user_string_nlen_fault_end:
|
||||
#if defined(CONFIG_ARMV7_R)
|
||||
#if defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
cmp r5, #0
|
||||
beq strlen_done
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ MAKE_REG_HELPER(sctlr, 0, 1, 0, 0);
|
|||
MAKE_REG_HELPER(prselr, 0, 6, 2, 1);
|
||||
MAKE_REG_HELPER(prbar, 0, 6, 3, 0);
|
||||
MAKE_REG_HELPER(prlar, 0, 6, 3, 1);
|
||||
MAKE_REG_HELPER(mair0, 0, 10, 2, 0);
|
||||
MAKE_REG_HELPER(vbar, 0, 12, 0, 0);
|
||||
MAKE_REG_HELPER(cntv_ctl, 0, 14, 3, 1);
|
||||
MAKE_REG64_HELPER(ICC_SGI1R, 0, 12);
|
||||
|
|
|
@ -10,12 +10,13 @@
|
|||
defined(CONFIG_CPU_CORTEX_M3) || \
|
||||
defined(CONFIG_CPU_CORTEX_M4) || \
|
||||
defined(CONFIG_CPU_CORTEX_M7) || \
|
||||
defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
defined(CONFIG_ARMV7_R)
|
||||
#include <zephyr/arch/arm/aarch32/mpu/arm_mpu_v7m.h>
|
||||
#elif defined(CONFIG_CPU_CORTEX_M23) || \
|
||||
defined(CONFIG_CPU_CORTEX_M33) || \
|
||||
defined(CONFIG_CPU_CORTEX_M55)
|
||||
#include <zephyr/arch/arm/aarch32/mpu/arm_mpu_v8m.h>
|
||||
defined(CONFIG_CPU_CORTEX_M55) || \
|
||||
defined(CONFIG_AARCH32_ARMV8_R)
|
||||
#include <zephyr/arch/arm/aarch32/mpu/arm_mpu_v8.h>
|
||||
#else
|
||||
#error "Unsupported ARM CPU"
|
||||
#endif
|
||||
|
@ -44,7 +45,7 @@ struct arm_mpu_config {
|
|||
const struct arm_mpu_region *mpu_regions;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
#if defined(CONFIG_ARMV7_R)
|
||||
#define MPU_REGION_ENTRY(_name, _base, _size, _attr) \
|
||||
{\
|
||||
.name = _name, \
|
||||
|
|
|
@ -7,12 +7,33 @@
|
|||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
#include <zephyr/arch/arm/aarch32/cortex_m/cmsis.h>
|
||||
|
||||
/* Convenience macros to represent the ARMv8-M-specific
|
||||
* configuration for memory access permission and
|
||||
* cache-ability attribution.
|
||||
*/
|
||||
#if defined(CONFIG_AARCH32_ARMV8_R)
|
||||
#define MPU_IR_REGION_Msk (0xFFU)
|
||||
#define MPU_IR_REGION_Pos 8U
|
||||
/* 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 3U
|
||||
#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos)
|
||||
#define MPU_RBAR_AP_Pos 1U
|
||||
#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos)
|
||||
/* RBAR XN */
|
||||
#define MPU_RBAR_XN_Pos 0U
|
||||
#define MPU_RBAR_XN_Msk (0x1UL << MPU_RBAR_XN_Pos)
|
||||
|
||||
/* MPU PLBAR 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)
|
||||
#else
|
||||
#include <zephyr/arch/arm/aarch32/cortex_m/cmsis.h>
|
||||
#endif
|
||||
|
||||
/* Privileged No Access, Unprivileged No Access */
|
||||
/*#define NO_ACCESS 0x0 */
|
||||
|
@ -60,8 +81,31 @@
|
|||
#define REGION_LIMIT_ADDR(base, size) \
|
||||
(((base & MPU_RBAR_BASE_Msk) + size - 1) & MPU_RLAR_LIMIT_Msk)
|
||||
|
||||
|
||||
/* Attribute flags for cache-ability */
|
||||
#if defined(CONFIG_AARCH32_ARMV8_R)
|
||||
/* 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
|
||||
#endif
|
||||
|
||||
/* Read/Write Allocation Configurations for Cacheable Memory */
|
||||
#define R_NON_W_NON 0x0 /* Do not allocate Read/Write */
|
||||
|
@ -109,15 +153,98 @@
|
|||
#define MPU_MAIR_ATTR_SRAM_NOCACHE MPU_CACHE_ATTRIBUTES_SRAM_NOCACHE
|
||||
#define MPU_MAIR_INDEX_SRAM_NOCACHE 2
|
||||
|
||||
#if defined(CONFIG_AARCH32_ARMV8_R)
|
||||
#define MPU_MAIR_ATTR_DEVICE DEVICE_nGnRnE
|
||||
#define MPU_MAIR_INDEX_DEVICE 3
|
||||
/* Flash region(s): Attribute-0
|
||||
* SRAM region(s): Attribute-1
|
||||
* SRAM no cache-able regions(s): Attribute-2
|
||||
* DEVICE no cache-able regions(s): Attribute-3
|
||||
*/
|
||||
#define MPU_MAIR_ATTRS \
|
||||
((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)) | \
|
||||
(MPU_MAIR_ATTR_DEVICE << (MPU_MAIR_INDEX_DEVICE * 8)))
|
||||
#else
|
||||
/* Flash region(s): Attribute-0
|
||||
* SRAM region(s): Attribute-1
|
||||
* SRAM no cache-able regions(s): Attribute-2
|
||||
*/
|
||||
#define MPU_MAIR_ATTRS \
|
||||
(((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_MAIR_ATTR_SRAM_NOCACHE << MPU_MAIR0_Attr2_Pos) & \
|
||||
MPU_MAIR0_Attr2_Msk))
|
||||
#endif
|
||||
|
||||
/* Some helper defines for common regions.
|
||||
*
|
||||
* Note that the ARMv8-M MPU architecture requires that the
|
||||
* Note that the ARMv8-M/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 (i.e. regions that are not
|
||||
* expected to be re-programmed or re-adjusted at run-time so
|
||||
* that they do not overlap with other MPU regions).
|
||||
*/
|
||||
#if defined(CONFIG_AARCH32_ARMV8_R)
|
||||
#define REGION_RAM_ATTR(limit) \
|
||||
{ \
|
||||
.rbar = NOT_EXEC | \
|
||||
P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
|
||||
/* Cache-ability */ \
|
||||
.mair_idx = MPU_MAIR_INDEX_SRAM, \
|
||||
.r_limit = limit - 1, /* Region Limit */ \
|
||||
}
|
||||
|
||||
#define REGION_RAM_TEXT_ATTR(limit) \
|
||||
{ \
|
||||
.rbar = P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
|
||||
/* Cache-ability */ \
|
||||
.mair_idx = MPU_MAIR_INDEX_SRAM, \
|
||||
.r_limit = limit - 1, /* Region Limit */ \
|
||||
}
|
||||
|
||||
#define REGION_RAM_RO_ATTR(limit) \
|
||||
{ \
|
||||
.rbar = NOT_EXEC | \
|
||||
P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
|
||||
/* Cache-ability */ \
|
||||
.mair_idx = MPU_MAIR_INDEX_SRAM, \
|
||||
.r_limit = limit - 1, /* Region Limit */ \
|
||||
}
|
||||
|
||||
#if defined(CONFIG_MPU_ALLOW_FLASH_WRITE)
|
||||
/* Note that the access permissions allow for un-privileged writes, contrary
|
||||
* to ARMv7-M where un-privileged code has Read-Only permissions.
|
||||
*/
|
||||
#define REGION_FLASH_ATTR(limit) \
|
||||
{ \
|
||||
.rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
|
||||
/* Cache-ability */ \
|
||||
.mair_idx = MPU_MAIR_INDEX_FLASH, \
|
||||
.r_limit = limit - 1, /* Region Limit */ \
|
||||
}
|
||||
#else /* CONFIG_MPU_ALLOW_FLASH_WRITE */
|
||||
#define REGION_FLASH_ATTR(limit) \
|
||||
{ \
|
||||
.rbar = RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
|
||||
/* Cache-ability */ \
|
||||
.mair_idx = MPU_MAIR_INDEX_FLASH, \
|
||||
.r_limit = limit - 1, /* Region Limit */ \
|
||||
}
|
||||
#endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */
|
||||
|
||||
#define REGION_DEVICE_ATTR(limit) \
|
||||
{ \
|
||||
/* AP, XN, SH */ \
|
||||
.rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, \
|
||||
/* Cache-ability */ \
|
||||
.mair_idx = MPU_MAIR_INDEX_DEVICE, \
|
||||
/* Region Limit */ \
|
||||
.r_limit = limit - 1, \
|
||||
}
|
||||
#else
|
||||
#define REGION_RAM_ATTR(base, size) \
|
||||
{\
|
||||
.rbar = NOT_EXEC | \
|
||||
|
@ -157,6 +284,7 @@
|
|||
}
|
||||
#endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */
|
||||
|
||||
#endif
|
||||
|
||||
struct arm_mpu_region_attr {
|
||||
/* Attributes belonging to RBAR */
|
Loading…
Reference in a new issue