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