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