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