1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2011-01-13 weety modified from mini2440 9 * 2015-04-15 ArdaFu Add code for IAR 10 */ 11 12 #include <rthw.h> 13 #include <rtthread.h> 14 15 #define ICACHE_MASK (rt_uint32_t)(1 << 12) 16 #define DCACHE_MASK (rt_uint32_t)(1 << 2) 17 18 extern void machine_reset(void); 19 extern void machine_shutdown(void); 20 21 #if defined(__GNUC__) || defined(__ICCARM__) 22 rt_inline rt_uint32_t cp15_rd(void) 23 { 24 rt_uint32_t i; 25 26 __asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); 27 return i; 28 } 29 30 rt_inline void cache_enable(rt_uint32_t bit) 31 { 32 __asm volatile(\ 33 "mrc p15,0,r0,c1,c0,0\n\t" \ 34 "orr r0,r0,%0\n\t" \ 35 "mcr p15,0,r0,c1,c0,0" \ 36 : \ 37 :"r" (bit) \ 38 :"memory"); 39 } 40 41 rt_inline void cache_disable(rt_uint32_t bit) 42 { 43 __asm volatile(\ 44 "mrc p15,0,r0,c1,c0,0\n\t" \ 45 "bic r0,r0,%0\n\t" \ 46 "mcr p15,0,r0,c1,c0,0" \ 47 : \ 48 :"r" (bit) \ 49 :"memory"); 50 } 51 #endif 52 53 #if defined(__CC_ARM) 54 rt_inline rt_uint32_t cp15_rd(void) 55 { 56 rt_uint32_t i; 57 58 __asm volatile 59 { 60 mrc p15, 0, i, c1, c0, 0 61 } 62 63 return i; 64 } 65 66 rt_inline void cache_enable(rt_uint32_t bit) 67 { 68 rt_uint32_t value; 69 70 __asm volatile 71 { 72 mrc p15, 0, value, c1, c0, 0 73 orr value, value, bit 74 mcr p15, 0, value, c1, c0, 0 75 } 76 } 77 78 rt_inline void cache_disable(rt_uint32_t bit) 79 { 80 rt_uint32_t value; 81 82 __asm volatile 83 { 84 mrc p15, 0, value, c1, c0, 0 85 bic value, value, bit 86 mcr p15, 0, value, c1, c0, 0 87 } 88 } 89 #endif 90 91 /** 92 * enable I-Cache 93 * 94 */ 95 void rt_hw_cpu_icache_enable() 96 { 97 cache_enable(ICACHE_MASK); 98 } 99 100 /** 101 * disable I-Cache 102 * 103 */ 104 void rt_hw_cpu_icache_disable() 105 { 106 cache_disable(ICACHE_MASK); 107 } 108 109 /** 110 * return the status of I-Cache 111 * 112 */ 113 rt_base_t rt_hw_cpu_icache_status() 114 { 115 return (cp15_rd() & ICACHE_MASK); 116 } 117 118 /** 119 * enable D-Cache 120 * 121 */ 122 void rt_hw_cpu_dcache_enable() 123 { 124 cache_enable(DCACHE_MASK); 125 } 126 127 /** 128 * disable D-Cache 129 * 130 */ 131 void rt_hw_cpu_dcache_disable() 132 { 133 cache_disable(DCACHE_MASK); 134 } 135 136 /** 137 * return the status of D-Cache 138 * 139 */ 140 rt_base_t rt_hw_cpu_dcache_status() 141 { 142 return (cp15_rd() & DCACHE_MASK); 143 } 144 145 /** 146 * reset cpu by dog's time-out 147 * 148 */ 149 void rt_hw_cpu_reset() 150 { 151 152 rt_kprintf("Restarting system...\n"); 153 machine_reset(); 154 155 while(1); /* loop forever and wait for reset to happen */ 156 157 /* NEVER REACHED */ 158 } 159 160 /** 161 * shutdown CPU 162 * 163 */ 164 void rt_hw_cpu_shutdown() 165 { 166 rt_uint32_t level; 167 rt_kprintf("shutdown...\n"); 168 169 level = rt_hw_interrupt_disable(); 170 machine_shutdown(); 171 while (level) 172 { 173 RT_ASSERT(0); 174 } 175 } 176 177 #ifdef RT_USING_CPU_FFS 178 /** 179 * This function finds the first bit set (beginning with the least significant bit) 180 * in value and return the index of that bit. 181 * 182 * Bits are numbered starting at 1 (the least significant bit). A return value of 183 * zero from any of these functions means that the argument was zero. 184 * 185 * @return return the index of the first bit set. If value is 0, then this function 186 * shall return 0. 187 */ 188 #if defined(__CC_ARM) 189 int __rt_ffs(int value) 190 { 191 register rt_uint32_t x; 192 193 if (value == 0) 194 return value; 195 196 __asm 197 { 198 rsb x, value, #0 199 and x, x, value 200 clz x, x 201 rsb x, x, #32 202 } 203 204 return x; 205 } 206 #elif defined(__GNUC__) || defined(__ICCARM__) 207 int __rt_ffs(int value) 208 { 209 register rt_uint32_t x; 210 211 if (value == 0) 212 return value; 213 214 __asm 215 ( 216 "rsb %[temp], %[val], #0\n" 217 "and %[temp], %[temp], %[val]\n" 218 "clz %[temp], %[temp]\n" 219 "rsb %[temp], %[temp], #32\n" 220 :[temp] "=r"(x) 221 :[val] "r"(value) 222 ); 223 return x; 224 } 225 #endif 226 227 #endif 228 229 230 /*@}*/ 231