fsl_cache.c 23 KB

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