diff options
| author | Wayne Ren <[email protected]> | 2019-01-23 17:29:54 +0800 |
|---|---|---|
| committer | Wayne Ren <[email protected]> | 2019-01-25 10:29:34 +0800 |
| commit | d8aa99a29c47da520986dcd79fff9861d97ca6ed (patch) | |
| tree | 95eecc243f5e9cab42869e33501643783ed69ba6 /libcpu | |
| parent | 99bef01983d9e74e6a261df0ff0feadc41e8e8ad (diff) | |
[bsp][synopsys] add the support of synopsys arc emsk
* the initial support of synopsys designware arc processor
* the initial support of synospsy ARC EM Starter Kit
* the bsp code is based on embarc which is a common SDK for
all synopsys ARC-based boards
* use "scons --gdb" to debug emsk with em9d configuration
* for detailed board information, pls go embarc.org
Signed-off-by: Wayne Ren <[email protected]>
Diffstat (limited to 'libcpu')
| -rw-r--r-- | libcpu/arc/SConscript | 17 | ||||
| -rw-r--r-- | libcpu/arc/common/SConscript | 10 | ||||
| -rw-r--r-- | libcpu/arc/em/SConscript | 17 | ||||
| -rw-r--r-- | libcpu/arc/em/contex_gcc.S | 266 | ||||
| -rw-r--r-- | libcpu/arc/em/cpuport.c | 69 |
5 files changed, 379 insertions, 0 deletions
diff --git a/libcpu/arc/SConscript b/libcpu/arc/SConscript new file mode 100644 index 0000000000..cbec0b5ec1 --- /dev/null +++ b/libcpu/arc/SConscript @@ -0,0 +1,17 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] + +# add common code files +group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) + +# cpu porting code files +group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/arc/common/SConscript b/libcpu/arc/common/SConscript new file mode 100644 index 0000000000..1c77347e61 --- /dev/null +++ b/libcpu/arc/common/SConscript @@ -0,0 +1,10 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + + +group = DefineGroup('cpu', src, depend = [], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arc/em/SConscript b/libcpu/arc/em/SConscript new file mode 100644 index 0000000000..49c32b689d --- /dev/null +++ b/libcpu/arc/em/SConscript @@ -0,0 +1,17 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_gcc.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arc/em/contex_gcc.S b/libcpu/arc/em/contex_gcc.S new file mode 100644 index 0000000000..a8abe089bf --- /dev/null +++ b/libcpu/arc/em/contex_gcc.S @@ -0,0 +1,266 @@ +/* + * 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/cpuport.c b/libcpu/arc/em/cpuport.c new file mode 100644 index 0000000000..88c2e12f9b --- /dev/null +++ b/libcpu/arc/em/cpuport.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, Synopsys, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include <rtthread.h> + +#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)) + + +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; + +struct init_stack_frame { + rt_uint32_t pc; + rt_uint32_t blink; + rt_uint32_t task; + rt_uint32_t status32; + rt_uint32_t r0; +}; + +/** + * shutdown CPU + */ +void rt_hw_cpu_shutdown(void) +{ + +} + +rt_uint8_t *rt_hw_stack_init(void *tentry, + void *parameter, + rt_uint8_t *stack_addr, + void *texit) +{ + struct init_stack_frame *stack_frame; + rt_uint8_t *stk; + + stk = stack_addr + sizeof(rt_uint32_t); + stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8); + stk -= sizeof(struct init_stack_frame); + + stack_frame = (struct init_stack_frame *)stk; + + stack_frame->pc = (rt_uint32_t)start_r; + stack_frame->blink = (rt_uint32_t)texit; + stack_frame->task = (rt_uint32_t)tentry; + stack_frame->status32 = ARC_INIT_STATUS; + stack_frame->r0 = (rt_uint32_t)parameter; + + return stk; +} + + +/** + * This function set the hook, which is invoked on fault exception handling. + * + * @param exception_handle the exception handling hook function. + */ +void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context)) +{ + exception_handle = exception_handle; +}
\ No newline at end of file |
