mips_cache.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * File : mips_cache.h
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2016-09-07 Urey the first version
  23. */
  24. #ifndef _MIPS_CACHE_H_
  25. #define _MIPS_CACHE_H_
  26. #ifndef __ASSEMBLER__
  27. #include <rtdef.h>
  28. #include <mips_cfg.h>
  29. /*
  30. * Cache Operations available on all MIPS processors with R4000-style caches
  31. */
  32. #define INDEX_INVALIDATE_I 0x00
  33. #define INDEX_WRITEBACK_INV_D 0x01
  34. #define INDEX_LOAD_TAG_I 0x04
  35. #define INDEX_LOAD_TAG_D 0x05
  36. #define INDEX_STORE_TAG_I 0x08
  37. #define INDEX_STORE_TAG_D 0x09
  38. #define HIT_INVALIDATE_I 0x10
  39. #define HIT_INVALIDATE_D 0x11
  40. #define HIT_WRITEBACK_INV_D 0x15
  41. /*
  42. *The lock state is cleared by executing an Index
  43. Invalidate, Index Writeback Invalidate, Hit
  44. Invalidate, or Hit Writeback Invalidate
  45. operation to the locked line, or via an Index
  46. Store Tag operation with the lock bit reset in
  47. the TagLo register.
  48. */
  49. #define FETCH_AND_LOCK_I 0x1c
  50. #define FETCH_AND_LOCK_D 0x1d
  51. enum dma_data_direction
  52. {
  53. DMA_BIDIRECTIONAL = 0,
  54. DMA_TO_DEVICE = 1,
  55. DMA_FROM_DEVICE = 2,
  56. DMA_NONE = 3,
  57. };
  58. /*
  59. * R4000-specific cacheops
  60. */
  61. #define CREATE_DIRTY_EXCL_D 0x0d
  62. #define FILL 0x14
  63. #define HIT_WRITEBACK_I 0x18
  64. #define HIT_WRITEBACK_D 0x19
  65. /*
  66. * R4000SC and R4400SC-specific cacheops
  67. */
  68. #define INDEX_INVALIDATE_SI 0x02
  69. #define INDEX_WRITEBACK_INV_SD 0x03
  70. #define INDEX_LOAD_TAG_SI 0x06
  71. #define INDEX_LOAD_TAG_SD 0x07
  72. #define INDEX_STORE_TAG_SI 0x0A
  73. #define INDEX_STORE_TAG_SD 0x0B
  74. #define CREATE_DIRTY_EXCL_SD 0x0f
  75. #define HIT_INVALIDATE_SI 0x12
  76. #define HIT_INVALIDATE_SD 0x13
  77. #define HIT_WRITEBACK_INV_SD 0x17
  78. #define HIT_WRITEBACK_SD 0x1b
  79. #define HIT_SET_VIRTUAL_SI 0x1e
  80. #define HIT_SET_VIRTUAL_SD 0x1f
  81. /*
  82. * R5000-specific cacheops
  83. */
  84. #define R5K_PAGE_INVALIDATE_S 0x17
  85. /*
  86. * RM7000-specific cacheops
  87. */
  88. #define PAGE_INVALIDATE_T 0x16
  89. /*
  90. * R10000-specific cacheops
  91. *
  92. * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
  93. * Most of the _S cacheops are identical to the R4000SC _SD cacheops.
  94. */
  95. #define INDEX_WRITEBACK_INV_S 0x03
  96. #define INDEX_LOAD_TAG_S 0x07
  97. #define INDEX_STORE_TAG_S 0x0B
  98. #define HIT_INVALIDATE_S 0x13
  99. #define CACHE_BARRIER 0x14
  100. #define HIT_WRITEBACK_INV_S 0x17
  101. #define INDEX_LOAD_DATA_I 0x18
  102. #define INDEX_LOAD_DATA_D 0x19
  103. #define INDEX_LOAD_DATA_S 0x1b
  104. #define INDEX_STORE_DATA_I 0x1c
  105. #define INDEX_STORE_DATA_D 0x1d
  106. #define INDEX_STORE_DATA_S 0x1f
  107. #define cache_op(op, addr) \
  108. __asm__ __volatile__( \
  109. ".set push\n" \
  110. ".set noreorder\n" \
  111. ".set mips3\n" \
  112. "cache %0, %1\n" \
  113. ".set pop\n" \
  114. : \
  115. : "i" (op), "R" (*(unsigned char *)(addr)))
  116. #define cache16_unroll32(base, op) \
  117. __asm__ __volatile__( \
  118. " .set noreorder \n" \
  119. " .set mips3 \n" \
  120. " cache %1, 0x000(%0); cache %1, 0x010(%0) \n" \
  121. " cache %1, 0x020(%0); cache %1, 0x030(%0) \n" \
  122. " cache %1, 0x040(%0); cache %1, 0x050(%0) \n" \
  123. " cache %1, 0x060(%0); cache %1, 0x070(%0) \n" \
  124. " cache %1, 0x080(%0); cache %1, 0x090(%0) \n" \
  125. " cache %1, 0x0a0(%0); cache %1, 0x0b0(%0) \n" \
  126. " cache %1, 0x0c0(%0); cache %1, 0x0d0(%0) \n" \
  127. " cache %1, 0x0e0(%0); cache %1, 0x0f0(%0) \n" \
  128. " cache %1, 0x100(%0); cache %1, 0x110(%0) \n" \
  129. " cache %1, 0x120(%0); cache %1, 0x130(%0) \n" \
  130. " cache %1, 0x140(%0); cache %1, 0x150(%0) \n" \
  131. " cache %1, 0x160(%0); cache %1, 0x170(%0) \n" \
  132. " cache %1, 0x180(%0); cache %1, 0x190(%0) \n" \
  133. " cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) \n" \
  134. " cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) \n" \
  135. " cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) \n" \
  136. " .set mips0 \n" \
  137. " .set reorder \n" \
  138. : \
  139. : "r" (base), \
  140. "i" (op));
  141. static inline void flush_icache_line_indexed(rt_ubase_t addr)
  142. {
  143. cache_op(INDEX_INVALIDATE_I, addr);
  144. }
  145. static inline void flush_dcache_line_indexed(rt_ubase_t addr)
  146. {
  147. cache_op(INDEX_WRITEBACK_INV_D, addr);
  148. }
  149. static inline void flush_icache_line(rt_ubase_t addr)
  150. {
  151. cache_op(HIT_INVALIDATE_I, addr);
  152. }
  153. static inline void lock_icache_line(rt_ubase_t addr)
  154. {
  155. cache_op(FETCH_AND_LOCK_I, addr);
  156. }
  157. static inline void lock_dcache_line(rt_ubase_t addr)
  158. {
  159. cache_op(FETCH_AND_LOCK_D, addr);
  160. }
  161. static inline void flush_dcache_line(rt_ubase_t addr)
  162. {
  163. cache_op(HIT_WRITEBACK_INV_D, addr);
  164. }
  165. static inline void invalidate_dcache_line(rt_ubase_t addr)
  166. {
  167. cache_op(HIT_INVALIDATE_D, addr);
  168. }
  169. static inline void blast_dcache16(void)
  170. {
  171. rt_ubase_t start = KSEG0BASE;
  172. rt_ubase_t end = start + g_mips_core.dcache_size;
  173. rt_ubase_t addr;
  174. for (addr = start; addr < end; addr += g_mips_core.dcache_line_size)
  175. cache16_unroll32(addr, INDEX_WRITEBACK_INV_D);
  176. }
  177. static inline void inv_dcache16(void)
  178. {
  179. rt_ubase_t start = KSEG0BASE;
  180. rt_ubase_t end = start + g_mips_core.dcache_size;
  181. rt_ubase_t addr;
  182. for (addr = start; addr < end; addr += g_mips_core.dcache_line_size)
  183. cache16_unroll32(addr, HIT_INVALIDATE_D);
  184. }
  185. static inline void blast_icache16(void)
  186. {
  187. rt_ubase_t start = KSEG0BASE;
  188. rt_ubase_t end = start + g_mips_core.icache_size;
  189. rt_ubase_t addr;
  190. for (addr = start; addr < end; addr += g_mips_core.icache_line_size)
  191. cache16_unroll32(addr, INDEX_INVALIDATE_I);
  192. }
  193. void r4k_cache_init(void);
  194. void r4k_cache_flush_all(void);
  195. void r4k_icache_flush_all(void);
  196. void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size);
  197. void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size);
  198. void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size);
  199. void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size);
  200. void r4k_dma_cache_sync(rt_ubase_t addr, rt_size_t size, enum dma_data_direction direction);
  201. #endif
  202. #endif /* _MIPS_CACHE_H_ */