From 44b6cf19da6305f98230dee0d2b3b72220a95ee3 Mon Sep 17 00:00:00 2001 From: Wayne Ren Date: Thu, 1 Aug 2019 12:39:35 +0800 Subject: [PATCH 1/4] arch: arc: add initial support of ARC TEE * it's based on ARC SecureShield * add basic secure service in arch/arc/core/secureshield * necesssary changes in arch level * thread switch * irq/exception handling * initialization * add secure time support Signed-off-by: Wayne Ren --- arch/arc/Kconfig | 60 ++++- arch/arc/core/CMakeLists.txt | 1 + arch/arc/core/fast_irq.S | 6 +- arch/arc/core/fault_s.S | 76 ++++--- arch/arc/core/irq_manage.c | 10 + arch/arc/core/mpu/arc_mpu_v3_internal.h | 147 ++++++++---- arch/arc/core/offsets/offsets.c | 3 + arch/arc/core/regular_irq.S | 13 +- arch/arc/core/reset.S | 6 +- arch/arc/core/secureshield/CMakeLists.txt | 12 + arch/arc/core/secureshield/arc_secure.S | 122 ++++++++++ arch/arc/core/secureshield/arc_sjli.c | 68 ++++++ .../core/secureshield/secure_sys_services.c | 89 ++++++++ arch/arc/core/switch.S | 33 ++- arch/arc/core/thread.c | 4 +- arch/arc/core/userspace.S | 22 +- arch/arc/include/kernel_arch_data.h | 4 + arch/arc/include/swap_macros.h | 29 ++- arch/arc/include/v2/irq.h | 13 ++ drivers/interrupt_controller/arcv2_irq_unit.c | 11 +- drivers/timer/arcv2_timer0.c | 16 ++ include/arch/arc/arch.h | 3 + include/arch/arc/v2/arcv2_irq_unit.h | 31 ++- include/arch/arc/v2/aux_regs.h | 11 + include/arch/arc/v2/secureshield/arc_secure.h | 212 ++++++++++++++++++ 25 files changed, 880 insertions(+), 122 deletions(-) create mode 100644 arch/arc/core/secureshield/CMakeLists.txt create mode 100644 arch/arc/core/secureshield/arc_secure.S create mode 100644 arch/arc/core/secureshield/arc_sjli.c create mode 100644 arch/arc/core/secureshield/secure_sys_services.c create mode 100644 include/arch/arc/v2/secureshield/arc_secure.h diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 2274ac03b7ba4..7884af8beee1d 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -177,12 +177,6 @@ config CODE_DENSITY help Enable code density option to get better code density -config ARC_HAS_SECURE - bool - # a hidden option - help - This option is enabled when ARC core supports secure mode - config ARC_HAS_ACCL_REGS bool "Reg Pair ACCL:ACCH (FPU and/or MPY > 6)" default y if FLOAT @@ -191,6 +185,60 @@ config ARC_HAS_ACCL_REGS (also referred to as r58:r59). These can also be used by gcc as GPR so kernel needs to save/restore per process +config ARC_HAS_SECURE + bool "ARC has SecureShield" + select CPU_HAS_TEE + select ARCH_HAS_TRUSTED_EXECUTION + help + This option is enabled when ARC core supports secure mode + +config SJLI_TABLE_SIZE + int "SJLI table size" + depends on ARC_SECURE_FIRMWARE + default 8 + help + The size of sjli (Secure Jump and Link Indexed) table. The + code in normal mode call secure services in secure mode through + sjli instruction. + +config ARC_SECURE_FIRMWARE + prompt "Generate Secure Firmware" + bool + depends on ARC_HAS_SECURE + default y if TRUSTED_EXECUTION_SECURE + help + This option indicates that we are building a Zephyr image that + is intended to execute in secure mode. The option is only + applicable to ARC processors that implement the SecureShield. + + This option enables Zephyr to include code that executes in + secure mode, as well as to exclude code that is designed to + execute only in normal mode. + + Code executing in secure mode has access to both the secure + and normal resources of the ARC processors. + +config ARC_NORMAL_FIRMWARE + prompt "Generate Normal Firmware" + bool + depends on !ARC_SECURE_FIRMWARE + depends on ARC_HAS_SECURE + default y if TRUSTED_EXECUTION_NONSECURE + help + This option indicates that we are building a Zephyr image that + is intended to execute in normal mode. Execution of this + image is triggered by secure firmware that executes in secure + mode. The option is only applicable to ARC processors that + implement the SecureShield. + + This option enables Zephyr to include code that executes in + normal mode only, as well as to exclude code that is + designed to execute only in secure mode. + + Code executing in normal mode has no access to secure + resources of the ARC processors, and, therefore, it shall avoid + accessing them. + menu "ARC MPU Options" depends on CPU_HAS_MPU diff --git a/arch/arc/core/CMakeLists.txt b/arch/arc/core/CMakeLists.txt index 8d6990fd6d2b6..da7f5e438b191 100644 --- a/arch/arc/core/CMakeLists.txt +++ b/arch/arc/core/CMakeLists.txt @@ -24,6 +24,7 @@ zephyr_library_sources_ifdef(CONFIG_ARC_FIRQ fast_irq.S) zephyr_library_sources_if_kconfig(irq_offload.c) add_subdirectory_ifdef(CONFIG_ARC_CORE_MPU mpu) +add_subdirectory_ifdef(CONFIG_ARC_SECURE_FIRMWARE secureshield) zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S) zephyr_library_sources_ifdef(CONFIG_ARC_CONNECT arc_connect.c) zephyr_library_sources_ifdef(CONFIG_SMP arc_smp.c) diff --git a/arch/arc/core/fast_irq.S b/arch/arc/core/fast_irq.S index 029899067e61d..eee3c0014be58 100644 --- a/arch/arc/core/fast_irq.S +++ b/arch/arc/core/fast_irq.S @@ -53,12 +53,10 @@ SECTION_FUNC(TEXT, _firq_enter) * This has already been done by _isr_wrapper. */ #ifdef CONFIG_ARC_STACK_CHECKING -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE lr r2, [_ARC_V2_SEC_STAT] bclr r2, r2, _ARC_V2_SEC_STAT_SSC_BIT - /* sflag r2 */ - /* sflag instruction is not supported in current ARC GNU */ - .long 0x00bf302f + sflag r2 #else /* disable stack checking */ lr r2, [_ARC_V2_STATUS32] diff --git a/arch/arc/core/fault_s.S b/arch/arc/core/fault_s.S index 58f440277806a..54a4249a123ba 100644 --- a/arch/arc/core/fault_s.S +++ b/arch/arc/core/fault_s.S @@ -81,6 +81,7 @@ _exc_entry: _create_irq_stack_frame #ifdef CONFIG_ARC_HAS_SECURE + /* ERSEC_STAT is IOW/RAZ in normal mode */ lr r0,[_ARC_V2_ERSEC_STAT] st_s r0, [sp, ___isf_t_sec_stat_OFFSET] #endif @@ -121,7 +122,7 @@ _exc_return: st_s r2, [r1, _kernel_offset_to_current] #endif -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE /* * sync up the ERSEC_STAT.ERM and SEC_STAT.IRM. * use a fake interrupt return to simulate an exception turn. @@ -130,11 +131,9 @@ _exc_return: */ lr r3,[_ARC_V2_ERSEC_STAT] btst r3, 31 - bset.nz r3, r3, 3 - bclr.z r3, r3, 3 - /* sflag r3 */ - /* sflag instruction is not supported in current ARC GNU */ - .long 0x00ff302f + bset.nz r3, r3, _ARC_V2_SEC_STAT_IRM_BIT + bclr.z r3, r3, _ARC_V2_SEC_STAT_IRM_BIT + sflag r3 #endif /* clear AE bit to forget this was an exception, and go to * register bank0 (if exception is raised in firq with 2 reg @@ -155,8 +154,23 @@ _exc_return: * raise exception again. The ignored interrupts will be re-triggered * if not cleared, or re-triggered by interrupt sources, or just missed */ - mov r3,(1 << (CONFIG_NUM_IRQ_PRIO_LEVELS - 1)) /* use lowest */ + +#ifdef CONFIG_ARC_SECURE_FIRMWARE + mov r3, (1 << (ARC_N_IRQ_START_LEVEL - 1)) +#else + mov r3, (1 << (CONFIG_NUM_IRQ_PRIO_LEVELS - 1)) +#endif + +#ifdef CONFIG_ARC_NORMAL_FIRMWARE + push r2 + mov r0, _ARC_V2_AUX_IRQ_ACT + mov r1, r3 + mov r6, ARC_S_CALL_AUX_WRITE + sjli SJLI_CALL_ARC_SECURE + pop r2 +#else sr r3, [_ARC_V2_AUX_IRQ_ACT] +#endif #if defined(CONFIG_ARC_FIRQ) && CONFIG_RGF_NUM_BANKS != 1 mov r2, ilink @@ -191,7 +205,7 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap) mov r6, K_SYSCALL_BAD valid_syscall_id: -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE lr ilink, [_ARC_V2_ERSEC_STAT] push ilink #endif @@ -268,17 +282,8 @@ exc_nest_handle: /* check if the current thread needs to be rescheduled */ ld_s r0, [r1, _kernel_offset_to_ready_q_cache] breq r0, r2, _exc_return_from_irqoffload_trap - - _save_callee_saved_regs - - st _CAUSE_RIRQ, [r2, _thread_offset_to_relinquish_cause] - /* note: Ok to use _CAUSE_RIRQ since everything is saved */ - - ld_s r2, [r1, _kernel_offset_to_ready_q_cache] - st_s r2, [r1, _kernel_offset_to_current] #endif - -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE /* * sync up the ERSEC_STAT.ERM and SEC_STAT.IRM. * use a fake interrupt return to simulate an exception turn. @@ -287,21 +292,42 @@ exc_nest_handle: */ lr r3,[_ARC_V2_ERSEC_STAT] btst r3, 31 - bset.nz r3, r3, 3 - bclr.z r3, r3, 3 - /* sflag r3 */ - /* sflag instruction is not supported in current ARC GNU */ - .long 0x00ff302f + bset.nz r3, r3, _ARC_V2_SEC_STAT_IRM_BIT + bclr.z r3, r3, _ARC_V2_SEC_STAT_IRM_BIT + sflag r3 #endif + + _save_callee_saved_regs + + st _CAUSE_RIRQ, [r2, _thread_offset_to_relinquish_cause] + /* note: Ok to use _CAUSE_RIRQ since everything is saved */ + + ld_s r2, [r1, _kernel_offset_to_ready_q_cache] + st_s r2, [r1, _kernel_offset_to_current] + /* clear AE bit to forget this was an exception */ lr r3, [_ARC_V2_STATUS32] and r3,r3,(~_ARC_V2_STATUS32_AE) kflag r3 /* pretend lowest priority interrupt happened to use common handler */ lr r3, [_ARC_V2_AUX_IRQ_ACT] - or r3,r3,(1<<(CONFIG_NUM_IRQ_PRIO_LEVELS-1)) /* use lowest */ - sr r3, [_ARC_V2_AUX_IRQ_ACT] +#ifdef CONFIG_ARC_SECURE_FIRMWARE + or r3, r3, (1 << (ARC_N_IRQ_START_LEVEL - 1)) +#else + or r3, r3, (1 << (CONFIG_NUM_IRQ_PRIO_LEVELS - 1)) +#endif + +#ifdef CONFIG_ARC_NORMAL_FIRMWARE + push_s r2 + mov r0, _ARC_V2_AUX_IRQ_ACT + mov r1, r3 + mov r6, ARC_S_CALL_AUX_WRITE + sjli SJLI_CALL_ARC_SECURE + pop_s r2 +#else + sr r3, [_ARC_V2_AUX_IRQ_ACT] +#endif /* Assumption: r2 has current thread */ b _rirq_common_interrupt_swap #endif diff --git a/arch/arc/core/irq_manage.c b/arch/arc/core/irq_manage.c index e091e0b552527..21663377f1a83 100644 --- a/arch/arc/core/irq_manage.c +++ b/arch/arc/core/irq_manage.c @@ -83,6 +83,16 @@ void z_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags) __ASSERT(prio < CONFIG_NUM_IRQ_PRIO_LEVELS, "invalid priority %d for irq %d", prio, irq); +/* 0 -> CONFIG_NUM_IRQ_PRIO_LEVELS allocted to secure world + * left prio levels allocated to normal world + */ +#if defined(CONFIG_ARC_SECURE_FIRMWARE) + prio = prio < ARC_N_IRQ_START_LEVEL ? + prio : (ARC_N_IRQ_START_LEVEL - 1); +#elif defined(CONFIG_ARC_NORMAL_FIRMWARE) + prio = prio < ARC_N_IRQ_START_LEVEL ? + ARC_N_IRQ_START_LEVEL : prio; +#endif z_arc_v2_irq_unit_prio_set(irq, prio); irq_unlock(key); } diff --git a/arch/arc/core/mpu/arc_mpu_v3_internal.h b/arch/arc/core/mpu/arc_mpu_v3_internal.h index b81931f0f9427..25ffcda3d592e 100644 --- a/arch/arc/core/mpu/arc_mpu_v3_internal.h +++ b/arch/arc/core/mpu/arc_mpu_v3_internal.h @@ -62,6 +62,68 @@ static u8_t dynamic_region_index; */ static struct dynamic_region_info dyn_reg_info[MPU_DYNAMIC_REGION_AREAS_NUM]; +#ifdef CONFIG_ARC_NORMAL_FIRMWARE +/* \todo through secure service to access mpu */ +static inline void _region_init(u32_t index, u32_t region_addr, u32_t size, + u32_t region_attr) +{ +} + +static inline void _region_set_attr(u32_t index, u32_t attr) +{ + +} + +static inline u32_t _region_get_attr(u32_t index) +{ + return 0; +} + +static inline u32_t _region_get_start(u32_t index) +{ + return 0; +} + +static inline void _region_set_start(u32_t index, u32_t start) +{ + +} + +static inline u32_t _region_get_end(u32_t index) +{ + return 0; +} + +static inline void _region_set_end(u32_t index, u32_t end) +{ +} + +/** + * This internal function probes the given addr's MPU index.if not + * in MPU, returns error + */ +static inline int _mpu_probe(u32_t addr) +{ + return -EINVAL; +} + +/** + * This internal function checks if MPU region is enabled or not + */ +static inline bool _is_enabled_region(u32_t r_index) +{ + return false; +} + +/** + * This internal function check if the region is user accessible or not + */ +static inline bool _is_user_accessible_region(u32_t r_index, int write) +{ + return false; +} +#else /* CONFIG_ARC_NORMAL_FIRMWARE */ +/* the following functions are prepared for SECURE_FRIMWARE */ static inline void _region_init(u32_t index, u32_t region_addr, u32_t size, u32_t region_attr) { @@ -77,7 +139,7 @@ static inline void _region_init(u32_t index, u32_t region_addr, u32_t size, z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index); z_arc_v2_aux_reg_write(_ARC_V2_MPU_RSTART, region_addr); z_arc_v2_aux_reg_write(_ARC_V2_MPU_REND, - CALC_REGION_END_ADDR(region_addr, size)); + CALC_REGION_END_ADDR(region_addr, size)); z_arc_v2_aux_reg_write(_ARC_V2_MPU_RPER, region_attr); } @@ -142,20 +204,6 @@ static inline int _mpu_probe(u32_t addr) } } -/** - * This internal function allocates a dynamic MPU region and returns - * the index or error - */ -static inline int _dynamic_region_allocate_index(void) -{ - if (dynamic_region_index >= get_num_regions()) { - LOG_ERR("no enough mpu entries %d", dynamic_region_index); - return -EINVAL; - } - - return dynamic_region_index++; -} - /** * This internal function checks if MPU region is enabled or not */ @@ -166,21 +214,6 @@ static inline bool _is_enabled_region(u32_t r_index) AUX_MPU_RPER_VALID_MASK) == AUX_MPU_RPER_VALID_MASK); } -/** - * This internal function checks the area given by (start, size) - * and returns the index if the area match one MPU entry - */ -static inline int _get_region_index(u32_t start, u32_t size) -{ - int index = _mpu_probe(start); - - if (index > 0 && index == _mpu_probe(start + size - 1)) { - return index; - } - - return -EINVAL; -} - /** * This internal function check if the region is user accessible or not */ @@ -201,6 +234,37 @@ static inline bool _is_user_accessible_region(u32_t r_index, int write) (AUX_MPU_ATTR_UR | AUX_MPU_ATTR_KR)); } +#endif /* CONFIG_ARC_NORMAL_FIRMWARE */ + +/** + * This internal function allocates a dynamic MPU region and returns + * the index or error + */ +static inline int _dynamic_region_allocate_index(void) +{ + if (dynamic_region_index >= get_num_regions()) { + LOG_ERR("no enough mpu entries %d", dynamic_region_index); + return -EINVAL; + } + + return dynamic_region_index++; +} + +/** + * This internal function checks the area given by (start, size) + * and returns the index if the area match one MPU entry + */ +static inline int _get_region_index(u32_t start, u32_t size) +{ + int index = _mpu_probe(start); + + if (index > 0 && index == _mpu_probe(start + size - 1)) { + return index; + } + + return -EINVAL; +} + /* @brief allocate and init a dynamic MPU region * * This internal function performs the allocation and initialization of @@ -353,7 +417,14 @@ static inline int _mpu_configure(u8_t type, u32_t base, u32_t size) */ void arc_core_mpu_enable(void) { -#define MPU_ENABLE_ATTR 0 +#ifdef CONFIG_ARC_SECURE_FIRMWARE +/* the default region: + * normal:0x000, SID:0x10000, KW:0x100 KR:0x80, KE:0x4 0 + */ +#define MPU_ENABLE_ATTR 0x101c0 +#else +#define MPU_ENABLE_ATTR 0 +#endif arc_core_mpu_default(MPU_ENABLE_ATTR); } @@ -365,7 +436,8 @@ void arc_core_mpu_disable(void) /* MPU is always enabled, use default region to * simulate MPU disable */ - arc_core_mpu_default(REGION_ALL_ATTR); + arc_core_mpu_default(REGION_ALL_ATTR | AUX_MPU_ATTR_S | + AUX_MPU_RPER_SID1); } /** @@ -474,12 +546,11 @@ void arc_core_mpu_configure_thread(struct k_thread *thread) */ void arc_core_mpu_default(u32_t region_attr) { - u32_t val = z_arc_v2_aux_reg_read(_ARC_V2_MPU_EN) & - (~AUX_MPU_RPER_ATTR_MASK); - - region_attr &= AUX_MPU_RPER_ATTR_MASK; - - z_arc_v2_aux_reg_write(_ARC_V2_MPU_EN, region_attr | val); +#ifdef CONFIG_ARC_NORMAL_FIRMWARE +/* \todo through secure service to access mpu */ +#else + z_arc_v2_aux_reg_write(_ARC_V2_MPU_EN, region_attr); +#endif } /** diff --git a/arch/arc/core/offsets/offsets.c b/arch/arc/core/offsets/offsets.c index 6e9289ff907c2..74227d5974660 100644 --- a/arch/arc/core/offsets/offsets.c +++ b/arch/arc/core/offsets/offsets.c @@ -85,6 +85,9 @@ GEN_OFFSET_SYM(_callee_saved_stack_t, r24); 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_ARC_SECURE_FIRMWARE +GEN_OFFSET_SYM(_callee_saved_stack_t, sec_stat); +#endif #ifdef CONFIG_USERSPACE #ifdef CONFIG_ARC_HAS_SECURE GEN_OFFSET_SYM(_callee_saved_stack_t, kernel_sp); diff --git a/arch/arc/core/regular_irq.S b/arch/arc/core/regular_irq.S index 9218ad35b7054..d7a9894ed9347 100644 --- a/arch/arc/core/regular_irq.S +++ b/arch/arc/core/regular_irq.S @@ -53,12 +53,11 @@ SECTION_FUNC(TEXT, _rirq_enter) #ifdef CONFIG_ARC_STACK_CHECKING -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE lr r2, [_ARC_V2_SEC_STAT] bclr r2, r2, _ARC_V2_SEC_STAT_SSC_BIT - /* sflag r2 */ - /* sflag instruction is not supported in current ARC GNU */ - .long 0x00bf302f + sflag r2 + #else /* disable stack checking */ lr r2, [_ARC_V2_STATUS32] @@ -199,6 +198,12 @@ _rirq_common_interrupt_swap: .balign 4 _rirq_return_from_coop: +#ifdef CONFIG_ARC_SECURE_FIRMWARE + /* must return to secure mode, so set IRM bit to 1 */ + lr r0, [_ARC_V2_SEC_STAT] + bset r0, r0, _ARC_V2_SEC_STAT_IRM_BIT + sflag r0 +#endif /* carve fake stack */ sub sp, sp, ___isf_t_pc_OFFSET diff --git a/arch/arc/core/reset.S b/arch/arc/core/reset.S index 2d881cb39b3a8..37943acd605f3 100644 --- a/arch/arc/core/reset.S +++ b/arch/arc/core/reset.S @@ -45,7 +45,6 @@ GTEXT(__start) SECTION_FUNC(TEXT,__reset) SECTION_FUNC(TEXT,__start) - /* lock interrupts: will get unlocked when switch to main task * also make sure the processor in the correct status */ @@ -62,8 +61,11 @@ SECTION_FUNC(TEXT,__start) sr r0, [_ARC_V2_TMR0_COUNT] #endif /* interrupt related init */ +#ifndef CONFIG_ARC_NORMAL_FIRMWARE + /* IRQ_ACT and IRQ_CTRL should be initialized and set in secure mode */ sr r0, [_ARC_V2_AUX_IRQ_ACT] sr r0, [_ARC_V2_AUX_IRQ_CTRL] +#endif sr r0, [_ARC_V2_AUX_IRQ_HINT] /* \todo: MPU init, gp for small data? */ @@ -72,7 +74,7 @@ SECTION_FUNC(TEXT,__start) * so that exception vectors can be handled. */ mov r0, _VectorTable -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE sr r0, [_ARC_V2_IRQ_VECT_BASE_S] #else sr r0, [_ARC_V2_IRQ_VECT_BASE] diff --git a/arch/arc/core/secureshield/CMakeLists.txt b/arch/arc/core/secureshield/CMakeLists.txt new file mode 100644 index 0000000000000..c32133af71fb4 --- /dev/null +++ b/arch/arc/core/secureshield/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2018 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources( + arc_sjli.c + arc_secure.S + secure_sys_services.c +) \ No newline at end of file diff --git a/arch/arc/core/secureshield/arc_secure.S b/arch/arc/core/secureshield/arc_secure.S new file mode 100644 index 0000000000000..bedef0df8c02f --- /dev/null +++ b/arch/arc/core/secureshield/arc_secure.S @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2018 Synopsys. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +.macro clear_scratch_regs + mov r1, 0 + mov r2, 0 + mov r3, 0 + mov r4, 0 + mov r5, 0 + mov r6, 0 + mov r7, 0 + mov r8, 0 + mov r9, 0 + mov r10, 0 + mov r11, 0 + mov r12, 0 +.endm + +.macro clear_callee_regs + mov r25, 0 + mov r24, 0 + mov r23, 0 + mov r22, 0 + mov r21, 0 + mov r20, 0 + mov r19, 0 + mov r18, 0 + mov r17, 0 + mov r16, 0 + + mov r15, 0 + mov r14, 0 + mov r13, 0 +.endm + +GTEXT(arc_go_to_normal) +GTEXT(_arc_do_secure_call) +GDATA(arc_s_call_table) + + +SECTION_FUNC(TEXT, _arc_do_secure_call) + /* r0-r5: arg1-arg6, r6 is call id */ + /* the call id should be checked */ + /* disable normal interrupt happened when processor in secure mode ? */ + /* seti (0x30 | (ARC_N_IRQ_START_LEVEL-1)) */ + breq r6, ARC_S_CALL_CLRI, _s_clri + breq r6, ARC_S_CALL_SETI, _s_seti + push_s blink + mov blink, arc_s_call_table + ld.as r6, [blink, r6] + + jl [r6] + + /* + * no need to clear callee regs, as they will be saved and restored + * automatically + */ + clear_scratch_regs + + mov r29, 0 + mov r30, 0 + + +_arc_do_secure_call_exit: + pop_s blink + + j [blink] + /* enable normal interrupt */ + /* + * j.d [blink] + * seti (0x30 | (CONFIG_NUM_IRQ_PRIO_LEVELS - 1)) + */ + +_s_clri: + lr r0, [_ARC_V2_STATUS32] + and r0, r0, 0x1e + asr r0, r0 + or r0, r0, 0x30 + mov r6, (0x30 | (ARC_N_IRQ_START_LEVEL-1)) + + j.d [blink] + seti r6 + +_s_seti: + btst r0, 4 + jnz __seti_0 + mov r0, (CONFIG_NUM_IRQ_PRIO_LEVELS - 1) + lr r6, [_ARC_V2_STATUS32] + and r6, r6, 0x1e + asr r6, r6 + cmp r0, r6 + mov.hs r0, r6 +__seti_0: + and r0, r0, 0xf + brhs r0, ARC_N_IRQ_START_LEVEL, __seti_1 + mov r0, ARC_N_IRQ_START_LEVEL +__seti_1: + or r0, r0, 0x30 + + j.d [blink] + seti r0 + + +SECTION_FUNC(TEXT, arc_go_to_normal) + clear_callee_regs + clear_scratch_regs + + mov fp, 0 + mov r29, 0 + mov r30, 0 + mov blink, 0 + + jl [r0] + /* should not come here */ + kflag 1 + diff --git a/arch/arc/core/secureshield/arc_sjli.c b/arch/arc/core/secureshield/arc_sjli.c new file mode 100644 index 0000000000000..02d8c5b9f7d28 --- /dev/null +++ b/arch/arc/core/secureshield/arc_sjli.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include + +static void _default_sjli_entry(void); +/* + * sjli vector table must be in instruction space + * \todo: how to let user to install customized sjli entry easily, e.g. + * through macros or with the help of compiler? + */ +const static u32_t _sjli_vector_table[CONFIG_SJLI_TABLE_SIZE] = { + [0] = (u32_t)_arc_do_secure_call, + [1 ... (CONFIG_SJLI_TABLE_SIZE - 1)] = (u32_t)_default_sjli_entry, +}; + +/* + * @brief default entry of sjli call + * + */ +static void _default_sjli_entry(void) +{ + printk("default sjli entry\n"); +} + +/* + * @brief initializaiton of sjli related functions + * + */ +static void sjli_table_init(void) +{ + /* install SJLI table */ + z_arc_v2_aux_reg_write(_ARC_V2_NSC_TABLE_BASE, _sjli_vector_table); + z_arc_v2_aux_reg_write(_ARC_V2_NSC_TABLE_TOP, + (_sjli_vector_table + CONFIG_SJLI_TABLE_SIZE)); +} + +/* + * @brief initializaiton of secureshield related functions. + */ +static int arc_secureshield_init(struct device *arg) +{ + sjli_table_init(); + + /* set nic bit to enable seti/clri and + * sleep/wevt in normal mode. + * If not set, direct call of seti/clri etc. will raise exception. + * Then, these seti/clri instructions should be replaced with secure + * secure services (sjli call) + * + */ + __asm__ volatile("sflag 0x20"); + + return 0; +} + +SYS_INIT(arc_secureshield_init, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/arch/arc/core/secureshield/secure_sys_services.c b/arch/arc/core/secureshield/secure_sys_services.c new file mode 100644 index 0000000000000..34ab80068a212 --- /dev/null +++ b/arch/arc/core/secureshield/secure_sys_services.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2018 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include + +#include + +#define IRQ_PRIO_MASK (0xffff << ARC_N_IRQ_START_LEVEL) +/* + * @brief read secure auxiliary regs on behalf of normal mode + * + * @param aux_reg address of aux reg + * + * Some aux regs require secure privilege, this function implements + * an secure service to access secure aux regs. Check should be done + * to decide whether the access is valid. + */ +static s32_t arc_s_aux_read(u32_t aux_reg) +{ + return -1; +} + +/* + * @brief write secure auxiliary regs on behalf of normal mode + * + * @param aux_reg address of aux reg + * @param val, the val to write + * + * Some aux regs require secure privilege, this function implements + * an secure service to access secure aux regs. Check should be done + * to decide whether the access is valid. + */ +static s32_t arc_s_aux_write(u32_t aux_reg, u32_t val) +{ + if (aux_reg == _ARC_V2_AUX_IRQ_ACT) { + /* 0 -> CONFIG_NUM_IRQ_PRIO_LEVELS allocated to secure world + * left prio levels allocated to normal world + */ + val &= IRQ_PRIO_MASK; + z_arc_v2_aux_reg_write(_ARC_V2_AUX_IRQ_ACT, val | + (z_arc_v2_aux_reg_read(_ARC_V2_AUX_IRQ_ACT) & + (~IRQ_PRIO_MASK))); + + return 0; + } + + return -1; +} + +/* + * @brief allocate interrupt for normal world + * + * @param intno, the interrupt to be allocated to normal world + * + * By default, most interrupts are configured to be secure in initialization. + * If normal world wants to use an interrupt, through this secure service to + * apply one. Necessary check should be done to decide whether the apply is + * valid + */ +static s32_t arc_s_irq_alloc(u32_t intno) +{ + z_arc_v2_irq_uinit_secure_set(intno, 0); + return 0; +} + + +/* + * \todo, to access MPU from normal mode, secure mpu service should be + * created. In the secure mpu service, the parameters should be checked + * (e.g., not overwrite the mpu regions for secure world)that operations + * are valid + */ + + +/* + * \todo, how to add secure service easily + */ +const _arc_s_call_handler_t arc_s_call_table[ARC_S_CALL_LIMIT] = { + [ARC_S_CALL_AUX_READ] = (_arc_s_call_handler_t)arc_s_aux_read, + [ARC_S_CALL_AUX_WRITE] = (_arc_s_call_handler_t)arc_s_aux_write, + [ARC_S_CALL_IRQ_ALLOC] = (_arc_s_call_handler_t)arc_s_irq_alloc, +}; diff --git a/arch/arc/core/switch.S b/arch/arc/core/switch.S index 81f58bed6a698..683b83abfe4cf 100644 --- a/arch/arc/core/switch.S +++ b/arch/arc/core/switch.S @@ -86,7 +86,11 @@ SECTION_FUNC(TEXT, z_arch_switch) push_s r3 #ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE lr r3, [_ARC_V2_SEC_STAT] +#else + mov r3, 0 +#endif push_s r3 #endif @@ -98,11 +102,9 @@ SECTION_FUNC(TEXT, z_arch_switch) /* disable stack checking here, as sp will be changed to target * thread'sp */ -#ifdef CONFIG_ARC_HAS_SECURE +#if defined(CONFIG_ARC_HAS_SECURE) && defined(CONFIG_ARC_SECURE_FIRMWARE) bclr r3, r3, _ARC_V2_SEC_STAT_SSC_BIT - /* sflag r3 */ - /* sflag instruction is not supported in current ARC GNU */ - .long 0x00ff302f + sflag r3 #else bclr r3, r3, _ARC_V2_STATUS32_SC_BIT kflag r3 @@ -144,9 +146,9 @@ _switch_return_from_coop: 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 +#ifdef CONFIG_ARC_SECURE_FIRMWARE + sflag r3 +#endif #endif pop_s r3 /* status32 into r3 */ kflag r3 /* write status32 */ @@ -166,22 +168,19 @@ _switch_return_from_firq: bbit1 r3, _ARC_V2_STATUS32_AE_BIT, _return_from_exc_irq /* pretend interrupt happened to use rtie instruction */ - -#ifdef CONFIG_ARC_HAS_SECURE - lr r3, [_ARC_V2_SEC_STAT] - /* set SEC_STAT.IRM = SECURE for interrupt return */ - bset r3, r3, 3 - /* sflag r3 */ - /* sflag instruction is not supported in current ARC GNU */ - .long 0x00ff302f -#endif - lr r3, [_ARC_V2_AUX_IRQ_ACT] brne r3, 0, _switch_already_in_irq /* use lowest interrupt priority */ or r3, r3, (1 << (CONFIG_NUM_IRQ_PRIO_LEVELS-1)) +#ifdef CONFIG_ARC_NORMAL_FIRMWARE + mov r0, _ARC_V2_AUX_IRQ_ACT + mov r1, r3 + mov r6, ARC_S_CALL_AUX_WRITE + sjli SJLI_CALL_ARC_SECURE +#else sr r3, [_ARC_V2_AUX_IRQ_ACT] +#endif _switch_already_in_irq: rtie diff --git a/arch/arc/core/thread.c b/arch/arc/core/thread.c index fd1463420cfdb..84a543aced46a 100644 --- a/arch/arc/core/thread.c +++ b/arch/arc/core/thread.c @@ -177,7 +177,7 @@ void z_new_thread(struct k_thread *thread, k_thread_stack_t *stack, pInitCtx->pc = ((u32_t)z_thread_entry_wrapper); #endif -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE pInitCtx->sec_stat = z_arc_v2_aux_reg_read(_ARC_V2_SEC_STAT); #endif @@ -188,7 +188,7 @@ void z_new_thread(struct k_thread *thread, k_thread_stack_t *stack, /* stack check configuration */ #ifdef CONFIG_ARC_STACK_CHECKING -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE pInitCtx->sec_stat |= _ARC_V2_SEC_STAT_SSC; #else pInitCtx->status32 |= _ARC_V2_STATUS32_SC; diff --git a/arch/arc/core/userspace.S b/arch/arc/core/userspace.S index 7848330ea15a2..3dea968c7a9bb 100644 --- a/arch/arc/core/userspace.S +++ b/arch/arc/core/userspace.S @@ -95,12 +95,10 @@ SECTION_FUNC(TEXT, z_arc_userspace_enter) */ #ifdef CONFIG_ARC_STACK_CHECKING /* disable stack checking as the stack should be initialized */ -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE lr blink, [_ARC_V2_SEC_STAT] bclr blink, blink, _ARC_V2_SEC_STAT_SSC_BIT - /* sflag blink */ - /* sflag instruction is not supported in current ARC GNU */ - .long 0x07ff302f + sflag blink #else lr blink, [_ARC_V2_STATUS32] bclr blink, blink, _ARC_V2_STATUS32_SC_BIT @@ -136,12 +134,10 @@ _clear_user_stack: _load_stack_check_regs -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE lr r0, [_ARC_V2_SEC_STAT] bset r0, r0, _ARC_V2_SEC_STAT_SSC_BIT - /* sflag r0 */ - /* sflag instruction is not supported in current ARC GNU */ - .long 0x003f302f + sflag r0 #else lr r0, [_ARC_V2_STATUS32] bset r0, r0, _ARC_V2_STATUS32_SC_BIT @@ -163,16 +159,16 @@ _arc_go_to_user_space: bclr r0, r0, _ARC_V2_STATUS32_AE_BIT kflag r0 -#ifdef CONFIG_ARC_HAS_SECURE +/* when exception returns from kernel to user, sp and _ARC_V2_USER_SP + * /_ARC_V2_SECU_SP will be switched + */ +#if defined(CONFIG_ARC_HAS_SECURE) && defined(CONFIG_ARC_SECURE_FIRMWARE) 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, blink @@ -236,7 +232,7 @@ SECTION_FUNC(TEXT, _arc_do_syscall) sr r6, [_ARC_V2_ERSTATUS] pop r6 sr r6, [_ARC_V2_ERET] -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE pop r6 sr r6, [_ARC_V2_ERSEC_STAT] #endif diff --git a/arch/arc/include/kernel_arch_data.h b/arch/arc/include/kernel_arch_data.h index c5b19ce40c7c3..65686ec376a7f 100644 --- a/arch/arc/include/kernel_arch_data.h +++ b/arch/arc/include/kernel_arch_data.h @@ -130,6 +130,10 @@ struct _callee_saved_stack { u32_t r26; u32_t fp; /* r27 */ +#ifdef CONFIG_ARC_SECURE_FIRMWARE + u32_t sec_stat; +#endif + #ifdef CONFIG_USERSPACE #ifdef CONFIG_ARC_HAS_SECURE u32_t user_sp; diff --git a/arch/arc/include/swap_macros.h b/arch/arc/include/swap_macros.h index c8c04bafcb922..b7eab4dab909d 100644 --- a/arch/arc/include/swap_macros.h +++ b/arch/arc/include/swap_macros.h @@ -42,12 +42,24 @@ extern "C" { st r26, [sp, ___callee_saved_stack_t_r26_OFFSET] st fp, [sp, ___callee_saved_stack_t_fp_OFFSET] +#ifdef CONFIG_ARC_SECURE_FIRMWARE + lr r13, [_ARC_V2_SEC_STAT] + st_s r13, [sp, ___callee_saved_stack_t_sec_stat_OFFSET] +#endif + #ifdef CONFIG_USERSPACE #ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE 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] + lr r13, [_ARC_V2_KERNEL_SP] + st r13, [sp, ___callee_saved_stack_t_kernel_sp_OFFSET] +#endif /* CONFIG_ARC_SECURE_FIRMWARE */ #else lr r13, [_ARC_V2_USER_SP] st r13, [sp, ___callee_saved_stack_t_user_sp_OFFSET] @@ -121,6 +133,7 @@ extern "C" { #ifdef CONFIG_USERSPACE #ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE 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] @@ -128,9 +141,21 @@ extern "C" { #else ld_s r13, [sp, ___callee_saved_stack_t_user_sp_OFFSET] sr r13, [_ARC_V2_USER_SP] + ld r13, [sp, ___callee_saved_stack_t_kernel_sp_OFFSET] + sr r13, [_ARC_V2_KERNEL_SP] +#endif /* CONFIG_ARC_SECURE_FIRMWARE */ +#else + ld r13, [sp, ___callee_saved_stack_t_user_sp_OFFSET] + sr r13, [_ARC_V2_USER_SP] #endif #endif +#ifdef CONFIG_ARC_SECURE_FIRMWARE + ld r13, [sp, ___callee_saved_stack_t_sec_stat_OFFSET] + + sflag r13 +#endif + ld_s r13, [sp, ___callee_saved_stack_t_r13_OFFSET] ld_s r14, [sp, ___callee_saved_stack_t_r14_OFFSET] ld_s r15, [sp, ___callee_saved_stack_t_r15_OFFSET] @@ -259,7 +284,7 @@ extern "C" { * _kernel.current. r3 is a scratch reg. */ .macro _load_stack_check_regs -#ifdef CONFIG_ARC_HAS_SECURE +#if defined(CONFIG_ARC_SECURE_FIRMWARE) ld r3, [r2, _thread_offset_to_k_stack_base] sr r3, [_ARC_V2_S_KSTACK_BASE] ld r3, [r2, _thread_offset_to_k_stack_top] @@ -281,7 +306,7 @@ extern "C" { ld r3, [r2, _thread_offset_to_u_stack_top] sr r3, [_ARC_V2_USTACK_TOP] #endif -#endif /* CONFIG_ARC_HAS_SECURE */ +#endif /* CONFIG_ARC_SECURE_FIRMWARE */ .endm diff --git a/arch/arc/include/v2/irq.h b/arch/arc/include/v2/irq.h index a45d7f1adf9cd..fdf42dc3022b6 100644 --- a/arch/arc/include/v2/irq.h +++ b/arch/arc/include/v2/irq.h @@ -15,6 +15,8 @@ #ifndef ZEPHYR_ARCH_ARC_INCLUDE_V2_IRQ_H_ #define ZEPHYR_ARCH_ARC_INCLUDE_V2_IRQ_H_ +#include + #ifdef __cplusplus extern "C" { #endif @@ -28,7 +30,12 @@ extern "C" { #define _ARC_V2_AUX_IRQ_CTRL_32_REGS 16 +#ifdef CONFIG_ARC_SECURE_FIRMWARE +#define _ARC_V2_DEF_IRQ_LEVEL (ARC_N_IRQ_START_LEVEL - 1) +#else #define _ARC_V2_DEF_IRQ_LEVEL (CONFIG_NUM_IRQ_PRIO_LEVELS - 1) +#endif + #define _ARC_V2_WAKE_IRQ_LEVEL _ARC_V2_DEF_IRQ_LEVEL /* @@ -59,7 +66,13 @@ static ALWAYS_INLINE void z_irq_setup(void) ); k_cpu_sleep_mode = _ARC_V2_WAKE_IRQ_LEVEL; + +#ifdef CONFIG_ARC_NORMAL_FIRMWARE + /* normal mode cannot write irq_ctrl, ignore it */ + aux_irq_ctrl_value = aux_irq_ctrl_value; +#else z_arc_v2_aux_reg_write(_ARC_V2_AUX_IRQ_CTRL, aux_irq_ctrl_value); +#endif } #endif /* _ASMLANGUAGE */ diff --git a/drivers/interrupt_controller/arcv2_irq_unit.c b/drivers/interrupt_controller/arcv2_irq_unit.c index b4160d0afabfb..30189f6ecfd18 100644 --- a/drivers/interrupt_controller/arcv2_irq_unit.c +++ b/drivers/interrupt_controller/arcv2_irq_unit.c @@ -27,7 +27,7 @@ extern void *_VectorTable; #include #include -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE #undef _ARC_V2_IRQ_VECT_BASE #define _ARC_V2_IRQ_VECT_BASE _ARC_V2_IRQ_VECT_BASE_S #endif @@ -71,8 +71,9 @@ static int arc_v2_irq_unit_init(struct device *unused) * values in this loop. */ for (irq = 16; irq < CONFIG_NUM_IRQS; irq++) { + z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq); -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, (CONFIG_NUM_IRQ_PRIO_LEVELS-1) | _ARC_V2_IRQ_PRIORITY_SECURE); /* lowest priority */ @@ -148,7 +149,7 @@ static int arc_v2_irq_unit_resume(struct device *dev) */ for (irq = 16U; irq < CONFIG_NUM_IRQS; irq++) { z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq); -#ifdef CONFIG_ARC_HAS_SECURE +#ifdef CONFIG_ARC_SECURE_FIRMWARE z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, ctx.irq_config[irq - 16] >> 2 | _ARC_V2_IRQ_PRIORITY_SECURE); @@ -162,7 +163,11 @@ static int arc_v2_irq_unit_resume(struct device *dev) ctx.irq_config[irq - 16] & BIT(0)); } +#ifdef CONFIG_ARC_NORMAL_FIRMWARE + /* \todo use sjli instruction to access irq_ctrl */ +#else z_arc_v2_aux_reg_write(_ARC_V2_AUX_IRQ_CTRL, ctx.irq_ctrl); +#endif z_arc_v2_aux_reg_write(_ARC_V2_IRQ_VECT_BASE, ctx.irq_vect_base); status32 = z_arc_v2_aux_reg_read(_ARC_V2_STATUS32); diff --git a/drivers/timer/arcv2_timer0.c b/drivers/timer/arcv2_timer0.c index 9f260c7df0a47..bcbe4f919ad55 100644 --- a/drivers/timer/arcv2_timer0.c +++ b/drivers/timer/arcv2_timer0.c @@ -13,8 +13,24 @@ /* * note: This implementation assumes Timer0 is present. Be sure * to build the ARC CPU with Timer0. + * + * If secureshield is present and secure firmware is configured, + * use secure Timer 0 */ +#ifdef CONFIG_ARC_SECURE_FIRMWARE + +#undef _ARC_V2_TMR0_COUNT +#undef _ARC_V2_TMR0_CONTROL +#undef _ARC_V2_TMR0_LIMIT +#undef IRQ_TIMER0 + +#define _ARC_V2_TMR0_COUNT _ARC_V2_S_TMR0_COUNT +#define _ARC_V2_TMR0_CONTROL _ARC_V2_S_TMR0_CONTROL +#define _ARC_V2_TMR0_LIMIT _ARC_V2_S_TMR0_LIMIT +#define IRQ_TIMER0 IRQ_SEC_TIMER0 + +#endif #define _ARC_V2_TMR_CTRL_IE 0x1 /* interrupt enable */ #define _ARC_V2_TMR_CTRL_NH 0x2 /* count only while not halted */ diff --git a/include/arch/arc/arch.h b/include/arch/arc/arch.h index 553ef21d9b258..ed55933eb05da 100644 --- a/include/arch/arc/arch.h +++ b/include/arch/arc/arch.h @@ -32,6 +32,9 @@ #ifdef CONFIG_ARC_CONNECT #include #endif +#ifdef CONFIG_ARC_HAS_SECURE +#include +#endif #endif #ifdef __cplusplus diff --git a/include/arch/arc/v2/arcv2_irq_unit.h b/include/arch/arc/v2/arcv2_irq_unit.h index a5e4fd4489197..fd169baa71e87 100644 --- a/include/arch/arc/v2/arcv2_irq_unit.h +++ b/include/arch/arc/v2/arcv2_irq_unit.h @@ -14,7 +14,7 @@ extern "C" { #endif /* configuration flags for interrupt unit */ - +#define _ARC_V2_INT_PRIO_MASK 0xf #define _ARC_V2_INT_DISABLE 0 #define _ARC_V2_INT_ENABLE 1 @@ -97,16 +97,35 @@ void z_arc_v2_irq_unit_int_disable(int irq) static ALWAYS_INLINE void z_arc_v2_irq_unit_prio_set(int irq, unsigned char prio) { + z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq); -#ifdef CONFIG_ARC_HAS_SECURE -/* if ARC has secure mode, all interrupt should be secure */ - z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, prio | - _ARC_V2_IRQ_PRIORITY_SECURE); +#if defined(CONFIG_ARC_SECURE_FIRMWARE) + z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, + (z_arc_v2_aux_reg_read(_ARC_V2_IRQ_PRIORITY) & (~_ARC_V2_INT_PRIO_MASK)) + | prio); #else z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, prio); #endif } +#if defined(CONFIG_ARC_SECURE_FIRMWARE) +static ALWAYS_INLINE +void z_arc_v2_irq_uinit_secure_set(int irq, bool secure) +{ + z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq); + + if (secure) { + z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, + z_arc_v2_aux_reg_read(_ARC_V2_IRQ_PRIORITY) | + _ARC_V2_IRQ_PRIORITY_SECURE); + } else { + z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, + z_arc_v2_aux_reg_read(_ARC_V2_IRQ_PRIORITY) & + _ARC_V2_INT_PRIO_MASK); + } +} +#endif + /* * @brief Set interrupt sensitivity * @@ -119,7 +138,7 @@ void z_arc_v2_irq_unit_prio_set(int irq, unsigned char prio) */ static ALWAYS_INLINE -void _arc_v2_irq_unit_sensitivity_set(int irq, int s) +void z_arc_v2_irq_unit_sensitivity_set(int irq, int s) { z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq); z_arc_v2_aux_reg_write(_ARC_V2_IRQ_TRIGGER, s); diff --git a/include/arch/arc/v2/aux_regs.h b/include/arch/arc/v2/aux_regs.h index 057968cc079ed..19f291370e093 100644 --- a/include/arch/arc/v2/aux_regs.h +++ b/include/arch/arc/v2/aux_regs.h @@ -37,6 +37,7 @@ 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_KERNEL_SP 0x38 #define _ARC_V2_SEC_U_SP 0x39 #define _ARC_V2_SEC_K_SP 0x3a #define _ARC_V2_AUX_IRQ_ACT 0x043 @@ -73,6 +74,12 @@ extern "C" { #define _ARC_V2_TMR1_COUNT 0x100 #define _ARC_V2_TMR1_CONTROL 0x101 #define _ARC_V2_TMR1_LIMIT 0x102 +#define _ARC_V2_S_TMR0_COUNT 0x106 +#define _ARC_V2_S_TMR0_CONTROL 0x107 +#define _ARC_V2_S_TMR0_LIMIT 0x108 +#define _ARC_V2_S_TMR1_COUNT 0x109 +#define _ARC_V2_S_TMR1_CONTROL 0x10a +#define _ARC_V2_S_TMR1_LIMIT 0x10b #define _ARC_V2_IRQ_PRIO_PEND 0x200 #define _ARC_V2_AUX_IRQ_HINT 0x201 #define _ARC_V2_IRQ_PRIORITY 0x206 @@ -84,6 +91,8 @@ extern "C" { #define _ARC_V2_KSTACK_BASE 0x265 #define _ARC_V2_S_KSTACK_TOP 0x266 #define _ARC_V2_S_KSTACK_BASE 0x267 +#define _ARC_V2_NSC_TABLE_TOP 0x268 +#define _ARC_V2_NSC_TABLE_BASE 0x269 #define _ARC_V2_JLI_BASE 0x290 #define _ARC_V2_LDI_BASE 0x291 #define _ARC_V2_EI_BASE 0x292 @@ -128,6 +137,8 @@ extern "C" { #define _ARC_V2_STATUS32_AD (1 << _ARC_V2_STATUS32_AD_BIT) #define _ARC_V2_STATUS32_US_BIT 20 #define _ARC_V2_STATUS32_US (1 << _ARC_V2_STATUS32_US_BIT) +#define _ARC_V2_STATUS32_S_BIT 21 +#define _ARC_V2_STATUS32_S (1 << _ARC_V2_STATUS32_US_BIT) #define _ARC_V2_STATUS32_IE (1 << 31) /* SEC_STAT bits */ diff --git a/include/arch/arc/v2/secureshield/arc_secure.h b/include/arch/arc/v2/secureshield/arc_secure.h new file mode 100644 index 0000000000000..764732632aeab --- /dev/null +++ b/include/arch/arc/v2/secureshield/arc_secure.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2018 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#ifndef ZEPHYR_INCLUDE_ARCH_ARC_V2_SJLI_H +#define ZEPHYR_INCLUDE_ARCH_ARC_V2_SJLI_H + +#define SJLI_CALL_ARC_SECURE 0 + +#define ARC_S_CALL_AUX_READ 0 +#define ARC_S_CALL_AUX_WRITE 1 +#define ARC_S_CALL_IRQ_ALLOC 2 +#define ARC_S_CALL_CLRI 3 +#define ARC_S_CALL_SETI 4 +#define ARC_S_CALL_LIMIT 5 + + + +#define ARC_N_IRQ_START_LEVEL ((CONFIG_NUM_IRQ_PRIO_LEVELS + 1) / 2) + +#ifndef _ASMLANGUAGE + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define arc_sjli(id) \ + (__asm__ volatile("sjli %[sjli_id]\n" :: [sjli_id] "i" (id))) + +#ifdef CONFIG_ARC_SECURE_FIRMWARE +typedef u32_t (*_arc_s_call_handler_t)(u32_t arg1, u32_t arg2, u32_t arg3, + u32_t arg4, u32_t arg5, u32_t arg6); + + +extern void arc_go_to_normal(u32_t addr); +extern void _arc_do_secure_call(void); +extern const _arc_s_call_handler_t arc_s_call_table[ARC_S_CALL_LIMIT]; + +#endif + + +#ifdef CONFIG_ARC_NORMAL_FIRMWARE + +static inline u32_t _arc_s_call_invoke6(u32_t arg1, u32_t arg2, u32_t arg3, + u32_t arg4, u32_t arg5, u32_t arg6, + u32_t call_id) +{ + register u32_t ret __asm__("r0") = arg1; + register u32_t r1 __asm__("r1") = arg2; + register u32_t r2 __asm__("r2") = arg3; + register u32_t r3 __asm__("r3") = arg4; + register u32_t r4 __asm__("r4") = arg5; + register u32_t r5 __asm__("r5") = arg6; + register u32_t r6 __asm__("r6") = call_id; + + compiler_barrier(); + + __asm__ volatile( + "sjli %[id]\n" + : "=r"(ret) + : [id] "i" (SJLI_CALL_ARC_SECURE), + "r" (ret), "r" (r1), "r" (r2), "r" (r3), + "r" (r4), "r" (r5), "r" (r6)); + + return ret; +} + +static inline u32_t _arc_s_call_invoke5(u32_t arg1, u32_t arg2, u32_t arg3, + u32_t arg4, u32_t arg5, u32_t call_id) +{ + register u32_t ret __asm__("r0") = arg1; + register u32_t r1 __asm__("r1") = arg2; + register u32_t r2 __asm__("r2") = arg3; + register u32_t r3 __asm__("r3") = arg4; + register u32_t r4 __asm__("r4") = arg5; + register u32_t r6 __asm__("r6") = call_id; + + compiler_barrier(); + + __asm__ volatile( + "sjli %[id]\n" + : "=r"(ret) + : [id] "i" (SJLI_CALL_ARC_SECURE), + "r" (ret), "r" (r1), "r" (r2), "r" (r3), + "r" (r4), "r" (r6)); + + return ret; +} + +static inline u32_t _arc_s_call_invoke4(u32_t arg1, u32_t arg2, u32_t arg3, + u32_t arg4, u32_t call_id) +{ + register u32_t ret __asm__("r0") = arg1; + register u32_t r1 __asm__("r1") = arg2; + register u32_t r2 __asm__("r2") = arg3; + register u32_t r3 __asm__("r3") = arg4; + register u32_t r6 __asm__("r6") = call_id; + + compiler_barrier(); + + __asm__ volatile( + "sjli %[id]\n" + : "=r"(ret) + : [id] "i" (SJLI_CALL_ARC_SECURE), + "r" (ret), "r" (r1), "r" (r2), "r" (r3), + "r" (r6)); + + return ret; +} + +static inline u32_t _arc_s_call_invoke3(u32_t arg1, u32_t arg2, u32_t arg3, + u32_t call_id) +{ + register u32_t ret __asm__("r0") = arg1; + register u32_t r1 __asm__("r1") = arg2; + register u32_t r2 __asm__("r2") = arg3; + register u32_t r6 __asm__("r6") = call_id; + + compiler_barrier(); + + __asm__ volatile( + "sjli %[id]\n" + : "=r"(ret) + : [id] "i" (SJLI_CALL_ARC_SECURE), + "r" (ret), "r" (r1), "r" (r2), "r" (r6)); + + return ret; +} + +static inline u32_t _arc_s_call_invoke2(u32_t arg1, u32_t arg2, u32_t call_id) +{ + register u32_t ret __asm__("r0") = arg1; + register u32_t r1 __asm__("r1") = arg2; + register u32_t r6 __asm__("r6") = call_id; + + compiler_barrier(); + + __asm__ volatile( + "sjli %[id]\n" + : "=r"(ret) + : [id] "i" (SJLI_CALL_ARC_SECURE), + "r" (ret), "r" (r1), "r" (r6)); + + return ret; +} + +static inline u32_t _arc_s_call_invoke1(u32_t arg1, u32_t call_id) +{ + register u32_t ret __asm__("r0") = arg1; + register u32_t r6 __asm__("r6") = call_id; + + compiler_barrier(); + + __asm__ volatile( + "sjli %[id]\n" + : "=r"(ret) + : [id] "i" (SJLI_CALL_ARC_SECURE), + "r" (ret), "r" (r6)); + + return ret; +} + +static inline u32_t _arc_s_call_invoke0(u32_t call_id) +{ + register u32_t ret __asm__("r0"); + register u32_t r6 __asm__("r6") = call_id; + + compiler_barrier(); + + __asm__ volatile( + "sjli %[id]\n" + : "=r"(ret) + : [id] "i" (SJLI_CALL_ARC_SECURE), + "r" (ret), "r" (r6)); + + return ret; +} + +static inline bool _arch_is_user_context(void) +{ + u32_t status; + + compiler_barrier(); + + __asm__ volatile("lr %0, [%[status32]]\n" + : "=r"(status) + : [status32] "i" (_ARC_V2_STATUS32)); + + return !(status & _ARC_V2_STATUS32_US) ? true : false; +} + + + + +#endif /* CONFIG_ARC_NORMAL_FIRMWARE */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_INCLUDE_ARCH_ARC_V2_SECURE_H */ From 2da3c315cdfe9624365fb62adce0cc8c90574a1f Mon Sep 17 00:00:00 2001 From: Wayne Ren Date: Thu, 1 Aug 2019 14:08:36 +0800 Subject: [PATCH 2/4] boards: emsk: add initial support of normal/non-secure application * Non-secure/normal application: em_starterkit_em7d_normal * secure application: em_starterkit_em7d Signed-off-by: Wayne Ren --- boards/arc/em_starterkit/Kconfig | 2 +- boards/arc/em_starterkit/arc_mpu_regions.c | 14 ++++++- .../em_starterkit_em7d_defconfig | 2 + .../em_starterkit_em7d_normal.dts | 42 +++++++++++++++++++ .../em_starterkit_em7d_normal.yaml | 18 ++++++++ .../em_starterkit_em7d_normal_defconfig | 18 ++++++++ soc/arc/snps_emsk/Kconfig | 1 - soc/arc/snps_emsk/Kconfig.soc | 4 +- 8 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 boards/arc/em_starterkit/em_starterkit_em7d_normal.dts create mode 100644 boards/arc/em_starterkit/em_starterkit_em7d_normal.yaml create mode 100644 boards/arc/em_starterkit/em_starterkit_em7d_normal_defconfig diff --git a/boards/arc/em_starterkit/Kconfig b/boards/arc/em_starterkit/Kconfig index 651608377e522..f9b0ebad44ea0 100644 --- a/boards/arc/em_starterkit/Kconfig +++ b/boards/arc/em_starterkit/Kconfig @@ -20,4 +20,4 @@ choice endchoice -endif +endif \ No newline at end of file diff --git a/boards/arc/em_starterkit/arc_mpu_regions.c b/boards/arc/em_starterkit/arc_mpu_regions.c index e75bbe5025c95..1a76267e629a1 100644 --- a/boards/arc/em_starterkit/arc_mpu_regions.c +++ b/boards/arc/em_starterkit/arc_mpu_regions.c @@ -9,6 +9,10 @@ #include #include +/* + * for secure firmware, MPU entries are only set up for secure world. + * All regions not listed here are shared by secure world and normal world. + */ static struct arc_mpu_region mpu_regions[] = { #if DT_ICCM_SIZE > 0 /* Region ICCM */ @@ -33,11 +37,19 @@ static struct arc_mpu_region mpu_regions[] = { AUX_MPU_ATTR_KW | AUX_MPU_ATTR_KR | AUX_MPU_ATTR_UR | AUX_MPU_ATTR_KE | AUX_MPU_ATTR_UE | REGION_DYNAMIC), #endif + +/* + * Region peripheral is shared by secure world and normal world by default, + * no need a static mpu entry. If some peripherals belong to secure world, + * add it here. + */ +#ifndef CONFIG_ARC_SECURE_FIRMWARE /* Region Peripheral */ MPU_REGION_ENTRY("PERIPHERAL", 0xF0000000, 64 * 1024, - REGION_KERNEL_RAM_ATTR), + REGION_KERNEL_RAM_ATTR) +#endif }; struct arc_mpu_config mpu_config = { diff --git a/boards/arc/em_starterkit/em_starterkit_em7d_defconfig b/boards/arc/em_starterkit/em_starterkit_em7d_defconfig index 316aca2c399d3..33274adddf624 100644 --- a/boards/arc/em_starterkit/em_starterkit_em7d_defconfig +++ b/boards/arc/em_starterkit/em_starterkit_em7d_defconfig @@ -17,3 +17,5 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_GPIO=y CONFIG_ARC_MPU_ENABLE=y +CONFIG_ARC_HAS_SECURE=y +CONFIG_TRUSTED_EXECUTION_SECURE=y diff --git a/boards/arc/em_starterkit/em_starterkit_em7d_normal.dts b/boards/arc/em_starterkit/em_starterkit_em7d_normal.dts new file mode 100644 index 0000000000000..6e558253773b3 --- /dev/null +++ b/boards/arc/em_starterkit/em_starterkit_em7d_normal.dts @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include "em_starterkit_r23.dtsi" +#include "board.dtsi" + +/ { + model = "em_starterkit_em7d_normal"; + compatible = "snps,em_starterkit_em7d_normal", "snps,em_starterkit"; + + aliases { + uart-0 = &uart0; + uart-1 = &uart1; + uart-2 = &uart2; + }; + + chosen { + zephyr,sram = &ddr0; + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + }; + + iccm@0 { + reg = <0x20000 DT_SIZE_K(128)>; + }; + + dccm@80000000 { + reg = <0x80010000 DT_SIZE_K(64)>; + }; +}; + +&uart1 { + status = "okay"; + current-speed = <115200>; +}; diff --git a/boards/arc/em_starterkit/em_starterkit_em7d_normal.yaml b/boards/arc/em_starterkit/em_starterkit_em7d_normal.yaml new file mode 100644 index 0000000000000..24e1ffa8ad3b9 --- /dev/null +++ b/boards/arc/em_starterkit/em_starterkit_em7d_normal.yaml @@ -0,0 +1,18 @@ +identifier: em_starterkit_em7d_normal +name: EM Starterkit EM7D normal world +type: mcu +arch: arc +toolchain: + - zephyr + - xtools +supported: + - i2c + - spi + - gpio +ram: 64 +flash: 128 +testing: + default: true + ignore_tags: + - net + - bluetooth diff --git a/boards/arc/em_starterkit/em_starterkit_em7d_normal_defconfig b/boards/arc/em_starterkit/em_starterkit_em7d_normal_defconfig new file mode 100644 index 0000000000000..228dc1f032173 --- /dev/null +++ b/boards/arc/em_starterkit/em_starterkit_em7d_normal_defconfig @@ -0,0 +1,18 @@ +CONFIG_ARC=y +CONFIG_SOC_EMSK=y +CONFIG_SOC_EMSK_EM7D=y +CONFIG_BOARD_EM_STARTERKIT=y +CONFIG_BOARD_EM_STARTERKIT_R23=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 +CONFIG_XIP=n +CONFIG_BUILD_OUTPUT_BIN=n +CONFIG_PRINTK=y +CONFIG_ARCV2_INTERRUPT_UNIT=y +CONFIG_ARCV2_TIMER=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_GPIO=y +CONFIG_ARC_MPU_ENABLE=y +CONFIG_TRUSTED_EXECUTION_NONSECURE=y diff --git a/soc/arc/snps_emsk/Kconfig b/soc/arc/snps_emsk/Kconfig index cac4fa0f9d4e9..8de3836f09775 100644 --- a/soc/arc/snps_emsk/Kconfig +++ b/soc/arc/snps_emsk/Kconfig @@ -14,7 +14,6 @@ default SOC_EMSK_EM7D config SOC_EMSK_EM7D bool "Synopsys ARC EM7D of EMSK" select CPU_HAS_MPU - select ARC_HAS_SECURE if BOARD_EM_STARTERKIT_R23 config SOC_EMSK_EM11D bool "Synopsys ARC EM11D of EMSK" diff --git a/soc/arc/snps_emsk/Kconfig.soc b/soc/arc/snps_emsk/Kconfig.soc index fcbe59a7c023a..00269c6e1fab4 100644 --- a/soc/arc/snps_emsk/Kconfig.soc +++ b/soc/arc/snps_emsk/Kconfig.soc @@ -7,5 +7,5 @@ config SOC_EMSK bool "Synopsys ARC EM Starter Kit SoC" - select HAS_I2C_DW - select HAS_SPI_DW + select HAS_I2C_DW if I2C + select HAS_SPI_DW if SPI From 2dd12870775343d5b1c59a49dc48d7f04863e94a Mon Sep 17 00:00:00 2001 From: Wayne Ren Date: Thu, 1 Aug 2019 14:25:50 +0800 Subject: [PATCH 3/4] boards: nsim: add initial support of normal/non-secure application normal/non-secure application: nsim_sem_normal Signed-off-by: Wayne Ren --- boards/arc/nsim/arc_mpu_regions.c | 12 +++++++ boards/arc/nsim/nsim_sem.dts | 24 +++++++++++--- boards/arc/nsim/nsim_sem_defconfig | 1 + .../nsim/nsim_sem_mpu_stack_guard_defconfig | 1 + boards/arc/nsim/nsim_sem_normal.dts | 33 +++++++++++++++++++ boards/arc/nsim/nsim_sem_normal.yaml | 11 +++++++ boards/arc/nsim/nsim_sem_normal_defconfig | 16 +++++++++ soc/arc/snps_nsim/Kconfig.defconfig.em | 2 +- soc/arc/snps_nsim/Kconfig.defconfig.sem | 2 +- 9 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 boards/arc/nsim/nsim_sem_normal.dts create mode 100644 boards/arc/nsim/nsim_sem_normal.yaml create mode 100644 boards/arc/nsim/nsim_sem_normal_defconfig diff --git a/boards/arc/nsim/arc_mpu_regions.c b/boards/arc/nsim/arc_mpu_regions.c index 0f98c800d4115..15e17f8af5987 100644 --- a/boards/arc/nsim/arc_mpu_regions.c +++ b/boards/arc/nsim/arc_mpu_regions.c @@ -9,6 +9,10 @@ #include #include +/* + * for secure firmware, MPU entries are only set up for secure world. + * All regions not listed here are shared by secure world and normal world. + */ static struct arc_mpu_region mpu_regions[] = { #if DT_ICCM_SIZE > 0 /* Region ICCM */ @@ -24,11 +28,19 @@ static struct arc_mpu_region mpu_regions[] = { DT_DCCM_SIZE * 1024, REGION_KERNEL_RAM_ATTR | REGION_DYNAMIC), #endif + +/* + * Region peripheral is shared by secure world and normal world by default, + * no need a static mpu entry. If some peripherals belong to secure world, + * add it here. + */ +#ifndef CONFIG_ARC_SECURE_FIRMWARE /* Region Peripheral */ MPU_REGION_ENTRY("PERIPHERAL", 0xF0000000, 64 * 1024, REGION_KERNEL_RAM_ATTR), +#endif }; struct arc_mpu_config mpu_config = { diff --git a/boards/arc/nsim/nsim_sem.dts b/boards/arc/nsim/nsim_sem.dts index f023c9e02b3b3..61358c9210c4b 100644 --- a/boards/arc/nsim/nsim_sem.dts +++ b/boards/arc/nsim/nsim_sem.dts @@ -1,18 +1,32 @@ /* - * Copyright (c) 2018, 2019, Synopsys, Inc. All rights reserved. + * Copyright (c) 2018, Synopsys, Inc. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ + /dts-v1/; #include "nsim_em.dtsi" / { - model = "snps,nsim_sem"; + + model = "nsim_sem"; compatible = "snps,nsim_sem"; -}; -&cpu0 { - clock-frequency = <5000000>; + iccm0: iccm@0 { + device_type = "memory"; + compatible = "arc,iccm"; + reg = <0x0 0x40000>; + }; + + dccm0: dccm@80000000 { + device_type = "memory"; + compatible = "arc,dccm"; + reg = <0x80000000 0x40000>; + }; + + chosen { + zephyr,sram = &dccm0; + }; }; diff --git a/boards/arc/nsim/nsim_sem_defconfig b/boards/arc/nsim/nsim_sem_defconfig index 5718c8bf3e1dc..b2a721f69eb7c 100644 --- a/boards/arc/nsim/nsim_sem_defconfig +++ b/boards/arc/nsim/nsim_sem_defconfig @@ -16,3 +16,4 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_ARC_EXCEPTION_DEBUG=y +CONFIG_TRUSTED_EXECUTION_SECURE=y diff --git a/boards/arc/nsim/nsim_sem_mpu_stack_guard_defconfig b/boards/arc/nsim/nsim_sem_mpu_stack_guard_defconfig index 78e027d4d7b05..d2a02a2eeb8f3 100644 --- a/boards/arc/nsim/nsim_sem_mpu_stack_guard_defconfig +++ b/boards/arc/nsim/nsim_sem_mpu_stack_guard_defconfig @@ -17,3 +17,4 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_ARC_EXCEPTION_DEBUG=y +CONFIG_TRUSTED_EXECUTION_SECURE=y \ No newline at end of file diff --git a/boards/arc/nsim/nsim_sem_normal.dts b/boards/arc/nsim/nsim_sem_normal.dts new file mode 100644 index 0000000000000..8e8cffcf32da4 --- /dev/null +++ b/boards/arc/nsim/nsim_sem_normal.dts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "nsim_em.dtsi" + +/ { + + model = "nsim_sem_normal"; + compatible = "snps,nsim_sem_normal"; + + iccm0: iccm@0 { + device_type = "memory"; + compatible = "arc,iccm"; + reg = <0x40000 DT_SIZE_K(256)>; + }; + + dccm0: dccm@80000000 { + device_type = "memory"; + compatible = "arc,dccm"; + reg = <0x80040000 DT_SIZE_K(256)>; + }; + + chosen { + zephyr,sram = &dccm0; + }; + +}; diff --git a/boards/arc/nsim/nsim_sem_normal.yaml b/boards/arc/nsim/nsim_sem_normal.yaml new file mode 100644 index 0000000000000..c940a46e72522 --- /dev/null +++ b/boards/arc/nsim/nsim_sem_normal.yaml @@ -0,0 +1,11 @@ +identifier: nsim_sem_normal +name: SEM in normal mode of Nsim simulator +type: mcu +arch: arc +simulation: nsim +toolchain: + - zephyr +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/arc/nsim/nsim_sem_normal_defconfig b/boards/arc/nsim/nsim_sem_normal_defconfig new file mode 100644 index 0000000000000..0d3578f4b5668 --- /dev/null +++ b/boards/arc/nsim/nsim_sem_normal_defconfig @@ -0,0 +1,16 @@ +CONFIG_ARC=y +CONFIG_CPU_ARCEM=y +CONFIG_SOC_NSIM=y +CONFIG_SOC_NSIM_SEM=y +CONFIG_BOARD_NSIM=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 +CONFIG_XIP=n +CONFIG_BUILD_OUTPUT_BIN=n +CONFIG_PRINTK=y +CONFIG_ARCV2_INTERRUPT_UNIT=y +CONFIG_ARCV2_TIMER=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_ARC_EXCEPTION_DEBUG=y +CONFIG_TRUSTED_EXECUTION_NONSECURE=y diff --git a/soc/arc/snps_nsim/Kconfig.defconfig.em b/soc/arc/snps_nsim/Kconfig.defconfig.em index dc50572552c57..ba19eeb5d7207 100644 --- a/soc/arc/snps_nsim/Kconfig.defconfig.em +++ b/soc/arc/snps_nsim/Kconfig.defconfig.em @@ -16,7 +16,7 @@ config NUM_IRQ_PRIO_LEVELS config NUM_IRQS # must be > the highest interrupt number used - default 20 + default 30 config ARC_MPU_VER default 2 diff --git a/soc/arc/snps_nsim/Kconfig.defconfig.sem b/soc/arc/snps_nsim/Kconfig.defconfig.sem index b605ff91922a7..f832dba93ebe9 100644 --- a/soc/arc/snps_nsim/Kconfig.defconfig.sem +++ b/soc/arc/snps_nsim/Kconfig.defconfig.sem @@ -16,7 +16,7 @@ config NUM_IRQ_PRIO_LEVELS config NUM_IRQS # must be > the highest interrupt number used - default 22 + default 30 config ARC_MPU_VER default 3 From 4908e17aaa065071877a6d994a8a76e16a260a37 Mon Sep 17 00:00:00 2001 From: Wayne Ren Date: Thu, 1 Aug 2019 14:36:14 +0800 Subject: [PATCH 4/4] samples: add sample to show how ARC TEE works * this is a simple sample to show how secure applicaiton and non-secure application work together. More details are in README.rst Signed-off-by: Wayne Ren --- .../boards/arc_secure_services/CMakeLists.txt | 8 ++ samples/boards/arc_secure_services/README.rst | 126 ++++++++++++++++++ samples/boards/arc_secure_services/prj.conf | 0 .../boards/arc_secure_services/sample.yaml | 8 ++ samples/boards/arc_secure_services/src/main.c | 59 ++++++++ 5 files changed, 201 insertions(+) create mode 100644 samples/boards/arc_secure_services/CMakeLists.txt create mode 100644 samples/boards/arc_secure_services/README.rst create mode 100644 samples/boards/arc_secure_services/prj.conf create mode 100644 samples/boards/arc_secure_services/sample.yaml create mode 100644 samples/boards/arc_secure_services/src/main.c diff --git a/samples/boards/arc_secure_services/CMakeLists.txt b/samples/boards/arc_secure_services/CMakeLists.txt new file mode 100644 index 0000000000000..7f657697a04f4 --- /dev/null +++ b/samples/boards/arc_secure_services/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.8.2) + +include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) +project(arc_secure_services) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/arc_secure_services/README.rst b/samples/boards/arc_secure_services/README.rst new file mode 100644 index 0000000000000..f9b25275a1581 --- /dev/null +++ b/samples/boards/arc_secure_services/README.rst @@ -0,0 +1,126 @@ +.. _arc_secure_service: + +ARC Secure Service +################## + +Overview +******** + +This sample implements a simple secure service based on ARC SecureShield to +demonstrate how a secure zephyr application runs together with a normal +Zephyr application. + +In this sample: + +* Secure application will be in the secure memory space defined in + ``arc_mpu_regions.c``. Half of RAM and ROM is allocated to secure world, + the other half is allocated to normal world. + +* Memory not allocated to the secure application is allocated to + the normal application. + +* By default, all the peripheral space is normal mode accessible, i.e., + the peripherals are shared between normal mode and secure mode. If some + peripherals are required by secure world, it can be done by adding static + mpu entry in ``arc_mpu_regions.c``. + +* The interrupts of two internal timers are configure as normal interrupts, + so the normal zephyr's kernel tick can work correctly. + +* Secure interrupts priority > secure threads priority > normal interrupts + priority > normal threads priority. + + +Requirements +************ + +To use this sample, ARC processor should be equipped with ARC SecureShield. In +Zephyr, the following board configurations are supported: + +* em_starterkit_em7d + * secure application: em_starterkit_em7d_secure + * normal application: em_starterkit_em7d_normal +* nsim_sem + * secure application: nsim_sem + * normal application: nsim_sem_normal + +Building and Running +******************** + +Building +======== + +Secure application +^^^^^^^^^^^^^^^^^^ + +First, you should build the secure application. + +.. zephyr-app-commands:: + :zephyr-app: samples/boards/arc_secure_services + :board: em_starterkit_em7d_secure nsim_sem + :goals: build + :compact: + +Normal application +^^^^^^^^^^^^^^^^^^ + +Currently, in normal application, MPU is not accessible, so no user space and +mpu-based stack checking. + +Here,take :ref:'dining-philosophers-sample' as an example for normal +application. + +.. zephyr-app-commands:: + :zephyr-app: samples/philosophers + :board: em_starterkit_em7d_normal nsim_sem_normal + :goals: build + :compact: + +Running +======= + +* Run using the bootloader + +The bootloader should load the secure and normal application into the correct place, +then jump to the entry of the secure application. The entry of normal application +is hardcoded in secure application. Secure application will boot normal application. + +* Run using the debugger (recommended) + +Use the gdb debugger to load and run the two applications. + +For em starter kit, run the following commands + +.. code-block:: console + + # load secure application first + $ cd samples/boards/arc_secure_services/build + $ west debug + # load normal application + $ monitor load_image ../../../philosophers/build/zepher/zephyr.elf + $ c + +For nsim sem, you need two consoles: one for application output, and one for +debugger. + +In the console for output: + +.. code-block:: console + + # open debug server + $ cd samples/boards/arc_secure_services/build + $ west debugserver + +In the console for debugger: + +.. code-block:: console + + # open debug server + $ cd samples/boards/arc_secure_services/build + $ arc-elf32-gdb zephyr/zephyr.elf + $ target remote :3333 + # load normal application + $ load ../../../philosophers/build/zepher/zephyr.elf + # load secure application + $ load + $ c diff --git a/samples/boards/arc_secure_services/prj.conf b/samples/boards/arc_secure_services/prj.conf new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/samples/boards/arc_secure_services/sample.yaml b/samples/boards/arc_secure_services/sample.yaml new file mode 100644 index 0000000000000..bade4ee1ebe56 --- /dev/null +++ b/samples/boards/arc_secure_services/sample.yaml @@ -0,0 +1,8 @@ +sample: + description: Sample application to verify the secure monitor for + Designware ARC SecureShiled. + name: Designware ARC Secure monitor +tests: + test: + platform_whitelist: nsim_sem em_starterkit_em7d_secure + tags: secure \ No newline at end of file diff --git a/samples/boards/arc_secure_services/src/main.c b/samples/boards/arc_secure_services/src/main.c new file mode 100644 index 0000000000000..8e7a7be238c2e --- /dev/null +++ b/samples/boards/arc_secure_services/src/main.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018 Synopsys. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#if defined(CONFIG_SOC_NSIM_SEM) +#define NORMAL_FIRMWARE_ENTRY 0x40000 +#elif defined(CONFIG_SOC_EMSK) +#define NORMAL_FIRMWARE_ENTRY 0x20000 +#endif + + +#define STACKSIZE 1024 +#define PRIORITY 7 +#define SLEEPTIME 1000 + + +void threadA(void *dummy1, void *dummy2, void *dummy3) +{ + ARG_UNUSED(dummy1); + ARG_UNUSED(dummy2); + ARG_UNUSED(dummy3); + + + printk("Go to normal application\n"); + + arc_go_to_normal(*((u32_t *)(NORMAL_FIRMWARE_ENTRY))); + + printk("should not come here\n"); + +} + +K_THREAD_DEFINE(thread_a, STACKSIZE, threadA, NULL, NULL, NULL, + PRIORITY, 0, K_NO_WAIT); + + +void main(void) +{ + /* necessary configuration before go to normal */ + s32_t i = 0; + + /* allocate timer 0 and timer1 to normal mode */ + z_arc_v2_irq_uinit_secure_set(IRQ_TIMER0, 0); + z_arc_v2_irq_uinit_secure_set(IRQ_TIMER1, 0); + + /* disable the secure interrupts for debug purpose*/ + /* _arc_v2_irq_unit_int_disable(IRQ_S_TIMER0); */ + + while (1) { + printk("I am the %s thread in secure world: %d\n", + __func__, i++); + k_sleep(SLEEPTIME); + } +}