Forráskód Böngészése

add nios

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1273 bbd45198-f89e-11dd-88c7-29a3b14d5316
wuyangyong 14 éve
szülő
commit
d128ba9169

+ 252 - 0
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
+
+/*@}*/

+ 22 - 0
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;
+
+/*@}*/

+ 72 - 0
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;
+}
+
+/*@}*/

+ 46 - 0
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
+