[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 <wei.ren@synopsys.com>
This commit is contained in:
Wayne Ren
2019-01-25 10:29:34 +08:00
parent 99bef01983
commit d8aa99a29c
66 changed files with 15704 additions and 0 deletions
+17
View File
@@ -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')
+266
View File
@@ -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
+69
View File
@@ -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;
}