summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/arc/SConscript17
-rw-r--r--libcpu/arc/common/SConscript10
-rw-r--r--libcpu/arc/em/SConscript17
-rw-r--r--libcpu/arc/em/contex_gcc.S266
-rw-r--r--libcpu/arc/em/cpuport.c69
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