1 /*
2 * File : cpu.c
3 * This file is part of RT-Thread RTOS
4 * COPYRIGHT (C) 2006 - 2013, 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 * 2013-7-14 Peng Fan sep6200 implementation
23 */
24
25 #include <rthw.h>
26 #include <rtthread.h>
27 #include <sep6200.h>
28
29 /**
30 * @addtogroup sep6200
31 */
32 /*@{*/
33
34 #ifdef __GNUC__
cache_invalid(void)35 rt_inline void cache_invalid(void)
36 {
37 __asm__ volatile ("movc p0.c5, r1, #28\n"
38 "nop;nop;nop;nop;nop;nop;nop;nop;\n"
39 :
40 :
41 :"memory", "cc"
42 );
43 }
44
cache_enable(void)45 rt_inline void cache_enable(void)
46 {
47 __asm__ volatile ( "movc r1, p0.c1, #0\n"
48 "or r1, r1, #0xc\n"
49 "movc p0.c1, r1, #0\n"
50 "nop;nop;nop;nop;nop;nop;nop;nop;\n"
51 :
52 :
53 :"r0", "memory", "cc");
54 }
55
clean_dcache(void)56 rt_inline void clean_dcache(void)
57 {
58 __asm__ volatile ( "mov ip, #0\n"
59 "movc p0.c5, ip, #10\n"
60 "nop; nop; nop; nop; nop; nop; nop; nop\n"
61 :
62 :
63 :"ip", "memory", "cc");
64 }
65
icache_status(void)66 rt_inline rt_uint32_t icache_status(void)
67 {
68 rt_uint32_t ret;
69
70 __asm__ volatile ( "movc %0, p0.c1, #0\n"
71 "and %0, %0, #8\n"
72 : "=&r" (ret)
73 :
74 :"memory", "cc");
75
76 return ret;
77 }
78
dcache_status(void)79 rt_inline rt_uint32_t dcache_status(void)
80 {
81 rt_uint32_t ret;
82
83 __asm__ volatile ( "movc %0, p0.c1, #0\n"
84 "and %0, %0, #4\n"
85 : "=&r" (ret)
86 :
87 :"memory", "cc");
88
89 return ret;
90 }
91
dcache_flush(void)92 rt_inline void dcache_flush(void)
93 {
94 __asm__ volatile ( "mov ip, #0\n"
95 "movc p0.c5, ip, #14\n"
96 "nop; nop; nop; nop; nop; nop; nop; nop\n"
97 :
98 :
99 : "ip" );
100 }
101
icache_invalid(void)102 rt_inline void icache_invalid(void)
103 {
104 __asm__ volatile ( "mov r0, #0\n"
105 "movc p0.c5, r0, #20\n"
106 "nop; nop; nop; nop; nop; nop; nop; nop\n"
107 :
108 :
109 :"r0", "memory", "cc");
110 }
111
dcache_invalid(void)112 rt_inline void dcache_invalid(void)
113 {
114 __asm__ volatile ( "mov r0, #0\n"
115 "movc p0.c5, r0, #12\n"
116 "nop; nop; nop; nop; nop; nop; nop; nop\n"
117 :
118 :
119 :"r0", "memory", "cc");
120 }
121
icache_disable(void)122 rt_inline void icache_disable(void)
123 {
124 icache_invalid();
125 __asm__ volatile ( "movc r0, p0.c1, #0\n"
126 "andn r0, r0, #8\n"
127 "movc p0.c1, r0, #0\n"
128 :
129 :
130 :"r0", "memory", "cc");
131 }
132
dcache_disable(void)133 rt_inline void dcache_disable(void)
134 {
135 dcache_flush();
136 __asm__ volatile ( "movc r0, p0.c1, #0\n"
137 "andn r0, r0, #20\n"
138 "movc p0.c1, r0, #0\n"
139 :
140 :
141 :"r0", "memory", "cc");
142
143 }
144
icache_enable(void)145 rt_inline void icache_enable(void)
146 {
147 __asm__ volatile ( "mov r0, #0\n"
148 "movc p0.c5, r0, #20\n"
149 "nop; nop; nop; nop; nop; nop; nop; nop\n"
150 :
151 :
152 :"r0", "memory", "cc");
153
154 __asm__ volatile ( "movc r0, p0.c1, #0\n"
155 "or r0, r0, #8\n"
156 "movc p0.c1, r0, #0\n"
157 :
158 :
159 :"r0", "memory", "cc");
160 }
161
dcache_enable(void)162 rt_inline void dcache_enable(void)
163 {
164 __asm__ volatile ( "mov r0, #0\n"
165 "movc p0.c5, r0, #12\n"
166 "nop; nop; nop; nop; nop; nop; nop; nop\n"
167 :
168 :
169 :"r0", "memory", "cc");
170
171 __asm__ volatile ( "movc r0, p0.c1, #0\n"
172 "or r0, r0, #20\n"
173 "movc p0.c1, r0, #0\n"
174 :
175 :
176 :"r0", "memory", "cc");
177 }
178 #endif
179
180
181 /**
182 * enable I-Cache
183 *
184 */
rt_hw_cpu_icache_enable()185 void rt_hw_cpu_icache_enable()
186 {
187 icache_enable();
188 }
189
190 /**
191 * disable I-Cache
192 *
193 */
rt_hw_cpu_icache_disable()194 void rt_hw_cpu_icache_disable()
195 {
196 icache_disable();
197 }
198
199 /**
200 * return the status of I-Cache
201 *
202 */
rt_hw_cpu_icache_status()203 rt_base_t rt_hw_cpu_icache_status()
204 {
205 return icache_status();
206 }
207
208 /**
209 * enable D-Cache
210 *
211 */
rt_hw_cpu_dcache_enable()212 void rt_hw_cpu_dcache_enable()
213 {
214 dcache_enable();
215 }
216
217 /**
218 * disable D-Cache
219 *
220 */
rt_hw_cpu_dcache_disable()221 void rt_hw_cpu_dcache_disable()
222 {
223 dcache_disable();
224 }
225
226 /**
227 * return the status of D-Cache
228 *
229 */
rt_hw_cpu_dcache_status()230 rt_base_t rt_hw_cpu_dcache_status()
231 {
232 return dcache_status();
233 }
234
sep6200_reset(rt_uint32_t addr)235 static void sep6200_reset(rt_uint32_t addr)
236 {
237 __asm__ volatile ( "mov ip, #0\n"
238 "movc p0.c5, ip, #28\n" /*Cache invalidate all*/
239 "movc p0.c6, ip, #6\n" /*TLB invalidate all*/
240 "nop;nop;nop;nop;nop;nop;nop;nop;\n"
241 "movc ip, p0.c1, #0\n" /*ctrl register*/
242 "andn ip, ip, #0x000f\n" /*disable caches and mmu*/
243 "movc p0.c1, ip, #0\n"
244 "nop\n"
245 "mov pc, %0\n"
246 "nop;nop;nop;nop;nop;nop;nop;nop;\n"
247 : "=&r" (addr)
248 :
249 :"memory", "cc");
250 }
251
sep6200_poweroff(void)252 static void sep6200_poweroff(void)
253 {
254 rt_kprintf("sep6200 power off not implemented\n");
255 while(1);
256 }
257
258 /**
259 * reset cpu by dog's time-out
260 *
261 */
rt_hw_cpu_reset()262 void rt_hw_cpu_reset()
263 {
264
265 rt_kprintf("Soft reset, Restarting system...\n");
266 sep6200_reset(0);
267
268 while(1); /* loop forever and wait for reset to happen */
269
270 /* NEVER REACHED */
271 }
272
273 /**
274 * shutdown CPU
275 *
276 */
rt_hw_cpu_shutdown()277 void rt_hw_cpu_shutdown()
278 {
279 rt_uint32_t level;
280 rt_kprintf("shutdown...\n");
281
282 level = rt_hw_interrupt_disable();
283 sep6200_poweroff();
284 while (level)
285 {
286 RT_ASSERT(0);
287 }
288 }
289
290 /*@}*/
291