drv_cache.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /**
  2. * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. ******************************************************************************
  6. * @file drv_cache.c
  7. * @version V0.1
  8. * @brief cpu cache interface
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2019-04-01 Cliff.Chen first implementation
  13. *
  14. ******************************************************************************
  15. */
  16. /** @addtogroup RKBSP_Driver_Reference
  17. * @{
  18. */
  19. /** @addtogroup Cache
  20. * @{
  21. */
  22. /** @defgroup Cache_How_To_Use How To Use
  23. * @{
  24. The Cache driver use to keeping data coherent between cpu and device, it can be used in the following three scenarios:
  25. - **The cpu want to read the latest data that has been modified by device**:
  26. - The device modify the data;
  27. - The cpu invalidate the data by rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE,
  28. addr, size);
  29. - The cpu read the latest data;
  30. - **The device want to read the latest data that was modified by cpu**:
  31. - The cpu modify the data;
  32. - The device flush the data by rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, addr, size);
  33. - The device read the latest data;
  34. - **The cpu want to execute two code section on the same memory**:
  35. - Loading the code A in the memory from start address of ADDR;
  36. - Executing the code A;
  37. - Loading the code B in the memory from start address of ADDR;
  38. - Invalidating by rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, ADDR, size);
  39. - Executing the code B
  40. @} */
  41. #include <rthw.h>
  42. #include "drv_cache.h"
  43. #include "hal_base.h"
  44. #if defined(ARCH_ARM_CORTEX_M)
  45. #ifdef RT_USING_CMBACKTRACE
  46. #include "cm_backtrace.h"
  47. #endif
  48. /********************* Private MACRO Definition ******************************/
  49. /** @defgroup CACHE_Private_Macro Private Macro
  50. * @{
  51. */
  52. /** @} */ // CACHE_Private_Macro
  53. /********************* Private Structure Definition **************************/
  54. /** @defgroup CACHE_Private_Structure Private Structure
  55. * @{
  56. */
  57. /** @} */ // CACHE_Private_Structure
  58. /********************* Private Variable Definition ***************************/
  59. /** @defgroup CACHE_Private_Variable Private Variable
  60. * @{
  61. */
  62. /** @} */ // CACHE_Private_Variable
  63. /********************* Private Function Definition ***************************/
  64. /** @defgroup CACHE_Private_Function Private Function
  65. * @{
  66. */
  67. /** @} */ // CACHE_Private_Function
  68. /********************* Public Function Definition ****************************/
  69. /** @defgroup CACHE_Public_Functions Public Functions
  70. * @{
  71. */
  72. /**
  73. * @brief Enable the icache of cpu.
  74. * @attention The cache will be enabled when board initialization, do not dynamically switch cache
  75. * unless specifically required.
  76. */
  77. void rt_hw_cpu_icache_enable(void)
  78. {
  79. HAL_ICACHE_Enable();
  80. }
  81. /**
  82. * @brief Disable the icache of cpu.
  83. * @attention The cache will be enabled when board initialization, do not dynamically switch cache
  84. * unless specifically required.
  85. */
  86. void rt_hw_cpu_icache_disable(void)
  87. {
  88. HAL_ICACHE_Disable();
  89. }
  90. /**
  91. * @brief Get icache status.
  92. * @return 0
  93. * @attention Not yet implemnted.
  94. */
  95. rt_base_t rt_hw_cpu_icache_status(void)
  96. {
  97. return 0;
  98. }
  99. /**
  100. * @brief Icache maintain operation.
  101. * @param ops: RT_HW_CACHE_INVALIDATE for cache invalidate.
  102. * @param addr: The start address of memory you want maintain.
  103. * @param size: The length of memory you want maintain.
  104. */
  105. void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
  106. {
  107. if (ops & RT_HW_CACHE_INVALIDATE)
  108. {
  109. HAL_ICACHE_InvalidateByRange((uint32_t)addr, size);
  110. }
  111. }
  112. /**
  113. * @brief Enable the dcache of cpu.
  114. * @attention The cache will be enabled when board initialization, do not dynamically switch cache
  115. * unless specifically required.
  116. */
  117. void rt_hw_cpu_dcache_enable(void)
  118. {
  119. HAL_DCACHE_Enable();
  120. }
  121. /**
  122. * @brief Disable the dcache of cpu.
  123. * @attention The cache will be enabled when board initialization, do not dynamically switch cache
  124. * unless specifically required.
  125. */
  126. void rt_hw_cpu_dcache_disable(void)
  127. {
  128. HAL_DCACHE_Disable();
  129. }
  130. /**
  131. * @brief Get dcache status.
  132. * @return 0
  133. * @attention Not yet implemnted.
  134. */
  135. rt_base_t rt_hw_cpu_dcache_status(void)
  136. {
  137. return 0;
  138. }
  139. /**
  140. * @brief Dcache maintain operation.
  141. * @param ops: RT_HW_CACHE_INVALIDATE for cache invalidate,
  142. * RT_HW_CACHE_FLUSH for cache clean.
  143. * @param addr: The start address of memory you want maintain.
  144. * @param size: The length of memory you want maintain.
  145. */
  146. void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
  147. {
  148. if ((ops & RT_HW_CACHE_FLUSH) && (ops & RT_HW_CACHE_INVALIDATE))
  149. {
  150. HAL_DCACHE_CleanInvalidateByRange((uint32_t)addr, size);
  151. }
  152. else if (ops & RT_HW_CACHE_FLUSH)
  153. {
  154. HAL_DCACHE_CleanByRange((uint32_t)addr, size);
  155. }
  156. else if (ops & RT_HW_CACHE_INVALIDATE)
  157. {
  158. HAL_DCACHE_InvalidateByRange((uint32_t)addr, size);
  159. }
  160. else
  161. {
  162. RT_ASSERT(0);
  163. }
  164. }
  165. /**
  166. * @brief Dump ahb error occur in icache & dcache, it called by cache interrupt.
  167. * @param fault_handler_lr: The value of LR register.
  168. * @param fault_handler_sp: The value of SP register.
  169. */
  170. void cache_dump_ahb_error(uint32_t fault_handler_lr, uint32_t fault_handler_sp)
  171. {
  172. uint32_t addr;
  173. if (HAL_ICACHE_GetInt())
  174. {
  175. addr = HAL_ICACHE_GetErrAddr();
  176. rt_kprintf("a ahb bus error occur in icache, addr=%p\n", (void *)addr);
  177. HAL_ICACHE_ClearInt();
  178. }
  179. if (HAL_DCACHE_GetInt())
  180. {
  181. addr = HAL_DCACHE_GetErrAddr();
  182. rt_kprintf("a ahb bus error occur in dcache, addr=%p\n", (void *)addr);
  183. HAL_DCACHE_ClearInt();
  184. }
  185. #ifdef RT_USING_CMBACKTRACE
  186. cm_backtrace_fault(fault_handler_lr, fault_handler_sp);
  187. #endif
  188. }
  189. extern void CACHE_IRQHandler(void);
  190. /**
  191. * @brief Enable cache interrupt and register the handler, it called by board initialization.
  192. * @return RT_EOK
  193. */
  194. int rt_hw_cpu_cache_init(void)
  195. {
  196. #if defined(ICACHE) || defined(DCACHE)
  197. HAL_ICACHE_EnableInt();
  198. HAL_DCACHE_EnableInt();
  199. #if defined(RKMCU_PISCES) || defined(RKMCU_RK2108)
  200. rt_hw_interrupt_install(CACHE_IRQn, (rt_isr_handler_t)CACHE_IRQHandler, RT_NULL, RT_NULL);
  201. rt_hw_interrupt_umask(CACHE_IRQn);
  202. #elif defined(RKMCU_RK2206)
  203. rt_hw_interrupt_install(CACHE0_I_IRQn, (rt_isr_handler_t)CACHE_IRQHandler, RT_NULL, RT_NULL);
  204. rt_hw_interrupt_install(CACHE0_D_IRQn, (rt_isr_handler_t)CACHE_IRQHandler, RT_NULL, RT_NULL);
  205. rt_hw_interrupt_umask(CACHE0_I_IRQn);
  206. rt_hw_interrupt_umask(CACHE0_D_IRQn);
  207. #endif
  208. #endif
  209. return RT_EOK;
  210. }
  211. /** @} */ // CACHE_Public_Functions
  212. #else
  213. RT_WEAK void rt_hw_cpu_icache_enable(void)
  214. {
  215. }
  216. RT_WEAK void rt_hw_cpu_icache_disable(void)
  217. {
  218. }
  219. RT_WEAK rt_base_t rt_hw_cpu_icache_status(void)
  220. {
  221. return 0;
  222. }
  223. RT_WEAK void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
  224. {
  225. }
  226. RT_WEAK void rt_hw_cpu_dcache_enable(void)
  227. {
  228. }
  229. RT_WEAK void rt_hw_cpu_dcache_disable(void)
  230. {
  231. }
  232. RT_WEAK rt_base_t rt_hw_cpu_dcache_status(void)
  233. {
  234. return 0;
  235. }
  236. RT_WEAK void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
  237. {
  238. }
  239. #endif
  240. /** @} */ // Cache
  241. /** @} */ // RKBSP_Driver_Reference