cache-v6.S 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * linux/arch/arm/mm/cache-v6.S
  4. *
  5. * Copyright (C) 2001 Deep Blue Solutions Ltd.
  6. *
  7. * This is the "shell" of the ARMv6 processor support.
  8. */
  9. #include <linux/linkage.h>
  10. #include <linux/init.h>
  11. #include <linux/cfi_types.h>
  12. #include <asm/assembler.h>
  13. #include <asm/errno.h>
  14. #include <asm/unwind.h>
  15. #include "proc-macros.S"
  16. #define HARVARD_CACHE
  17. #define CACHE_LINE_SIZE 32
  18. #define D_CACHE_LINE_SIZE 32
  19. #define BTB_FLUSH_SIZE 8
  20. .arch armv6
  21. /*
  22. * v6_flush_icache_all()
  23. *
  24. * Flush the whole I-cache.
  25. *
  26. * ARM1136 erratum 411920 - Invalidate Instruction Cache operation can fail.
  27. * This erratum is present in 1136, 1156 and 1176. It does not affect the
  28. * MPCore.
  29. *
  30. * Registers:
  31. * r0 - set to 0
  32. * r1 - corrupted
  33. */
  34. SYM_TYPED_FUNC_START(v6_flush_icache_all)
  35. mov r0, #0
  36. #ifdef CONFIG_ARM_ERRATA_411920
  37. mrs r1, cpsr
  38. cpsid ifa @ disable interrupts
  39. mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache
  40. mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache
  41. mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache
  42. mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache
  43. msr cpsr_cx, r1 @ restore interrupts
  44. .rept 11 @ ARM Ltd recommends at least
  45. nop @ 11 NOPs
  46. .endr
  47. #else
  48. mcr p15, 0, r0, c7, c5, 0 @ invalidate I-cache
  49. #endif
  50. ret lr
  51. SYM_FUNC_END(v6_flush_icache_all)
  52. /*
  53. * v6_flush_cache_all()
  54. *
  55. * Flush the entire cache.
  56. *
  57. * It is assumed that:
  58. */
  59. SYM_TYPED_FUNC_START(v6_flush_kern_cache_all)
  60. mov r0, #0
  61. #ifdef HARVARD_CACHE
  62. mcr p15, 0, r0, c7, c14, 0 @ D cache clean+invalidate
  63. #ifndef CONFIG_ARM_ERRATA_411920
  64. mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate
  65. #else
  66. b v6_flush_icache_all
  67. #endif
  68. #else
  69. mcr p15, 0, r0, c7, c15, 0 @ Cache clean+invalidate
  70. #endif
  71. ret lr
  72. SYM_FUNC_END(v6_flush_kern_cache_all)
  73. /*
  74. * v6_flush_cache_all()
  75. *
  76. * Flush all TLB entries in a particular address space
  77. *
  78. * - mm - mm_struct describing address space
  79. */
  80. SYM_TYPED_FUNC_START(v6_flush_user_cache_all)
  81. ret lr
  82. SYM_FUNC_END(v6_flush_user_cache_all)
  83. /*
  84. * v6_flush_cache_range(start, end, flags)
  85. *
  86. * Flush a range of TLB entries in the specified address space.
  87. *
  88. * - start - start address (may not be aligned)
  89. * - end - end address (exclusive, may not be aligned)
  90. * - flags - vm_area_struct flags describing address space
  91. *
  92. * It is assumed that:
  93. * - we have a VIPT cache.
  94. */
  95. SYM_TYPED_FUNC_START(v6_flush_user_cache_range)
  96. ret lr
  97. SYM_FUNC_END(v6_flush_user_cache_range)
  98. /*
  99. * v6_coherent_kern_range(start,end)
  100. *
  101. * Ensure that the I and D caches are coherent within specified
  102. * region. This is typically used when code has been written to
  103. * a memory region, and will be executed.
  104. *
  105. * - start - virtual start address of region
  106. * - end - virtual end address of region
  107. *
  108. * It is assumed that:
  109. * - the Icache does not read data from the write buffer
  110. */
  111. SYM_TYPED_FUNC_START(v6_coherent_kern_range)
  112. #ifdef CONFIG_CFI /* Fallthrough if !CFI */
  113. b v6_coherent_user_range
  114. #endif
  115. SYM_FUNC_END(v6_coherent_kern_range)
  116. /*
  117. * v6_coherent_user_range(start,end)
  118. *
  119. * Ensure that the I and D caches are coherent within specified
  120. * region. This is typically used when code has been written to
  121. * a memory region, and will be executed.
  122. *
  123. * - start - virtual start address of region
  124. * - end - virtual end address of region
  125. *
  126. * It is assumed that:
  127. * - the Icache does not read data from the write buffer
  128. */
  129. SYM_TYPED_FUNC_START(v6_coherent_user_range)
  130. UNWIND(.fnstart )
  131. #ifdef HARVARD_CACHE
  132. bic r0, r0, #CACHE_LINE_SIZE - 1
  133. 1:
  134. USER( mcr p15, 0, r0, c7, c10, 1 ) @ clean D line
  135. add r0, r0, #CACHE_LINE_SIZE
  136. cmp r0, r1
  137. blo 1b
  138. #endif
  139. mov r0, #0
  140. #ifdef HARVARD_CACHE
  141. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  142. #ifndef CONFIG_ARM_ERRATA_411920
  143. mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate
  144. #else
  145. b v6_flush_icache_all
  146. #endif
  147. #else
  148. mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB
  149. #endif
  150. ret lr
  151. /*
  152. * Fault handling for the cache operation above. If the virtual address in r0
  153. * isn't mapped, fail with -EFAULT.
  154. */
  155. 9001:
  156. mov r0, #-EFAULT
  157. ret lr
  158. UNWIND(.fnend )
  159. SYM_FUNC_END(v6_coherent_user_range)
  160. /*
  161. * v6_flush_kern_dcache_area(void *addr, size_t size)
  162. *
  163. * Ensure that the data held in the page kaddr is written back
  164. * to the page in question.
  165. *
  166. * - addr - kernel address
  167. * - size - region size
  168. */
  169. SYM_TYPED_FUNC_START(v6_flush_kern_dcache_area)
  170. add r1, r0, r1
  171. bic r0, r0, #D_CACHE_LINE_SIZE - 1
  172. 1:
  173. #ifdef HARVARD_CACHE
  174. mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
  175. #else
  176. mcr p15, 0, r0, c7, c15, 1 @ clean & invalidate unified line
  177. #endif
  178. add r0, r0, #D_CACHE_LINE_SIZE
  179. cmp r0, r1
  180. blo 1b
  181. #ifdef HARVARD_CACHE
  182. mov r0, #0
  183. mcr p15, 0, r0, c7, c10, 4
  184. #endif
  185. ret lr
  186. SYM_FUNC_END(v6_flush_kern_dcache_area)
  187. /*
  188. * v6_dma_inv_range(start,end)
  189. *
  190. * Invalidate the data cache within the specified region; we will
  191. * be performing a DMA operation in this region and we want to
  192. * purge old data in the cache.
  193. *
  194. * - start - virtual start address of region
  195. * - end - virtual end address of region
  196. */
  197. v6_dma_inv_range:
  198. tst r0, #D_CACHE_LINE_SIZE - 1
  199. bic r0, r0, #D_CACHE_LINE_SIZE - 1
  200. #ifdef HARVARD_CACHE
  201. mcrne p15, 0, r0, c7, c10, 1 @ clean D line
  202. #else
  203. mcrne p15, 0, r0, c7, c11, 1 @ clean unified line
  204. #endif
  205. tst r1, #D_CACHE_LINE_SIZE - 1
  206. bic r1, r1, #D_CACHE_LINE_SIZE - 1
  207. #ifdef HARVARD_CACHE
  208. mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line
  209. #else
  210. mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line
  211. #endif
  212. 1:
  213. #ifdef HARVARD_CACHE
  214. mcr p15, 0, r0, c7, c6, 1 @ invalidate D line
  215. #else
  216. mcr p15, 0, r0, c7, c7, 1 @ invalidate unified line
  217. #endif
  218. add r0, r0, #D_CACHE_LINE_SIZE
  219. cmp r0, r1
  220. blo 1b
  221. mov r0, #0
  222. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  223. ret lr
  224. /*
  225. * v6_dma_clean_range(start,end)
  226. * - start - virtual start address of region
  227. * - end - virtual end address of region
  228. */
  229. v6_dma_clean_range:
  230. bic r0, r0, #D_CACHE_LINE_SIZE - 1
  231. 1:
  232. #ifdef HARVARD_CACHE
  233. mcr p15, 0, r0, c7, c10, 1 @ clean D line
  234. #else
  235. mcr p15, 0, r0, c7, c11, 1 @ clean unified line
  236. #endif
  237. add r0, r0, #D_CACHE_LINE_SIZE
  238. cmp r0, r1
  239. blo 1b
  240. mov r0, #0
  241. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  242. ret lr
  243. /*
  244. * v6_dma_flush_range(start,end)
  245. * - start - virtual start address of region
  246. * - end - virtual end address of region
  247. */
  248. SYM_TYPED_FUNC_START(v6_dma_flush_range)
  249. bic r0, r0, #D_CACHE_LINE_SIZE - 1
  250. 1:
  251. #ifdef HARVARD_CACHE
  252. mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
  253. #else
  254. mcr p15, 0, r0, c7, c15, 1 @ clean & invalidate line
  255. #endif
  256. add r0, r0, #D_CACHE_LINE_SIZE
  257. cmp r0, r1
  258. blo 1b
  259. mov r0, #0
  260. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  261. ret lr
  262. SYM_FUNC_END(v6_dma_flush_range)
  263. /*
  264. * dma_map_area(start, size, dir)
  265. * - start - kernel virtual start address
  266. * - size - size of region
  267. * - dir - DMA direction
  268. */
  269. SYM_TYPED_FUNC_START(v6_dma_map_area)
  270. add r1, r1, r0
  271. teq r2, #DMA_FROM_DEVICE
  272. beq v6_dma_inv_range
  273. b v6_dma_clean_range
  274. SYM_FUNC_END(v6_dma_map_area)
  275. /*
  276. * dma_unmap_area(start, size, dir)
  277. * - start - kernel virtual start address
  278. * - size - size of region
  279. * - dir - DMA direction
  280. */
  281. SYM_TYPED_FUNC_START(v6_dma_unmap_area)
  282. add r1, r1, r0
  283. teq r2, #DMA_TO_DEVICE
  284. bne v6_dma_inv_range
  285. ret lr
  286. SYM_FUNC_END(v6_dma_unmap_area)