xref: /nrf52832-nimble/rt-thread/libcpu/mips/loongson_1c/cpuport.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * File      : cpuport.c
3  * This file is part of RT-Thread RTOS
4  * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
5  *
6  * The license and distribution terms for this file may be
7  * found in the file LICENSE in this distribution or at
8  * http://www.rt-thread.org/license/LICENSE
9  *
10  * Change Logs:
11  * Date                Author         Notes
12  * 2010-07-09     Bernard        first version
13  * 2010-09-11     Bernard        add CPU reset implementation
14  * 2015-07-06     chinesebear  modified for loongson 1c
15  */
16 
17 #include <rtthread.h>
18 #include "ls1c.h"
19 
20 register rt_uint32_t $GP __asm__ ("$28");
21 
22 /**
23  * @addtogroup Loongson LS1B
24  */
25 
26 /*@{*/
27 
28 /**
29  * this function will reset CPU
30  *
31  */
rt_hw_cpu_reset(void)32 void rt_hw_cpu_reset(void)
33 {
34 	/* open the watch-dog */
35 	WDT_EN = 0x01; 		/* watch dog enable */
36 	WDT_TIMER = 0x01;	/* watch dog will be timeout after 1 tick */
37 	WDT_SET = 0x01;		/* watch dog start */
38 
39 	rt_kprintf("reboot system...\n");
40 	while (1);
41 }
42 
43 /**
44  * this function will shutdown CPU
45  *
46  */
rt_hw_cpu_shutdown(void)47 void rt_hw_cpu_shutdown(void)
48 {
49 	rt_kprintf("shutdown...\n");
50 
51 	while (1);
52 }
53 
54 extern rt_uint32_t cp0_get_cause(void);
55 extern rt_uint32_t cp0_get_status(void);
56 extern rt_uint32_t cp0_get_hi(void);
57 extern rt_uint32_t cp0_get_lo(void);
58 
59 /**
60  * This function will initialize thread stack
61  *
62  * @param tentry the entry of thread
63  * @param parameter the parameter of entry
64  * @param stack_addr the beginning stack address
65  * @param texit the function will be called when thread exit
66  *
67  * @return stack address
68  */
rt_hw_stack_init(void * tentry,void * parameter,rt_uint8_t * stack_addr,void * texit)69 rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit)
70 {
71 	rt_uint32_t *stk;
72     static rt_uint32_t g_sr = 0;
73 	static rt_uint32_t g_gp = 0;
74 
75     if (g_sr == 0)
76     {
77     	g_sr = cp0_get_status();
78     	g_sr &= 0xfffffffe;
79     	g_sr |= 0x8401;
80 
81 		g_gp = $GP;
82     }
83 
84     /** Start at stack top */
85     stk = (rt_uint32_t *)stack_addr;
86 	*(stk)   = (rt_uint32_t) tentry;        /* pc: Entry Point */
87 	*(--stk) = (rt_uint32_t) 0xeeee; 		/* c0_cause */
88 	*(--stk) = (rt_uint32_t) 0xffff;		/* c0_badvaddr */
89 	*(--stk) = (rt_uint32_t) cp0_get_lo();	/* lo */
90 	*(--stk) = (rt_uint32_t) cp0_get_hi();	/* hi */
91 	*(--stk) = (rt_uint32_t) g_sr; 			/* C0_SR: HW2 = En, IE = En */
92 	*(--stk) = (rt_uint32_t) texit;	        /* ra */
93 	*(--stk) = (rt_uint32_t) 0x0000001e;	/* s8 */
94 	*(--stk) = (rt_uint32_t) stack_addr;	/* sp */
95 	*(--stk) = (rt_uint32_t) g_gp;	        /* gp */
96 	*(--stk) = (rt_uint32_t) 0x0000001b;	/* k1 */
97 	*(--stk) = (rt_uint32_t) 0x0000001a;	/* k0 */
98 	*(--stk) = (rt_uint32_t) 0x00000019;	/* t9 */
99 	*(--stk) = (rt_uint32_t) 0x00000018;	/* t8 */
100 	*(--stk) = (rt_uint32_t) 0x00000017;	/* s7 */
101 	*(--stk) = (rt_uint32_t) 0x00000016;	/* s6 */
102 	*(--stk) = (rt_uint32_t) 0x00000015;	/* s5 */
103 	*(--stk) = (rt_uint32_t) 0x00000014;	/* s4 */
104 	*(--stk) = (rt_uint32_t) 0x00000013;	/* s3 */
105 	*(--stk) = (rt_uint32_t) 0x00000012;	/* s2 */
106 	*(--stk) = (rt_uint32_t) 0x00000011;	/* s1 */
107 	*(--stk) = (rt_uint32_t) 0x00000010;	/* s0 */
108 	*(--stk) = (rt_uint32_t) 0x0000000f;	/* t7 */
109 	*(--stk) = (rt_uint32_t) 0x0000000e;	/* t6 */
110 	*(--stk) = (rt_uint32_t) 0x0000000d;	/* t5 */
111 	*(--stk) = (rt_uint32_t) 0x0000000c;	/* t4 */
112 	*(--stk) = (rt_uint32_t) 0x0000000b;	/* t3 */
113 	*(--stk) = (rt_uint32_t) 0x0000000a; 	/* t2 */
114 	*(--stk) = (rt_uint32_t) 0x00000009;	/* t1 */
115 	*(--stk) = (rt_uint32_t) 0x00000008;	/* t0 */
116 	*(--stk) = (rt_uint32_t) 0x00000007;	/* a3 */
117 	*(--stk) = (rt_uint32_t) 0x00000006;	/* a2 */
118 	*(--stk) = (rt_uint32_t) 0x00000005;	/* a1 */
119 	*(--stk) = (rt_uint32_t) parameter;	    /* a0 */
120 	*(--stk) = (rt_uint32_t) 0x00000003;	/* v1 */
121 	*(--stk) = (rt_uint32_t) 0x00000002;	/* v0 */
122 	*(--stk) = (rt_uint32_t) 0x00000001;	/* at */
123 	*(--stk) = (rt_uint32_t) 0x00000000;	/* zero */
124 
125 	/* return task's current stack address */
126 	return (rt_uint8_t *)stk;
127 }
128 
129 #define cache_op(op,addr)                       \
130 	    __asm__ __volatile__(                       \
131 				    "   .set    push                    \n" \
132 				    "   .set    noreorder               \n" \
133 				    "   .set    mips3\n\t               \n" \
134 				    "   cache   %0, %1                  \n" \
135 				    "   .set    pop                 \n" \
136 				    :                               \
137 				    : "i" (op), "R" (*(unsigned char *)(addr)))
138 
139 #if defined(CONFIG_CPU_LOONGSON2)
140 #define Hit_Invalidate_I    0x00
141 #else
142 #define Hit_Invalidate_I    0x10
143 #endif
144 #define Hit_Invalidate_D    0x11
145 #define CONFIG_SYS_CACHELINE_SIZE   32
146 #define Hit_Writeback_Inv_D 0x15
147 
148 
flush_cache(unsigned long start_addr,unsigned long size)149 void flush_cache(unsigned long start_addr, unsigned long size)
150 {
151 	unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
152 	unsigned long addr = start_addr & ~(lsize - 1);
153 	unsigned long aend = (start_addr + size - 1) & ~(lsize - 1);
154 
155 	while (1) {
156 		cache_op(Hit_Writeback_Inv_D, addr);
157 		cache_op(Hit_Invalidate_I, addr);
158 		if (addr == aend)
159 			break;
160 		addr += lsize;
161 	}
162 }
163 
164 
165 /*@}*/
166 
167