diff options
| author | wuyangyong <[email protected]> | 2011-02-16 15:49:53 +0000 |
|---|---|---|
| committer | wuyangyong <[email protected]> | 2011-02-16 15:49:53 +0000 |
| commit | d128ba91691534b3e64b6736d4dfbfbe81244055 (patch) | |
| tree | a20f271a0668231d1b11084e75a251ca9be2abcb /libcpu/nios | |
| parent | fac560d432d21a4aa285fa720893b7aebbbb015e (diff) | |
add nios
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1273 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'libcpu/nios')
| -rw-r--r-- | libcpu/nios/nios_ii/context_gcc.S | 252 | ||||
| -rw-r--r-- | libcpu/nios/nios_ii/interrupt.c | 22 | ||||
| -rw-r--r-- | libcpu/nios/nios_ii/stack.c | 72 | ||||
| -rw-r--r-- | libcpu/nios/nios_ii/vector.S | 46 |
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
+
|
