1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2011-09-15     Bernard      first version
9  * 2022-09-20     YangZhongQing
10  *                             add IAR assembler
11  */
12 
13 #include <rthw.h>
14 #include <rtthread.h>
15 #include "am33xx.h"
16 
17 /**
18  * @addtogroup AM33xx
19  */
20 /*@{*/
21 
22 #define ICACHE_MASK (rt_uint32_t)(1 << 12)
23 #define DCACHE_MASK (rt_uint32_t)(1 << 2)
24 
25 #if defined(__CC_ARM)
cp15_rd(void)26 rt_inline rt_uint32_t cp15_rd(void)
27 {
28     rt_uint32_t i;
29 
30     __asm
31     {
32         mrc p15, 0, i, c1, c0, 0
33     }
34 
35     return i;
36 }
37 
cache_enable(rt_uint32_t bit)38 rt_inline void cache_enable(rt_uint32_t bit)
39 {
40     rt_uint32_t value;
41 
42     __asm
43     {
44         mrc p15, 0, value, c1, c0, 0
45         orr value, value, bit
46         mcr p15, 0, value, c1, c0, 0
47     }
48 }
49 
cache_disable(rt_uint32_t bit)50 rt_inline void cache_disable(rt_uint32_t bit)
51 {
52     rt_uint32_t value;
53 
54     __asm
55     {
56         mrc p15, 0, value, c1, c0, 0
57         bic value, value, bit
58         mcr p15, 0, value, c1, c0, 0
59     }
60 }
61 #elif defined(__GNUC__)
cp15_rd(void)62 rt_inline rt_uint32_t cp15_rd(void)
63 {
64     rt_uint32_t i;
65 
66     asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
67     return i;
68 }
69 
cache_enable(rt_uint32_t bit)70 rt_inline void cache_enable(rt_uint32_t bit)
71 {
72     __asm__ __volatile__(           \
73         "mrc  p15,0,r0,c1,c0,0\n\t" \
74         "orr  r0,r0,%0\n\t"         \
75         "mcr  p15,0,r0,c1,c0,0"     \
76         :                           \
77         :"r" (bit)                  \
78         :"memory");
79 }
80 
cache_disable(rt_uint32_t bit)81 rt_inline void cache_disable(rt_uint32_t bit)
82 {
83     __asm__ __volatile__(           \
84         "mrc  p15,0,r0,c1,c0,0\n\t" \
85         "bic  r0,r0,%0\n\t"         \
86         "mcr  p15,0,r0,c1,c0,0"     \
87         :                           \
88         :"r" (bit)                  \
89         :"memory");
90 }
91 #elif defined(__ICCARM__)
cp15_rd(void)92 rt_inline rt_uint32_t cp15_rd(void)
93 {
94     rt_uint32_t i;
95 
96     __asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
97     return i;
98 }
99 
cache_enable(rt_uint32_t bit)100 rt_inline void cache_enable(rt_uint32_t bit)
101 {
102     rt_uint32_t tmp;
103 
104     __asm volatile(                 \
105         "mrc  p15,0,%0,c1,c0,0\n\t" \
106         "orr  %0,%0,%1\n\t"         \
107         "mcr  p15,0,%0,c1,c0,0"     \
108         :"+r"(tmp)                  \
109         :"r"(bit)                   \
110         :"memory");
111 }
112 
cache_disable(rt_uint32_t bit)113 rt_inline void cache_disable(rt_uint32_t bit)
114 {
115     rt_uint32_t tmp;
116 
117     __asm volatile(                 \
118         "mrc  p15,0,%0,c1,c0,0\n\t" \
119         "bic  %0,%0,%1\n\t"         \
120         "mcr  p15,0,%0,c1,c0,0"     \
121         :"+r"(tmp)                  \
122         :"r"(bit)                   \
123         :"memory");
124 }
125 #endif
126 
127 /**
128  * enable I-Cache
129  *
130  */
rt_hw_cpu_icache_enable()131 void rt_hw_cpu_icache_enable()
132 {
133     cache_enable(ICACHE_MASK);
134 }
135 
136 /**
137  * disable I-Cache
138  *
139  */
rt_hw_cpu_icache_disable()140 void rt_hw_cpu_icache_disable()
141 {
142     cache_disable(ICACHE_MASK);
143 }
144 
145 /**
146  * return the status of I-Cache
147  *
148  */
rt_hw_cpu_icache_status()149 rt_base_t rt_hw_cpu_icache_status()
150 {
151     return (cp15_rd() & ICACHE_MASK);
152 }
153 
154 /**
155  * enable D-Cache
156  *
157  */
rt_hw_cpu_dcache_enable()158 void rt_hw_cpu_dcache_enable()
159 {
160     cache_enable(DCACHE_MASK);
161 }
162 
163 /**
164  * disable D-Cache
165  *
166  */
rt_hw_cpu_dcache_disable()167 void rt_hw_cpu_dcache_disable()
168 {
169     cache_disable(DCACHE_MASK);
170 }
171 
172 /**
173  * return the status of D-Cache
174  *
175  */
rt_hw_cpu_dcache_status()176 rt_base_t rt_hw_cpu_dcache_status()
177 {
178     return (cp15_rd() & DCACHE_MASK);
179 }
180 
181 /**
182  *  shutdown CPU
183  *
184  */
rt_hw_cpu_shutdown(void)185 void rt_hw_cpu_shutdown(void)
186 {
187     rt_base_t level;
188     rt_kprintf("shutdown...\n");
189 
190     level = rt_hw_interrupt_disable();
191     while (level)
192     {
193         RT_ASSERT(0);
194     }
195 }
196 
197 /*@}*/
198