cache_hal.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <sys/param.h>
  7. #include <stdint.h>
  8. #include <stdbool.h>
  9. #include "sdkconfig.h"
  10. #include "esp_err.h"
  11. #include "esp_attr.h"
  12. #include "hal/assert.h"
  13. #include "hal/cache_hal.h"
  14. #include "hal/cache_types.h"
  15. #include "hal/cache_ll.h"
  16. #include "hal/mmu_hal.h"
  17. #include "hal/mmu_ll.h"
  18. #include "soc/soc_caps.h"
  19. #include "rom/cache.h"
  20. /*------------------------------------------------------------------------------
  21. * Unified Cache Control
  22. * See cache_hal.h for more info about these HAL APIs
  23. * This file is in internal RAM.
  24. * Now this file doesn't compile on ESP32
  25. *----------------------------------------------------------------------------*/
  26. /**
  27. * Necessary hal contexts, could be maintained by upper layer in the future
  28. */
  29. typedef struct {
  30. bool i_autoload_en;
  31. bool d_autoload_en;
  32. #if CACHE_LL_ENABLE_DISABLE_STATE_SW
  33. // There's no register indicating if cache is enabled on these chips, use sw flag to save this state.
  34. bool i_cache_enabled;
  35. bool d_cache_enabled;
  36. #endif
  37. } cache_hal_state_t;
  38. typedef struct {
  39. cache_hal_state_t l1;
  40. cache_hal_state_t l2;
  41. } cache_hal_context_t;
  42. static cache_hal_context_t ctx;
  43. void s_cache_hal_init_ctx(void)
  44. {
  45. ctx.l1.d_autoload_en = cache_ll_is_cache_autoload_enabled(1, CACHE_TYPE_DATA, CACHE_LL_ID_ALL);
  46. ctx.l1.i_autoload_en = cache_ll_is_cache_autoload_enabled(1, CACHE_TYPE_INSTRUCTION, CACHE_LL_ID_ALL);
  47. ctx.l2.d_autoload_en = cache_ll_is_cache_autoload_enabled(2, CACHE_TYPE_DATA, CACHE_LL_ID_ALL);
  48. ctx.l2.i_autoload_en = cache_ll_is_cache_autoload_enabled(2, CACHE_TYPE_INSTRUCTION, CACHE_LL_ID_ALL);
  49. }
  50. void cache_hal_init(void)
  51. {
  52. s_cache_hal_init_ctx();
  53. if (CACHE_LL_LEVEL_EXT_MEM == 1) {
  54. cache_ll_enable_cache(1, CACHE_TYPE_ALL, CACHE_LL_ID_ALL, ctx.l1.i_autoload_en, ctx.l1.d_autoload_en);
  55. } else if (CACHE_LL_LEVEL_EXT_MEM == 2) {
  56. cache_ll_enable_cache(2, CACHE_TYPE_ALL, CACHE_LL_ID_ALL, ctx.l2.i_autoload_en, ctx.l2.d_autoload_en);
  57. }
  58. cache_ll_l1_enable_bus(0, CACHE_LL_DEFAULT_DBUS_MASK);
  59. cache_ll_l1_enable_bus(0, CACHE_LL_DEFAULT_IBUS_MASK);
  60. #if !CONFIG_FREERTOS_UNICORE
  61. cache_ll_l1_enable_bus(1, CACHE_LL_DEFAULT_DBUS_MASK);
  62. cache_ll_l1_enable_bus(1, CACHE_LL_DEFAULT_IBUS_MASK);
  63. #endif
  64. #if CACHE_LL_ENABLE_DISABLE_STATE_SW
  65. ctx.l1.i_cache_enabled = 1;
  66. ctx.l1.d_cache_enabled = 1;
  67. ctx.l2.i_cache_enabled = 1;
  68. ctx.l2.d_cache_enabled = 1;
  69. #endif
  70. }
  71. #if CACHE_LL_ENABLE_DISABLE_STATE_SW
  72. void s_update_cache_state(uint32_t cache_level, cache_type_t type, bool en)
  73. {
  74. HAL_ASSERT(cache_level && (cache_level <= CACHE_LL_LEVEL_NUMS));
  75. switch (cache_level) {
  76. case 1:
  77. if (type == CACHE_TYPE_INSTRUCTION) {
  78. ctx.l1.i_cache_enabled = en;
  79. break;
  80. } else if (type == CACHE_TYPE_DATA) {
  81. ctx.l1.d_cache_enabled = en;
  82. break;
  83. } else if (type == CACHE_TYPE_ALL) {
  84. ctx.l1.i_cache_enabled = en;
  85. ctx.l1.d_cache_enabled = en;
  86. break;
  87. } else {
  88. HAL_ASSERT(false);
  89. break;
  90. }
  91. case 2:
  92. if (type == CACHE_TYPE_INSTRUCTION) {
  93. ctx.l2.i_cache_enabled = en;
  94. break;
  95. } else if (type == CACHE_TYPE_DATA) {
  96. ctx.l2.d_cache_enabled = en;
  97. break;
  98. } else if (type == CACHE_TYPE_ALL) {
  99. ctx.l2.i_cache_enabled = en;
  100. ctx.l2.d_cache_enabled = en;
  101. break;
  102. } else {
  103. HAL_ASSERT(false);
  104. break;
  105. }
  106. default:
  107. HAL_ASSERT(false);
  108. break;
  109. }
  110. }
  111. bool s_get_cache_state(uint32_t cache_level, cache_type_t type)
  112. {
  113. HAL_ASSERT(cache_level && (cache_level <= CACHE_LL_LEVEL_NUMS));
  114. bool enabled = false;
  115. switch (cache_level) {
  116. case 1:
  117. if (type == CACHE_TYPE_INSTRUCTION) {
  118. enabled = ctx.l1.i_cache_enabled;
  119. break;
  120. } else if (type == CACHE_TYPE_DATA) {
  121. enabled = ctx.l1.d_cache_enabled;
  122. break;
  123. } else if (type == CACHE_TYPE_ALL) {
  124. enabled = ctx.l1.i_cache_enabled;
  125. enabled &= ctx.l1.d_cache_enabled;
  126. break;
  127. } else {
  128. HAL_ASSERT(false);
  129. break;
  130. }
  131. case 2:
  132. if (type == CACHE_TYPE_INSTRUCTION) {
  133. enabled = ctx.l2.i_cache_enabled;
  134. break;
  135. } else if (type == CACHE_TYPE_DATA) {
  136. enabled = ctx.l2.d_cache_enabled;
  137. break;
  138. } else if (type == CACHE_TYPE_ALL) {
  139. enabled = ctx.l2.i_cache_enabled;
  140. enabled &= ctx.l2.d_cache_enabled;
  141. break;
  142. } else {
  143. HAL_ASSERT(false);
  144. break;
  145. }
  146. default:
  147. HAL_ASSERT(false);
  148. break;
  149. }
  150. return enabled;
  151. }
  152. #endif //#if CACHE_LL_ENABLE_DISABLE_STATE_SW
  153. void cache_hal_disable(uint32_t cache_level, cache_type_t type)
  154. {
  155. HAL_ASSERT(cache_level && (cache_level <= CACHE_LL_LEVEL_NUMS));
  156. cache_ll_disable_cache(cache_level, type, CACHE_LL_ID_ALL);
  157. #if CACHE_LL_ENABLE_DISABLE_STATE_SW
  158. s_update_cache_state(cache_level, type, false);
  159. #endif
  160. }
  161. void cache_hal_enable(uint32_t cache_level, cache_type_t type)
  162. {
  163. HAL_ASSERT(cache_level && (cache_level <= CACHE_LL_LEVEL_NUMS));
  164. if (cache_level == 1) {
  165. cache_ll_enable_cache(1, type, CACHE_LL_ID_ALL, ctx.l1.i_autoload_en, ctx.l1.d_autoload_en);
  166. } else if (cache_level == 2) {
  167. cache_ll_enable_cache(2, type, CACHE_LL_ID_ALL, ctx.l2.i_autoload_en, ctx.l2.d_autoload_en);
  168. }
  169. #if CACHE_LL_ENABLE_DISABLE_STATE_SW
  170. s_update_cache_state(cache_level, type, true);
  171. #endif
  172. }
  173. void cache_hal_suspend(uint32_t cache_level, cache_type_t type)
  174. {
  175. HAL_ASSERT(cache_level && (cache_level <= CACHE_LL_LEVEL_NUMS));
  176. cache_ll_suspend_cache(cache_level, type, CACHE_LL_ID_ALL);
  177. #if CACHE_LL_ENABLE_DISABLE_STATE_SW
  178. s_update_cache_state(cache_level, type, false);
  179. #endif
  180. }
  181. void cache_hal_resume(uint32_t cache_level, cache_type_t type)
  182. {
  183. HAL_ASSERT(cache_level && (cache_level <= CACHE_LL_LEVEL_NUMS));
  184. if (cache_level == 1) {
  185. cache_ll_resume_cache(1, type, CACHE_LL_ID_ALL, ctx.l1.i_autoload_en, ctx.l1.d_autoload_en);
  186. } else if (cache_level == 2) {
  187. cache_ll_resume_cache(2, type, CACHE_LL_ID_ALL, ctx.l2.i_autoload_en, ctx.l2.d_autoload_en);
  188. }
  189. #if CACHE_LL_ENABLE_DISABLE_STATE_SW
  190. s_update_cache_state(cache_level, type, true);
  191. #endif
  192. }
  193. bool cache_hal_is_cache_enabled(uint32_t cache_level, cache_type_t type)
  194. {
  195. bool enabled = false;
  196. #if CACHE_LL_ENABLE_DISABLE_STATE_SW
  197. enabled = s_get_cache_state(cache_level, type);
  198. #else
  199. enabled = cache_ll_is_cache_enabled(type);
  200. #endif //CACHE_LL_ENABLE_DISABLE_STATE_SW
  201. return enabled;
  202. }
  203. bool cache_hal_vaddr_to_cache_level_id(uint32_t vaddr_start, uint32_t len, uint32_t *out_level, uint32_t *out_id)
  204. {
  205. if (!out_level || !out_id) {
  206. return false;
  207. }
  208. return cache_ll_vaddr_to_cache_level_id(vaddr_start, len, out_level, out_id);
  209. }
  210. bool cache_hal_invalidate_addr(uint32_t vaddr, uint32_t size)
  211. {
  212. bool valid = false;
  213. uint32_t cache_level = 0;
  214. uint32_t cache_id = 0;
  215. valid = cache_hal_vaddr_to_cache_level_id(vaddr, size, &cache_level, &cache_id);
  216. if (valid) {
  217. cache_ll_invalidate_addr(cache_level, CACHE_TYPE_ALL, cache_id, vaddr, size);
  218. }
  219. return valid;
  220. }
  221. #if SOC_CACHE_WRITEBACK_SUPPORTED
  222. bool cache_hal_writeback_addr(uint32_t vaddr, uint32_t size)
  223. {
  224. bool valid = false;
  225. uint32_t cache_level = 0;
  226. uint32_t cache_id = 0;
  227. valid = cache_hal_vaddr_to_cache_level_id(vaddr, size, &cache_level, &cache_id);
  228. if (valid) {
  229. cache_ll_writeback_addr(cache_level, CACHE_TYPE_DATA, cache_id, vaddr, size);
  230. }
  231. return valid;
  232. }
  233. #endif //#if SOC_CACHE_WRITEBACK_SUPPORTED
  234. #if SOC_CACHE_FREEZE_SUPPORTED
  235. void cache_hal_freeze(uint32_t cache_level, cache_type_t type)
  236. {
  237. HAL_ASSERT(cache_level && (cache_level <= CACHE_LL_LEVEL_NUMS));
  238. cache_ll_freeze_cache(cache_level, type, CACHE_LL_ID_ALL);
  239. }
  240. void cache_hal_unfreeze(uint32_t cache_level, cache_type_t type)
  241. {
  242. HAL_ASSERT(cache_level && (cache_level <= CACHE_LL_LEVEL_NUMS));
  243. cache_ll_unfreeze_cache(cache_level, type, CACHE_LL_ID_ALL);
  244. }
  245. #endif //#if SOC_CACHE_FREEZE_SUPPORTED
  246. uint32_t cache_hal_get_cache_line_size(uint32_t cache_level, cache_type_t type)
  247. {
  248. HAL_ASSERT(cache_level <= CACHE_LL_LEVEL_NUMS);
  249. uint32_t line_size = 0;
  250. #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
  251. line_size = cache_ll_get_line_size(cache_level, type, CACHE_LL_ID_ALL);
  252. #else
  253. if (cache_level == CACHE_LL_LEVEL_EXT_MEM) {
  254. line_size = cache_ll_get_line_size(cache_level, type, CACHE_LL_ID_ALL);
  255. }
  256. #endif
  257. return line_size;
  258. }