From b2f78b2e776107298a66ff610591c990d1296436 Mon Sep 17 00:00:00 2001 From: dzzxzz Date: Tue, 29 Jun 2010 02:33:54 +0000 Subject: port rt-thread to NEC V850E git-svn-id: https://rt-thread.googlecode.com/svn/trunk@779 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- libcpu/v850/context.asm | 218 ++++++++++++++++++++++++++++++++++++++++++++++++ libcpu/v850/interrupt.c | 22 +++++ libcpu/v850/macdefs.inc | 125 +++++++++++++++++++++++++++ libcpu/v850/stack.c | 61 ++++++++++++++ 4 files changed, 426 insertions(+) create mode 100644 libcpu/v850/context.asm create mode 100644 libcpu/v850/interrupt.c create mode 100644 libcpu/v850/macdefs.inc create mode 100644 libcpu/v850/stack.c (limited to 'libcpu') diff --git a/libcpu/v850/context.asm b/libcpu/v850/context.asm new file mode 100644 index 0000000000..7783a94c51 --- /dev/null +++ b/libcpu/v850/context.asm @@ -0,0 +1,218 @@ +#include "macdefs.inc" + + name OS_Core + + COMMON INTVEC:CODE + +;******************************************************************** +; +; function: +; description: Trap 0x10 vector used for context switch +; Right now, all TRAPs to $1x are trated the same way +; + org 50h + jr OSCtxSW + + +;******************************************************************** +; +; function: +; description: Timer 40 compare match interrupt used for system +; tick interrupt +; + org 0x220 + jr OSTickIntr + + org 0x0520 + jr uarta1_int_r + + RSEG CODE(1) + + EXTERN rt_thread_switch_interrput_flag + EXTERN rt_interrupt_from_thread + EXTERN rt_interrupt_to_thread + + EXTERN rt_interrupt_enter + EXTERN rt_interrupt_leave + EXTERN rt_tick_increase + EXTERN uarta1_receive_handler + + PUBLIC rt_hw_interrupt_disable + PUBLIC rt_hw_interrupt_enable + PUBLIC rt_hw_context_switch_to + PUBLIC rt_hw_context_switch + PUBLIC rt_hw_context_switch_interrupt + PUBLIC OSCtxSW + PUBLIC OS_Restore_CPU_Context + +rt_hw_interrupt_disable: + stsr psw, r1 + di + jmp [lp] + +rt_hw_interrupt_enable: + ldsr r1, psw + jmp [lp] + +OS_Restore_CPU_Context: + mov sp, ep + sld.w 4[ep], r2 + sld.w 8[ep], r5 + sld.w 12[ep],r6 + sld.w 16[ep],r7 + sld.w 20[ep],r8 + sld.w 24[ep],r9 + sld.w 28[ep],r10 + sld.w 32[ep],r11 + sld.w 36[ep],r12 + sld.w 40[ep],r13 + sld.w 44[ep],r14 + sld.w 48[ep],r15 + sld.w 52[ep],r16 + + ;See what was the latest interruption (trap or interrupt) + stsr ecr, r17 ;Move ecr to r17 + mov 0x050,r1 + cmp r1, r17 ;If latest break was due to TRAP, set EP + be _SetEP + +_ClrEP: + mov 0x20, r17 ;Set only ID + ldsr r17, psw + + ;Restore caller address + sld.w 56[ep], r1 + ldsr r1, EIPC + ;Restore PSW + sld.w 60[ep], r1 + andi 0xffdf,r1,r1 + ldsr r1, EIPSW + sld.w 0[ep], r1 + dispose (8+(4*14)),{r23,r24,r25,r26,r27,r28,r29,r30,r31} + + ;Return from interrupt starts new task! + reti + +_SetEP: + mov 0x60, r17 ;Set both EIPC and ID bits + ldsr r17, psw + + ;Restore caller address + sld.w 56[ep], r1 + ldsr r1, EIPC + ;Restore PSW + sld.w 60[ep], r1 + andi 0xffdf,r1,r1 + ldsr r1, EIPSW + sld.w 0[ep], r1 + dispose (8+(4*14)),{r23,r24,r25,r26,r27,r28,r29,r30,r31} + + ;Return from interrupt starts new task! + reti + +//rseg CODE:CODE +//public rt_hw_context_switch_to +rt_hw_context_switch_to: + ;Load stack pointer of the task to run + ld.w 0[r1], sp ;load sp from struct + + ;Restore all Processor registers from stack and return from interrupt + jr OS_Restore_CPU_Context + +OSCtxSW: + SAVE_CPU_CTX ;Save all CPU registers + + mov rt_thread_switch_interrput_flag, r1 + ld.w 0[r1],r5 + cmp 0, r5 + be exit + + mov 0, r5 + st.b r5, 0[r1] + + mov rt_interrupt_from_thread, r21 + ld.w 0[r21], r21 + st.w sp, 0[r21] + + mov rt_interrupt_to_thread, r1 + ld.w 0[r1], r1 + ld.w 0[r1], sp + +exit: + ;Restore all Processor registers from stack and return from interrupt + jr OS_Restore_CPU_Context + +;R1 -> rt_interrupt_from_thread +;R5 -> rt_interrupt_to_thread +rt_hw_context_switch: + mov rt_thread_switch_interrput_flag, r8 + ld.w 0[r8],r9 + cmp 1, r9 + be jump1 + ;mov rt_thread_switch_interrput_flag, r1 + mov 1, r9 + st.b r9, 0[r8] + mov rt_interrupt_from_thread, r10 + st.w r1, 0[r10] +jump1 + mov rt_interrupt_to_thread, r11 + st.w r5, 0[r11] + trap 0x10 + jmp [lp] + +rt_hw_context_switch_interrupt: + mov rt_thread_switch_interrput_flag, r8 + ld.w 0[r8],r9 + cmp 1, r9 + be jump2 + ;mov rt_thread_switch_interrput_flag, r1 + mov 1, r9 + st.b r9, 0[r8] + mov rt_interrupt_from_thread, r10 + st.w r1, 0[r10] +jump2 + mov rt_interrupt_to_thread, r11 + st.w r5, 0[r11] + jmp [lp] + +rt_hw_context_switch_interrupt_do + mov rt_thread_switch_interrput_flag, r8 + mov 0, r9 + st.b r9, 0[r8] + + mov rt_interrupt_from_thread, r21 + ld.w 0[r21], r21 + st.w sp, 0[r21] + + mov rt_interrupt_to_thread, r1 + ld.w 0[r1], r1 + ld.w 0[r1], sp + jr OS_Restore_CPU_Context + +OSTickIntr: + SAVE_CPU_CTX ;Save current task's registers + jarl rt_interrupt_enter,lp + jarl rt_tick_increase,lp + jarl rt_interrupt_leave,lp + + mov rt_thread_switch_interrput_flag, r8 + ld.w 0[r8],r9 + cmp 1, r9 + be rt_hw_context_switch_interrupt_do + + jr OS_Restore_CPU_Context + +uarta1_int_r: + SAVE_CPU_CTX ;Save current task's registers + jarl rt_interrupt_enter,lp + jarl uarta1_receive_handler,lp + jarl rt_interrupt_leave,lp + + mov rt_thread_switch_interrput_flag, r8 + ld.w 0[r8],r9 + cmp 1, r9 + be rt_hw_context_switch_interrupt_do + + jr OS_Restore_CPU_Context + + END diff --git a/libcpu/v850/interrupt.c b/libcpu/v850/interrupt.c new file mode 100644 index 0000000000..79fcaae014 --- /dev/null +++ b/libcpu/v850/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 + * 2010-06-29 lgnq the first version + * + * For : NEC V850E + * Toolchain : IAR Embedded Workbench for V850 v3.71 +*/ + +#include + +rt_uint32_t rt_interrupt_from_thread; +rt_uint32_t rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrput_flag; \ No newline at end of file diff --git a/libcpu/v850/macdefs.inc b/libcpu/v850/macdefs.inc new file mode 100644 index 0000000000..4a0c4d4823 --- /dev/null +++ b/libcpu/v850/macdefs.inc @@ -0,0 +1,125 @@ +; +; These are the macros used by the v850 port of the uCOS/II. +; + + + + + +;******************************************************************** +; function: +; description: +; --- Modifies ---------------------------------------------- +; IO : +; Mem: +; CPU: +; --- Uses -------------------------------------------------- +; IO : +; Mem: +; --- Input ------------------------------------------------- +; --- Output ------------------------------------------------ +; --- Notes ------------------------------------------------- +;==================================================================== + +SAVE_CPU_CTX MACRO + ;Save all registers on entry (r3 is the stack pointer) + prepare {r23,r24,r25,r26,r27,r28,r29,r30,r31},(8+(4*14)) ;Add 8 bytes for 2 more registers + mov sp, ep + sst.w r1, 0[ep] + sst.w r2, 4[ep] + sst.w r5, 8[ep] + sst.w r6, 12[ep] + sst.w r7, 16[ep] + sst.w r8, 20[ep] + sst.w r9, 24[ep] + sst.w r10, 28[ep] + sst.w r11, 32[ep] + sst.w r12, 36[ep] + sst.w r13, 40[ep] + sst.w r14, 44[ep] + sst.w r15, 48[ep] + sst.w r16, 52[ep] + ;Save caller's PC + stsr EIPC, r1 + sst.w r1, 56[ep] + ;Save caller's PSW + stsr EIPSW, r1 + sst.w r1, 60[ep] + + ENDMAC + + + + + +;******************************************************************** +; function: +; description: +; --- Modifies ---------------------------------------------- +; IO : +; Mem: +; CPU: +; --- Uses -------------------------------------------------- +; IO : +; Mem: +; --- Input ------------------------------------------------- +; --- Output ------------------------------------------------ +; --- Notes ------------------------------------------------- +;==================================================================== +SAVE_SP MACRO + ;Save stack pointer on OSTCBCur->OSTCBStkPtr (OSTCBStkPtr=0) + mov OSTCBCur, r21 + ld.w 0[r21], r21 + st.w sp, 0[r21] + ENDMAC + + + +;******************************************************************** +; function: +; description: +; --- Modifies ---------------------------------------------- +; IO : +; Mem: +; CPU: +; --- Uses -------------------------------------------------- +; IO : +; Mem: +; --- Input ------------------------------------------------- +; --- Output ------------------------------------------------ +; --- Notes ------------------------------------------------- +;==================================================================== +ISR_ENTRY MACRO + LOCAL _DontSaveSP + + ;Save all CPU registers according to the standard stack frame + SAVE_CPU_CTX + + mov OSIntNesting, r1 ;Increment OSNesting by one + LD.BU 0[r1],r2 + add 1, r2 + ST.B r2, 0[r1] + cmp 1, r2 ;If OSNesting==1 save SP in current TCB + bne _DontSaveSP + SAVE_SP +_DontSaveSP: + ENDMAC + +;******************************************************************** +; function: +; description: +; --- Modifies ---------------------------------------------- +; IO : +; Mem: +; CPU: +; --- Uses -------------------------------------------------- +; IO : +; Mem: +; --- Input ------------------------------------------------- +; --- Output ------------------------------------------------ +; --- Notes ------------------------------------------------- +;==================================================================== +ISR_EXIT MACRO + jarl OSIntExit, lp ;Call OSIntExit() + jr OS_Restore_CPU_Context ;Restore processors registers and execute RETI + ENDMAC diff --git a/libcpu/v850/stack.c b/libcpu/v850/stack.c new file mode 100644 index 0000000000..2658716485 --- /dev/null +++ b/libcpu/v850/stack.c @@ -0,0 +1,61 @@ +/* + * File : stack.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 + * 2010-06-29 lgnq the first version + * + * For : NEC V850E + * Toolchain : IAR Embedded Workbench for V850 v3.71 +*/ + +#include + +/** + * 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) +{ + rt_uint32_t *stk; + + stk = (rt_uint32_t *)stack_addr; /* Load stack pointer */ + *(--stk) = (rt_uint32_t) 0x23232323; /* r23 */ + *(--stk) = (rt_uint32_t) 0x24242424; /* r24 */ + *(--stk) = (rt_uint32_t) 0x25252525; /* r25 */ + *(--stk) = (rt_uint32_t) 0x26262626; /* r26 */ + *(--stk) = (rt_uint32_t) 0x27272727; /* r27 */ + *(--stk) = (rt_uint32_t) 0x28282828; /* r28 */ + *(--stk) = (rt_uint32_t) 0x29292929; /* r29 */ + *(--stk) = (rt_uint32_t) 0x30303030; /* r30 */ + *(--stk) = (rt_uint32_t) 0x31313131; /* r31 */ + *(--stk) = (rt_uint32_t) 0x00000000; /* Task PSW = Interrupts enabled */ + *(--stk) = (rt_uint32_t) tentry; /* Task's PC */ + *(--stk) = (rt_uint32_t) 0x16161616; /* r16 */ + *(--stk) = (rt_uint32_t) 0x15151515; /* r15 */ + *(--stk) = (rt_uint32_t) 0x14141414; /* r14 */ + *(--stk) = (rt_uint32_t) 0x13131313; /* r13 */ + *(--stk) = (rt_uint32_t) 0x12121212; /* r12 */ + *(--stk) = (rt_uint32_t) 0x11111111; /* r11 */ + *(--stk) = (rt_uint32_t) 0x10101010; /* r10 */ + *(--stk) = (rt_uint32_t) 0x09090909; /* r9 */ + *(--stk) = (rt_uint32_t) 0x08080808; /* r8 */ + *(--stk) = (rt_uint32_t) 0x07070707; /* r7 */ + *(--stk) = (rt_uint32_t) 0x06060606; /* r6 */ + *(--stk) = (rt_uint32_t) 0x05050505; /* r5 */ + *(--stk) = (rt_uint32_t) 0x02020202; /* r2 */ + *(--stk) = (rt_uint32_t) parameter; /* r1 */ + return ((rt_uint8_t *)stk); +} -- cgit v1.3.1