1 /*
2  * Copyright 2016-2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_cache.h"
9 /*******************************************************************************
10  * Definitions
11  ******************************************************************************/
12 
13 /* Component ID definition, used by tools. */
14 #ifndef FSL_COMPONENT_ID
15 #define FSL_COMPONENT_ID "platform.drivers.cache_lmem"
16 #endif
17 
18 #define L1CACHE_ONEWAYSIZE_BYTE      (4096U)       /*!< Cache size is 4K-bytes one way. */
19 #define L1CACHE_CODEBUSADDR_BOUNDARY (0x1FFFFFFFU) /*!< The processor code bus address boundary. */
20 
21 /*******************************************************************************
22  * Code
23  ******************************************************************************/
24 #if (FSL_FEATURE_SOC_LMEM_COUNT == 1)
25 /*!
26  * brief Enables the processor code bus cache.
27  *
28  */
L1CACHE_EnableCodeCache(void)29 void L1CACHE_EnableCodeCache(void)
30 {
31     if (0U == (LMEM->PCCCR & LMEM_PCCCR_ENCACHE_MASK))
32     {
33         /* First, invalidate the entire cache. */
34         L1CACHE_InvalidateCodeCache();
35 
36         /* Now enable the cache. */
37         LMEM->PCCCR |= LMEM_PCCCR_ENCACHE_MASK;
38     }
39 }
40 
41 /*!
42  * brief Disables the processor code bus cache.
43  *
44  */
L1CACHE_DisableCodeCache(void)45 void L1CACHE_DisableCodeCache(void)
46 {
47     /* First, push any modified contents. */
48     L1CACHE_CleanCodeCache();
49 
50     /* Now disable the cache. */
51     LMEM->PCCCR &= ~LMEM_PCCCR_ENCACHE_MASK;
52 }
53 
54 /*!
55  * brief Invalidates the processor code bus cache.
56  *
57  */
L1CACHE_InvalidateCodeCache(void)58 void L1CACHE_InvalidateCodeCache(void)
59 {
60     /* Enables the processor code bus to invalidate all lines in both ways.
61     and Initiate the processor code bus code cache command. */
62     LMEM->PCCCR |= LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_GO_MASK;
63 
64     /* Wait until the cache command completes. */
65     while ((LMEM->PCCCR & LMEM_PCCCR_GO_MASK) != 0U)
66     {
67     }
68 
69     /* As a precaution clear the bits to avoid inadvertently re-running this command. */
70     LMEM->PCCCR &= ~(LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK);
71 }
72 
73 /*!
74  * brief Invalidates processor code bus cache by range.
75  *
76  * param address The physical address of cache.
77  * param size_byte size of the memory to be invalidated.
78  * note Address and size should be aligned to "L1CODCACHE_LINESIZE_BYTE".
79  * The startAddr here will be forced to align to L1CODEBUSCACHE_LINESIZE_BYTE if
80  * startAddr is not aligned. For the size_byte, application should make sure the
81  * alignment or make sure the right operation order if the size_byte is not aligned.
82  */
L1CACHE_InvalidateCodeCacheByRange(uint32_t address,uint32_t size_byte)83 void L1CACHE_InvalidateCodeCacheByRange(uint32_t address, uint32_t size_byte)
84 {
85     uint32_t endAddr = address + size_byte;
86     uint32_t pccReg  = 0;
87     /* Align address to cache line size. */
88     uint32_t startAddr = address & ~((uint32_t)L1CODEBUSCACHE_LINESIZE_BYTE - 1U);
89 
90     /* Set the invalidate by line command and use the physical address. */
91     pccReg       = (LMEM->PCCLCR & ~LMEM_PCCLCR_LCMD_MASK) | LMEM_PCCLCR_LCMD(1) | LMEM_PCCLCR_LADSEL_MASK;
92     LMEM->PCCLCR = pccReg;
93 
94     while (startAddr < endAddr)
95     {
96         /* Set the address and initiate the command. */
97         LMEM->PCCSAR = (startAddr & LMEM_PCCSAR_PHYADDR_MASK) | LMEM_PCCSAR_LGO_MASK;
98 
99         /* Wait until the cache command completes. */
100         while ((LMEM->PCCSAR & LMEM_PCCSAR_LGO_MASK) != 0U)
101         {
102         }
103         startAddr += (uint32_t)L1CODEBUSCACHE_LINESIZE_BYTE;
104     }
105 }
106 
107 /*!
108  * brief Cleans the processor code bus cache.
109  *
110  */
L1CACHE_CleanCodeCache(void)111 void L1CACHE_CleanCodeCache(void)
112 {
113     /* Enable the processor code bus to push all modified lines. */
114     LMEM->PCCCR |= LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_GO_MASK;
115 
116     /* Wait until the cache command completes. */
117     while ((LMEM->PCCCR & LMEM_PCCCR_GO_MASK) != 0U)
118     {
119     }
120 
121     /* As a precaution clear the bits to avoid inadvertently re-running this command. */
122     LMEM->PCCCR &= ~(LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK);
123 }
124 
125 /*!
126  * brief Cleans processor code bus cache by range.
127  *
128  * param address The physical address of cache.
129  * param size_byte size of the memory to be cleaned.
130  * note Address and size should be aligned to "L1CODEBUSCACHE_LINESIZE_BYTE".
131  * The startAddr here will be forced to align to L1CODEBUSCACHE_LINESIZE_BYTE if
132  * startAddr is not aligned. For the size_byte, application should make sure the
133  * alignment or make sure the right operation order if the size_byte is not aligned.
134  */
L1CACHE_CleanCodeCacheByRange(uint32_t address,uint32_t size_byte)135 void L1CACHE_CleanCodeCacheByRange(uint32_t address, uint32_t size_byte)
136 {
137     uint32_t endAddr = address + size_byte;
138     uint32_t pccReg  = 0;
139     /* Align address to cache line size. */
140     uint32_t startAddr = address & ~((uint32_t)L1CODEBUSCACHE_LINESIZE_BYTE - 1U);
141 
142     /* Set the push by line command. */
143     pccReg       = (LMEM->PCCLCR & ~LMEM_PCCLCR_LCMD_MASK) | LMEM_PCCLCR_LCMD(2) | LMEM_PCCLCR_LADSEL_MASK;
144     LMEM->PCCLCR = pccReg;
145 
146     while (startAddr < endAddr)
147     {
148         /* Set the address and initiate the command. */
149         LMEM->PCCSAR = (startAddr & LMEM_PCCSAR_PHYADDR_MASK) | LMEM_PCCSAR_LGO_MASK;
150 
151         /* Wait until the cache command completes. */
152         while ((LMEM->PCCSAR & LMEM_PCCSAR_LGO_MASK) != 0U)
153         {
154         }
155         startAddr += (uint32_t)L1CODEBUSCACHE_LINESIZE_BYTE;
156     }
157 }
158 
159 /*!
160  * brief Cleans and invalidates the processor code bus cache.
161  *
162  */
L1CACHE_CleanInvalidateCodeCache(void)163 void L1CACHE_CleanInvalidateCodeCache(void)
164 {
165     /* Push and invalidate all. */
166     LMEM->PCCCR |= LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK |
167                    LMEM_PCCCR_GO_MASK;
168 
169     /* Wait until the cache command completes. */
170     while ((LMEM->PCCCR & LMEM_PCCCR_GO_MASK) != 0U)
171     {
172     }
173 
174     /* As a precaution clear the bits to avoid inadvertently re-running this command. */
175     LMEM->PCCCR &= ~(LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK);
176 }
177 
178 /*!
179  * brief Cleans and invalidate processor code bus cache by range.
180  *
181  * param address The physical address of cache.
182  * param size_byte size of the memory to be Cleaned and Invalidated.
183  * note Address and size should be aligned to "L1CODEBUSCACHE_LINESIZE_BYTE".
184  * The startAddr here will be forced to align to L1CODEBUSCACHE_LINESIZE_BYTE if
185  * startAddr is not aligned. For the size_byte, application should make sure the
186  * alignment or make sure the right operation order if the size_byte is not aligned.
187  */
L1CACHE_CleanInvalidateCodeCacheByRange(uint32_t address,uint32_t size_byte)188 void L1CACHE_CleanInvalidateCodeCacheByRange(uint32_t address, uint32_t size_byte)
189 {
190     uint32_t endAddr = address + size_byte;
191     uint32_t pccReg  = 0;
192     /* Align address to cache line size. */
193     uint32_t startAddr = address & ~((uint32_t)L1CODEBUSCACHE_LINESIZE_BYTE - 1U);
194 
195     /* Set the push by line command. */
196     pccReg       = (LMEM->PCCLCR & ~LMEM_PCCLCR_LCMD_MASK) | LMEM_PCCLCR_LCMD(3) | LMEM_PCCLCR_LADSEL_MASK;
197     LMEM->PCCLCR = pccReg;
198 
199     while (startAddr < endAddr)
200     {
201         /* Set the address and initiate the command. */
202         LMEM->PCCSAR = (startAddr & LMEM_PCCSAR_PHYADDR_MASK) | LMEM_PCCSAR_LGO_MASK;
203 
204         /* Wait until the cache command completes. */
205         while ((LMEM->PCCSAR & LMEM_PCCSAR_LGO_MASK) != 0U)
206         {
207         }
208         startAddr += (uint32_t)L1CODEBUSCACHE_LINESIZE_BYTE;
209     }
210 }
211 
212 #if defined(FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE) && FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE
213 /*!
214  * brief Enables the processor system bus cache.
215  *
216  */
L1CACHE_EnableSystemCache(void)217 void L1CACHE_EnableSystemCache(void)
218 {
219     /* Only enable when not enabled. */
220     if (0U == (LMEM->PSCCR & LMEM_PSCCR_ENCACHE_MASK))
221     {
222         /* First, invalidate the entire cache. */
223         L1CACHE_InvalidateSystemCache();
224 
225         /* Now enable the cache. */
226         LMEM->PSCCR |= LMEM_PSCCR_ENCACHE_MASK;
227     }
228 }
229 
230 /*!
231  * brief Disables the processor system bus cache.
232  *
233  */
L1CACHE_DisableSystemCache(void)234 void L1CACHE_DisableSystemCache(void)
235 {
236     /* First, push any modified contents. */
237     L1CACHE_CleanSystemCache();
238 
239     /* Now disable the cache. */
240     LMEM->PSCCR &= ~LMEM_PSCCR_ENCACHE_MASK;
241 }
242 
243 /*!
244  * brief Invalidates the processor system bus cache.
245  *
246  */
L1CACHE_InvalidateSystemCache(void)247 void L1CACHE_InvalidateSystemCache(void)
248 {
249     /* Enables the processor system bus to invalidate all lines in both ways.
250     and Initiate the processor system bus cache command. */
251     LMEM->PSCCR |= LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_GO_MASK;
252 
253     /* Wait until the cache command completes */
254     while ((LMEM->PSCCR & LMEM_PSCCR_GO_MASK) != 0U)
255     {
256     }
257 
258     /* As a precaution clear the bits to avoid inadvertently re-running this command. */
259     LMEM->PSCCR &= ~(LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK);
260 }
261 
262 /*!
263  * brief Invalidates processor system bus cache by range.
264  *
265  * param address The physical address of cache.
266  * param size_byte size of the memory to be invalidated.
267  * note Address and size should be aligned to "L1SYSTEMBUSCACHE_LINESIZE_BYTE".
268  * The startAddr here will be forced to align to L1SYSTEMBUSCACHE_LINESIZE_BYTE if
269  * startAddr is not aligned. For the size_byte, application should make sure the
270  * alignment or make sure the right operation order if the size_byte is not aligned.
271  */
L1CACHE_InvalidateSystemCacheByRange(uint32_t address,uint32_t size_byte)272 void L1CACHE_InvalidateSystemCacheByRange(uint32_t address, uint32_t size_byte)
273 {
274     uint32_t endAddr = address + size_byte;
275     uint32_t pscReg  = 0;
276     uint32_t startAddr =
277         address & ~((uint32_t)L1SYSTEMBUSCACHE_LINESIZE_BYTE - 1U); /* Align address to cache line size */
278 
279     /* Set the invalidate by line command and use the physical address. */
280     pscReg       = (LMEM->PSCLCR & ~LMEM_PSCLCR_LCMD_MASK) | LMEM_PSCLCR_LCMD(1) | LMEM_PSCLCR_LADSEL_MASK;
281     LMEM->PSCLCR = pscReg;
282 
283     while (startAddr < endAddr)
284     {
285         /* Set the address and initiate the command. */
286         LMEM->PSCSAR = (startAddr & LMEM_PSCSAR_PHYADDR_MASK) | LMEM_PSCSAR_LGO_MASK;
287 
288         /* Wait until the cache command completes. */
289         while ((LMEM->PSCSAR & LMEM_PSCSAR_LGO_MASK) != 0U)
290         {
291         }
292         startAddr += (uint32_t)L1SYSTEMBUSCACHE_LINESIZE_BYTE;
293     }
294 }
295 
296 /*!
297  * brief Cleans the processor system bus cache.
298  *
299  */
L1CACHE_CleanSystemCache(void)300 void L1CACHE_CleanSystemCache(void)
301 {
302     /* Enable the processor system bus to push all modified lines. */
303     LMEM->PSCCR |= LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_GO_MASK;
304 
305     /* Wait until the cache command completes. */
306     while ((LMEM->PSCCR & LMEM_PSCCR_GO_MASK) != 0U)
307     {
308     }
309 
310     /* As a precaution clear the bits to avoid inadvertently re-running this command. */
311     LMEM->PSCCR &= ~(LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK);
312 }
313 
314 /*!
315  * brief Cleans processor system bus cache by range.
316  *
317  * param address The physical address of cache.
318  * param size_byte size of the memory to be cleaned.
319  * note Address and size should be aligned to "L1SYSTEMBUSCACHE_LINESIZE_BYTE".
320  * The startAddr here will be forced to align to L1SYSTEMBUSCACHE_LINESIZE_BYTE if
321  * startAddr is not aligned. For the size_byte, application should make sure the
322  * alignment or make sure the right operation order if the size_byte is not aligned.
323  */
L1CACHE_CleanSystemCacheByRange(uint32_t address,uint32_t size_byte)324 void L1CACHE_CleanSystemCacheByRange(uint32_t address, uint32_t size_byte)
325 {
326     uint32_t endAddr = address + size_byte;
327     uint32_t pscReg  = 0;
328     uint32_t startAddr =
329         address & ~((uint32_t)L1SYSTEMBUSCACHE_LINESIZE_BYTE - 1U); /* Align address to cache line size. */
330 
331     /* Set the push by line command. */
332     pscReg       = (LMEM->PSCLCR & ~LMEM_PSCLCR_LCMD_MASK) | LMEM_PSCLCR_LCMD(2) | LMEM_PSCLCR_LADSEL_MASK;
333     LMEM->PSCLCR = pscReg;
334 
335     while (startAddr < endAddr)
336     {
337         /* Set the address and initiate the command. */
338         LMEM->PSCSAR = (startAddr & LMEM_PSCSAR_PHYADDR_MASK) | LMEM_PSCSAR_LGO_MASK;
339 
340         /* Wait until the cache command completes. */
341         while ((LMEM->PSCSAR & LMEM_PSCSAR_LGO_MASK) != 0U)
342         {
343         }
344         startAddr += (uint32_t)L1SYSTEMBUSCACHE_LINESIZE_BYTE;
345     }
346 }
347 
348 /*!
349  * brief Cleans and invalidates the processor system bus cache.
350  *
351  */
L1CACHE_CleanInvalidateSystemCache(void)352 void L1CACHE_CleanInvalidateSystemCache(void)
353 {
354     /* Push and invalidate all. */
355     LMEM->PSCCR |= LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK |
356                    LMEM_PSCCR_GO_MASK;
357 
358     /* Wait until the cache command completes. */
359     while ((LMEM->PSCCR & LMEM_PSCCR_GO_MASK) != 0U)
360     {
361     }
362 
363     /* As a precaution clear the bits to avoid inadvertently re-running this command. */
364     LMEM->PSCCR &= ~(LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK);
365 }
366 
367 /*!
368  * brief Cleans and Invalidates processor system bus cache by range.
369  *
370  * param address The physical address of cache.
371  * param size_byte size of the memory to be Clean and Invalidated.
372  * note Address and size should be aligned to "L1SYSTEMBUSCACHE_LINESIZE_BYTE".
373  * The startAddr here will be forced to align to L1SYSTEMBUSCACHE_LINESIZE_BYTE if
374  * startAddr is not aligned. For the size_byte, application should make sure the
375  * alignment or make sure the right operation order if the size_byte is not aligned.
376  */
L1CACHE_CleanInvalidateSystemCacheByRange(uint32_t address,uint32_t size_byte)377 void L1CACHE_CleanInvalidateSystemCacheByRange(uint32_t address, uint32_t size_byte)
378 {
379     uint32_t endAddr = address + size_byte;
380     uint32_t pscReg  = 0;
381     uint32_t startAddr =
382         address & ~((uint32_t)L1SYSTEMBUSCACHE_LINESIZE_BYTE - 1U); /* Align address to cache line size. */
383 
384     /* Set the push by line command. */
385     pscReg       = (LMEM->PSCLCR & ~LMEM_PSCLCR_LCMD_MASK) | LMEM_PSCLCR_LCMD(3) | LMEM_PSCLCR_LADSEL_MASK;
386     LMEM->PSCLCR = pscReg;
387 
388     while (startAddr < endAddr)
389     {
390         /* Set the address and initiate the command. */
391         LMEM->PSCSAR = (startAddr & LMEM_PSCSAR_PHYADDR_MASK) | LMEM_PSCSAR_LGO_MASK;
392 
393         /* Wait until the cache command completes. */
394         while ((LMEM->PSCSAR & LMEM_PSCSAR_LGO_MASK) != 0U)
395         {
396         }
397         startAddr += (uint32_t)L1SYSTEMBUSCACHE_LINESIZE_BYTE;
398     }
399 }
400 
401 #endif /* FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE */
402 #endif /* FSL_FEATURE_SOC_LMEM_COUNT == 1 */
403 
404 /*!
405  * brief Invalidates cortex-m4 L1 instrument cache by range.
406  *
407  * param address  The start address of the memory to be invalidated.
408  * param size_byte  The memory size.
409  * note The start address and size_byte should be 16-Byte(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) aligned.
410  */
L1CACHE_InvalidateICacheByRange(uint32_t address,uint32_t size_byte)411 void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte)
412 {
413 #if (FSL_FEATURE_SOC_LMEM_COUNT == 1)
414     uint32_t endAddr = address + size_byte;
415     uint32_t size    = size_byte;
416 
417     if (endAddr <= L1CACHE_CODEBUSADDR_BOUNDARY)
418     {
419         L1CACHE_InvalidateCodeCacheByRange(address, size);
420     }
421     else if (address <= L1CACHE_CODEBUSADDR_BOUNDARY)
422     {
423         size = L1CACHE_CODEBUSADDR_BOUNDARY - address;
424         L1CACHE_InvalidateCodeCacheByRange(address, size);
425 #if defined(FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE) && FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE
426         size = size_byte - size;
427         L1CACHE_InvalidateSystemCacheByRange((L1CACHE_CODEBUSADDR_BOUNDARY + 1U), size);
428 #endif /* FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE */
429     }
430     else
431     {
432 #if defined(FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE) && FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE
433         L1CACHE_InvalidateSystemCacheByRange(address, size);
434 #endif /* FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE */
435     }
436 #endif /* FSL_FEATURE_SOC_LMEM_COUNT == 1 */
437 }
438 
439 /*!
440  * brief Cleans cortex-m4 L1 data cache by range.
441  *
442  * param address  The start address of the memory to be cleaned.
443  * param size_byte  The memory size.
444  * note The start address and size_byte should be 16-Byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
445  */
L1CACHE_CleanDCacheByRange(uint32_t address,uint32_t size_byte)446 void L1CACHE_CleanDCacheByRange(uint32_t address, uint32_t size_byte)
447 {
448 #if (FSL_FEATURE_SOC_LMEM_COUNT == 1)
449     uint32_t endAddr = address + size_byte;
450     uint32_t size    = size_byte;
451 
452     if (endAddr <= L1CACHE_CODEBUSADDR_BOUNDARY)
453     {
454         L1CACHE_CleanCodeCacheByRange(address, size);
455     }
456     else if (address <= L1CACHE_CODEBUSADDR_BOUNDARY)
457     {
458         size = L1CACHE_CODEBUSADDR_BOUNDARY - address;
459         L1CACHE_CleanCodeCacheByRange(address, size);
460 #if defined(FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE) && FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE
461         size = size_byte - size;
462         L1CACHE_CleanSystemCacheByRange((L1CACHE_CODEBUSADDR_BOUNDARY + 1U), size);
463 #endif /* FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE */
464     }
465     else
466     {
467 #if defined(FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE) && FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE
468         L1CACHE_CleanSystemCacheByRange(address, size);
469 #endif /* FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE */
470     }
471 #endif /* FSL_FEATURE_SOC_LMEM_COUNT == 1 */
472 }
473 
474 /*!
475  * brief Cleans and Invalidates cortex-m4 L1 data cache by range.
476  *
477  * param address  The start address of the memory to be clean and invalidated.
478  * param size_byte  The memory size.
479  * note The start address and size_byte should be 16-Byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
480  */
L1CACHE_CleanInvalidateDCacheByRange(uint32_t address,uint32_t size_byte)481 void L1CACHE_CleanInvalidateDCacheByRange(uint32_t address, uint32_t size_byte)
482 {
483 #if (FSL_FEATURE_SOC_LMEM_COUNT == 1)
484     uint32_t endAddr = address + size_byte;
485     uint32_t size    = size_byte;
486 
487     if (endAddr <= L1CACHE_CODEBUSADDR_BOUNDARY)
488     {
489         L1CACHE_CleanInvalidateCodeCacheByRange(address, size);
490     }
491     else if (address <= L1CACHE_CODEBUSADDR_BOUNDARY)
492     {
493         size = L1CACHE_CODEBUSADDR_BOUNDARY - address;
494         L1CACHE_CleanInvalidateCodeCacheByRange(address, size);
495 #if defined(FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE) && FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE
496         size = size_byte - size;
497         L1CACHE_CleanInvalidateSystemCacheByRange((L1CACHE_CODEBUSADDR_BOUNDARY + 1U), size);
498 #endif /* FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE */
499     }
500     else
501     {
502 #if defined(FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE) && FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE
503         L1CACHE_CleanInvalidateSystemCacheByRange(address, size);
504 #endif /* FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE */
505     }
506 #endif /* FSL_FEATURE_SOC_LMEM_COUNT == 1 */
507 }
508