cache-ucv2.S 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * linux/arch/unicore32/mm/cache-ucv2.S
  3. *
  4. * Code specific to PKUnity SoC and UniCore ISA
  5. *
  6. * Copyright (C) 2001-2010 GUAN Xue-tao
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. *
  12. * This is the "shell" of the UniCore-v2 processor support.
  13. */
  14. #include <linux/linkage.h>
  15. #include <linux/init.h>
  16. #include <asm/assembler.h>
  17. #include <asm/page.h>
  18. #include "proc-macros.S"
  19. /*
  20. * __cpuc_flush_icache_all()
  21. * __cpuc_flush_kern_all()
  22. * __cpuc_flush_user_all()
  23. *
  24. * Flush the entire cache.
  25. */
  26. ENTRY(__cpuc_flush_icache_all)
  27. /*FALLTHROUGH*/
  28. ENTRY(__cpuc_flush_kern_all)
  29. /*FALLTHROUGH*/
  30. ENTRY(__cpuc_flush_user_all)
  31. mov r0, #0
  32. movc p0.c5, r0, #14 @ Dcache flush all
  33. nop8
  34. mov r0, #0
  35. movc p0.c5, r0, #20 @ Icache invalidate all
  36. nop8
  37. mov pc, lr
  38. /*
  39. * __cpuc_flush_user_range(start, end, flags)
  40. *
  41. * Flush a range of TLB entries in the specified address space.
  42. *
  43. * - start - start address (may not be aligned)
  44. * - end - end address (exclusive, may not be aligned)
  45. * - flags - vm_area_struct flags describing address space
  46. */
  47. ENTRY(__cpuc_flush_user_range)
  48. cxor.a r2, #0
  49. beq __cpuc_dma_flush_range
  50. #ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
  51. andn r0, r0, #CACHE_LINESIZE - 1 @ Safety check
  52. sub r1, r1, r0
  53. csub.a r1, #MAX_AREA_SIZE
  54. bsg 2f
  55. andn r1, r1, #CACHE_LINESIZE - 1
  56. add r1, r1, #CACHE_LINESIZE
  57. 101: dcacheline_flush r0, r11, r12
  58. add r0, r0, #CACHE_LINESIZE
  59. sub.a r1, r1, #CACHE_LINESIZE
  60. bns 101b
  61. b 3f
  62. #endif
  63. 2: mov ip, #0
  64. movc p0.c5, ip, #14 @ Dcache flush all
  65. nop8
  66. 3: mov ip, #0
  67. movc p0.c5, ip, #20 @ Icache invalidate all
  68. nop8
  69. mov pc, lr
  70. /*
  71. * __cpuc_coherent_kern_range(start,end)
  72. * __cpuc_coherent_user_range(start,end)
  73. *
  74. * Ensure that the I and D caches are coherent within specified
  75. * region. This is typically used when code has been written to
  76. * a memory region, and will be executed.
  77. *
  78. * - start - virtual start address of region
  79. * - end - virtual end address of region
  80. */
  81. ENTRY(__cpuc_coherent_kern_range)
  82. /* FALLTHROUGH */
  83. ENTRY(__cpuc_coherent_user_range)
  84. #ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
  85. andn r0, r0, #CACHE_LINESIZE - 1 @ Safety check
  86. sub r1, r1, r0
  87. csub.a r1, #MAX_AREA_SIZE
  88. bsg 2f
  89. andn r1, r1, #CACHE_LINESIZE - 1
  90. add r1, r1, #CACHE_LINESIZE
  91. @ r0 va2pa r10
  92. mov r9, #PAGE_SZ
  93. sub r9, r9, #1 @ PAGE_MASK
  94. 101: va2pa r0, r10, r11, r12, r13, 2f @ r10 is PA
  95. b 103f
  96. 102: cand.a r0, r9
  97. beq 101b
  98. 103: movc p0.c5, r10, #11 @ Dcache clean line of R10
  99. nop8
  100. add r0, r0, #CACHE_LINESIZE
  101. add r10, r10, #CACHE_LINESIZE
  102. sub.a r1, r1, #CACHE_LINESIZE
  103. bns 102b
  104. b 3f
  105. #endif
  106. 2: mov ip, #0
  107. movc p0.c5, ip, #10 @ Dcache clean all
  108. nop8
  109. 3: mov ip, #0
  110. movc p0.c5, ip, #20 @ Icache invalidate all
  111. nop8
  112. mov pc, lr
  113. /*
  114. * __cpuc_flush_kern_dcache_area(void *addr, size_t size)
  115. *
  116. * - addr - kernel address
  117. * - size - region size
  118. */
  119. ENTRY(__cpuc_flush_kern_dcache_area)
  120. mov ip, #0
  121. movc p0.c5, ip, #14 @ Dcache flush all
  122. nop8
  123. mov pc, lr
  124. /*
  125. * __cpuc_dma_clean_range(start,end)
  126. * - start - virtual start address of region
  127. * - end - virtual end address of region
  128. */
  129. ENTRY(__cpuc_dma_clean_range)
  130. #ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
  131. andn r0, r0, #CACHE_LINESIZE - 1
  132. sub r1, r1, r0
  133. andn r1, r1, #CACHE_LINESIZE - 1
  134. add r1, r1, #CACHE_LINESIZE
  135. csub.a r1, #MAX_AREA_SIZE
  136. bsg 2f
  137. @ r0 va2pa r10
  138. mov r9, #PAGE_SZ
  139. sub r9, r9, #1 @ PAGE_MASK
  140. 101: va2pa r0, r10, r11, r12, r13, 2f @ r10 is PA
  141. b 1f
  142. 102: cand.a r0, r9
  143. beq 101b
  144. 1: movc p0.c5, r10, #11 @ Dcache clean line of R10
  145. nop8
  146. add r0, r0, #CACHE_LINESIZE
  147. add r10, r10, #CACHE_LINESIZE
  148. sub.a r1, r1, #CACHE_LINESIZE
  149. bns 102b
  150. mov pc, lr
  151. #endif
  152. 2: mov ip, #0
  153. movc p0.c5, ip, #10 @ Dcache clean all
  154. nop8
  155. mov pc, lr
  156. /*
  157. * __cpuc_dma_inv_range(start,end)
  158. * __cpuc_dma_flush_range(start,end)
  159. * - start - virtual start address of region
  160. * - end - virtual end address of region
  161. */
  162. __cpuc_dma_inv_range:
  163. /* FALLTHROUGH */
  164. ENTRY(__cpuc_dma_flush_range)
  165. #ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
  166. andn r0, r0, #CACHE_LINESIZE - 1
  167. sub r1, r1, r0
  168. andn r1, r1, #CACHE_LINESIZE - 1
  169. add r1, r1, #CACHE_LINESIZE
  170. csub.a r1, #MAX_AREA_SIZE
  171. bsg 2f
  172. @ r0 va2pa r10
  173. 101: dcacheline_flush r0, r11, r12
  174. add r0, r0, #CACHE_LINESIZE
  175. sub.a r1, r1, #CACHE_LINESIZE
  176. bns 101b
  177. mov pc, lr
  178. #endif
  179. 2: mov ip, #0
  180. movc p0.c5, ip, #14 @ Dcache flush all
  181. nop8
  182. mov pc, lr