summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/nios/nios_ii/context_gcc.S252
-rw-r--r--libcpu/nios/nios_ii/interrupt.c22
-rw-r--r--libcpu/nios/nios_ii/stack.c72
-rw-r--r--libcpu/nios/nios_ii/vector.S46
4 files changed, 392 insertions, 0 deletions
diff --git a/libcpu/nios/nios_ii/context_gcc.S b/libcpu/nios/nios_ii/context_gcc.S
new file mode 100644
index 0000000000..9c17d1afe7
--- /dev/null
+++ b/libcpu/nios/nios_ii/context_gcc.S
@@ -0,0 +1,252 @@
+/*
+ * File : context_gcc.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006-2011, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2011-02-14 aozima first implementation for Nios II.
+ */
+
+/**
+ * @addtogroup NIOS_II
+ */
+/*@{*/
+
+.text
+
+.set noat
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.global rt_hw_interrupt_disable
+.type rt_hw_interrupt_disable, %function
+rt_hw_interrupt_disable:
+ rdctl r2, status /* return status */
+ wrctl status, zero /* disable interrupt */
+ ret
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.global rt_hw_interrupt_enable
+.type rt_hw_interrupt_enable, %function
+rt_hw_interrupt_enable:
+ wrctl status, r4 /* enable interrupt by argument */
+ ret
+
+/* void rt_hw_context_switch_interrupt_do(void) */
+.global rt_hw_context_switch_interrupt_do
+.type rt_hw_context_switch_interrupt_do, %function
+rt_hw_context_switch_interrupt_do:
+ /* save from thread */
+ addi sp,sp,-72
+
+ rdctl r2, status
+ stw r2, 68(sp) /* status */
+
+ stw r2, 4(sp)
+ stw r3, 8(sp)
+ stw r4, 12(sp)
+
+ /* get & save from thread pc */
+ ldw r4,%gprel(rt_current_thread_entry)(gp)
+ stw r4, 0(sp) /* thread back */
+
+ stw r5, 16(sp)
+ stw r6, 20(sp)
+ stw r7, 24(sp)
+
+ stw r16, 28(sp)
+ stw r17, 32(sp)
+ stw r18, 36(sp)
+ stw r19, 40(sp)
+ stw r20, 44(sp)
+ stw r21, 48(sp)
+ stw r22, 52(sp)
+ stw r23, 56(sp)
+
+ stw fp, 60(sp)
+ stw ra, 64(sp)
+
+ /* save from thread sp */
+ ldw r4, %gprel(rt_interrupt_from_thread)(gp)
+ stw sp, (r4)
+
+ /* clear rt_thread_switch_interrput_flag */
+ stw zero,%gprel(rt_thread_switch_interrput_flag)(gp)
+
+ /* load to thread sp */
+ ldw r4, %gprel(rt_interrupt_to_thread)(gp)
+ ldw sp, (r4)
+
+ ldw r2, 68(sp) /* status */
+ wrctl status, r2
+
+ ldw at, 0(sp) /* thread pc */
+ ldw r2, 4(sp)
+ ldw r3, 8(sp)
+ ldw r4, 12(sp)
+ ldw r5, 16(sp)
+ ldw r6, 20(sp)
+ ldw r7, 24(sp)
+
+ ldw r16, 28(sp)
+ ldw r17, 32(sp)
+ ldw r18, 36(sp)
+ ldw r19, 40(sp)
+ ldw r20, 44(sp)
+ ldw r21, 48(sp)
+ ldw r22, 52(sp)
+ ldw r23, 56(sp)
+
+ ldw fp, 60(sp)
+ ldw ra, 64(sp)
+
+ addi sp, sp, 72
+
+ jmp at
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r4: from
+ * r5: to
+ */
+.global rt_hw_context_switch
+.type rt_hw_context_switch, %function
+rt_hw_context_switch:
+ /* save from thread */
+ addi sp,sp,-72
+
+ rdctl r2, status
+ stw r2, 68(sp) /* status */
+
+ stw ra, 0(sp) /* thread back */
+ stw r2, 4(sp)
+ stw r3, 8(sp)
+ stw r4, 12(sp)
+ stw r5, 16(sp)
+ stw r6, 20(sp)
+ stw r7, 24(sp)
+
+ stw r16, 28(sp)
+ stw r17, 32(sp)
+ stw r18, 36(sp)
+ stw r19, 40(sp)
+ stw r20, 44(sp)
+ stw r21, 48(sp)
+ stw r22, 52(sp)
+ stw r23, 56(sp)
+
+ stw fp, 60(sp)
+ stw ra, 64(sp)
+
+ /* save form thread sp */
+ stw sp, (r4)
+
+ /* update rt_interrupt_from_thread */
+ stw r4,%gprel(rt_interrupt_from_thread)(gp)
+
+ /* update rt_interrupt_to_thread */
+ stw r5,%gprel(rt_interrupt_to_thread)(gp)
+
+ /* get to thread sp */
+ ldw sp, (r5)
+
+ ldw r2, 68(sp) /* status */
+ wrctl status, r2
+
+ ldw at, 0(sp) /* thread pc */
+ ldw r2, 4(sp)
+ ldw r3, 8(sp)
+ ldw r4, 12(sp)
+ ldw r5, 16(sp)
+ ldw r6, 20(sp)
+ ldw r7, 24(sp)
+
+ ldw r16, 28(sp)
+ ldw r17, 32(sp)
+ ldw r18, 36(sp)
+ ldw r19, 40(sp)
+ ldw r20, 44(sp)
+ ldw r21, 48(sp)
+ ldw r22, 52(sp)
+ ldw r23, 56(sp)
+
+ ldw fp, 60(sp)
+ ldw ra, 64(sp)
+
+ addi sp, sp, 72
+
+ jmp at
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ * r4: from
+ * r5: to
+ */
+.global rt_hw_context_switch_interrupt
+.type rt_hw_context_switch_interrupt, %function
+rt_hw_context_switch_interrupt:
+ /* save ea -> rt_current_thread_entry */
+ addi ea,ea,-4
+ stw ea,%gprel(rt_current_thread_entry)(gp)
+
+ /* set rt_thread_switch_interrput_flag to 1 */
+ movi r2, 1
+ stw r2,%gprel(rt_thread_switch_interrput_flag)(gp)
+
+ /* update rt_interrupt_from_thread */
+ stw r4,%gprel(rt_interrupt_from_thread)(gp)
+
+ /* update rt_interrupt_to_thread */
+ stw r5,%gprel(rt_interrupt_to_thread)(gp)
+
+ ret
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r4: to
+ */
+.global rt_hw_context_switch_to
+.type rt_hw_context_switch_to, %function
+rt_hw_context_switch_to:
+ /* save to thread */
+ stw r4,%gprel(rt_interrupt_to_thread)(gp)
+
+ /* get sp */
+ ldw sp, (r4) // sp = *r4
+
+ ldw r2, 68(sp) /* status */
+ wrctl status, r2
+
+ ldw at, 0(sp) /* thread entry */
+ ldw r2, 4(sp)
+ ldw r3, 8(sp)
+ ldw r4, 12(sp)
+ ldw r5, 16(sp)
+ ldw r6, 20(sp)
+ ldw r7, 24(sp)
+
+ ldw r16, 28(sp)
+ ldw r17, 32(sp)
+ ldw r18, 36(sp)
+ ldw r19, 40(sp)
+ ldw r20, 44(sp)
+ ldw r21, 48(sp)
+ ldw r22, 52(sp)
+ ldw r23, 56(sp)
+
+ ldw fp, 60(sp)
+ ldw ra, 64(sp)
+
+ addi sp, sp, 72
+
+ jmp at
+
+/*@}*/
diff --git a/libcpu/nios/nios_ii/interrupt.c b/libcpu/nios/nios_ii/interrupt.c
new file mode 100644
index 0000000000..18c4abd6d8
--- /dev/null
+++ b/libcpu/nios/nios_ii/interrupt.c
@@ -0,0 +1,22 @@
+/*
+ * File : interrupt.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-01-05 Bernard first version
+ */
+
+#include <rtthread.h>
+
+/* exception and interrupt handler table */
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+rt_uint32_t rt_current_thread_entry;
+
+/*@}*/
diff --git a/libcpu/nios/nios_ii/stack.c b/libcpu/nios/nios_ii/stack.c
new file mode 100644
index 0000000000..01fbb2c468
--- /dev/null
+++ b/libcpu/nios/nios_ii/stack.c
@@ -0,0 +1,72 @@
+/*
+ * File : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006-2011, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2011-02-14 aozima first implementation for Nios II.
+ */
+
+#include <rtthread.h>
+
+/**
+ * @addtogroup NIOS_II
+ */
+/*@{*/
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+ rt_uint8_t *stack_addr, void *texit)
+{
+ unsigned long *stk;
+
+ stk = (unsigned long *)stack_addr;
+ *(stk) = 0x01; /* status */
+ *(--stk) = (unsigned long)texit; /* ra */
+ *(--stk) = 0xdeadbeef; /* fp */
+ *(--stk) = 0xdeadbeef; /* r23 */
+ *(--stk) = 0xdeadbeef; /* r22 */
+ *(--stk) = 0xdeadbeef; /* r21 */
+ *(--stk) = 0xdeadbeef; /* r20 */
+ *(--stk) = 0xdeadbeef; /* r19 */
+ *(--stk) = 0xdeadbeef; /* r18 */
+ *(--stk) = 0xdeadbeef; /* r17 */
+ *(--stk) = 0xdeadbeef; /* r16 */
+// *(--stk) = 0xdeadbeef; /* r15 */
+// *(--stk) = 0xdeadbeef; /* r14 */
+// *(--stk) = 0xdeadbeef; /* r13 */
+// *(--stk) = 0xdeadbeef; /* r12 */
+// *(--stk) = 0xdeadbeef; /* r11 */
+// *(--stk) = 0xdeadbeef; /* r10 */
+// *(--stk) = 0xdeadbeef; /* r9 */
+// *(--stk) = 0xdeadbeef; /* r8 */
+ *(--stk) = 0xdeadbeef; /* r7 */
+ *(--stk) = 0xdeadbeef; /* r6 */
+ *(--stk) = 0xdeadbeef; /* r5 */
+ *(--stk) = (unsigned long)parameter; /* r4 argument */
+ *(--stk) = 0xdeadbeef; /* r3 */
+ *(--stk) = 0xdeadbeef; /* r2 */
+ *(--stk) = (unsigned long)tentry; /* pc */
+
+// *(stk) = (unsigned long)tentry; /* thread entry (ra) */
+// *(--stk) = (unsigned long)parameter; /* thread argument, r4 */
+
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
+}
+
+/*@}*/
diff --git a/libcpu/nios/nios_ii/vector.S b/libcpu/nios/nios_ii/vector.S
new file mode 100644
index 0000000000..b23a2b8379
--- /dev/null
+++ b/libcpu/nios/nios_ii/vector.S
@@ -0,0 +1,46 @@
+.set noat
+
+.globl .Lexception_exit
+
+.section .exceptions.exit.label
+.Lexception_exit:
+.section .exceptions.exit, "xa"
+ ldw r5, 68(sp)
+
+ /* get exception back */
+ ldw ea, 72(sp)
+ ldw r4,%gprel(rt_thread_switch_interrput_flag)(gp)
+ beq r4,zero,no_need_context
+need_context:
+ movia ea, rt_hw_context_switch_interrupt_do
+
+no_need_context:
+ ldw ra, 0(sp)
+
+ wrctl estatus, r5
+
+ /*
+ * Leave a gap in the stack frame at 4(sp) for the muldiv handler to
+ * store zero into.
+ */
+
+ ldw r1, 8(sp)
+ ldw r2, 12(sp)
+ ldw r3, 16(sp)
+ ldw r4, 20(sp)
+ ldw r5, 24(sp)
+ ldw r6, 28(sp)
+ ldw r7, 32(sp)
+ ldw r8, 36(sp)
+ ldw r9, 40(sp)
+ ldw r10, 44(sp)
+ ldw r11, 48(sp)
+ ldw r12, 52(sp)
+ ldw r13, 56(sp)
+ ldw r14, 60(sp)
+ ldw r15, 64(sp)
+
+ addi sp, sp, 76
+
+ eret
+