1 /*
2 * File : stack.c
3 * This file is part of RT-Thread RTOS
4 * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Change Logs:
21 * Date Author Notes
22 * 2016��9��8�� Urey the first version
23 */
24
25 #include <rtthread.h>
26
27 #include "../common/mips.h"
28
29 register U32 $GP __asm__ ("$28");
30
rt_hw_stack_init(void * tentry,void * parameter,rt_uint8_t * stack_addr,void * texit)31 rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit)
32 {
33 static rt_uint32_t wSR=0;
34 static rt_uint32_t wGP;
35
36 mips_reg_ctx *regCtx;
37 mips_arg_ctx *argCtx;
38 rt_uint32_t i;
39
40 if (wSR == 0)
41 {
42 wSR = read_c0_status();
43 wSR &= 0xfffffffe;
44 wSR |= 0x0403;
45
46 wGP = $GP;
47 }
48
49 if ((rt_uint32_t) stack_addr & 0x7)
50 {
51 stack_addr = (rt_uint8_t *)((rt_uint32_t)stack_addr - 4);
52 }
53
54 argCtx = (mips_arg_ctx *)((rt_uint32_t)stack_addr - sizeof(mips_arg_ctx));
55 regCtx = (mips_reg_ctx *)((rt_uint32_t)stack_addr - sizeof(mips_arg_ctx) - sizeof(mips_reg_ctx));
56
57 for (i = 0; i < 4; ++i)
58 {
59 argCtx->args[i] = i;
60 }
61
62 //����ͨ�üĴ���
63 for (i = 0; i < 32; ++i)
64 {
65 regCtx->regs[i] = i;
66 }
67
68 regCtx->regs[REG_SP] = (rt_uint32_t)stack_addr;
69 regCtx->regs[REG_A0] = (rt_uint32_t)parameter;
70 regCtx->regs[REG_GP] = (rt_uint32_t)wGP;
71 regCtx->regs[REG_FP] = (rt_uint32_t)0x0;
72 regCtx->regs[REG_RA] = (rt_uint32_t)texit;
73
74 regCtx->CP0DataLO = 0x00;
75 regCtx->CP0DataHI = 0x00;
76 regCtx->CP0Cause = read_c0_cause();
77 regCtx->CP0Status = wSR;
78 regCtx->CP0EPC = (rt_uint32_t)tentry;
79 regCtx->CP0BadVAddr= 0x00;
80
81 return (rt_uint8_t *)(regCtx);
82 }
83