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