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