1 /*
2  * Copyright (c) 2006-2022, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 20011-05-23    aozima       the first version for PIC32.
9  * 20011-09-05    aozima       merge all of C source code into cpuport.c.
10  */
11 
12 #include <rtthread.h>
13 
14 /**
15  * @addtogroup PIC32
16  */
17 /*@{*/
18 
19 /* exception and interrupt handler table */
20 rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
21 rt_uint32_t rt_thread_switch_interrupt_flag;
22 
_get_gp(void)23 rt_uint32_t __attribute__((nomips16)) _get_gp(void)
24 {
25     rt_uint32_t result;
26 
27     // get the gp reg
28     asm volatile("move   %0, $28" : "=r"(result));
29 
30     return result;
31 }
32 
33 /**
34  * This function will initialize thread stack
35  *
36  * @param tentry the entry of thread
37  * @param parameter the parameter of entry
38  * @param stack_addr the beginning stack address
39  * @param texit the function will be called when thread exit
40  *
41  * @return stack address
42  */
rt_hw_stack_init(void * tentry,void * parameter,rt_uint8_t * stack_addr,void * texit)43 rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit)
44 {
45     rt_uint32_t *stk;
46 
47     /** Start at stack top */
48     stk = (rt_uint32_t *)stack_addr;
49     *(stk)   = (rt_uint32_t) tentry;        /* pc: Entry Point */
50     *(--stk) = (rt_uint32_t) 0x00800000;    /* c0_cause: IV=1, */
51     *(--stk) = (rt_uint32_t) 0;             /* c0_badvaddr */
52     *(--stk) = (rt_uint32_t) 0;             /* lo */
53     *(--stk) = (rt_uint32_t) 0;             /* hi */
54     *(--stk) = (rt_uint32_t) 1;             /* C0_SR: IE = En, */
55     *(--stk) = (rt_uint32_t) texit;         /* 31 ra */
56     *(--stk) = (rt_uint32_t) 0x0000001e;    /* 30 s8 */
57     *(--stk) = (rt_uint32_t) stack_addr;    /* 29 sp */
58     *(--stk) = (rt_uint32_t) _get_gp();     /* 28 gp */
59     *(--stk) = (rt_uint32_t) 0x0000001b;    /* 27 k1 */
60     *(--stk) = (rt_uint32_t) 0x0000001a;    /* 26 k0 */
61     *(--stk) = (rt_uint32_t) 0x00000019;    /* 25 t9 */
62     *(--stk) = (rt_uint32_t) 0x00000018;    /* 24 t8 */
63     *(--stk) = (rt_uint32_t) 0x00000017;    /* 23 s7 */
64     *(--stk) = (rt_uint32_t) 0x00000016;    /* 22 s6 */
65     *(--stk) = (rt_uint32_t) 0x00000015;    /* 21 s5 */
66     *(--stk) = (rt_uint32_t) 0x00000014;    /* 20 s4 */
67     *(--stk) = (rt_uint32_t) 0x00000013;    /* 19 s3 */
68     *(--stk) = (rt_uint32_t) 0x00000012;    /* 18 s2 */
69     *(--stk) = (rt_uint32_t) 0x00000011;    /* 17 s1 */
70     *(--stk) = (rt_uint32_t) 0x00000010;    /* 16 s0 */
71     *(--stk) = (rt_uint32_t) 0x0000000f;    /* 15 t7 */
72     *(--stk) = (rt_uint32_t) 0x0000000e;    /* 14 t6 */
73     *(--stk) = (rt_uint32_t) 0x0000000d;    /* 13 t5 */
74     *(--stk) = (rt_uint32_t) 0x0000000c;    /* 12 t4 */
75     *(--stk) = (rt_uint32_t) 0x0000000b;    /* 11 t3 */
76     *(--stk) = (rt_uint32_t) 0x0000000a;    /* 10 t2 */
77     *(--stk) = (rt_uint32_t) 0x00000009;    /* 9 t1 */
78     *(--stk) = (rt_uint32_t) 0x00000008;    /* 8 t0 */
79     *(--stk) = (rt_uint32_t) 0x00000007;    /* 7 a3 */
80     *(--stk) = (rt_uint32_t) 0x00000006;    /* 6 a2 */
81     *(--stk) = (rt_uint32_t) 0x00000005;    /* 5 a1 */
82     *(--stk) = (rt_uint32_t) parameter;     /* 4 a0 */
83     *(--stk) = (rt_uint32_t) 0x00000003;    /* 3 v1 */
84     *(--stk) = (rt_uint32_t) 0x00000002;    /* 2 v0 */
85     *(--stk) = (rt_uint32_t) 0x00000001;    /* 1 at */
86     *(--stk) = (rt_uint32_t) 0x00000000;    /* 0 zero */
87 
88     /* return task's current stack address */
89     return (rt_uint8_t *)stk;
90 }
91 
92 
93 /*@}*/
94