cache-fa.S 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * linux/arch/arm/mm/cache-fa.S
  4. *
  5. * Copyright (C) 2005 Faraday Corp.
  6. * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
  7. *
  8. * Based on cache-v4wb.S:
  9. * Copyright (C) 1997-2002 Russell king
  10. *
  11. * Processors: FA520 FA526 FA626
  12. */
  13. #include <linux/linkage.h>
  14. #include <linux/init.h>
  15. #include <linux/cfi_types.h>
  16. #include <asm/assembler.h>
  17. #include <asm/page.h>
  18. #include "proc-macros.S"
  19. /*
  20. * The size of one data cache line.
  21. */
  22. #define CACHE_DLINESIZE 16
  23. /*
  24. * The total size of the data cache.
  25. */
  26. #ifdef CONFIG_ARCH_GEMINI
  27. #define CACHE_DSIZE 8192
  28. #else
  29. #define CACHE_DSIZE 16384
  30. #endif
  31. /* FIXME: put optimal value here. Current one is just estimation */
  32. #define CACHE_DLIMIT (CACHE_DSIZE * 2)
  33. /*
  34. * flush_icache_all()
  35. *
  36. * Unconditionally clean and invalidate the entire icache.
  37. */
  38. SYM_TYPED_FUNC_START(fa_flush_icache_all)
  39. mov r0, #0
  40. mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
  41. ret lr
  42. SYM_FUNC_END(fa_flush_icache_all)
  43. /*
  44. * flush_user_cache_all()
  45. *
  46. * Clean and invalidate all cache entries in a particular address
  47. * space.
  48. */
  49. SYM_FUNC_ALIAS(fa_flush_user_cache_all, fa_flush_kern_cache_all)
  50. /*
  51. * flush_kern_cache_all()
  52. *
  53. * Clean and invalidate the entire cache.
  54. */
  55. SYM_TYPED_FUNC_START(fa_flush_kern_cache_all)
  56. mov ip, #0
  57. mov r2, #VM_EXEC
  58. __flush_whole_cache:
  59. mcr p15, 0, ip, c7, c14, 0 @ clean/invalidate D cache
  60. tst r2, #VM_EXEC
  61. mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
  62. mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB
  63. mcrne p15, 0, ip, c7, c10, 4 @ drain write buffer
  64. mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
  65. ret lr
  66. SYM_FUNC_END(fa_flush_kern_cache_all)
  67. /*
  68. * flush_user_cache_range(start, end, flags)
  69. *
  70. * Invalidate a range of cache entries in the specified
  71. * address space.
  72. *
  73. * - start - start address (inclusive, page aligned)
  74. * - end - end address (exclusive, page aligned)
  75. * - flags - vma_area_struct flags describing address space
  76. */
  77. SYM_TYPED_FUNC_START(fa_flush_user_cache_range)
  78. mov ip, #0
  79. sub r3, r1, r0 @ calculate total size
  80. cmp r3, #CACHE_DLIMIT @ total size >= limit?
  81. bhs __flush_whole_cache @ flush whole D cache
  82. 1: tst r2, #VM_EXEC
  83. mcrne p15, 0, r0, c7, c5, 1 @ invalidate I line
  84. mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
  85. add r0, r0, #CACHE_DLINESIZE
  86. cmp r0, r1
  87. blo 1b
  88. tst r2, #VM_EXEC
  89. mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB
  90. mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
  91. mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
  92. ret lr
  93. SYM_FUNC_END(fa_flush_user_cache_range)
  94. /*
  95. * coherent_kern_range(start, end)
  96. *
  97. * Ensure coherency between the Icache and the Dcache in the
  98. * region described by start. If you have non-snooping
  99. * Harvard caches, you need to implement this function.
  100. *
  101. * - start - virtual start address
  102. * - end - virtual end address
  103. */
  104. SYM_TYPED_FUNC_START(fa_coherent_kern_range)
  105. #ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
  106. b fa_coherent_user_range
  107. #endif
  108. SYM_FUNC_END(fa_coherent_kern_range)
  109. /*
  110. * coherent_user_range(start, end)
  111. *
  112. * Ensure coherency between the Icache and the Dcache in the
  113. * region described by start. If you have non-snooping
  114. * Harvard caches, you need to implement this function.
  115. *
  116. * - start - virtual start address
  117. * - end - virtual end address
  118. */
  119. SYM_TYPED_FUNC_START(fa_coherent_user_range)
  120. bic r0, r0, #CACHE_DLINESIZE - 1
  121. 1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
  122. mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
  123. add r0, r0, #CACHE_DLINESIZE
  124. cmp r0, r1
  125. blo 1b
  126. mov r0, #0
  127. mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB
  128. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  129. mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
  130. ret lr
  131. SYM_FUNC_END(fa_coherent_user_range)
  132. /*
  133. * flush_kern_dcache_area(void *addr, size_t size)
  134. *
  135. * Ensure that the data held in the page kaddr is written back
  136. * to the page in question.
  137. *
  138. * - addr - kernel address
  139. * - size - size of region
  140. */
  141. SYM_TYPED_FUNC_START(fa_flush_kern_dcache_area)
  142. add r1, r0, r1
  143. 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
  144. add r0, r0, #CACHE_DLINESIZE
  145. cmp r0, r1
  146. blo 1b
  147. mov r0, #0
  148. mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
  149. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  150. ret lr
  151. SYM_FUNC_END(fa_flush_kern_dcache_area)
  152. /*
  153. * dma_inv_range(start, end)
  154. *
  155. * Invalidate (discard) the specified virtual address range.
  156. * May not write back any entries. If 'start' or 'end'
  157. * are not cache line aligned, those lines must be written
  158. * back.
  159. *
  160. * - start - virtual start address
  161. * - end - virtual end address
  162. */
  163. fa_dma_inv_range:
  164. tst r0, #CACHE_DLINESIZE - 1
  165. bic r0, r0, #CACHE_DLINESIZE - 1
  166. mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry
  167. tst r1, #CACHE_DLINESIZE - 1
  168. bic r1, r1, #CACHE_DLINESIZE - 1
  169. mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D entry
  170. 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
  171. add r0, r0, #CACHE_DLINESIZE
  172. cmp r0, r1
  173. blo 1b
  174. mov r0, #0
  175. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  176. ret lr
  177. /*
  178. * dma_clean_range(start, end)
  179. *
  180. * Clean (write back) the specified virtual address range.
  181. *
  182. * - start - virtual start address
  183. * - end - virtual end address
  184. */
  185. fa_dma_clean_range:
  186. bic r0, r0, #CACHE_DLINESIZE - 1
  187. 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  188. add r0, r0, #CACHE_DLINESIZE
  189. cmp r0, r1
  190. blo 1b
  191. mov r0, #0
  192. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  193. ret lr
  194. /*
  195. * dma_flush_range(start,end)
  196. * - start - virtual start address of region
  197. * - end - virtual end address of region
  198. */
  199. SYM_TYPED_FUNC_START(fa_dma_flush_range)
  200. bic r0, r0, #CACHE_DLINESIZE - 1
  201. 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry
  202. add r0, r0, #CACHE_DLINESIZE
  203. cmp r0, r1
  204. blo 1b
  205. mov r0, #0
  206. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  207. ret lr
  208. SYM_FUNC_END(fa_dma_flush_range)
  209. /*
  210. * dma_map_area(start, size, dir)
  211. * - start - kernel virtual start address
  212. * - size - size of region
  213. * - dir - DMA direction
  214. */
  215. SYM_TYPED_FUNC_START(fa_dma_map_area)
  216. add r1, r1, r0
  217. cmp r2, #DMA_TO_DEVICE
  218. beq fa_dma_clean_range
  219. bcs fa_dma_inv_range
  220. b fa_dma_flush_range
  221. SYM_FUNC_END(fa_dma_map_area)
  222. /*
  223. * dma_unmap_area(start, size, dir)
  224. * - start - kernel virtual start address
  225. * - size - size of region
  226. * - dir - DMA direction
  227. */
  228. SYM_TYPED_FUNC_START(fa_dma_unmap_area)
  229. ret lr
  230. SYM_FUNC_END(fa_dma_unmap_area)