fsl_cache.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. /*
  2. * Copyright 2016-2021 NXP
  3. * All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. */
  7. #include "fsl_cache.h"
  8. /*******************************************************************************
  9. * Definitions
  10. ******************************************************************************/
  11. /* Component ID definition, used by tools. */
  12. #ifndef FSL_COMPONENT_ID
  13. #define FSL_COMPONENT_ID "platform.drivers.cache_armv7_m7"
  14. #endif
  15. #if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
  16. #define L2CACHE_OPERATION_TIMEOUT 0xFFFFFU
  17. #define L2CACHE_8WAYS_MASK 0xFFU
  18. #define L2CACHE_16WAYS_MASK 0xFFFFU
  19. #define L2CACHE_SMALLWAYS_NUM 8U
  20. #define L2CACHE_1KBCOVERTOB 1024U
  21. #define L2CACHE_SAMLLWAYS_SIZE 16U
  22. #define L2CACHE_LOCKDOWN_REGNUM 8 /*!< Lock down register numbers.*/
  23. /*******************************************************************************
  24. * Prototypes
  25. ******************************************************************************/
  26. /*!
  27. * @brief Set for all ways and waiting for the operation finished.
  28. * This is provided for all the background operations.
  29. *
  30. * @param auxCtlReg The auxiliary control register.
  31. * @param regAddr The register address to be operated.
  32. */
  33. static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr);
  34. /*!
  35. * @brief Invalidates the Level 2 cache line by physical address.
  36. * This function invalidates a cache line by physcial address.
  37. *
  38. * @param address The physical addderss of the cache.
  39. * The format of the address shall be :
  40. * bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
  41. * Tag | index | 0
  42. * Note: the physical address shall be aligned to the line size - 32B (256 bit).
  43. * so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
  44. * If the input address is not aligned, it will be changed to 32-byte aligned address.
  45. * The n is varies according to the index width.
  46. * @return The actual 32-byte aligned physical address be operated.
  47. */
  48. static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address);
  49. /*!
  50. * @brief Cleans the Level 2 cache line based on the physical address.
  51. * This function cleans a cache line based on a physcial address.
  52. *
  53. * @param address The physical addderss of the cache.
  54. * The format of the address shall be :
  55. * bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
  56. * Tag | index | 0
  57. * Note: the physical address shall be aligned to the line size - 32B (256 bit).
  58. * so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
  59. * If the input address is not aligned, it will be changed to 32-byte aligned address.
  60. * The n is varies according to the index width.
  61. * @return The actual 32-byte aligned physical address be operated.
  62. */
  63. static uint32_t L2CACHE_CleanLineByAddr(uint32_t address);
  64. /*!
  65. * @brief Cleans and invalidates the Level 2 cache line based on the physical address.
  66. * This function cleans and invalidates a cache line based on a physcial address.
  67. *
  68. * @param address The physical addderss of the cache.
  69. * The format of the address shall be :
  70. * bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
  71. * Tag | index | 0
  72. * Note: the physical address shall be aligned to the line size - 32B (256 bit).
  73. * so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
  74. * If the input address is not aligned, it will be changed to 32-byte aligned address.
  75. * The n is varies according to the index width.
  76. * @return The actual 32-byte aligned physical address be operated.
  77. */
  78. static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address);
  79. /*!
  80. * @brief Gets the number of the Level 2 cache and the way size.
  81. * This function cleans and invalidates a cache line based on a physcial address.
  82. *
  83. * @param num_ways The number of the cache way.
  84. * @param size_way The way size.
  85. */
  86. static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way);
  87. /*******************************************************************************
  88. * Code
  89. ******************************************************************************/
  90. static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr)
  91. {
  92. uint16_t mask = L2CACHE_8WAYS_MASK;
  93. uint32_t timeout = L2CACHE_OPERATION_TIMEOUT;
  94. /* Check the ways used at first. */
  95. if (auxCtlReg & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
  96. {
  97. mask = L2CACHE_16WAYS_MASK;
  98. }
  99. /* Set the opeartion for all ways/entries of the cache. */
  100. *(uint32_t *)regAddr = mask;
  101. /* Waiting for until the operation is complete. */
  102. while ((*(volatile uint32_t *)regAddr & mask) && timeout)
  103. {
  104. __ASM("nop");
  105. timeout--;
  106. }
  107. }
  108. static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address)
  109. {
  110. /* Align the address first. */
  111. address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
  112. /* Invalidate the cache line by physical address. */
  113. L2CACHEC->REG7_INV_PA = address;
  114. return address;
  115. }
  116. static uint32_t L2CACHE_CleanLineByAddr(uint32_t address)
  117. {
  118. /* Align the address first. */
  119. address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
  120. /* Invalidate the cache line by physical address. */
  121. L2CACHEC->REG7_CLEAN_PA = address;
  122. return address;
  123. }
  124. static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address)
  125. {
  126. /* Align the address first. */
  127. address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
  128. /* Clean and invalidate the cache line by physical address. */
  129. L2CACHEC->REG7_CLEAN_INV_PA = address;
  130. return address;
  131. }
  132. static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way)
  133. {
  134. assert(num_ways);
  135. assert(size_way);
  136. uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
  137. L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
  138. uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
  139. L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
  140. *num_ways = (number + 1) * L2CACHE_SMALLWAYS_NUM;
  141. if (!size)
  142. {
  143. /* 0 internally mapped to the same size as 1 - 16KB.*/
  144. size += 1;
  145. }
  146. *size_way = (1 << (size - 1)) * L2CACHE_SAMLLWAYS_SIZE * L2CACHE_1KBCOVERTOB;
  147. }
  148. /*!
  149. * brief Initializes the level 2 cache controller module.
  150. *
  151. * param config Pointer to configuration structure. See "l2cache_config_t".
  152. */
  153. void L2CACHE_Init(l2cache_config_t *config)
  154. {
  155. assert(config);
  156. uint16_t waysNum = 0xFFU; /* Default use the 8-way mask. */
  157. uint8_t count;
  158. uint32_t auxReg = 0;
  159. /*The aux register must be configured when the cachec is disabled
  160. * So disable first if the cache controller is enabled.
  161. */
  162. if (L2CACHEC->REG1_CONTROL & L2CACHEC_REG1_CONTROL_CE_MASK)
  163. {
  164. L2CACHE_Disable();
  165. }
  166. /* Unlock all entries. */
  167. if (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
  168. {
  169. waysNum = 0xFFFFU;
  170. }
  171. for (count = 0; count < L2CACHE_LOCKDOWN_REGNUM; count++)
  172. {
  173. L2CACHE_LockdownByWayEnable(count, waysNum, false);
  174. }
  175. /* Set the ways and way-size etc. */
  176. auxReg = L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY(config->wayNum) |
  177. L2CACHEC_REG1_AUX_CONTROL_WAYSIZE(config->waySize) | L2CACHEC_REG1_AUX_CONTROL_CRP(config->repacePolicy) |
  178. L2CACHEC_REG1_AUX_CONTROL_IPE(config->istrPrefetchEnable) |
  179. L2CACHEC_REG1_AUX_CONTROL_DPE(config->dataPrefetchEnable) |
  180. L2CACHEC_REG1_AUX_CONTROL_NLE(config->nsLockdownEnable) |
  181. L2CACHEC_REG1_AUX_CONTROL_FWA(config->writeAlloc) | L2CACHEC_REG1_AUX_CONTROL_HPSDRE(config->writeAlloc);
  182. L2CACHEC->REG1_AUX_CONTROL = auxReg;
  183. /* Set the tag/data ram latency. */
  184. if (config->lateConfig)
  185. {
  186. uint32_t data = 0;
  187. /* Tag latency. */
  188. data = L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) |
  189. L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) |
  190. L2CACHEC_REG1_TAG_RAM_CONTROL_RAL(config->lateConfig->tagReadLate) |
  191. L2CACHEC_REG1_TAG_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
  192. L2CACHEC->REG1_TAG_RAM_CONTROL = data;
  193. /* Data latency. */
  194. data = L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) |
  195. L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) |
  196. L2CACHEC_REG1_DATA_RAM_CONTROL_RAL(config->lateConfig->dataReadLate) |
  197. L2CACHEC_REG1_DATA_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
  198. L2CACHEC->REG1_DATA_RAM_CONTROL = data;
  199. }
  200. }
  201. /*!
  202. * brief Gets an available default settings for the cache controller.
  203. *
  204. * This function initializes the cache controller configuration structure with default settings.
  205. * The default values are:
  206. * code
  207. * config->waysNum = kL2CACHE_8ways;
  208. * config->waySize = kL2CACHE_32KbSize;
  209. * config->repacePolicy = kL2CACHE_Roundrobin;
  210. * config->lateConfig = NULL;
  211. * config->istrPrefetchEnable = false;
  212. * config->dataPrefetchEnable = false;
  213. * config->nsLockdownEnable = false;
  214. * config->writeAlloc = kL2CACHE_UseAwcache;
  215. * endcode
  216. * param config Pointer to the configuration structure.
  217. */
  218. void L2CACHE_GetDefaultConfig(l2cache_config_t *config)
  219. {
  220. assert(config);
  221. /* Initializes the configure structure to zero. */
  222. memset(config, 0, sizeof(*config));
  223. uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
  224. L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
  225. uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
  226. L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
  227. /* Get the default value */
  228. config->wayNum = (l2cache_way_num_t)number;
  229. config->waySize = (l2cache_way_size)size;
  230. config->repacePolicy = kL2CACHE_Roundrobin;
  231. config->lateConfig = NULL;
  232. config->istrPrefetchEnable = false;
  233. config->dataPrefetchEnable = false;
  234. config->nsLockdownEnable = false;
  235. config->writeAlloc = kL2CACHE_UseAwcache;
  236. }
  237. /*!
  238. * brief Enables the level 2 cache controller.
  239. * This function enables the cache controller. Must be written using a secure access.
  240. * If write with a Non-secure access will cause a DECERR response.
  241. *
  242. */
  243. void L2CACHE_Enable(void)
  244. {
  245. /* Invalidate first. */
  246. L2CACHE_Invalidate();
  247. /* Enable the level 2 cache controller. */
  248. L2CACHEC->REG1_CONTROL = L2CACHEC_REG1_CONTROL_CE_MASK;
  249. }
  250. /*!
  251. * brief Disables the level 2 cache controller.
  252. * This function disables the cache controller. Must be written using a secure access.
  253. * If write with a Non-secure access will cause a DECERR response.
  254. *
  255. */
  256. void L2CACHE_Disable(void)
  257. {
  258. /* First CleanInvalidate all enties in the cache. */
  259. L2CACHE_CleanInvalidate();
  260. /* Disable the level 2 cache controller. */
  261. L2CACHEC->REG1_CONTROL &= ~L2CACHEC_REG1_CONTROL_CE_MASK;
  262. /* DSB - data sync barrier.*/
  263. __DSB();
  264. }
  265. /*!
  266. * brief Invalidates the Level 2 cache.
  267. * This function invalidates all entries in cache.
  268. *
  269. */
  270. void L2CACHE_Invalidate(void)
  271. {
  272. /* Invalidate all entries in cache. */
  273. L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_INV_WAY);
  274. /* Cache sync. */
  275. L2CACHEC->REG7_CACHE_SYNC = 0;
  276. }
  277. /*!
  278. * brief Cleans the level 2 cache controller.
  279. * This function cleans all entries in the level 2 cache controller.
  280. *
  281. */
  282. void L2CACHE_Clean(void)
  283. {
  284. /* Clean all entries of the cache. */
  285. L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_WAY);
  286. /* Cache sync. */
  287. L2CACHEC->REG7_CACHE_SYNC = 0;
  288. }
  289. /*!
  290. * brief Cleans and invalidates the level 2 cache controller.
  291. * This function cleans and invalidates all entries in the level 2 cache controller.
  292. *
  293. */
  294. void L2CACHE_CleanInvalidate(void)
  295. {
  296. /* Clean all entries of the cache. */
  297. L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_INV_WAY);
  298. /* Cache sync. */
  299. L2CACHEC->REG7_CACHE_SYNC = 0;
  300. }
  301. /*!
  302. * brief Invalidates the Level 2 cache lines in the range of two physical addresses.
  303. * This function invalidates all cache lines between two physical addresses.
  304. *
  305. * param address The start address of the memory to be invalidated.
  306. * param size_byte The memory size.
  307. * note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
  308. * The startAddr here will be forced to align to L2 line size if startAddr
  309. * is not aligned. For the size_byte, application should make sure the
  310. * alignment or make sure the right operation order if the size_byte is not aligned.
  311. */
  312. void L2CACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
  313. {
  314. uint32_t endAddr = address + size_byte;
  315. /* Invalidate addresses in the range. */
  316. while (address < endAddr)
  317. {
  318. address = L2CACHE_InvalidateLineByAddr(address);
  319. /* Update the size. */
  320. address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
  321. }
  322. /* Cache sync. */
  323. L2CACHEC->REG7_CACHE_SYNC = 0;
  324. }
  325. /*!
  326. * brief Cleans the Level 2 cache lines in the range of two physical addresses.
  327. * This function cleans all cache lines between two physical addresses.
  328. *
  329. * param address The start address of the memory to be cleaned.
  330. * param size_byte The memory size.
  331. * note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
  332. * The startAddr here will be forced to align to L2 line size if startAddr
  333. * is not aligned. For the size_byte, application should make sure the
  334. * alignment or make sure the right operation order if the size_byte is not aligned.
  335. */
  336. void L2CACHE_CleanByRange(uint32_t address, uint32_t size_byte)
  337. {
  338. uint32_t num_ways = 0;
  339. uint32_t size_way = 0;
  340. uint32_t endAddr = address + size_byte;
  341. /* Get the number and size of the cache way. */
  342. L2CACHE_GetWayNumSize(&num_ways, &size_way);
  343. /* Check if the clean size is over the cache size. */
  344. if ((endAddr - address) > num_ways * size_way)
  345. {
  346. L2CACHE_Clean();
  347. return;
  348. }
  349. /* Clean addresses in the range. */
  350. while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
  351. {
  352. /* Clean the address in the range. */
  353. address = L2CACHE_CleanLineByAddr(address);
  354. address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
  355. }
  356. L2CACHEC->REG7_CACHE_SYNC = 0;
  357. }
  358. /*!
  359. * brief Cleans and invalidates the Level 2 cache lines in the range of two physical addresses.
  360. * This function cleans and invalidates all cache lines between two physical addresses.
  361. *
  362. * param address The start address of the memory to be cleaned and invalidated.
  363. * param size_byte The memory size.
  364. * note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
  365. * The startAddr here will be forced to align to L2 line size if startAddr
  366. * is not aligned. For the size_byte, application should make sure the
  367. * alignment or make sure the right operation order if the size_byte is not aligned.
  368. */
  369. void L2CACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
  370. {
  371. uint32_t num_ways = 0;
  372. uint32_t size_way = 0;
  373. uint32_t endAddr = address + size_byte;
  374. /* Get the number and size of the cache way. */
  375. L2CACHE_GetWayNumSize(&num_ways, &size_way);
  376. /* Check if the clean size is over the cache size. */
  377. if ((endAddr - address) > num_ways * size_way)
  378. {
  379. L2CACHE_CleanInvalidate();
  380. return;
  381. }
  382. /* Clean addresses in the range. */
  383. while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
  384. {
  385. /* Clean the address in the range. */
  386. address = L2CACHE_CleanInvalidateLineByAddr(address);
  387. address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
  388. }
  389. L2CACHEC->REG7_CACHE_SYNC = 0;
  390. }
  391. /*!
  392. * brief Enables or disables to lock down the data and instruction by way.
  393. * This function locks down the cached instruction/data by way and prevent the adresses from
  394. * being allocated and prevent dara from being evicted out of the level 2 cache.
  395. * But the normal cache maintenance operations that invalidate, clean or clean
  396. * and validate cache contents affect the locked-down cache lines as normal.
  397. *
  398. * param masterId The master id, range from 0 ~ 7.
  399. * param mask The ways to be enabled or disabled to lockdown.
  400. * each bit in value is related to each way of the cache. for example:
  401. * value: bit 0 ------ way 0.
  402. * value: bit 1 ------ way 1.
  403. * --------------------------
  404. * value: bit 15 ------ way 15.
  405. * Note: please make sure the value setting is align with your supported ways.
  406. * param enable True enable the lockdown, false to disable the lockdown.
  407. */
  408. void L2CACHE_LockdownByWayEnable(uint32_t masterId, uint32_t mask, bool enable)
  409. {
  410. uint8_t num_ways = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
  411. L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
  412. num_ways = (num_ways + 1) * L2CACHE_SMALLWAYS_NUM;
  413. assert(mask < (1U << num_ways));
  414. assert(masterId < L2CACHE_LOCKDOWN_REGNUM);
  415. uint32_t dataReg = L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN;
  416. uint32_t istrReg = L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN;
  417. if (enable)
  418. {
  419. /* Data lockdown. */
  420. L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg | mask;
  421. /* Instruction lockdown. */
  422. L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg | mask;
  423. }
  424. else
  425. {
  426. /* Data lockdown. */
  427. L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg & ~mask;
  428. /* Instruction lockdown. */
  429. L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg & ~mask;
  430. }
  431. }
  432. #endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
  433. /*!
  434. * brief Invalidate cortex-m7 L1 instruction cache by range.
  435. *
  436. * param address The start address of the memory to be invalidated.
  437. * param size_byte The memory size.
  438. * note The start address and size_byte should be 32-byte(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) aligned.
  439. * The startAddr here will be forced to align to L1 I-cache line size if
  440. * startAddr is not aligned. For the size_byte, application should make sure the
  441. * alignment or make sure the right operation order if the size_byte is not aligned.
  442. */
  443. void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte)
  444. {
  445. #if (__DCACHE_PRESENT == 1U)
  446. uint32_t addr = address & ~((uint32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE - 1U);
  447. uint32_t align_len = address - addr;
  448. int32_t size = (int32_t)size_byte + (int32_t)align_len;
  449. __DSB();
  450. while (size > 0)
  451. {
  452. SCB->ICIMVAU = addr;
  453. addr += (uint32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE;
  454. size -= (int32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE;
  455. }
  456. __DSB();
  457. __ISB();
  458. #endif
  459. }
  460. /*!
  461. * brief Invalidates all instruction caches by range.
  462. *
  463. * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
  464. *
  465. * param address The physical address.
  466. * param size_byte size of the memory to be invalidated.
  467. * note address and size should be aligned to cache line size
  468. * 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
  469. * to align to the cache line size if startAddr is not aligned. For the size_byte, application should
  470. * make sure the alignment or make sure the right operation order if the size_byte is not aligned.
  471. */
  472. void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
  473. {
  474. #if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
  475. #if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
  476. L2CACHE_InvalidateByRange(address, size_byte);
  477. #endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
  478. #endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
  479. L1CACHE_InvalidateICacheByRange(address, size_byte);
  480. }
  481. /*!
  482. * brief Invalidates all data caches by range.
  483. *
  484. * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
  485. *
  486. * param address The physical address.
  487. * param size_byte size of the memory to be invalidated.
  488. * note address and size should be aligned to cache line size
  489. * 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
  490. * to align to the cache line size if startAddr is not aligned. For the size_byte, application should
  491. * make sure the alignment or make sure the right operation order if the size_byte is not aligned.
  492. */
  493. void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
  494. {
  495. #if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
  496. #if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
  497. L2CACHE_InvalidateByRange(address, size_byte);
  498. #endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
  499. #endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
  500. L1CACHE_InvalidateDCacheByRange(address, size_byte);
  501. }
  502. /*!
  503. * brief Cleans all data caches by range.
  504. *
  505. * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
  506. *
  507. * param address The physical address.
  508. * param size_byte size of the memory to be cleaned.
  509. * note address and size should be aligned to cache line size
  510. * 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
  511. * to align to the cache line size if startAddr is not aligned. For the size_byte, application should
  512. * make sure the alignment or make sure the right operation order if the size_byte is not aligned.
  513. */
  514. void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte)
  515. {
  516. L1CACHE_CleanDCacheByRange(address, size_byte);
  517. #if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
  518. #if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
  519. L2CACHE_CleanByRange(address, size_byte);
  520. #endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
  521. #endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
  522. }
  523. /*!
  524. * brief Cleans and Invalidates all data caches by range.
  525. *
  526. * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
  527. *
  528. * param address The physical address.
  529. * param size_byte size of the memory to be cleaned and invalidated.
  530. * note address and size should be aligned to cache line size
  531. * 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
  532. * to align to the cache line size if startAddr is not aligned. For the size_byte, application should
  533. * make sure the alignment or make sure the right operation order if the size_byte is not aligned.
  534. */
  535. void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
  536. {
  537. L1CACHE_CleanInvalidateDCacheByRange(address, size_byte);
  538. #if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
  539. #if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
  540. L2CACHE_CleanInvalidateByRange(address, size_byte);
  541. #endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
  542. #endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
  543. }