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:
Wayne Ren 2018-02-01 16:34:47 +08:00 committed by ruuddw
commit e91733c78b
10 changed files with 78 additions and 10 deletions

View file

@ -232,8 +232,12 @@ SECTION_FUNC(TEXT, _isr_wrapper)
#if CONFIG_USERSPACE
/* utilize the fact that Z bit is set if interrupt taken in U mode*/
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 */
aex sp, [_ARC_V2_USER_SP]
#endif
_isr_from_privilege:
#endif
#if CONFIG_ARC_FIRQ

View file

@ -356,18 +356,21 @@ void arc_core_mpu_configure(u8_t type, u32_t base, u32_t size)
*/
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
* One way to do this is splitting the ram region as follow:
*
* Take THREAD_STACK_GUARD_REGION as example:
* RAM region 0: the ram region before THREAD_STACK_GUARD_REGION, rw
* 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
* 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 */
if (index == last_region) {
/* already split */

View file

@ -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, fp);
#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);
#else
GEN_OFFSET_SYM(_callee_saved_stack_t, user_sp);
#endif
#endif
GEN_OFFSET_SYM(_callee_saved_stack_t, r30);
#ifdef CONFIG_FP_SHARING

View file

@ -90,6 +90,11 @@ SECTION_FUNC(TEXT, __swap)
bclr r3, r3, _ARC_V2_STATUS32_SC_BIT
kflag r3
#endif
#ifdef CONFIG_ARC_HAS_SECURE
lr r3, [_ARC_V2_SEC_STAT]
push_s r3
#endif
push_s blink
_save_callee_saved_regs
@ -137,6 +142,12 @@ _swap_return_from_coop:
bbit1 ilink, _ARC_V2_STATUS32_AE_BIT, _return_from_exc
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 */
kflag r3 /* write status32 */
@ -172,6 +183,8 @@ _return_from_exc:
ld ilink, [sp] /* pc into ilink */
sr ilink, [_ARC_V2_ERET]
/* SEC_STAT is bypassed when CONFIG_ARC_HAS_SECURE */
/* put status32 into estatus */
ld ilink, [sp, ___isf_t_status32_OFFSET - ___isf_t_pc_OFFSET]
sr ilink, [_ARC_V2_ERSTATUS]

View file

@ -22,6 +22,9 @@
/* initial stack frame */
struct init_stack_frame {
u32_t pc;
#ifdef CONFIG_ARC_HAS_SECURE
u32_t sec_stat;
#endif
u32_t status32;
u32_t r3;
u32_t r2;
@ -99,6 +102,11 @@ void _new_thread(struct k_thread *thread, k_thread_stack_t *stack,
#else
pInitCtx->pc = ((u32_t)_thread_entry_wrapper);
#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->r1 = (u32_t)parameter1;
pInitCtx->r2 = (u32_t)parameter2;

View file

@ -56,12 +56,19 @@ _clear_user_stack:
sr r0, [_ARC_V2_ERSTATUS]
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
* will be switched
*/
sr r5, [_ARC_V2_USER_SP]
#endif
mov sp, r2
rtie
/**
@ -94,6 +101,12 @@ SECTION_FUNC(TEXT, _arc_do_syscall)
/* through fake exception return, go back to the caller */
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 */
pop r6
sr r6, [_ARC_V2_ERSTATUS]

View file

@ -131,7 +131,12 @@ struct _callee_saved_stack {
u32_t fp; /* r27 */
#ifdef CONFIG_USERSPACE
#ifdef CONFIG_ARC_HAS_SECURE
u32_t user_sp;
u32_t kernel_sp;
#else
u32_t user_sp;
#endif
#endif
/* r28 is the stack pointer and saved separately */
/* r29 is ILINK and does not need to be saved */

View file

@ -43,8 +43,15 @@ extern "C" {
st fp, [sp, ___callee_saved_stack_t_fp_OFFSET]
#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]
st r13, [sp, ___callee_saved_stack_t_user_sp_OFFSET]
#endif
#endif
st r30, [sp, ___callee_saved_stack_t_r30_OFFSET]
@ -101,8 +108,15 @@ extern "C" {
#endif
#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]
sr r13, [_ARC_V2_USER_SP]
#endif
#endif
ld_s r13, [sp, ___callee_saved_stack_t_r13_OFFSET]

View file

@ -13,16 +13,16 @@ static struct arc_mpu_region mpu_regions[] = {
#if CONFIG_ARC_MPU_VER == 3 && defined(CONFIG_APPLICATION_MEMORY)
/* Region ICCM */
MPU_REGION_ENTRY("IMAGE ROM",
_image_rom_start,
_image_rom_end,
(u32_t) _image_rom_start,
(u32_t) _image_rom_end,
REGION_FLASH_ATTR),
MPU_REGION_ENTRY("APP MEMORY",
__app_ram_start,
__app_ram_size,
(u32_t) __app_ram_start,
(u32_t) __app_ram_size,
REGION_RAM_ATTR),
MPU_REGION_ENTRY("KERNEL MEMORY",
__kernel_ram_start,
__kernel_ram_size,
(u32_t) __kernel_ram_start,
(u32_t) __kernel_ram_size,
AUX_MPU_RDP_KW | AUX_MPU_RDP_KR),
#else

View file

@ -37,6 +37,8 @@ extern "C" {
#define _ARC_V2_TMR0_LIMIT 0x023
#define _ARC_V2_IRQ_VECT_BASE 0x025
#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_DC_IVDC 0x047
#define _ARC_V2_DC_CTRL 0x048
@ -83,6 +85,7 @@ extern "C" {
#define _ARC_V2_ERSTATUS 0x402
#define _ARC_V2_ECR 0x403
#define _ARC_V2_EFA 0x404
#define _ARC_V2_ERSEC_STAT 0x406
#define _ARC_V2_ICAUSE 0x40a
#define _ARC_V2_IRQ_SELECT 0x40b
#define _ARC_V2_IRQ_ENABLE 0x40c