arc_cache.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /* ------------------------------------------
  2. * Copyright (c) 2016, Synopsys, Inc. All rights reserved.
  3. * Redistribution and use in source and binary forms, with or without modification,
  4. * are permitted provided that the following conditions are met:
  5. * 1) Redistributions of source code must retain the above copyright notice, this
  6. * list of conditions and the following disclaimer.
  7. * 2) Redistributions in binary form must reproduce the above copyright notice,
  8. * this list of conditions and the following disclaimer in the documentation and/or
  9. * other materials provided with the distribution.
  10. * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may
  11. * be used to endorse or promote products derived from this software without
  12. * specific prior written permission.
  13. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  14. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  17. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  18. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  19. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  20. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  22. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. *
  24. * \version 2016.05
  25. * \date 2014-07-15
  26. * \author Wayne Ren(Wei.Ren@synopsys.com)
  27. --------------------------------------------- */
  28. /**
  29. * \file
  30. * \ingroup ARC_HAL_MISC_CACHE
  31. * \brief header file of cache module
  32. */
  33. #ifndef _ARC_HAL_CACHE_H_
  34. #define _ARC_HAL_CACHE_H_
  35. #include "inc/embARC_toolchain.h"
  36. #include "inc/arc/arc.h"
  37. #include "inc/arc/arc_builtin.h"
  38. #include "inc/arc/arc_exception.h"
  39. /**
  40. * \name instruction cache control register related definition
  41. * \todo this definitions will be reviewed.
  42. * @{
  43. */
  44. #define IC_CTRL_IC_ENABLE 0x0 /*!< enable instruction cache */
  45. #define IC_CTRL_IC_DISABLE 0x1 /*!< disable instruction cache */
  46. #define IC_CTRL_DIRECT_ACCESS 0x0 /*!< direct access mode */
  47. #define IC_CTRL_INDIRECT_ACCESS 0x20 /*!< indirect access mode */
  48. #define IC_CTRL_OP_SUCCEEDED 0x8 /*!< instruction cache operation succeeded */
  49. /** @} */
  50. /**
  51. * \name data cache control register related definition
  52. * \todo this definition will be reviewed.
  53. * @{
  54. */
  55. #define IC_CTRL_I
  56. #define DC_CTRL_DC_ENABLE 0x0 /*!< enable data cache */
  57. #define DC_CTRL_DC_DISABLE 0x1 /*!< disable data cache */
  58. #define DC_CTRL_INVALID_ONLY 0x0 /*!< invalid data cache only */
  59. #define DC_CTRL_INVALID_FLUSH 0x40 /*!< invalid and flush data cache */
  60. #define DC_CTRL_ENABLE_FLUSH_LOCKED 0x80 /*!< the locked data cache can be flushed */
  61. #define DC_CTRL_DISABLE_FLUSH_LOCKED 0x0 /*!< the locked data cache cannot be flushed */
  62. #define DC_CTRL_FLUSH_STATUS 0x100 /*!< flush status */
  63. #define DC_CTRL_DIRECT_ACCESS 0x0 /*!< direct access mode */
  64. #define DC_CTRL_INDIRECT_ACCESS 0x20 /*!< indirect access mode */
  65. #define DC_CTRL_OP_SUCCEEDED 0x4 /*!< data cache operation succeeded */
  66. /** @} */
  67. /**
  68. * \name instruction cache related inline function
  69. * @{
  70. */
  71. /**
  72. * \brief check whether instruction cache is available,
  73. * 0 for not available, >0 for available
  74. */
  75. Inline uint8_t icache_available(void)
  76. {
  77. return (_arc_aux_read(AUX_BCR_I_CACHE) & 0xF);
  78. }
  79. /**
  80. * \brief enable instruction cache
  81. * \param[in] icache_en_mask operation mask
  82. */
  83. Inline void icache_enable(uint32_t icache_en_mask)
  84. {
  85. if (!icache_available()) return;
  86. _arc_aux_write(AUX_IC_CTRL, icache_en_mask);
  87. }
  88. /**
  89. * \brief disable instruction cache
  90. */
  91. Inline void icache_disable(void)
  92. {
  93. if (!icache_available()) return;
  94. _arc_aux_write(AUX_IC_CTRL, IC_CTRL_IC_DISABLE);
  95. }
  96. /**
  97. * \brief invalidate the entire instruction cache
  98. */
  99. Inline void icache_invalidate(void)
  100. {
  101. if (!icache_available()) return;
  102. /* invalidate the entire icache */
  103. _arc_aux_write(AUX_IC_IVIC, 0);
  104. Asm("nop_s");
  105. Asm("nop_s");
  106. Asm("nop_s");
  107. }
  108. /**
  109. * \brief invalidate specific cache line
  110. * \param[in] address memory address
  111. */
  112. Inline void icache_invalidate_line(uint32_t address)
  113. {
  114. if (!icache_available()) return;
  115. _arc_aux_write(AUX_IC_IVIL, address);
  116. /* the 3 nops are required by ARCv2 ISA */
  117. Asm("nop_s");
  118. Asm("nop_s");
  119. Asm("nop_s");
  120. }
  121. /**
  122. * \brief lock specific cache line
  123. * \param[in] address memory address
  124. * \return 0, succeeded, -1, failed
  125. */
  126. Inline int32_t icache_lock_line(uint32_t address)
  127. {
  128. if (!icache_available()) return -1;
  129. _arc_aux_write(AUX_IC_LIL, address);
  130. if(_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_OP_SUCCEEDED) {
  131. return 0;
  132. } else {
  133. return -1;
  134. }
  135. }
  136. /**
  137. * \brief set icache access mode
  138. * \param[in] mode, access mode, 1: indirect access 0:direct access
  139. */
  140. Inline void icache_access_mode(uint32_t mode)
  141. {
  142. if (!icache_available()) return;
  143. if (mode) {
  144. _arc_aux_write(AUX_IC_CTRL, _arc_aux_read(AUX_IC_CTRL) | IC_CTRL_INDIRECT_ACCESS);
  145. } else {
  146. _arc_aux_write(AUX_IC_CTRL, _arc_aux_read(AUX_IC_CTRL) & (~IC_CTRL_INDIRECT_ACCESS));
  147. }
  148. }
  149. /** @} */
  150. /**
  151. * \name data cache related inline functions
  152. * @{
  153. */
  154. /**
  155. * \brief check whether data cache is available,
  156. * 0 for not available, >0 for available
  157. */
  158. Inline uint8_t dcache_available(void)
  159. {
  160. return (_arc_aux_read(AUX_BCR_D_CACHE) & 0xF);
  161. }
  162. /**
  163. * \brief invalidate the entire data cache
  164. */
  165. Inline void dcache_invalidate(void)
  166. {
  167. if (!dcache_available()) return;
  168. uint32_t status;
  169. status = cpu_lock_save();
  170. _arc_aux_write(AUX_DC_IVDC, 1);
  171. /* wait for flush completion */
  172. while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS);
  173. cpu_unlock_restore(status);
  174. }
  175. /**
  176. * \brief invalidate the specific cache line
  177. * \param[in] address memory address
  178. */
  179. Inline void dcache_invalidate_line(uint32_t address)
  180. {
  181. if (!dcache_available()) return;
  182. _arc_aux_write(AUX_DC_IVDL, address);
  183. Asm("nop_s");
  184. Asm("nop_s");
  185. Asm("nop_s");
  186. }
  187. /**
  188. * \brief enable data cache
  189. * \param[in] dcache_en_mask operation mask
  190. */
  191. Inline void dcache_enable(uint32_t dcache_en_mask)
  192. {
  193. if (!dcache_available()) return;
  194. _arc_aux_write(AUX_DC_CTRL, dcache_en_mask);
  195. }
  196. /**
  197. * \brief disable data cache
  198. */
  199. Inline void dcache_disable(void)
  200. {
  201. if (!dcache_available()) return;
  202. _arc_aux_write(AUX_DC_CTRL, DC_CTRL_DC_DISABLE);
  203. }
  204. /**
  205. * \brief flush data cache
  206. */
  207. Inline void dcache_flush(void)
  208. {
  209. if (!dcache_available()) return;
  210. uint32_t status;
  211. status = cpu_lock_save();
  212. _arc_aux_write(AUX_DC_FLSH, 1);
  213. /* wait for flush completion */
  214. while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS);
  215. cpu_unlock_restore(status);
  216. }
  217. /**
  218. * \brief flush the specific data cache line
  219. * \param[in] address memory address
  220. */
  221. Inline void dcache_flush_line(uint32_t address)
  222. {
  223. if (!dcache_available()) return;
  224. uint32_t status;
  225. status = cpu_lock_save();
  226. _arc_aux_write(AUX_DC_FLDL, address);
  227. while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS);
  228. cpu_unlock_restore(status);
  229. }
  230. /**
  231. * \brief lock the specific data cache line
  232. * \param[in] address memory address
  233. * \return 0, succeeded, -1, failed
  234. */
  235. Inline int dcache_lock_line(uint32_t address)
  236. {
  237. if (!dcache_available()) return -1;
  238. _arc_aux_write(AUX_DC_LDL, address);
  239. if(_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_OP_SUCCEEDED) {
  240. return 0;
  241. } else {
  242. return -1;
  243. }
  244. }
  245. /**
  246. * \brief set dcache access mode
  247. * \param[in] mode, access mode, 1: indirect access 0:direct access
  248. */
  249. Inline void dcache_access_mode(uint32_t mode)
  250. {
  251. if (!dcache_available()) return;
  252. if (mode) {
  253. _arc_aux_write(AUX_DC_CTRL, _arc_aux_read(AUX_DC_CTRL) | DC_CTRL_INDIRECT_ACCESS);
  254. } else {
  255. _arc_aux_write(AUX_DC_CTRL, _arc_aux_read(AUX_DC_CTRL) & (~DC_CTRL_INDIRECT_ACCESS));
  256. }
  257. }
  258. /** @} */
  259. #ifdef __cplusplus
  260. extern "C" {
  261. #endif
  262. /**
  263. * \name declarations of cache related functions
  264. * @{
  265. */
  266. extern int32_t icache_invalidate_mlines(uint32_t start_addr, uint32_t size);
  267. extern int32_t icache_lock_mlines(uint32_t start_addr, uint32_t size);
  268. extern int32_t icache_direct_write(uint32_t cache_addr, uint32_t tag, uint32_t data);
  269. extern int32_t icache_direct_read(uint32_t cache_addr, uint32_t *tag, uint32_t *data);
  270. extern int32_t icache_indirect_read(uint32_t mem_addr, uint32_t *tag, uint32_t *data);
  271. extern int32_t dcache_invalidate_mlines(uint32_t start_addr, uint32_t size);
  272. extern int32_t dcache_flush_mlines(uint32_t start_addr, uint32_t size);
  273. extern int32_t dcache_lock_mlines(uint32_t start_addr, uint32_t size);
  274. extern int32_t dcache_direct_write(uint32_t cache_addr, uint32_t tag, uint32_t data);
  275. extern int32_t dcache_direct_read(uint32_t cache_addr, uint32_t *tag, uint32_t *data);
  276. extern int32_t dcache_indirect_read(uint32_t mem_addr, uint32_t *tag, uint32_t *data);
  277. extern void arc_cache_init(void);
  278. #ifdef __cplusplus
  279. }
  280. #endif
  281. /** @} */
  282. #endif /* _ARC_HAL_CACHE_H_ */