1 /**************************************************************************//**
2 * @file core_cache.h
3 * @brief Realtek TM4 TM0 CMSIS Core Peripheral Access Layer Header File
4 * @version V5.0.1
5 * @date 25. November 2016
6 ******************************************************************************/
7 /*
8 * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
9 *
10 * SPDX-License-Identifier: Apache-2.0
11 *
12 * Licensed under the Apache License, Version 2.0 (the License); you may
13 * not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
20 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 */
24
25 #ifndef __CORE_CACHE_H
26 #define __CORE_CACHE_H
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 #define __ICACHE_PRESENT 1U
33 #define __DCACHE_PRESENT 1U
34
35 /* check device defines and use defaults */
36 #if defined __CHECK_DEVICE_DEFINES
37 #ifndef __ICACHE_PRESENT
38 #define __ICACHE_PRESENT 0U
39 #warning "__ICACHE_PRESENT not defined in device header file; using default!"
40 #endif
41
42 #ifndef __DCACHE_PRESENT
43 #define __DCACHE_PRESENT 0U
44 #warning "__DCACHE_PRESENT not defined in device header file; using default!"
45 #endif
46 #endif
47
48
49 /* ########################## Cache functions #################################### */
50 /**
51 \ingroup CMSIS_Core_FunctionInterface
52 \defgroup CMSIS_Core_CacheFunctions Cache Functions
53 \brief Functions that configure Instruction and Data cache.
54 @{
55 */
56
57 /* Cache Size ID Register Macros */
58 #define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
59 #define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos )
60
61
62 /**
63 \brief Enable I-Cache
64 \details Turns on I-Cache
65 */
SCB_EnableICache(void)66 __STATIC_INLINE void SCB_EnableICache (void)
67 {
68 #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
69 __DSB();
70 __ISB();
71 SCB->ICIALLU = 0UL; /* invalidate I-Cache */
72 __DSB();
73 __ISB();
74 SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */
75 __DSB();
76 __ISB();
77 #endif
78 }
79
80
81 /**
82 \brief Disable I-Cache
83 \details Turns off I-Cache
84 */
SCB_DisableICache(void)85 __STATIC_INLINE void SCB_DisableICache (void)
86 {
87 #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
88 __DSB();
89 __ISB();
90 SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */
91 SCB->ICIALLU = 0UL; /* invalidate I-Cache */
92 __DSB();
93 __ISB();
94 #endif
95 }
96
97
98 /**
99 \brief Invalidate I-Cache
100 \details Invalidates I-Cache
101 */
SCB_InvalidateICache(void)102 __STATIC_INLINE void SCB_InvalidateICache (void)
103 {
104 #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
105 __DSB();
106 __ISB();
107 SCB->ICIALLU = 0UL;
108 __DSB();
109 __ISB();
110 #endif
111 }
112
113
114 /**
115 \brief Enable D-Cache
116 \details Turns on D-Cache
117 */
SCB_EnableDCache(void)118 __STATIC_INLINE void SCB_EnableDCache (void)
119 {
120 #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
121 uint32_t ccsidr;
122 uint32_t sets;
123 uint32_t ways;
124
125 SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */
126 __DSB();
127
128 ccsidr = SCB->CCSIDR;
129
130 /* invalidate D-Cache */
131 sets = (uint32_t)(CCSIDR_SETS(ccsidr));
132 do {
133 ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
134 do {
135 SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
136 ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
137 #if defined ( __CC_ARM )
138 __schedule_barrier();
139 #endif
140 } while (ways-- != 0U);
141 } while(sets-- != 0U);
142 __DSB();
143
144 SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */
145
146 __DSB();
147 __ISB();
148 #endif
149 }
150
151
152 /**
153 \brief Disable D-Cache
154 \details Turns off D-Cache
155 */
SCB_DisableDCache(void)156 __STATIC_INLINE void SCB_DisableDCache (void)
157 {
158 #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
159 register uint32_t ccsidr;
160 register uint32_t sets;
161 register uint32_t ways;
162
163 SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */
164 __DSB();
165
166 SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */
167 __DSB();
168
169 ccsidr = SCB->CCSIDR;
170
171 /* clean & invalidate D-Cache */
172 sets = (uint32_t)(CCSIDR_SETS(ccsidr));
173 do {
174 ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
175 do {
176 SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
177 ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
178 #if defined ( __CC_ARM )
179 __schedule_barrier();
180 #endif
181 } while (ways-- != 0U);
182 } while(sets-- != 0U);
183
184 __DSB();
185 __ISB();
186 #endif
187 }
188
189
190 /**
191 \brief Invalidate D-Cache
192 \details Invalidates D-Cache
193 */
SCB_InvalidateDCache(void)194 __STATIC_INLINE void SCB_InvalidateDCache (void)
195 {
196 #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
197 uint32_t ccsidr;
198 uint32_t sets;
199 uint32_t ways;
200
201 SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */
202 __DSB();
203
204 ccsidr = SCB->CCSIDR;
205
206 /* invalidate D-Cache */
207 sets = (uint32_t)(CCSIDR_SETS(ccsidr));
208 do {
209 ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
210 do {
211 SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
212 ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
213 #if defined ( __CC_ARM )
214 __schedule_barrier();
215 #endif
216 } while (ways-- != 0U);
217 } while(sets-- != 0U);
218
219 __DSB();
220 __ISB();
221 #endif
222 }
223
224
225 /**
226 \brief Clean D-Cache
227 \details Cleans D-Cache
228 */
SCB_CleanDCache(void)229 __STATIC_INLINE void SCB_CleanDCache (void)
230 {
231 #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
232 uint32_t ccsidr;
233 uint32_t sets;
234 uint32_t ways;
235
236 SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */
237 __DSB();
238
239 ccsidr = SCB->CCSIDR;
240
241 /* clean D-Cache */
242 sets = (uint32_t)(CCSIDR_SETS(ccsidr));
243 do {
244 ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
245 do {
246 SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) |
247 ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) );
248 #if defined ( __CC_ARM )
249 __schedule_barrier();
250 #endif
251 } while (ways-- != 0U);
252 } while(sets-- != 0U);
253
254 __DSB();
255 __ISB();
256 #endif
257 }
258
259
260 /**
261 \brief Clean & Invalidate D-Cache
262 \details Cleans and Invalidates D-Cache
263 */
SCB_CleanInvalidateDCache(void)264 __STATIC_INLINE void SCB_CleanInvalidateDCache (void)
265 {
266 #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
267 uint32_t ccsidr;
268 uint32_t sets;
269 uint32_t ways;
270
271 SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */
272 __DSB();
273
274 ccsidr = SCB->CCSIDR;
275
276 /* clean & invalidate D-Cache */
277 sets = (uint32_t)(CCSIDR_SETS(ccsidr));
278 do {
279 ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
280 do {
281 SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
282 ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
283 #if defined ( __CC_ARM )
284 __schedule_barrier();
285 #endif
286 } while (ways-- != 0U);
287 } while(sets-- != 0U);
288
289 __DSB();
290 __ISB();
291 #endif
292 }
293
294
295 /**
296 \brief D-Cache Invalidate by address
297 \details Invalidates D-Cache for the given address
298 \param[in] addr address (aligned to 32-byte boundary)
299 \param[in] dsize size of memory block (in number of bytes)
300 */
SCB_InvalidateDCache_by_Addr(uint32_t * addr,int32_t dsize)301 __STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
302 {
303 #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
304 int32_t op_size = dsize;
305 uint32_t op_addr = (uint32_t)addr;
306 int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */
307
308 __DSB();
309
310 while (op_size > 0) {
311 SCB->DCIMVAC = op_addr;
312 op_addr += (uint32_t)linesize;
313 op_size -= linesize;
314 }
315
316 __DSB();
317 __ISB();
318 #endif
319 }
320
321
322 /**
323 \brief D-Cache Clean by address
324 \details Cleans D-Cache for the given address
325 \param[in] addr address (aligned to 32-byte boundary)
326 \param[in] dsize size of memory block (in number of bytes)
327 */
SCB_CleanDCache_by_Addr(uint32_t * addr,int32_t dsize)328 __STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize)
329 {
330 #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
331 int32_t op_size = dsize;
332 uint32_t op_addr = (uint32_t) addr;
333 int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */
334
335 __DSB();
336
337 while (op_size > 0) {
338 SCB->DCCMVAC = op_addr;
339 op_addr += (uint32_t)linesize;
340 op_size -= linesize;
341 }
342
343 __DSB();
344 __ISB();
345 #endif
346 }
347
348
349 /**
350 \brief D-Cache Clean and Invalidate by address
351 \details Cleans and invalidates D_Cache for the given address
352 \param[in] addr address (aligned to 32-byte boundary)
353 \param[in] dsize size of memory block (in number of bytes)
354 */
SCB_CleanInvalidateDCache_by_Addr(uint32_t * addr,int32_t dsize)355 __STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
356 {
357 #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
358 int32_t op_size = dsize;
359 uint32_t op_addr = (uint32_t) addr;
360 int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */
361
362 __DSB();
363
364 while (op_size > 0) {
365 SCB->DCCIMVAC = op_addr;
366 op_addr += (uint32_t)linesize;
367 op_size -= linesize;
368 }
369
370 __DSB();
371 __ISB();
372 #endif
373 }
374
375
376 /*@} end of CMSIS_Core_CacheFunctions */
377
378 #ifdef __cplusplus
379 }
380 #endif
381
382 #endif /* __CORE_CACHE_H */
383
384