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__)
cp15_rd(void)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
cache_enable(rt_uint32_t bit)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
cache_disable(rt_uint32_t bit)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)
cp15_rd(void)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
cache_enable(rt_uint32_t bit)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
cache_disable(rt_uint32_t bit)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 */
rt_hw_cpu_icache_enable()95 void rt_hw_cpu_icache_enable()
96 {
97 cache_enable(ICACHE_MASK);
98 }
99
100 /**
101 * disable I-Cache
102 *
103 */
rt_hw_cpu_icache_disable()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 */
rt_hw_cpu_icache_status()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 */
rt_hw_cpu_dcache_enable()122 void rt_hw_cpu_dcache_enable()
123 {
124 cache_enable(DCACHE_MASK);
125 }
126
127 /**
128 * disable D-Cache
129 *
130 */
rt_hw_cpu_dcache_disable()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 */
rt_hw_cpu_dcache_status()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 */
rt_hw_cpu_reset()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 */
rt_hw_cpu_shutdown()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)
__rt_ffs(int value)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__)
__rt_ffs(int value)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