Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:58

0001 /*
0002  * Copyright 2016-2021 NXP
0003  * All rights reserved.
0004  *
0005  * SPDX-License-Identifier: BSD-3-Clause
0006  */
0007 
0008 #include "fsl_cache.h"
0009 
0010 /*******************************************************************************
0011  * Definitions
0012  ******************************************************************************/
0013 
0014 /* Component ID definition, used by tools. */
0015 #ifndef FSL_COMPONENT_ID
0016 #define FSL_COMPONENT_ID "platform.drivers.cache_armv7_m7"
0017 #endif
0018 
0019 #if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
0020 #define L2CACHE_OPERATION_TIMEOUT 0xFFFFFU
0021 #define L2CACHE_8WAYS_MASK        0xFFU
0022 #define L2CACHE_16WAYS_MASK       0xFFFFU
0023 #define L2CACHE_SMALLWAYS_NUM     8U
0024 #define L2CACHE_1KBCOVERTOB       1024U
0025 #define L2CACHE_SAMLLWAYS_SIZE    16U
0026 #define L2CACHE_LOCKDOWN_REGNUM   8 /*!< Lock down register numbers.*/
0027                                     /*******************************************************************************
0028                                      * Prototypes
0029                                      ******************************************************************************/
0030 /*!
0031  * @brief Set for all ways and waiting for the operation finished.
0032  *  This is provided for all the background operations.
0033  *
0034  * @param auxCtlReg  The auxiliary control register.
0035  * @param regAddr The register address to be operated.
0036  */
0037 static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr);
0038 
0039 /*!
0040  * @brief Invalidates the Level 2 cache line by physical address.
0041  * This function invalidates a cache line by physcial address.
0042  *
0043  * @param address  The physical addderss of the cache.
0044  *        The format of the address shall be :
0045  *        bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
0046  *              Tag        |    index    |      0
0047  *  Note: the physical address shall be aligned to the line size - 32B (256 bit).
0048  *  so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
0049  *  If the input address is not aligned, it will be changed to 32-byte aligned address.
0050  *  The n is varies according to the index width.
0051  * @return The actual 32-byte aligned physical address be operated.
0052  */
0053 static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address);
0054 
0055 /*!
0056  * @brief Cleans the Level 2 cache line based on the physical address.
0057  * This function cleans a cache line based on a physcial address.
0058  *
0059  * @param address  The physical addderss of the cache.
0060  *        The format of the address shall be :
0061  *        bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
0062  *              Tag        |    index    |      0
0063  *  Note: the physical address shall be aligned to the line size - 32B (256 bit).
0064  *  so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
0065  *  If the input address is not aligned, it will be changed to 32-byte aligned address.
0066  *  The n is varies according to the index width.
0067  * @return The actual 32-byte aligned physical address be operated.
0068  */
0069 static uint32_t L2CACHE_CleanLineByAddr(uint32_t address);
0070 
0071 /*!
0072  * @brief Cleans and invalidates the Level 2 cache line based on the physical address.
0073  * This function cleans and invalidates a cache line based on a physcial address.
0074  *
0075  * @param address  The physical addderss of the cache.
0076  *        The format of the address shall be :
0077  *        bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
0078  *              Tag        |    index    |      0
0079  *  Note: the physical address shall be aligned to the line size - 32B (256 bit).
0080  *  so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
0081  *  If the input address is not aligned, it will be changed to 32-byte aligned address.
0082  *  The n is varies according to the index width.
0083  * @return The actual 32-byte aligned physical address be operated.
0084  */
0085 static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address);
0086 
0087 /*!
0088  * @brief Gets the number of the Level 2 cache and the way size.
0089  * This function cleans and invalidates a cache line based on a physcial address.
0090  *
0091  * @param num_ways  The number of the cache way.
0092  * @param size_way  The way size.
0093  */
0094 static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way);
0095 /*******************************************************************************
0096  * Code
0097  ******************************************************************************/
0098 static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr)
0099 {
0100     uint16_t mask    = L2CACHE_8WAYS_MASK;
0101     uint32_t timeout = L2CACHE_OPERATION_TIMEOUT;
0102 
0103     /* Check the ways used at first. */
0104     if (auxCtlReg & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
0105     {
0106         mask = L2CACHE_16WAYS_MASK;
0107     }
0108 
0109     /* Set the opeartion for all ways/entries of the cache. */
0110     *(uint32_t *)regAddr = mask;
0111     /* Waiting for until the operation is complete. */
0112     while ((*(volatile uint32_t *)regAddr & mask) && timeout)
0113     {
0114         __ASM("nop");
0115         timeout--;
0116     }
0117 }
0118 
0119 static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address)
0120 {
0121     /* Align the address first. */
0122     address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
0123     /* Invalidate the cache line by physical address. */
0124     L2CACHEC->REG7_INV_PA = address;
0125 
0126     return address;
0127 }
0128 
0129 static uint32_t L2CACHE_CleanLineByAddr(uint32_t address)
0130 {
0131     /* Align the address first. */
0132     address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
0133     /* Invalidate the cache line by physical address. */
0134     L2CACHEC->REG7_CLEAN_PA = address;
0135 
0136     return address;
0137 }
0138 
0139 static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address)
0140 {
0141     /* Align the address first. */
0142     address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
0143     /* Clean and invalidate the cache line by physical address. */
0144     L2CACHEC->REG7_CLEAN_INV_PA = address;
0145 
0146     return address;
0147 }
0148 
0149 static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way)
0150 {
0151     assert(num_ways);
0152     assert(size_way);
0153 
0154     uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
0155                       L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
0156     uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
0157                     L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
0158 
0159     *num_ways = (number + 1) * L2CACHE_SMALLWAYS_NUM;
0160     if (!size)
0161     {
0162         /* 0 internally mapped to the same size as 1 - 16KB.*/
0163         size += 1;
0164     }
0165     *size_way = (1 << (size - 1)) * L2CACHE_SAMLLWAYS_SIZE * L2CACHE_1KBCOVERTOB;
0166 }
0167 
0168 /*!
0169  * brief Initializes the level 2 cache controller module.
0170  *
0171  * param config Pointer to configuration structure. See "l2cache_config_t".
0172  */
0173 void L2CACHE_Init(l2cache_config_t *config)
0174 {
0175     assert(config);
0176 
0177     uint16_t waysNum = 0xFFU; /* Default use the 8-way mask. */
0178     uint8_t count;
0179     uint32_t auxReg = 0;
0180 
0181     /*The aux register must be configured when the cachec is disabled
0182      * So disable first if the cache controller is enabled.
0183      */
0184     if (L2CACHEC->REG1_CONTROL & L2CACHEC_REG1_CONTROL_CE_MASK)
0185     {
0186         L2CACHE_Disable();
0187     }
0188 
0189     /* Unlock all entries. */
0190     if (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
0191     {
0192         waysNum = 0xFFFFU;
0193     }
0194 
0195     for (count = 0; count < L2CACHE_LOCKDOWN_REGNUM; count++)
0196     {
0197         L2CACHE_LockdownByWayEnable(count, waysNum, false);
0198     }
0199 
0200     /* Set the ways and way-size etc. */
0201     auxReg = L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY(config->wayNum) |
0202              L2CACHEC_REG1_AUX_CONTROL_WAYSIZE(config->waySize) | L2CACHEC_REG1_AUX_CONTROL_CRP(config->repacePolicy) |
0203              L2CACHEC_REG1_AUX_CONTROL_IPE(config->istrPrefetchEnable) |
0204              L2CACHEC_REG1_AUX_CONTROL_DPE(config->dataPrefetchEnable) |
0205              L2CACHEC_REG1_AUX_CONTROL_NLE(config->nsLockdownEnable) |
0206              L2CACHEC_REG1_AUX_CONTROL_FWA(config->writeAlloc) | L2CACHEC_REG1_AUX_CONTROL_HPSDRE(config->writeAlloc);
0207     L2CACHEC->REG1_AUX_CONTROL = auxReg;
0208 
0209     /* Set the tag/data ram latency. */
0210     if (config->lateConfig)
0211     {
0212         uint32_t data = 0;
0213         /* Tag latency. */
0214         data = L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) |
0215                L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) |
0216                L2CACHEC_REG1_TAG_RAM_CONTROL_RAL(config->lateConfig->tagReadLate) |
0217                L2CACHEC_REG1_TAG_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
0218         L2CACHEC->REG1_TAG_RAM_CONTROL = data;
0219         /* Data latency. */
0220         data = L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) |
0221                L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) |
0222                L2CACHEC_REG1_DATA_RAM_CONTROL_RAL(config->lateConfig->dataReadLate) |
0223                L2CACHEC_REG1_DATA_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
0224         L2CACHEC->REG1_DATA_RAM_CONTROL = data;
0225     }
0226 }
0227 
0228 /*!
0229  * brief Gets an available default settings for the cache controller.
0230  *
0231  * This function initializes the cache controller configuration structure with default settings.
0232  * The default values are:
0233  * code
0234  *   config->waysNum = kL2CACHE_8ways;
0235  *   config->waySize = kL2CACHE_32KbSize;
0236  *   config->repacePolicy = kL2CACHE_Roundrobin;
0237  *   config->lateConfig = NULL;
0238  *   config->istrPrefetchEnable = false;
0239  *   config->dataPrefetchEnable = false;
0240  *   config->nsLockdownEnable = false;
0241  *   config->writeAlloc = kL2CACHE_UseAwcache;
0242  * endcode
0243  * param config Pointer to the configuration structure.
0244  */
0245 void L2CACHE_GetDefaultConfig(l2cache_config_t *config)
0246 {
0247     assert(config);
0248 
0249     /* Initializes the configure structure to zero. */
0250     memset(config, 0, sizeof(*config));
0251 
0252     uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
0253                       L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
0254     uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
0255                     L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
0256 
0257     /* Get the default value */
0258     config->wayNum             = (l2cache_way_num_t)number;
0259     config->waySize            = (l2cache_way_size)size;
0260     config->repacePolicy       = kL2CACHE_Roundrobin;
0261     config->lateConfig         = NULL;
0262     config->istrPrefetchEnable = false;
0263     config->dataPrefetchEnable = false;
0264     config->nsLockdownEnable   = false;
0265     config->writeAlloc         = kL2CACHE_UseAwcache;
0266 }
0267 
0268 /*!
0269  * brief Enables the level 2 cache controller.
0270  * This function enables the cache controller. Must be written using a secure access.
0271  * If write with a Non-secure access will cause a DECERR response.
0272  *
0273  */
0274 void L2CACHE_Enable(void)
0275 {
0276     /* Invalidate first. */
0277     L2CACHE_Invalidate();
0278     /* Enable the level 2 cache controller. */
0279     L2CACHEC->REG1_CONTROL = L2CACHEC_REG1_CONTROL_CE_MASK;
0280 }
0281 
0282 /*!
0283  * brief Disables the level 2 cache controller.
0284  * This function disables the cache controller. Must be written using a secure access.
0285  * If write with a Non-secure access will cause a DECERR response.
0286  *
0287  */
0288 void L2CACHE_Disable(void)
0289 {
0290     /* First CleanInvalidate all enties in the cache. */
0291     L2CACHE_CleanInvalidate();
0292     /* Disable the level 2 cache controller. */
0293     L2CACHEC->REG1_CONTROL &= ~L2CACHEC_REG1_CONTROL_CE_MASK;
0294     /* DSB - data sync barrier.*/
0295     __DSB();
0296 }
0297 
0298 /*!
0299  * brief Invalidates the Level 2 cache.
0300  * This function invalidates all entries in cache.
0301  *
0302  */
0303 void L2CACHE_Invalidate(void)
0304 {
0305     /* Invalidate all entries in cache. */
0306     L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_INV_WAY);
0307     /* Cache sync. */
0308     L2CACHEC->REG7_CACHE_SYNC = 0;
0309 }
0310 
0311 /*!
0312  * brief Cleans the level 2 cache controller.
0313  * This function cleans all entries in the level 2 cache controller.
0314  *
0315  */
0316 void L2CACHE_Clean(void)
0317 {
0318     /* Clean all entries of the cache. */
0319     L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_WAY);
0320     /* Cache sync. */
0321     L2CACHEC->REG7_CACHE_SYNC = 0;
0322 }
0323 
0324 /*!
0325  * brief Cleans and invalidates the level 2 cache controller.
0326  * This function cleans and invalidates all entries in the level 2 cache controller.
0327  *
0328  */
0329 void L2CACHE_CleanInvalidate(void)
0330 {
0331     /* Clean all entries of the cache. */
0332     L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_INV_WAY);
0333     /* Cache sync. */
0334     L2CACHEC->REG7_CACHE_SYNC = 0;
0335 }
0336 
0337 /*!
0338  * brief Invalidates the Level 2 cache lines in the range of two physical addresses.
0339  * This function invalidates all cache lines between two physical addresses.
0340  *
0341  * param address  The start address of the memory to be invalidated.
0342  * param size_byte  The memory size.
0343  * note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
0344  * The startAddr here will be forced to align to L2 line size if startAddr
0345  * is not aligned. For the size_byte, application should make sure the
0346  * alignment or make sure the right operation order if the size_byte is not aligned.
0347  */
0348 void L2CACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
0349 {
0350     uint32_t endAddr = address + size_byte;
0351 
0352     /* Invalidate addresses in the range. */
0353     while (address < endAddr)
0354     {
0355         address = L2CACHE_InvalidateLineByAddr(address);
0356         /* Update the size. */
0357         address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
0358     }
0359 
0360     /* Cache sync. */
0361     L2CACHEC->REG7_CACHE_SYNC = 0;
0362 }
0363 
0364 /*!
0365  * brief Cleans the Level 2 cache lines in the range of two physical addresses.
0366  * This function cleans all cache lines between two physical addresses.
0367  *
0368  * param address  The start address of the memory to be cleaned.
0369  * param size_byte  The memory size.
0370  * note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
0371  * The startAddr here will be forced to align to L2 line size if startAddr
0372  * is not aligned. For the size_byte, application should make sure the
0373  * alignment or make sure the right operation order if the size_byte is not aligned.
0374  */
0375 void L2CACHE_CleanByRange(uint32_t address, uint32_t size_byte)
0376 {
0377     uint32_t num_ways = 0;
0378     uint32_t size_way = 0;
0379     uint32_t endAddr  = address + size_byte;
0380 
0381     /* Get the number and size of the cache way. */
0382     L2CACHE_GetWayNumSize(&num_ways, &size_way);
0383 
0384     /* Check if the clean size is over the cache size. */
0385     if ((endAddr - address) > num_ways * size_way)
0386     {
0387         L2CACHE_Clean();
0388         return;
0389     }
0390 
0391     /* Clean addresses in the range. */
0392     while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
0393     {
0394         /* Clean the address in the range. */
0395         address = L2CACHE_CleanLineByAddr(address);
0396         address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
0397     }
0398 
0399     L2CACHEC->REG7_CACHE_SYNC = 0;
0400 }
0401 
0402 /*!
0403  * brief Cleans and invalidates the Level 2 cache lines in the range of two physical addresses.
0404  * This function cleans and invalidates all cache lines between two physical addresses.
0405  *
0406  * param address  The start address of the memory to be cleaned and invalidated.
0407  * param size_byte  The memory size.
0408  * note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
0409  * The startAddr here will be forced to align to L2 line size if startAddr
0410  * is not aligned. For the size_byte, application should make sure the
0411  * alignment or make sure the right operation order if the size_byte is not aligned.
0412  */
0413 void L2CACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
0414 {
0415     uint32_t num_ways = 0;
0416     uint32_t size_way = 0;
0417     uint32_t endAddr  = address + size_byte;
0418 
0419     /* Get the number and size of the cache way. */
0420     L2CACHE_GetWayNumSize(&num_ways, &size_way);
0421 
0422     /* Check if the clean size is over the cache size. */
0423     if ((endAddr - address) > num_ways * size_way)
0424     {
0425         L2CACHE_CleanInvalidate();
0426         return;
0427     }
0428 
0429     /* Clean addresses in the range. */
0430     while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
0431     {
0432         /* Clean the address in the range. */
0433         address = L2CACHE_CleanInvalidateLineByAddr(address);
0434         address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
0435     }
0436 
0437     L2CACHEC->REG7_CACHE_SYNC = 0;
0438 }
0439 
0440 /*!
0441  * brief Enables or disables to lock down the data and instruction by way.
0442  * This function locks down the cached instruction/data by way and prevent the adresses from
0443  * being allocated and prevent dara from being evicted out of the level 2 cache.
0444  * But the normal cache maintenance operations that invalidate, clean or clean
0445  * and validate cache contents affect the locked-down cache lines as normal.
0446  *
0447  * param masterId  The master id, range from 0 ~ 7.
0448  * param mask  The ways to be enabled or disabled to lockdown.
0449  *               each bit in value is related to each way of the cache. for example:
0450  *               value: bit 0  ------ way 0.
0451  *               value: bit 1  ------ way 1.
0452  *               --------------------------
0453  *               value: bit 15 ------ way 15.
0454  * Note: please make sure the value setting is align with your supported ways.
0455  * param enable  True enable the lockdown, false to disable the lockdown.
0456  */
0457 void L2CACHE_LockdownByWayEnable(uint32_t masterId, uint32_t mask, bool enable)
0458 {
0459     uint8_t num_ways = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
0460                        L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
0461     num_ways = (num_ways + 1) * L2CACHE_SMALLWAYS_NUM;
0462 
0463     assert(mask < (1U << num_ways));
0464     assert(masterId < L2CACHE_LOCKDOWN_REGNUM);
0465 
0466     uint32_t dataReg = L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN;
0467     uint32_t istrReg = L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN;
0468 
0469     if (enable)
0470     {
0471         /* Data lockdown. */
0472         L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg | mask;
0473         /* Instruction lockdown. */
0474         L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg | mask;
0475     }
0476     else
0477     {
0478         /* Data lockdown. */
0479         L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg & ~mask;
0480         /* Instruction lockdown. */
0481         L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg & ~mask;
0482     }
0483 }
0484 #endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
0485 
0486 /*!
0487  * brief Invalidate cortex-m7 L1 instruction cache by range.
0488  *
0489  * param address  The start address of the memory to be invalidated.
0490  * param size_byte  The memory size.
0491  * note The start address and size_byte should be 32-byte(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) aligned.
0492  * The startAddr here will be forced to align to L1 I-cache line size if
0493  * startAddr is not aligned. For the size_byte, application should make sure the
0494  * alignment or make sure the right operation order if the size_byte is not aligned.
0495  */
0496 void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte)
0497 {
0498 #if (__DCACHE_PRESENT == 1U)
0499     uint32_t addr      = address & ~((uint32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE - 1U);
0500     uint32_t align_len = address - addr;
0501     int32_t size       = (int32_t)size_byte + (int32_t)align_len;
0502 
0503     __DSB();
0504     while (size > 0)
0505     {
0506         SCB->ICIMVAU = addr;
0507         addr += (uint32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE;
0508         size -= (int32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE;
0509     }
0510     __DSB();
0511     __ISB();
0512 #endif
0513 }
0514 
0515 /*!
0516  * brief Invalidates all instruction caches by range.
0517  *
0518  * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
0519  *
0520  * param address The physical address.
0521  * param size_byte size of the memory to be invalidated.
0522  * note address and size should be aligned to cache line size
0523  *  32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
0524  * to align to the cache line size if startAddr is not aligned. For the size_byte, application should
0525  * make sure the alignment or make sure the right operation order if the size_byte is not aligned.
0526  */
0527 void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
0528 {
0529 #if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
0530 #if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
0531     L2CACHE_InvalidateByRange(address, size_byte);
0532 #endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
0533 #endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
0534 
0535     L1CACHE_InvalidateICacheByRange(address, size_byte);
0536 }
0537 
0538 /*!
0539  * brief Invalidates all data caches by range.
0540  *
0541  * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
0542  *
0543  * param address The physical address.
0544  * param size_byte size of the memory to be invalidated.
0545  * note address and size should be aligned to cache line size
0546  *  32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
0547  * to align to the cache line size if startAddr is not aligned. For the size_byte, application should
0548  * make sure the alignment or make sure the right operation order if the size_byte is not aligned.
0549  */
0550 void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
0551 {
0552 #if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
0553 #if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
0554     L2CACHE_InvalidateByRange(address, size_byte);
0555 #endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
0556 #endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
0557     L1CACHE_InvalidateDCacheByRange(address, size_byte);
0558 }
0559 
0560 /*!
0561  * brief Cleans all data caches by range.
0562  *
0563  * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
0564  *
0565  * param address The physical address.
0566  * param size_byte size of the memory to be cleaned.
0567  * note address and size should be aligned to cache line size
0568  *  32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
0569  * to align to the cache line size if startAddr is not aligned. For the size_byte, application should
0570  * make sure the alignment or make sure the right operation order if the size_byte is not aligned.
0571  */
0572 void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte)
0573 {
0574     L1CACHE_CleanDCacheByRange(address, size_byte);
0575 #if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
0576 #if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
0577     L2CACHE_CleanByRange(address, size_byte);
0578 #endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
0579 #endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
0580 }
0581 
0582 /*!
0583  * brief Cleans and Invalidates all data caches by range.
0584  *
0585  * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
0586  *
0587  * param address The physical address.
0588  * param size_byte size of the memory to be cleaned and invalidated.
0589  * note address and size should be aligned to cache line size
0590  *  32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
0591  * to align to the cache line size if startAddr is not aligned. For the size_byte, application should
0592  * make sure the alignment or make sure the right operation order if the size_byte is not aligned.
0593  */
0594 void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
0595 {
0596     L1CACHE_CleanInvalidateDCacheByRange(address, size_byte);
0597 #if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
0598 #if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
0599     L2CACHE_CleanInvalidateByRange(address, size_byte);
0600 #endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
0601 #endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
0602 }