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__ 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 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 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 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 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 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 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 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 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 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 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 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 */ 185 void rt_hw_cpu_icache_enable() 186 { 187 icache_enable(); 188 } 189 190 /** 191 * disable I-Cache 192 * 193 */ 194 void rt_hw_cpu_icache_disable() 195 { 196 icache_disable(); 197 } 198 199 /** 200 * return the status of I-Cache 201 * 202 */ 203 rt_base_t rt_hw_cpu_icache_status() 204 { 205 return icache_status(); 206 } 207 208 /** 209 * enable D-Cache 210 * 211 */ 212 void rt_hw_cpu_dcache_enable() 213 { 214 dcache_enable(); 215 } 216 217 /** 218 * disable D-Cache 219 * 220 */ 221 void rt_hw_cpu_dcache_disable() 222 { 223 dcache_disable(); 224 } 225 226 /** 227 * return the status of D-Cache 228 * 229 */ 230 rt_base_t rt_hw_cpu_dcache_status() 231 { 232 return dcache_status(); 233 } 234 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 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 */ 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 */ 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