xref: /nrf52832-nimble/rt-thread/libcpu/arm/armv6/cpuport.c (revision 104654410c56c573564690304ae786df310c91fc)
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__
cp15_rd(void)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 
cache_enable(rt_uint32_t bit)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 
cache_disable(rt_uint32_t bit)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
cp15_rd(void)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 
cache_enable(rt_uint32_t bit)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 
cache_disable(rt_uint32_t bit)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  */
rt_hw_cpu_icache_enable()96 void rt_hw_cpu_icache_enable()
97 {
98 	cache_enable(ICACHE_MASK);
99 }
100 
101 /**
102  * disable I-Cache
103  *
104  */
rt_hw_cpu_icache_disable()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  */
rt_hw_cpu_icache_status()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  */
rt_hw_cpu_dcache_enable()123 void rt_hw_cpu_dcache_enable()
124 {
125 	cache_enable(DCACHE_MASK);
126 }
127 
128 /**
129  * disable D-Cache
130  *
131  */
rt_hw_cpu_dcache_disable()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  */
rt_hw_cpu_dcache_status()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  */
rt_hw_cpu_reset()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  */
rt_hw_cpu_shutdown()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)
__rt_ffs(int value)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__)
__rt_ffs(int value)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__)
__rt_ffs(int value)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