1*10465441SEvalZero /*
2*10465441SEvalZero * File : cpuport.c
3*10465441SEvalZero * This file is part of RT-Thread RTOS
4*10465441SEvalZero * COPYRIGHT (C) 2009 - 2012, RT-Thread Development Team
5*10465441SEvalZero *
6*10465441SEvalZero * The license and distribution terms for this file may be
7*10465441SEvalZero * found in the file LICENSE in this distribution or at
8*10465441SEvalZero * http://www.rt-thread.org/license/LICENSE
9*10465441SEvalZero *
10*10465441SEvalZero * Change Logs:
11*10465441SEvalZero * Date Author Notes
12*10465441SEvalZero * 2011-02-23 Bernard the first version
13*10465441SEvalZero * 2012-09-23 lgnq set the texit to R31
14*10465441SEvalZero */
15*10465441SEvalZero
16*10465441SEvalZero #include <rtthread.h>
17*10465441SEvalZero
18*10465441SEvalZero extern volatile rt_uint8_t rt_interrupt_nest;
19*10465441SEvalZero
20*10465441SEvalZero /* switch flag on interrupt and thread pointer to save switch record */
21*10465441SEvalZero rt_uint32_t rt_interrupt_from_thread;
22*10465441SEvalZero rt_uint32_t rt_interrupt_to_thread;
23*10465441SEvalZero rt_uint32_t rt_thread_switch_interrupt_flag;
24*10465441SEvalZero
25*10465441SEvalZero /**
26*10465441SEvalZero * This function will initialize hardware interrupt
27*10465441SEvalZero */
rt_hw_interrupt_init(void)28*10465441SEvalZero void rt_hw_interrupt_init(void)
29*10465441SEvalZero {
30*10465441SEvalZero /* init interrupt nest, and context in thread sp */
31*10465441SEvalZero rt_interrupt_nest = 0;
32*10465441SEvalZero rt_interrupt_from_thread = 0;
33*10465441SEvalZero rt_interrupt_to_thread = 0;
34*10465441SEvalZero rt_thread_switch_interrupt_flag = 0;
35*10465441SEvalZero }
36*10465441SEvalZero
37*10465441SEvalZero /**
38*10465441SEvalZero * This function will initialize thread stack
39*10465441SEvalZero *
40*10465441SEvalZero * @param tentry the entry of thread
41*10465441SEvalZero * @param parameter the parameter of entry
42*10465441SEvalZero * @param stack_addr the beginning stack address
43*10465441SEvalZero * @param texit the function will be called when thread exit
44*10465441SEvalZero *
45*10465441SEvalZero * @return stack address
46*10465441SEvalZero */
rt_hw_stack_init(void * tentry,void * parameter,rt_uint8_t * stack_addr,void * texit)47*10465441SEvalZero rt_uint8_t *rt_hw_stack_init(void *tentry,
48*10465441SEvalZero void *parameter,
49*10465441SEvalZero rt_uint8_t *stack_addr,
50*10465441SEvalZero void *texit)
51*10465441SEvalZero {
52*10465441SEvalZero rt_uint32_t *stk;
53*10465441SEvalZero
54*10465441SEvalZero stk = (rt_uint32_t *)stack_addr; /* Load stack pointer */
55*10465441SEvalZero
56*10465441SEvalZero *(--stk) = (rt_uint32_t)0x23232323; /* r23 */
57*10465441SEvalZero *(--stk) = (rt_uint32_t)0x24242424; /* r24 */
58*10465441SEvalZero *(--stk) = (rt_uint32_t)0x25252525; /* r25 */
59*10465441SEvalZero *(--stk) = (rt_uint32_t)0x26262626; /* r26 */
60*10465441SEvalZero *(--stk) = (rt_uint32_t)0x27272727; /* r27 */
61*10465441SEvalZero *(--stk) = (rt_uint32_t)0x28282828; /* r28 */
62*10465441SEvalZero *(--stk) = (rt_uint32_t)0x29292929; /* r29 */
63*10465441SEvalZero *(--stk) = (rt_uint32_t)0x30303030; /* r30 */
64*10465441SEvalZero *(--stk) = (rt_uint32_t)texit; /* r31 */
65*10465441SEvalZero *(--stk) = (rt_uint32_t)0x00000000; /* Task PSW = Interrupts enabled */
66*10465441SEvalZero *(--stk) = (rt_uint32_t)tentry; /* Task's PC */
67*10465441SEvalZero *(--stk) = (rt_uint32_t)0x16161616; /* r16 */
68*10465441SEvalZero *(--stk) = (rt_uint32_t)0x15151515; /* r15 */
69*10465441SEvalZero *(--stk) = (rt_uint32_t)0x14141414; /* r14 */
70*10465441SEvalZero *(--stk) = (rt_uint32_t)0x13131313; /* r13 */
71*10465441SEvalZero *(--stk) = (rt_uint32_t)0x12121212; /* r12 */
72*10465441SEvalZero *(--stk) = (rt_uint32_t)0x11111111; /* r11 */
73*10465441SEvalZero *(--stk) = (rt_uint32_t)0x10101010; /* r10 */
74*10465441SEvalZero *(--stk) = (rt_uint32_t)0x09090909; /* r9 */
75*10465441SEvalZero *(--stk) = (rt_uint32_t)0x08080808; /* r8 */
76*10465441SEvalZero *(--stk) = (rt_uint32_t)0x07070707; /* r7 */
77*10465441SEvalZero *(--stk) = (rt_uint32_t)0x06060606; /* r6 */
78*10465441SEvalZero *(--stk) = (rt_uint32_t)0x05050505; /* r5 */
79*10465441SEvalZero *(--stk) = (rt_uint32_t)0x02020202; /* r2 */
80*10465441SEvalZero *(--stk) = (rt_uint32_t)parameter; /* r1 */
81*10465441SEvalZero
82*10465441SEvalZero return ((rt_uint8_t *)stk);
83*10465441SEvalZero }
84*10465441SEvalZero
rt_hw_context_switch(rt_uint32_t from,rt_uint32_t to)85*10465441SEvalZero void rt_hw_context_switch(rt_uint32_t from, rt_uint32_t to)
86*10465441SEvalZero {
87*10465441SEvalZero rt_interrupt_from_thread = from;
88*10465441SEvalZero rt_interrupt_to_thread = to;
89*10465441SEvalZero asm("trap 0x10");
90*10465441SEvalZero }
91*10465441SEvalZero
rt_hw_context_switch_interrupt(rt_uint32_t from,rt_uint32_t to)92*10465441SEvalZero void rt_hw_context_switch_interrupt(rt_uint32_t from, rt_uint32_t to)
93*10465441SEvalZero {
94*10465441SEvalZero if (rt_thread_switch_interrupt_flag != 1)
95*10465441SEvalZero {
96*10465441SEvalZero rt_thread_switch_interrupt_flag = 1;
97*10465441SEvalZero rt_interrupt_from_thread = from;
98*10465441SEvalZero }
99*10465441SEvalZero rt_interrupt_to_thread = to;
100*10465441SEvalZero }
101