From fe24ae7ca422a735f22fedb6ac03150ba49401a7 Mon Sep 17 00:00:00 2001 From: Watson Zeng Date: Thu, 16 Jan 2020 16:00:13 +0800 Subject: [bsp][synopsys] add basic new embarc bsp support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * the initial support of synopsys designware ARC processor using embARC_BSP, all synopsys ARC-based boards are supported: -ARC Software Development Platform -ARC EM Starter Kit -ARC EM Software Development Platform -ARC HS Development Kit -ARC IoT Development Kit * The embARC BSP is a new generation embARC software development package. ​It is designed to be the inter-layer between hardware and operating system. ​ BSP could hide the difference of hardware/boards, provide a unified interface to upper-layer. * the initial support of synopsys MWDT toolchain. The DesignWare® ARC® MetaWare Development Toolkit builds upon a 25-year legacy of industry-leading compiler and debugger products. It is a complete solution that contains all the components needed to support the development, debugging and tuning of embedded applications for the DesignWare ARC processors. * for detailed board information, pls go embarc.org. Signed-off-by: Watson Zeng --- libcpu/arc/em/SConscript | 4 +- libcpu/arc/em/contex_gcc.S | 266 ------------------------------ libcpu/arc/em/contex_gcc_mw.S | 364 ++++++++++++++++++++++++++++++++++++++++++ libcpu/arc/em/cpuport.c | 28 +++- 4 files changed, 388 insertions(+), 274 deletions(-) delete mode 100644 libcpu/arc/em/contex_gcc.S create mode 100644 libcpu/arc/em/contex_gcc_mw.S (limited to 'libcpu') diff --git a/libcpu/arc/em/SConscript b/libcpu/arc/em/SConscript index 49c32b689d..ff1d8c134d 100644 --- a/libcpu/arc/em/SConscript +++ b/libcpu/arc/em/SConscript @@ -8,9 +8,7 @@ cwd = GetCurrentDir() src = Glob('*.c') CPPPATH = [cwd] - -if rtconfig.PLATFORM == 'gcc': - src += Glob('*_gcc.S') +src += Glob('*.S') group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) diff --git a/libcpu/arc/em/contex_gcc.S b/libcpu/arc/em/contex_gcc.S deleted file mode 100644 index a8abe089bf..0000000000 --- a/libcpu/arc/em/contex_gcc.S +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (c) 2018, Synopsys, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#define __ASSEMBLY__ -#include "inc/arc/arc.h" -#include "inc/arc/arc_asm_common.h" - -.global rt_interrupt_enter; .type rt_interrupt_enter, %function -.global rt_interrupt_leave; .type rt_interrupt_leave, %function -.global context_switch_reqflg; .type context_switch_reqflg, %object -.global rt_interrupt_from_thread; .type rt_interrupt_from_thread, %object -.global rt_interrupt_to_thread; .type rt_interrupt_to_thread, %object - - .text - .align 4 -dispatcher: - st sp, [r0] - ld sp, [r1] - pop r0 - j [r0] - -/* return routine when task dispatch happened in task context */ -dispatch_r: - RESTORE_NONSCRATCH_REGS - j [blink] - -/* - * rt_base_t rt_hw_interrupt_disable(); - */ -.global rt_hw_interrupt_disable -.type rt_hw_interrupt_disable, %function -rt_hw_interrupt_disable: - clri r0 - j [blink] - - -/* - * void rt_hw_interrupt_enable(rt_base_t level); - */ -.global rt_hw_interrupt_enable -.type rt_hw_interrupt_enable, %function -rt_hw_interrupt_enable: - seti r0 - j [blink] - - -.global rt_hw_context_switch_interrupt -.type rt_hw_context_switch_interrupt, %function -rt_hw_context_switch_interrupt: - st r0, [rt_interrupt_from_thread] - st r1, [rt_interrupt_to_thread] - mov r0, 1 - st r0, [context_switch_reqflg] - j [blink] - - -/* - * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); - * r0 --> from - * r1 --> to - */ -.global rt_hw_context_switch -.type rt_hw_context_switch, %function -rt_hw_context_switch: - SAVE_NONSCRATCH_REGS - mov r2, dispatch_r - push r2 - b dispatcher - - -/* - * void rt_hw_context_switch_to(rt_uint32 to); - * r0 --> to - */ -.global rt_hw_context_switch_to -.type rt_hw_context_switch_to, %function -rt_hw_context_switch_to: - ld sp, [r0] - pop r0 - j [r0] - -.global start_r -.type start_r, %function -start_r: - pop blink; - pop r1 - pop r2 - pop r0 - - j_s.d [r1] - kflag r2 - -/****** exceptions and interrupts handing ******/ -/****** entry for exception handling ******/ - .global exc_entry_cpu - .align 4 -exc_entry_cpu: - - EXCEPTION_PROLOGUE - - mov blink, sp - mov r3, sp /* as exception handler's para(p_excinfo) */ - - ld r0, [exc_nest_count] - add r1, r0, 1 - st r1, [exc_nest_count] - cmp r0, 0 - bne exc_handler_1 -/* change to exception stack if interrupt happened in task context */ - mov sp, _e_stack -exc_handler_1: - PUSH blink - - lr r0, [AUX_ECR] - lsr r0, r0, 16 - mov r1, exc_int_handler_table - ld.as r2, [r1, r0] - - mov r0, r3 - jl [r2] - -/* interrupts are not allowed */ -ret_exc: - POP sp - mov r1, exc_nest_count - ld r0, [r1] - sub r0, r0, 1 - cmp r0, 0 - bne.d ret_exc_1 - st r0, [r1] - - ld r0, [context_switch_reqflg] - cmp r0, 0 - bne ret_exc_2 -ret_exc_1: /* return from non-task context, interrupts or exceptions are nested */ - EXCEPTION_EPILOGUE - rtie - -/* there is a dispatch request */ -ret_exc_2: - /* clear dispatch request */ - mov r0, 0 - st r0, [context_switch_reqflg] - - SAVE_CALLEE_REGS /* save callee save registers */ - - /* clear exception bit to do exception exit by SW */ - lr r0, [AUX_STATUS32] - bclr r0, r0, AUX_STATUS_BIT_AE - kflag r0 - - mov r1, ret_exc_r /* save return address */ - PUSH r1 - - ld r0, [rt_interrupt_from_thread] - ld r1, [rt_interrupt_to_thread] - b dispatcher - -ret_exc_r: - /* recover exception status */ - lr r0, [AUX_STATUS32] - bset r0, r0, AUX_STATUS_BIT_AE - kflag r0 - - RESTORE_CALLEE_REGS - EXCEPTION_EPILOGUE - rtie - -/****** entry for normal interrupt exception handling ******/ - .global exc_entry_int /* entry for interrupt handling */ - .align 4 -exc_entry_int: -#if ARC_FEATURE_FIRQ == 1 -/* check whether it is P0 interrupt */ -#if ARC_FEATURE_RGF_NUM_BANKS > 1 - lr r0, [AUX_IRQ_ACT] - btst r0, 0 - jnz exc_entry_firq -#else - PUSH r10 - lr r10, [AUX_IRQ_ACT] - btst r10, 0 - POP r10 - jnz exc_entry_firq -#endif -#endif - INTERRUPT_PROLOGUE - - mov blink, sp - - clri /* disable interrupt */ - ld r3, [exc_nest_count] - add r2, r3, 1 - st r2, [exc_nest_count] - seti /* enable higher priority interrupt */ - - cmp r3, 0 - bne irq_handler_1 -/* change to exception stack if interrupt happened in task context */ - mov sp, _e_stack -irq_handler_1: - PUSH blink - - jl rt_interrupt_enter - - lr r0, [AUX_IRQ_CAUSE] - sr r0, [AUX_IRQ_SELECT] - mov r1, exc_int_handler_table - ld.as r2, [r1, r0] /* r2 = exc_int_handler_table + irqno *4 */ -/* handle software triggered interrupt */ - lr r3, [AUX_IRQ_HINT] - cmp r3, r0 - bne.d irq_hint_handled - xor r3, r3, r3 - sr r3, [AUX_IRQ_HINT] -irq_hint_handled: - lr r3, [AUX_IRQ_PRIORITY] - PUSH r3 /* save irq priority */ - - jl [r2] /* jump to interrupt handler */ - jl rt_interrupt_leave -ret_int: - clri /* disable interrupt */ - POP r3 /* irq priority */ - POP sp - mov r1, exc_nest_count - ld r0, [r1] - sub r0, r0, 1 - cmp r0, 0 - bne.d ret_int_1 - st r0, [r1] - - ld r0, [context_switch_reqflg] - cmp r0, 0 - bne ret_int_2 -ret_int_1: /* return from non-task context */ - INTERRUPT_EPILOGUE - rtie -/* there is a dispatch request */ -ret_int_2: - /* clear dispatch request */ - mov r0, 0 - st r0, [context_switch_reqflg] - - /* interrupt return by SW */ - lr r10, [AUX_IRQ_ACT] - PUSH r10 - bclr r10, r10, r3 /* clear related bits in IRQ_ACT */ - sr r10, [AUX_IRQ_ACT] - - SAVE_CALLEE_REGS /* save callee save registers */ - mov r1, ret_int_r /* save return address */ - PUSH r1 - - ld r0, [rt_interrupt_from_thread] - ld r1, [rt_interrupt_to_thread] - b dispatcher - -ret_int_r: - RESTORE_CALLEE_REGS - /* recover AUX_IRQ_ACT to restore the interrup status */ - POPAX AUX_IRQ_ACT - INTERRUPT_EPILOGUE - rtie \ No newline at end of file diff --git a/libcpu/arc/em/contex_gcc_mw.S b/libcpu/arc/em/contex_gcc_mw.S new file mode 100644 index 0000000000..81b291c1c8 --- /dev/null +++ b/libcpu/arc/em/contex_gcc_mw.S @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#define __ASSEMBLY__ +#include "include/arc/arc.h" +#include "include/arc/arc_asm_common.h" + +.global rt_interrupt_enter; +.global rt_interrupt_leave; +.global context_switch_reqflg; +.global rt_interrupt_from_thread; +.global rt_interrupt_to_thread; +.global exc_nest_count; +.global set_hw_stack_check; + + .text + .align 4 +dispatcher: + st sp, [r0] + ld sp, [r1] +#if ARC_FEATURE_STACK_CHECK +#if ARC_FEATURE_SEC_PRESENT + lr r0, [AUX_SEC_STAT] + bclr r0, r0, AUX_SEC_STAT_BIT_SSC + sflag r0 +#else + lr r0, [AUX_STATUS32] + bclr r0, r0, AUX_STATUS_BIT_SC + kflag r0 +#endif + jl set_hw_stack_check +#if ARC_FEATURE_SEC_PRESENT + lr r0, [AUX_SEC_STAT] + bset r0, r0, AUX_SEC_STAT_BIT_SSC + sflag r0 +#else + lr r0, [AUX_STATUS32] + bset r0, r0, AUX_STATUS_BIT_SC + kflag r0 +#endif +#endif + pop r0 + j [r0] + +/* return routine when task dispatch happened in task context */ +dispatch_r: + RESTORE_NONSCRATCH_REGS + j [blink] + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ + .global rt_hw_interrupt_disable + .align 4 +rt_hw_interrupt_disable: + clri r0 + j [blink] + + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ + .global rt_hw_interrupt_enable + .align 4 +rt_hw_interrupt_enable: + seti r0 + j [blink] + + + .global rt_hw_context_switch_interrupt + .align 4 +rt_hw_context_switch_interrupt: + st r0, [rt_interrupt_from_thread] + st r1, [rt_interrupt_to_thread] + mov r0, 1 + st r0, [context_switch_reqflg] + j [blink] + + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + * r0 --> from + * r1 --> to + */ + .global rt_hw_context_switch + .align 4 +rt_hw_context_switch: + SAVE_NONSCRATCH_REGS + mov r2, dispatch_r + push r2 + b dispatcher + + +/* + * void rt_hw_context_switch_to(rt_uint32 to); + * r0 --> to + */ + .global rt_hw_context_switch_to + .align 4 +rt_hw_context_switch_to: + ld sp, [r0] +#if ARC_FEATURE_STACK_CHECK + mov r1, r0 +#if ARC_FEATURE_SEC_PRESENT + lr r0, [AUX_SEC_STAT] + bclr r0, r0, AUX_SEC_STAT_BIT_SSC + sflag r0 +#else + lr r0, [AUX_STATUS32] + bclr r0, r0, AUX_STATUS_BIT_SC + kflag r0 +#endif + jl set_hw_stack_check +#if ARC_FEATURE_SEC_PRESENT + lr r0, [AUX_SEC_STAT] + bset r0, r0, AUX_SEC_STAT_BIT_SSC + sflag r0 +#else + lr r0, [AUX_STATUS32] + bset r0, r0, AUX_STATUS_BIT_SC + kflag r0 +#endif +#endif + pop r0 + j [r0] + + .global start_r + .align 4 +start_r: + pop blink; + pop r1 + pop r2 + pop r0 + + j_s.d [r1] + kflag r2 + +/* + * int __rt_ffs(int value); + * r0 --> value + */ + .global __rt_ffs + .align 4 +__rt_ffs: + breq r0, 0, __rt_ffs_return + ffs r1, r0 + add r0, r1, 1 +__rt_ffs_return: + j [blink] + +/****** exceptions and interrupts handing ******/ +/****** entry for exception handling ******/ + .global exc_entry_cpu + .align 4 +exc_entry_cpu: + + EXCEPTION_PROLOGUE + + mov blink, sp + mov r3, sp /* as exception handler's para(p_excinfo) */ + + ld r0, [exc_nest_count] + add r1, r0, 1 + st r1, [exc_nest_count] + brne r0, 0, exc_handler_1 +/* change to exception stack if interrupt happened in task context */ + mov sp, _e_stack +exc_handler_1: + PUSH blink + + lr r0, [AUX_ECR] + lsr r0, r0, 16 + mov r1, exc_int_handler_table + ld.as r2, [r1, r0] + + mov r0, r3 + jl [r2] + +/* interrupts are not allowed */ +ret_exc: + POP sp + mov r1, exc_nest_count + ld r0, [r1] + sub r0, r0, 1 + st r0, [r1] + brne r0, 0, ret_exc_1 /* nest exception case */ + lr r1, [AUX_IRQ_ACT] /* nest interrupt case */ + brne r1, 0, ret_exc_1 + + ld r0, [context_switch_reqflg] + brne r0, 0, ret_exc_2 +ret_exc_1: /* return from non-task context, interrupts or exceptions are nested */ + EXCEPTION_EPILOGUE + rtie + +/* there is a dispatch request */ +ret_exc_2: + /* clear dispatch request */ + mov r0, 0 + st r0, [context_switch_reqflg] + + SAVE_CALLEE_REGS /* save callee save registers */ + + /* clear exception bit to do exception exit by SW */ + lr r0, [AUX_STATUS32] + bclr r0, r0, AUX_STATUS_BIT_AE + kflag r0 + + mov r1, ret_exc_r /* save return address */ + PUSH r1 + + ld r0, [rt_interrupt_from_thread] + ld r1, [rt_interrupt_to_thread] + b dispatcher + +ret_exc_r: + /* recover exception status */ + lr r0, [AUX_STATUS32] + bset r0, r0, AUX_STATUS_BIT_AE + kflag r0 + + RESTORE_CALLEE_REGS + EXCEPTION_EPILOGUE + rtie + +/****** entry for normal interrupt exception handling ******/ + .global exc_entry_int /* entry for interrupt handling */ + .align 4 +exc_entry_int: +#if ARC_FEATURE_FIRQ == 1 +/* check whether it is P0 interrupt */ +#if ARC_FEATURE_RGF_NUM_BANKS > 1 + lr r0, [AUX_IRQ_ACT] + btst r0, 0 + jnz exc_entry_firq +#else + PUSH r10 + lr r10, [AUX_IRQ_ACT] + btst r10, 0 + POP r10 + jnz exc_entry_firq +#endif +#endif + INTERRUPT_PROLOGUE + + mov blink, sp + + clri /* disable interrupt */ + ld r3, [exc_nest_count] + add r2, r3, 1 + st r2, [exc_nest_count] + seti /* enable higher priority interrupt */ + + brne r3, 0, irq_handler_1 +/* change to exception stack if interrupt happened in task context */ + mov sp, _e_stack +#if ARC_FEATURE_STACK_CHECK +#if ARC_FEATURE_SEC_PRESENT + lr r0, [AUX_SEC_STAT] + bclr r0, r0, AUX_SEC_STAT_BIT_SSC + sflag r0 +#else + lr r0, [AUX_STATUS32] + bclr r0, r0, AUX_STATUS_BIT_SC + kflag r0 +#endif +#endif +irq_handler_1: + PUSH blink + + jl rt_interrupt_enter + + lr r0, [AUX_IRQ_CAUSE] + sr r0, [AUX_IRQ_SELECT] + mov r1, exc_int_handler_table + ld.as r2, [r1, r0] /* r2 = exc_int_handler_table + irqno *4 */ +/* handle software triggered interrupt */ + lr r3, [AUX_IRQ_HINT] + cmp r3, r0 + bne.d irq_hint_handled + xor r3, r3, r3 + sr r3, [AUX_IRQ_HINT] +irq_hint_handled: + lr r3, [AUX_IRQ_PRIORITY] + PUSH r3 /* save irq priority */ + + jl [r2] /* jump to interrupt handler */ + jl rt_interrupt_leave +ret_int: + clri /* disable interrupt */ + POP r3 /* irq priority */ + POP sp + mov r1, exc_nest_count + ld r0, [r1] + sub r0, r0, 1 + st r0, [r1] +/* if there are multi-bits set in IRQ_ACT, it's still in nest interrupt */ + lr r0, [AUX_IRQ_CAUSE] + sr r0, [AUX_IRQ_SELECT] + lr r3, [AUX_IRQ_PRIORITY] + lr r1, [AUX_IRQ_ACT] + bclr r2, r1, r3 + brne r2, 0, ret_int_1 + + ld r0, [context_switch_reqflg] + brne r0, 0, ret_int_2 +ret_int_1: /* return from non-task context */ + INTERRUPT_EPILOGUE + rtie +/* there is a dispatch request */ +ret_int_2: + /* clear dispatch request */ + mov r0, 0 + st r0, [context_switch_reqflg] + + /* interrupt return by SW */ + lr r10, [AUX_IRQ_ACT] + PUSH r10 + bclr r10, r10, r3 /* clear related bits in IRQ_ACT */ + sr r10, [AUX_IRQ_ACT] + + SAVE_CALLEE_REGS /* save callee save registers */ + mov r1, ret_int_r /* save return address */ + PUSH r1 + + ld r0, [rt_interrupt_from_thread] + ld r1, [rt_interrupt_to_thread] + b dispatcher + +ret_int_r: + RESTORE_CALLEE_REGS + /* recover AUX_IRQ_ACT to restore the interrup status */ + POPAX AUX_IRQ_ACT + INTERRUPT_EPILOGUE + rtie + +/****** entry for fast irq exception handling ******/ + .global exc_entry_firq + .weak exc_entry_firq + .align 4 +exc_entry_firq: + SAVE_FIQ_EXC_REGS + + lr r0, [AUX_IRQ_CAUSE] + mov r1, exc_int_handler_table +/* r2 = _kernel_exc_tbl + irqno *4 */ + ld.as r2, [r1, r0] + +/* for the case of software triggered interrupt */ + lr r3, [AUX_IRQ_HINT] + cmp r3, r0 + bne.d firq_hint_handled + xor r3, r3, r3 + sr r3, [AUX_IRQ_HINT] +firq_hint_handled: +/* jump to interrupt handler */ + mov r0, sp + jl [r2] + +firq_return: + RESTORE_FIQ_EXC_REGS + rtie diff --git a/libcpu/arc/em/cpuport.c b/libcpu/arc/em/cpuport.c index 88c2e12f9b..34f538881f 100644 --- a/libcpu/arc/em/cpuport.c +++ b/libcpu/arc/em/cpuport.c @@ -5,11 +5,13 @@ */ #include -#include "inc/arc/arc_exception.h" - -/* enable interrupt and set interrupt priority mask */ -#define ARC_INIT_STATUS (AUX_STATUS_MASK_IE | ((-1 - INT_PRI_MIN) << 1)) +#include "arc/arc_exception.h" +#if ARC_FEATURE_STACK_CHECK +#define ARC_INIT_STATUS ((1 << AUX_STATUS_BIT_SC) | AUX_STATUS_MASK_IE | ((-1 - INT_PRI_MIN) << 1) | STATUS32_RESET_VALUE) +#else +#define ARC_INIT_STATUS (AUX_STATUS_MASK_IE | ((-1 - INT_PRI_MIN) << 1) | STATUS32_RESET_VALUE) +#endif extern void start_r(void); @@ -17,6 +19,7 @@ extern void start_r(void); rt_uint32_t context_switch_reqflg; rt_uint32_t rt_interrupt_from_thread; rt_uint32_t rt_interrupt_to_thread; +rt_uint32_t exc_nest_count; struct init_stack_frame { rt_uint32_t pc; @@ -66,4 +69,19 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context)) { exception_handle = exception_handle; -} \ No newline at end of file +} + +void set_hw_stack_check(rt_uint32_t *from, rt_uint32_t *to) +{ + struct rt_thread *rt_thread_to; + if (to != NULL) { + rt_thread_to = rt_container_of(to, struct rt_thread, sp); +#if ARC_FEATURE_SEC_PRESENT + arc_aux_write(AUX_S_KSTACK_TOP, (uint32_t)(rt_thread_to->stack_addr)); + arc_aux_write(AUX_S_KSTACK_BASE, (uint32_t)(rt_thread_to->stack_addr)+rt_thread_to->stack_size); +#else + arc_aux_write(AUX_KSTACK_TOP, (uint32_t)(rt_thread_to->stack_addr)); + arc_aux_write(AUX_KSTACK_BASE, (uint32_t)(rt_thread_to->stack_addr)+rt_thread_to->stack_size); +#endif + } +} -- cgit v1.3.1