arch: arc: bug fixes and add user space support in secure mode
* bug fixes * add user space support in secure mode Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
This commit is contained in:
parent
f81dee0b2b
commit
e91733c78b
10 changed files with 78 additions and 10 deletions
|
@ -232,8 +232,12 @@ SECTION_FUNC(TEXT, _isr_wrapper)
|
||||||
#if CONFIG_USERSPACE
|
#if CONFIG_USERSPACE
|
||||||
/* utilize the fact that Z bit is set if interrupt taken in U mode*/
|
/* utilize the fact that Z bit is set if interrupt taken in U mode*/
|
||||||
bnz _isr_from_privilege
|
bnz _isr_from_privilege
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
lr sp, [_ARC_V2_SEC_U_SP]
|
||||||
|
#else
|
||||||
/* get the correct stack pointer, don't touch _ARC_V2_USER_SP in the future */
|
/* get the correct stack pointer, don't touch _ARC_V2_USER_SP in the future */
|
||||||
aex sp, [_ARC_V2_USER_SP]
|
aex sp, [_ARC_V2_USER_SP]
|
||||||
|
#endif
|
||||||
_isr_from_privilege:
|
_isr_from_privilege:
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_ARC_FIRQ
|
#if CONFIG_ARC_FIRQ
|
||||||
|
|
|
@ -356,18 +356,21 @@ void arc_core_mpu_configure(u8_t type, u32_t base, u32_t size)
|
||||||
*/
|
*/
|
||||||
index = _mpu_probe(base);
|
index = _mpu_probe(base);
|
||||||
|
|
||||||
/* ARC MPU version doesn't support region overlap.
|
/* ARC MPU version 3 doesn't support region overlap.
|
||||||
* So it can not be directly used for stack/stack guard protect
|
* So it can not be directly used for stack/stack guard protect
|
||||||
* One way to do this is splitting the ram region as follow:
|
* One way to do this is splitting the ram region as follow:
|
||||||
*
|
*
|
||||||
* Take THREAD_STACK_GUARD_REGION as example:
|
* Take THREAD_STACK_GUARD_REGION as example:
|
||||||
* RAM region 0: the ram region before THREAD_STACK_GUARD_REGION, rw
|
* RAM region 0: the ram region before THREAD_STACK_GUARD_REGION, rw
|
||||||
* RAM THREAD_STACK_GUARD_REGION: RO
|
* RAM THREAD_STACK_GUARD_REGION: RO
|
||||||
* RAM region 1: the region after THREAD_STACK_GUARD_REGIO, same
|
* RAM region 1: the region after THREAD_STACK_GUARD_REGION, same
|
||||||
* as region 0
|
* as region 0
|
||||||
|
* if region_index == index, it means the same thread comes back,
|
||||||
|
* no need to split
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (index >= 0) { /* need to split, only 1 split is allowed */
|
if (index >= 0 && region_index != index) {
|
||||||
|
/* need to split, only 1 split is allowed */
|
||||||
/* find the correct region to mpu_config.mpu_regions */
|
/* find the correct region to mpu_config.mpu_regions */
|
||||||
if (index == last_region) {
|
if (index == last_region) {
|
||||||
/* already split */
|
/* already split */
|
||||||
|
|
|
@ -80,7 +80,12 @@ GEN_OFFSET_SYM(_callee_saved_stack_t, r25);
|
||||||
GEN_OFFSET_SYM(_callee_saved_stack_t, r26);
|
GEN_OFFSET_SYM(_callee_saved_stack_t, r26);
|
||||||
GEN_OFFSET_SYM(_callee_saved_stack_t, fp);
|
GEN_OFFSET_SYM(_callee_saved_stack_t, fp);
|
||||||
#ifdef CONFIG_USERSPACE
|
#ifdef CONFIG_USERSPACE
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
GEN_OFFSET_SYM(_callee_saved_stack_t, kernel_sp);
|
||||||
GEN_OFFSET_SYM(_callee_saved_stack_t, user_sp);
|
GEN_OFFSET_SYM(_callee_saved_stack_t, user_sp);
|
||||||
|
#else
|
||||||
|
GEN_OFFSET_SYM(_callee_saved_stack_t, user_sp);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
GEN_OFFSET_SYM(_callee_saved_stack_t, r30);
|
GEN_OFFSET_SYM(_callee_saved_stack_t, r30);
|
||||||
#ifdef CONFIG_FP_SHARING
|
#ifdef CONFIG_FP_SHARING
|
||||||
|
|
|
@ -90,6 +90,11 @@ SECTION_FUNC(TEXT, __swap)
|
||||||
bclr r3, r3, _ARC_V2_STATUS32_SC_BIT
|
bclr r3, r3, _ARC_V2_STATUS32_SC_BIT
|
||||||
kflag r3
|
kflag r3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
lr r3, [_ARC_V2_SEC_STAT]
|
||||||
|
push_s r3
|
||||||
|
#endif
|
||||||
push_s blink
|
push_s blink
|
||||||
|
|
||||||
_save_callee_saved_regs
|
_save_callee_saved_regs
|
||||||
|
@ -137,6 +142,12 @@ _swap_return_from_coop:
|
||||||
bbit1 ilink, _ARC_V2_STATUS32_AE_BIT, _return_from_exc
|
bbit1 ilink, _ARC_V2_STATUS32_AE_BIT, _return_from_exc
|
||||||
|
|
||||||
pop_s blink /* pc into blink */
|
pop_s blink /* pc into blink */
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
pop_s r3 /* pop SEC_STAT */
|
||||||
|
/* sflag r3 */
|
||||||
|
/* sflag instruction is not supported in current ARC GNU */
|
||||||
|
.long 0x00ff302f
|
||||||
|
#endif
|
||||||
pop_s r3 /* status32 into r3 */
|
pop_s r3 /* status32 into r3 */
|
||||||
kflag r3 /* write status32 */
|
kflag r3 /* write status32 */
|
||||||
|
|
||||||
|
@ -172,6 +183,8 @@ _return_from_exc:
|
||||||
ld ilink, [sp] /* pc into ilink */
|
ld ilink, [sp] /* pc into ilink */
|
||||||
sr ilink, [_ARC_V2_ERET]
|
sr ilink, [_ARC_V2_ERET]
|
||||||
|
|
||||||
|
/* SEC_STAT is bypassed when CONFIG_ARC_HAS_SECURE */
|
||||||
|
|
||||||
/* put status32 into estatus */
|
/* put status32 into estatus */
|
||||||
ld ilink, [sp, ___isf_t_status32_OFFSET - ___isf_t_pc_OFFSET]
|
ld ilink, [sp, ___isf_t_status32_OFFSET - ___isf_t_pc_OFFSET]
|
||||||
sr ilink, [_ARC_V2_ERSTATUS]
|
sr ilink, [_ARC_V2_ERSTATUS]
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
/* initial stack frame */
|
/* initial stack frame */
|
||||||
struct init_stack_frame {
|
struct init_stack_frame {
|
||||||
u32_t pc;
|
u32_t pc;
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
u32_t sec_stat;
|
||||||
|
#endif
|
||||||
u32_t status32;
|
u32_t status32;
|
||||||
u32_t r3;
|
u32_t r3;
|
||||||
u32_t r2;
|
u32_t r2;
|
||||||
|
@ -99,6 +102,11 @@ void _new_thread(struct k_thread *thread, k_thread_stack_t *stack,
|
||||||
#else
|
#else
|
||||||
pInitCtx->pc = ((u32_t)_thread_entry_wrapper);
|
pInitCtx->pc = ((u32_t)_thread_entry_wrapper);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
pInitCtx->sec_stat = _arc_v2_aux_reg_read(_ARC_V2_SEC_STAT);
|
||||||
|
#endif
|
||||||
|
|
||||||
pInitCtx->r0 = (u32_t)pEntry;
|
pInitCtx->r0 = (u32_t)pEntry;
|
||||||
pInitCtx->r1 = (u32_t)parameter1;
|
pInitCtx->r1 = (u32_t)parameter1;
|
||||||
pInitCtx->r2 = (u32_t)parameter2;
|
pInitCtx->r2 = (u32_t)parameter2;
|
||||||
|
|
|
@ -56,12 +56,19 @@ _clear_user_stack:
|
||||||
sr r0, [_ARC_V2_ERSTATUS]
|
sr r0, [_ARC_V2_ERSTATUS]
|
||||||
sr r1, [_ARC_V2_ERET]
|
sr r1, [_ARC_V2_ERET]
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
lr r0, [_ARC_V2_SEC_STAT]
|
||||||
|
/* the mode returns from exception return is secure mode */
|
||||||
|
bset r0, r0, 31
|
||||||
|
sr r0, [_ARC_V2_ERSEC_STAT]
|
||||||
|
sr r5, [_ARC_V2_SEC_U_SP]
|
||||||
|
#else
|
||||||
/* when exception returns from kernel to user, sp and _ARC_V2_USER_SP
|
/* when exception returns from kernel to user, sp and _ARC_V2_USER_SP
|
||||||
* will be switched
|
* will be switched
|
||||||
*/
|
*/
|
||||||
sr r5, [_ARC_V2_USER_SP]
|
sr r5, [_ARC_V2_USER_SP]
|
||||||
|
#endif
|
||||||
mov sp, r2
|
mov sp, r2
|
||||||
|
|
||||||
rtie
|
rtie
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,6 +101,12 @@ SECTION_FUNC(TEXT, _arc_do_syscall)
|
||||||
/* through fake exception return, go back to the caller */
|
/* through fake exception return, go back to the caller */
|
||||||
kflag _ARC_V2_STATUS32_AE
|
kflag _ARC_V2_STATUS32_AE
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
lr r6, [_ARC_V2_SEC_STAT]
|
||||||
|
/* the mode returns from exception return is secure mode */
|
||||||
|
bset r6, r6, 31
|
||||||
|
sr r6, [_ARC_V2_ERSEC_STAT]
|
||||||
|
#endif
|
||||||
/* the status and return addesss are saved in trap_s handler */
|
/* the status and return addesss are saved in trap_s handler */
|
||||||
pop r6
|
pop r6
|
||||||
sr r6, [_ARC_V2_ERSTATUS]
|
sr r6, [_ARC_V2_ERSTATUS]
|
||||||
|
|
|
@ -131,7 +131,12 @@ struct _callee_saved_stack {
|
||||||
u32_t fp; /* r27 */
|
u32_t fp; /* r27 */
|
||||||
|
|
||||||
#ifdef CONFIG_USERSPACE
|
#ifdef CONFIG_USERSPACE
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
u32_t user_sp;
|
u32_t user_sp;
|
||||||
|
u32_t kernel_sp;
|
||||||
|
#else
|
||||||
|
u32_t user_sp;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
/* r28 is the stack pointer and saved separately */
|
/* r28 is the stack pointer and saved separately */
|
||||||
/* r29 is ILINK and does not need to be saved */
|
/* r29 is ILINK and does not need to be saved */
|
||||||
|
|
|
@ -43,8 +43,15 @@ extern "C" {
|
||||||
st fp, [sp, ___callee_saved_stack_t_fp_OFFSET]
|
st fp, [sp, ___callee_saved_stack_t_fp_OFFSET]
|
||||||
|
|
||||||
#ifdef CONFIG_USERSPACE
|
#ifdef CONFIG_USERSPACE
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
lr r13, [_ARC_V2_SEC_U_SP]
|
||||||
|
st r13, [sp, ___callee_saved_stack_t_user_sp_OFFSET]
|
||||||
|
lr r13, [_ARC_V2_SEC_K_SP]
|
||||||
|
st r13, [sp, ___callee_saved_stack_t_kernel_sp_OFFSET]
|
||||||
|
#else
|
||||||
lr r13, [_ARC_V2_USER_SP]
|
lr r13, [_ARC_V2_USER_SP]
|
||||||
st r13, [sp, ___callee_saved_stack_t_user_sp_OFFSET]
|
st r13, [sp, ___callee_saved_stack_t_user_sp_OFFSET]
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
st r30, [sp, ___callee_saved_stack_t_r30_OFFSET]
|
st r30, [sp, ___callee_saved_stack_t_r30_OFFSET]
|
||||||
|
|
||||||
|
@ -101,8 +108,15 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_USERSPACE
|
#ifdef CONFIG_USERSPACE
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
ld r13, [sp, ___callee_saved_stack_t_user_sp_OFFSET]
|
||||||
|
sr r13, [_ARC_V2_SEC_U_SP]
|
||||||
|
ld r13, [sp, ___callee_saved_stack_t_kernel_sp_OFFSET]
|
||||||
|
sr r13, [_ARC_V2_SEC_K_SP]
|
||||||
|
#else
|
||||||
ld_s r13, [sp, ___callee_saved_stack_t_user_sp_OFFSET]
|
ld_s r13, [sp, ___callee_saved_stack_t_user_sp_OFFSET]
|
||||||
sr r13, [_ARC_V2_USER_SP]
|
sr r13, [_ARC_V2_USER_SP]
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ld_s r13, [sp, ___callee_saved_stack_t_r13_OFFSET]
|
ld_s r13, [sp, ___callee_saved_stack_t_r13_OFFSET]
|
||||||
|
|
|
@ -13,16 +13,16 @@ static struct arc_mpu_region mpu_regions[] = {
|
||||||
#if CONFIG_ARC_MPU_VER == 3 && defined(CONFIG_APPLICATION_MEMORY)
|
#if CONFIG_ARC_MPU_VER == 3 && defined(CONFIG_APPLICATION_MEMORY)
|
||||||
/* Region ICCM */
|
/* Region ICCM */
|
||||||
MPU_REGION_ENTRY("IMAGE ROM",
|
MPU_REGION_ENTRY("IMAGE ROM",
|
||||||
_image_rom_start,
|
(u32_t) _image_rom_start,
|
||||||
_image_rom_end,
|
(u32_t) _image_rom_end,
|
||||||
REGION_FLASH_ATTR),
|
REGION_FLASH_ATTR),
|
||||||
MPU_REGION_ENTRY("APP MEMORY",
|
MPU_REGION_ENTRY("APP MEMORY",
|
||||||
__app_ram_start,
|
(u32_t) __app_ram_start,
|
||||||
__app_ram_size,
|
(u32_t) __app_ram_size,
|
||||||
REGION_RAM_ATTR),
|
REGION_RAM_ATTR),
|
||||||
MPU_REGION_ENTRY("KERNEL MEMORY",
|
MPU_REGION_ENTRY("KERNEL MEMORY",
|
||||||
__kernel_ram_start,
|
(u32_t) __kernel_ram_start,
|
||||||
__kernel_ram_size,
|
(u32_t) __kernel_ram_size,
|
||||||
AUX_MPU_RDP_KW | AUX_MPU_RDP_KR),
|
AUX_MPU_RDP_KW | AUX_MPU_RDP_KR),
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -37,6 +37,8 @@ extern "C" {
|
||||||
#define _ARC_V2_TMR0_LIMIT 0x023
|
#define _ARC_V2_TMR0_LIMIT 0x023
|
||||||
#define _ARC_V2_IRQ_VECT_BASE 0x025
|
#define _ARC_V2_IRQ_VECT_BASE 0x025
|
||||||
#define _ARC_V2_IRQ_VECT_BASE_S 0x26
|
#define _ARC_V2_IRQ_VECT_BASE_S 0x26
|
||||||
|
#define _ARC_V2_SEC_U_SP 0x39
|
||||||
|
#define _ARC_V2_SEC_K_SP 0x3a
|
||||||
#define _ARC_V2_AUX_IRQ_ACT 0x043
|
#define _ARC_V2_AUX_IRQ_ACT 0x043
|
||||||
#define _ARC_V2_DC_IVDC 0x047
|
#define _ARC_V2_DC_IVDC 0x047
|
||||||
#define _ARC_V2_DC_CTRL 0x048
|
#define _ARC_V2_DC_CTRL 0x048
|
||||||
|
@ -83,6 +85,7 @@ extern "C" {
|
||||||
#define _ARC_V2_ERSTATUS 0x402
|
#define _ARC_V2_ERSTATUS 0x402
|
||||||
#define _ARC_V2_ECR 0x403
|
#define _ARC_V2_ECR 0x403
|
||||||
#define _ARC_V2_EFA 0x404
|
#define _ARC_V2_EFA 0x404
|
||||||
|
#define _ARC_V2_ERSEC_STAT 0x406
|
||||||
#define _ARC_V2_ICAUSE 0x40a
|
#define _ARC_V2_ICAUSE 0x40a
|
||||||
#define _ARC_V2_IRQ_SELECT 0x40b
|
#define _ARC_V2_IRQ_SELECT 0x40b
|
||||||
#define _ARC_V2_IRQ_ENABLE 0x40c
|
#define _ARC_V2_IRQ_ENABLE 0x40c
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue