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