1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 
7 /***********************************************************************************************************************
8  * Includes   <System Includes> , "Project Includes"
9  **********************************************************************************************************************/
10 #include "bsp_api.h"
11 
12 /***********************************************************************************************************************
13  * Macro definitions
14  **********************************************************************************************************************/
15 #define BSP_PRV_SCTLR_ELX_BIT_I                 (0x1000U)
16 #define BSP_PRV_SCTLR_ELX_BIT_C                 (0x4U)
17 #define BSP_PRV_SCTLR_ELX_BIT_M                 (0x1U)
18 
19 #define BSP_PRV_CLIDR_CTYPE_OFFSET              (3U)
20 #define BSP_PRV_CLIDR_CTYPE_MASK                (7U)
21 #define BSP_PRV_CLIDR_CTYPE_EXIST_DATACACHE     (2U)
22 #define BSP_PRV_CLIDR_LOC_OFFSET                (24U)
23 #define BSP_PRV_CLIDR_LOC_MASK                  (7U)
24 
25 #define BSP_PRV_CCSIDR_LINESIZE_OFFSET          (0U)
26 #define BSP_PRV_CCSIDR_LINESIZE_MASK            (7U)
27 #define BSP_PRV_CCSIDR_LINESIZE_ACTUAL_VALUE    (4U)
28 #define BSP_PRV_CCSIDR_ASSOCIATIVITY_OFFSET     (3U)
29 #define BSP_PRV_CCSIDR_ASSOCIATIVITY_MASK       (0x3FFU)
30 #define BSP_PRV_CCSIDR_NUMSETS_OFFSET           (13U)
31 #define BSP_PRV_CCSIDR_NUMSETS_MASK             (0x7FFFU)
32 #define BSP_PRV_CCSIDR_SHIFT_MAX                (32U)
33 
34 #define BSP_PRV_CSSELR_LEVEL_OFFSET             (1U)
35 
36 #define BSP_PRV_CTR_IMINLINE_OFFSET             (0U)
37 #define BSP_PRV_CTR_IMINLINE_MASK               (0xFU)
38 #define BSP_PRV_CTR_IMINLINE_NUMBER_OF_WORDS    (4U)
39 #define BSP_PRV_CTR_IMINLINE_ADDRESS_MASK       (1U)
40 #define BSP_PRV_CTR_DMINLINE_OFFSET             (16U)
41 #define BSP_PRV_CTR_DMINLINE_MASK               (0xFU)
42 #define BSP_PRV_CTR_DMINLINE_NUMBER_OF_WORDS    (4U)
43 #define BSP_PRV_CTR_DMINLINE_ADDRESS_MASK       (1U)
44 
45 /***********************************************************************************************************************
46  * Typedef definitions
47  **********************************************************************************************************************/
48 
49 /***********************************************************************************************************************
50  * Exported global variables (to be accessed by other files)
51  **********************************************************************************************************************/
52 
53 /***********************************************************************************************************************
54  * Private global variables and functions
55  **********************************************************************************************************************/
56 
57 /*******************************************************************************************************************//**
58  * @addtogroup BSP_MCU
59  * @{
60  **********************************************************************************************************************/
61 
62 /*******************************************************************************************************************//**
63  * Enable instruction caching.
64  **********************************************************************************************************************/
R_BSP_CacheEnableInst(void)65 void R_BSP_CacheEnableInst (void)
66 {
67     uintptr_t sctlr;
68 
69     sctlr  = __get_SCTLR();
70     sctlr |= BSP_PRV_SCTLR_ELX_BIT_I;
71 
72     __asm volatile ("DSB SY");
73 
74     __set_SCTLR(sctlr);
75 
76     __asm volatile ("ISB SY");
77 }
78 
79 /*******************************************************************************************************************//**
80  * Enable data caching.
81  **********************************************************************************************************************/
R_BSP_CacheEnableData(void)82 void R_BSP_CacheEnableData (void)
83 {
84     uintptr_t sctlr;
85 
86     sctlr  = __get_SCTLR();
87     sctlr |= BSP_PRV_SCTLR_ELX_BIT_C;
88 
89     __asm volatile ("DSB SY");
90 
91     __set_SCTLR(sctlr);
92 
93     __asm volatile ("ISB SY");
94 }
95 
96 /*******************************************************************************************************************//**
97  * Enable memory protect.
98  **********************************************************************************************************************/
R_BSP_CacheEnableMemoryProtect(void)99 void R_BSP_CacheEnableMemoryProtect (void)
100 {
101     uintptr_t sctlr;
102 
103     sctlr  = __get_SCTLR();
104     sctlr |= BSP_PRV_SCTLR_ELX_BIT_M;
105 
106     __asm volatile ("DSB SY");
107 
108     __set_SCTLR(sctlr);
109 
110     __asm volatile ("ISB SY");
111 }
112 
113 /*******************************************************************************************************************//**
114  * Disable instruction caching.
115  **********************************************************************************************************************/
R_BSP_CacheDisableInst(void)116 void R_BSP_CacheDisableInst (void)
117 {
118     uintptr_t sctlr;
119 
120     sctlr  = __get_SCTLR();
121     sctlr &= ~(BSP_PRV_SCTLR_ELX_BIT_I);
122 
123     __asm volatile ("DSB SY");
124 
125     __set_SCTLR(sctlr);
126 
127     __asm volatile ("ISB SY");
128 }
129 
130 /*******************************************************************************************************************//**
131  * Disable data caching.
132  **********************************************************************************************************************/
R_BSP_CacheDisableData(void)133 void R_BSP_CacheDisableData (void)
134 {
135     uintptr_t sctlr;
136 
137     sctlr  = __get_SCTLR();
138     sctlr &= ~(BSP_PRV_SCTLR_ELX_BIT_C);
139 
140     __asm volatile ("DSB SY");
141 
142     __set_SCTLR(sctlr);
143 
144     __asm volatile ("ISB SY");
145 }
146 
147 /*******************************************************************************************************************//**
148  * Disable memory protect.
149  **********************************************************************************************************************/
R_BSP_CacheDisableMemoryProtect(void)150 void R_BSP_CacheDisableMemoryProtect (void)
151 {
152     uintptr_t sctlr;
153 
154     sctlr  = __get_SCTLR();
155     sctlr &= ~(BSP_PRV_SCTLR_ELX_BIT_M);
156 
157     __asm volatile ("DSB SY");
158 
159     __set_SCTLR(sctlr);
160 
161     __asm volatile ("ISB SY");
162 }
163 
164 /*******************************************************************************************************************//**
165  * Clean data cache by set/way.
166  * Clean means writing the cache data to memory and clear the dirty bits
167  * if there is a discrepancy between the cache and memory data.
168  **********************************************************************************************************************/
R_BSP_CacheCleanAll(void)169 void R_BSP_CacheCleanAll (void)
170 {
171     uintptr_t clidr;
172     uintptr_t clidr_loc;
173     uintptr_t clidr_ctype;
174     uintptr_t clidr_ctype_shift;
175 
176     uintptr_t csselr;
177     uintptr_t csselr_level;
178 
179     uintptr_t ccsidr;
180     uintptr_t ccsidr_linesize;
181     uintptr_t ccsidr_associativity;
182     uintptr_t ccsidr_associativity_clz;
183     uintptr_t ccsidr_associativity_value;
184     uintptr_t ccsidr_associativity_msb;
185     uintptr_t ccsidr_numsets;
186     uintptr_t ccsidr_numsets_total;
187 
188     uintptr_t dccsw;
189 
190     __asm volatile ("DSB SY");
191 
192     __set_ICIALLU(0);
193 
194     __asm volatile ("DMB SY");
195 
196     /* Reads the maximum level of cache implemented */
197     clidr     = __get_CLIDR();
198     clidr_loc = (clidr >> BSP_PRV_CLIDR_LOC_OFFSET) & BSP_PRV_CLIDR_LOC_MASK;
199 
200     /* If the cache does not exist, do not process */
201     if (0 != clidr_loc)
202     {
203         /* Loop until all levels of cache are processed */
204         for (csselr = 0; csselr < clidr_loc; csselr++)
205         {
206             /* Read the current level cache type */
207             clidr_ctype_shift = csselr * BSP_PRV_CLIDR_CTYPE_OFFSET;
208             clidr_ctype       = (clidr >> clidr_ctype_shift) & BSP_PRV_CLIDR_CTYPE_MASK;
209 
210             /* If no data cache exists in the current level of cache, do not process  */
211             if (BSP_PRV_CLIDR_CTYPE_EXIST_DATACACHE <= clidr_ctype)
212             {
213                 /* Set the current level to Cache Size Selection Register */
214                 csselr_level = csselr << BSP_PRV_CSSELR_LEVEL_OFFSET;
215                 __set_CSSELR(csselr_level);
216 
217                 __asm volatile ("DSB SY");
218 
219                 /* Read the line size, number of ways, and number of sets for the current level of cache */
220                 ccsidr          = __get_CCSIDR();
221                 ccsidr_linesize = ((ccsidr >> BSP_PRV_CCSIDR_LINESIZE_OFFSET) & BSP_PRV_CCSIDR_LINESIZE_MASK) +
222                                   BSP_PRV_CCSIDR_LINESIZE_ACTUAL_VALUE;
223                 ccsidr_associativity = (ccsidr >> BSP_PRV_CCSIDR_ASSOCIATIVITY_OFFSET) &
224                                        BSP_PRV_CCSIDR_ASSOCIATIVITY_MASK;
225                 ccsidr_numsets = (ccsidr >> BSP_PRV_CCSIDR_NUMSETS_OFFSET) & BSP_PRV_CCSIDR_NUMSETS_MASK;
226 
227                 /* Count consecutive number of 0 starting from the most significant bit (CLZ = Count Leading Zeros) */
228                 ccsidr_associativity_clz = __CLZ((uint32_t) ccsidr_associativity);
229                 if (BSP_PRV_CCSIDR_SHIFT_MAX == ccsidr_associativity_clz)
230                 {
231                     ccsidr_associativity_clz--;
232                 }
233                 else
234                 {
235                     /* Do Nothing */
236                 }
237 
238                 /* Loop until all sets are processed */
239                 while (1)
240                 {
241                     /* Working copy of number of ways */
242                     ccsidr_associativity_value = ccsidr_associativity;
243 
244                     /* Loop until all ways are processed */
245                     while (1)
246                     {
247                         ccsidr_associativity_msb = (ccsidr_associativity_value << ccsidr_associativity_clz) |
248                                                    csselr_level;                                /* Left shift way */
249                         ccsidr_numsets_total = ccsidr_numsets << ccsidr_linesize;               /* Left shift set */
250                         dccsw                = ccsidr_associativity_msb | ccsidr_numsets_total; /* Combine set and way */
251 
252                         /* DCCSW - Data or unified Cache line Clean by Set/Way */
253                         __set_DCCSW(dccsw);
254 
255                         if (0 != ccsidr_associativity_value)
256                         {
257                             ccsidr_associativity_value--;
258                         }
259                         else
260                         {
261                             break;
262                         }
263                     }
264 
265                     if (0 != ccsidr_numsets)
266                     {
267                         ccsidr_numsets--;
268                     }
269                     else
270                     {
271                         break;
272                     }
273                 }
274             }
275             else
276             {
277                 /* Do Nothing */
278             }
279         }
280 
281         __asm volatile ("DSB SY");
282         __asm volatile ("ISB SY");
283     }
284     else
285     {
286         /* Do Nothing */
287     }
288 }
289 
290 /*******************************************************************************************************************//**
291  * Invalidate data cache by set/way.
292  * Also Invalidate instruction cache.
293  *
294  * Invalidate means to delete cache data.
295  **********************************************************************************************************************/
R_BSP_CacheInvalidateAll(void)296 void R_BSP_CacheInvalidateAll (void)
297 {
298     uintptr_t clidr;
299     uintptr_t clidr_loc;
300     uintptr_t clidr_ctype;
301     uintptr_t clidr_ctype_shift;
302 
303     uintptr_t csselr;
304     uintptr_t csselr_level;
305 
306     uintptr_t ccsidr;
307     uintptr_t ccsidr_linesize;
308     uintptr_t ccsidr_associativity;
309     uintptr_t ccsidr_associativity_clz;
310     uintptr_t ccsidr_associativity_value;
311     uintptr_t ccsidr_associativity_msb;
312     uintptr_t ccsidr_numsets;
313     uintptr_t ccsidr_numsets_total;
314 
315     uintptr_t dcisw;
316 
317     __asm volatile ("DSB SY");
318 
319     __set_ICIALLU(0);
320 
321     __asm volatile ("DMB SY");
322 
323     /* Reads the maximum level of cache implemented */
324     clidr     = __get_CLIDR();
325     clidr_loc = (clidr >> BSP_PRV_CLIDR_LOC_OFFSET) & BSP_PRV_CLIDR_LOC_MASK;
326 
327     /* If the cache does not exist, do not process */
328     if (0 != clidr_loc)
329     {
330         /* Loop until all levels of cache are processed */
331         for (csselr = 0; csselr < clidr_loc; csselr++)
332         {
333             /* Read the current level cache type */
334             clidr_ctype_shift = csselr * BSP_PRV_CLIDR_CTYPE_OFFSET;
335             clidr_ctype       = (clidr >> clidr_ctype_shift) & BSP_PRV_CLIDR_CTYPE_MASK;
336 
337             /* If no data cache exists in the current level of cache, do not process  */
338             if (BSP_PRV_CLIDR_CTYPE_EXIST_DATACACHE <= clidr_ctype)
339             {
340                 /* Set the current level to Cache Size Selection Register */
341                 csselr_level = csselr << BSP_PRV_CSSELR_LEVEL_OFFSET;
342                 __set_CSSELR(csselr_level);
343 
344                 __asm volatile ("DSB SY");
345 
346                 /* Read the line size, number of ways, and number of sets for the current level of cache */
347                 ccsidr          = __get_CCSIDR();
348                 ccsidr_linesize = ((ccsidr >> BSP_PRV_CCSIDR_LINESIZE_OFFSET) & BSP_PRV_CCSIDR_LINESIZE_MASK) +
349                                   BSP_PRV_CCSIDR_LINESIZE_ACTUAL_VALUE;
350                 ccsidr_associativity = (ccsidr >> BSP_PRV_CCSIDR_ASSOCIATIVITY_OFFSET) &
351                                        BSP_PRV_CCSIDR_ASSOCIATIVITY_MASK;
352                 ccsidr_numsets = (ccsidr >> BSP_PRV_CCSIDR_NUMSETS_OFFSET) & BSP_PRV_CCSIDR_NUMSETS_MASK;
353 
354                 /* Count consecutive number of 0 starting from the most significant bit (CLZ = Count Leading Zeros) */
355                 ccsidr_associativity_clz = __CLZ((uint32_t) ccsidr_associativity);
356                 if (BSP_PRV_CCSIDR_SHIFT_MAX == ccsidr_associativity_clz)
357                 {
358                     ccsidr_associativity_clz--;
359                 }
360                 else
361                 {
362                     /* Do Nothing */
363                 }
364 
365                 /* Loop until all sets are processed */
366                 while (1)
367                 {
368                     /* Working copy of number of ways */
369                     ccsidr_associativity_value = ccsidr_associativity;
370 
371                     /* Loop until all ways are processed */
372                     while (1)
373                     {
374                         ccsidr_associativity_msb = (ccsidr_associativity_value << ccsidr_associativity_clz) |
375                                                    csselr_level;                                /* Left shift way */
376                         ccsidr_numsets_total = ccsidr_numsets << ccsidr_linesize;               /* Left shift set */
377                         dcisw                = ccsidr_associativity_msb | ccsidr_numsets_total; /* Combine set and way */
378 
379                         /* DCISW - Data or unified Cache line Invalidate by Set/Way */
380                         __set_DCISW(dcisw);
381 
382                         if (0 != ccsidr_associativity_value)
383                         {
384                             ccsidr_associativity_value--;
385                         }
386                         else
387                         {
388                             break;
389                         }
390                     }
391 
392                     if (0 != ccsidr_numsets)
393                     {
394                         ccsidr_numsets--;
395                     }
396                     else
397                     {
398                         break;
399                     }
400                 }
401             }
402             else
403             {
404                 /* Do Nothing */
405             }
406         }
407 
408         __asm volatile ("DSB SY");
409         __asm volatile ("ISB SY");
410     }
411     else
412     {
413         /* Do Nothing */
414     }
415 }
416 
417 /*******************************************************************************************************************//**
418  * Clean and Invalidate data cache by set/way.
419  * Also Invalidate instruction cache.
420  *
421  * Clean means writing the cache data to memory and clear the dirty bits
422  * if there is a discrepancy between the cache and memory data.
423  *
424  * Invalidate means to delete cache data.
425  **********************************************************************************************************************/
R_BSP_CacheCleanInvalidateAll(void)426 void R_BSP_CacheCleanInvalidateAll (void)
427 {
428     uintptr_t clidr;
429     uintptr_t clidr_loc;
430     uintptr_t clidr_ctype;
431     uintptr_t clidr_ctype_shift;
432 
433     uintptr_t csselr;
434     uintptr_t csselr_level;
435 
436     uintptr_t ccsidr;
437     uintptr_t ccsidr_linesize;
438     uintptr_t ccsidr_associativity;
439     uintptr_t ccsidr_associativity_clz;
440     uintptr_t ccsidr_associativity_value;
441     uintptr_t ccsidr_associativity_msb;
442     uintptr_t ccsidr_numsets;
443     uintptr_t ccsidr_numsets_total;
444 
445     uintptr_t dccisw;
446 
447     __asm volatile ("DSB SY");
448 
449     __set_ICIALLU(0);
450 
451     __asm volatile ("DMB SY");
452 
453     /* Reads the maximum level of cache implemented */
454     clidr     = __get_CLIDR();
455     clidr_loc = (clidr >> BSP_PRV_CLIDR_LOC_OFFSET) & BSP_PRV_CLIDR_LOC_MASK;
456 
457     /* If the cache does not exist, do not process */
458     if (0 != clidr_loc)
459     {
460         /* Loop until all levels of cache are processed */
461         for (csselr = 0; csselr < clidr_loc; csselr++)
462         {
463             /* Read the current level cache type */
464             clidr_ctype_shift = csselr * BSP_PRV_CLIDR_CTYPE_OFFSET;
465             clidr_ctype       = (clidr >> clidr_ctype_shift) & BSP_PRV_CLIDR_CTYPE_MASK;
466 
467             /* If no data cache exists in the current level of cache, do not process  */
468             if (BSP_PRV_CLIDR_CTYPE_EXIST_DATACACHE <= clidr_ctype)
469             {
470                 /* Set the current level to Cache Size Selection Register */
471                 csselr_level = csselr << BSP_PRV_CSSELR_LEVEL_OFFSET;
472                 __set_CSSELR(csselr_level);
473 
474                 __asm volatile ("DSB SY");
475 
476                 /* Read the line size, number of ways, and number of sets for the current level of cache */
477                 ccsidr          = __get_CCSIDR();
478                 ccsidr_linesize = ((ccsidr >> BSP_PRV_CCSIDR_LINESIZE_OFFSET) & BSP_PRV_CCSIDR_LINESIZE_MASK) +
479                                   BSP_PRV_CCSIDR_LINESIZE_ACTUAL_VALUE;
480                 ccsidr_associativity = (ccsidr >> BSP_PRV_CCSIDR_ASSOCIATIVITY_OFFSET) &
481                                        BSP_PRV_CCSIDR_ASSOCIATIVITY_MASK;
482                 ccsidr_numsets = (ccsidr >> BSP_PRV_CCSIDR_NUMSETS_OFFSET) & BSP_PRV_CCSIDR_NUMSETS_MASK;
483 
484                 /* Count consecutive number of 0 starting from the most significant bit (CLZ = Count Leading Zeros) */
485                 ccsidr_associativity_clz = __CLZ((uint32_t) ccsidr_associativity);
486                 if (BSP_PRV_CCSIDR_SHIFT_MAX == ccsidr_associativity_clz)
487                 {
488                     ccsidr_associativity_clz--;
489                 }
490                 else
491                 {
492                     /* Do Nothing */
493                 }
494 
495                 /* Loop until all sets are processed */
496                 while (1)
497                 {
498                     /* Working copy of number of ways */
499                     ccsidr_associativity_value = ccsidr_associativity;
500 
501                     /* Loop until all ways are processed */
502                     while (1)
503                     {
504                         ccsidr_associativity_msb = (ccsidr_associativity_value << ccsidr_associativity_clz) |
505                                                    csselr_level;                                /* Left shift way */
506                         ccsidr_numsets_total = ccsidr_numsets << ccsidr_linesize;               /* Left shift set */
507                         dccisw               = ccsidr_associativity_msb | ccsidr_numsets_total; /* Combine set and way */
508 
509                         /* DCCISW - Data or unified Cache line Clean and Invalidate by Set/Way */
510                         __set_DCCISW(dccisw);
511 
512                         if (0 != ccsidr_associativity_value)
513                         {
514                             ccsidr_associativity_value--;
515                         }
516                         else
517                         {
518                             break;
519                         }
520                     }
521 
522                     if (0 != ccsidr_numsets)
523                     {
524                         ccsidr_numsets--;
525                     }
526                     else
527                     {
528                         break;
529                     }
530                 }
531             }
532             else
533             {
534                 /* Do Nothing */
535             }
536         }
537 
538         __asm volatile ("DSB SY");
539         __asm volatile ("ISB SY");
540     }
541     else
542     {
543         /* Do Nothing */
544     }
545 }
546 
547 /*******************************************************************************************************************//**
548  * Clean data cache and Invalidate instruction cache by address.
549  *
550  * Clean means writing the cache data to memory and clear the dirty bits
551  * if there is a discrepancy between the cache and memory data.
552  *
553  * Invalidate means to delete cache data.
554  *
555  * @param[in] base_address    Start address of area you want to Clean.
556  * @param[in] length          Size of area you want to Clean.
557  **********************************************************************************************************************/
R_BSP_CacheCleanRange(uintptr_t base_address,uintptr_t length)558 void R_BSP_CacheCleanRange (uintptr_t base_address, uintptr_t length)
559 {
560     uintptr_t end_address;
561     uintptr_t ctr;
562 
563     uintptr_t dminline;
564     uintptr_t dminline_size;
565     uintptr_t dccvac;
566 
567     uintptr_t iminline;
568     uintptr_t iminline_size;
569     uintptr_t icivau;
570 
571     end_address = base_address + length;
572 
573     /* Calculate data cache line size */
574     ctr           = __get_CTR();
575     dminline      = (ctr >> BSP_PRV_CTR_DMINLINE_OFFSET) & BSP_PRV_CTR_DMINLINE_MASK;
576     dminline_size = (BSP_PRV_CTR_DMINLINE_NUMBER_OF_WORDS << dminline);
577 
578     /* Align base address with cache line */
579     dccvac = base_address & ~(dminline_size - BSP_PRV_CTR_DMINLINE_ADDRESS_MASK);
580     do
581     {
582         /* Data or unified Cache line Clean by VA to PoC */
583         __set_DCCVAC(dccvac);
584 
585         dccvac += dminline_size;       /* Next data line */
586     } while (end_address > dccvac);
587 
588     __asm volatile ("DSB SY");
589 
590     /* Calculate instruction cache line size */
591     iminline      = (ctr >> BSP_PRV_CTR_IMINLINE_OFFSET) & BSP_PRV_CTR_IMINLINE_MASK;
592     iminline_size = (BSP_PRV_CTR_IMINLINE_NUMBER_OF_WORDS << iminline);
593 
594     /* Align base address with cache line */
595     icivau = base_address & ~(iminline_size - BSP_PRV_CTR_IMINLINE_ADDRESS_MASK);
596     do
597     {
598         /* Instruction Cache line Invalidate by VA to PoU */
599         __set_ICIVAU(icivau);
600 
601         icivau += iminline_size;       /* Next data line */
602     } while (end_address == icivau);
603 
604     __asm volatile ("DSB SY");
605     __asm volatile ("ISB SY");
606 }
607 
608 /*******************************************************************************************************************//**
609  * Invalidate instruction and data cache by address.
610  *
611  * Invalidate means to delete cache data.
612  *
613  * @param[in] base_address    Start address of area you want to Invalidate.
614  * @param[in] length          Size of area you want to Invalidate.
615  **********************************************************************************************************************/
R_BSP_CacheInvalidateRange(uintptr_t base_address,uintptr_t length)616 void R_BSP_CacheInvalidateRange (uintptr_t base_address, uintptr_t length)
617 {
618     uintptr_t end_address;
619     uintptr_t ctr;
620 
621     uintptr_t dminline;
622     uintptr_t dminline_size;
623     uintptr_t dcivac;
624 
625     uintptr_t iminline;
626     uintptr_t iminline_size;
627     uintptr_t icivau;
628 
629     end_address = base_address + length;
630 
631     /* Calculate data cache line size */
632     ctr           = __get_CTR();
633     dminline      = (ctr >> BSP_PRV_CTR_DMINLINE_OFFSET) & BSP_PRV_CTR_DMINLINE_MASK;
634     dminline_size = (BSP_PRV_CTR_DMINLINE_NUMBER_OF_WORDS << dminline);
635 
636     /* Align base address with cache line */
637     dcivac = base_address & ~(dminline_size - BSP_PRV_CTR_DMINLINE_ADDRESS_MASK);
638     do
639     {
640         /* Data or unified Cache line Invalidate by VA to PoC */
641         __set_DCIVAC(dcivac);
642 
643         dcivac += dminline_size;       /* Next data line */
644     } while (end_address > dcivac);
645 
646     __asm volatile ("DSB SY");
647 
648     /* Calculate instruction cache line size */
649     iminline      = (ctr >> BSP_PRV_CTR_IMINLINE_OFFSET) & BSP_PRV_CTR_IMINLINE_MASK;
650     iminline_size = (BSP_PRV_CTR_IMINLINE_NUMBER_OF_WORDS << iminline);
651 
652     /* Align base address with cache line */
653     icivau = base_address & ~(iminline_size - BSP_PRV_CTR_IMINLINE_ADDRESS_MASK);
654     do
655     {
656         /* Instruction Cache line Invalidate by VA to PoU */
657         __set_ICIVAU(icivau);
658 
659         icivau += iminline_size;       /* Next data line */
660     } while (end_address == icivau);
661 
662     __asm volatile ("DSB SY");
663     __asm volatile ("ISB SY");
664 }
665 
666 /*******************************************************************************************************************//**
667  * Clean and Invalidate data cache and Invalidate instruction cache by address.
668  *
669  * Clean means writing the cache data to memory and clear the dirty bits
670  * if there is a discrepancy between the cache and memory data.
671  *
672  * Invalidate means to delete cache data.
673  *
674  * @param[in] base_address    Start address of area you want to Clean and Invalidate.
675  * @param[in] length          Size of area you want to Clean and Invalidate.
676  **********************************************************************************************************************/
R_BSP_CacheCleanInvalidateRange(uintptr_t base_address,uintptr_t length)677 void R_BSP_CacheCleanInvalidateRange (uintptr_t base_address, uintptr_t length)
678 {
679     uintptr_t end_address;
680     uintptr_t ctr;
681 
682     uintptr_t dminline;
683     uintptr_t dminline_size;
684     uintptr_t dccivac;
685 
686     uintptr_t iminline;
687     uintptr_t iminline_size;
688     uintptr_t icivau;
689 
690     end_address = base_address + length;
691 
692     /* Calculate data cache line size */
693     ctr           = __get_CTR();
694     dminline      = (ctr >> BSP_PRV_CTR_DMINLINE_OFFSET) & BSP_PRV_CTR_DMINLINE_MASK;
695     dminline_size = (BSP_PRV_CTR_DMINLINE_NUMBER_OF_WORDS << dminline);
696 
697     /* Align base address with cache line */
698     dccivac = base_address & ~(dminline_size - BSP_PRV_CTR_DMINLINE_ADDRESS_MASK);
699     do
700     {
701         /* Data or unified Cache line Clean and Invalidate by VA to PoC */
702         __set_DCCIVAC(dccivac);
703 
704         dccivac += dminline_size;      /* Next data line */
705     } while (end_address > dccivac);
706 
707     __asm volatile ("DSB SY");
708 
709     /* Calculate instruction cache line size */
710     iminline      = (ctr >> BSP_PRV_CTR_IMINLINE_OFFSET) & BSP_PRV_CTR_IMINLINE_MASK;
711     iminline_size = (BSP_PRV_CTR_IMINLINE_NUMBER_OF_WORDS << iminline);
712 
713     /* Align base address with cache line */
714     icivau = base_address & ~(iminline_size - BSP_PRV_CTR_IMINLINE_ADDRESS_MASK);
715     do
716     {
717         /* Instruction Cache line Invalidate by VA to PoU */
718         __set_ICIVAU(icivau);
719 
720         icivau += iminline_size;       /* Next data line */
721     } while (end_address == icivau);
722 
723     __asm volatile ("DSB SY");
724     __asm volatile ("ISB SY");
725 }
726 
727 /*******************************************************************************************************************//**
728  * Powers on and off the L3 cache way.
729  * CA55 only.
730  **********************************************************************************************************************/
R_BSP_CacheL3PowerCtrl(void)731 void R_BSP_CacheL3PowerCtrl (void)
732 {
733     r_bsp_cache_l3_power_ctrl();
734 }
735 
736 /*******************************************************************************************************************//**
737  * @} (end addtogroup BSP_MCU)
738  **********************************************************************************************************************/
739