cache_helpers.S 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright (c) 2016-2021, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <arch.h>
  7. #include <asm_macros.S>
  8. .globl flush_dcache_range
  9. .globl clean_dcache_range
  10. .globl inv_dcache_range
  11. .globl dcsw_op_louis
  12. .globl dcsw_op_all
  13. .globl dcsw_op_level1
  14. .globl dcsw_op_level2
  15. .globl dcsw_op_level3
  16. /*
  17. * This macro can be used for implementing various data cache operations `op`
  18. */
  19. .macro do_dcache_maintenance_by_mva op, coproc, opc1, CRn, CRm, opc2
  20. /* Exit early if size is zero */
  21. cmp r1, #0
  22. beq exit_loop_\op
  23. dcache_line_size r2, r3
  24. add r1, r0, r1
  25. sub r3, r2, #1
  26. bic r0, r0, r3
  27. loop_\op:
  28. stcopr r0, \coproc, \opc1, \CRn, \CRm, \opc2
  29. add r0, r0, r2
  30. cmp r0, r1
  31. blo loop_\op
  32. dsb sy
  33. exit_loop_\op:
  34. bx lr
  35. .endm
  36. /* ------------------------------------------
  37. * Clean+Invalidate from base address till
  38. * size. 'r0' = addr, 'r1' = size
  39. * ------------------------------------------
  40. */
  41. func flush_dcache_range
  42. do_dcache_maintenance_by_mva cimvac, DCCIMVAC
  43. endfunc flush_dcache_range
  44. /* ------------------------------------------
  45. * Clean from base address till size.
  46. * 'r0' = addr, 'r1' = size
  47. * ------------------------------------------
  48. */
  49. func clean_dcache_range
  50. do_dcache_maintenance_by_mva cmvac, DCCMVAC
  51. endfunc clean_dcache_range
  52. /* ------------------------------------------
  53. * Invalidate from base address till
  54. * size. 'r0' = addr, 'r1' = size
  55. * ------------------------------------------
  56. */
  57. func inv_dcache_range
  58. do_dcache_maintenance_by_mva imvac, DCIMVAC
  59. endfunc inv_dcache_range
  60. /* ----------------------------------------------------------------
  61. * Data cache operations by set/way to the level specified
  62. *
  63. * The main function, do_dcsw_op requires:
  64. * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
  65. * as defined in arch.h
  66. * r1: The cache level to begin operation from
  67. * r2: clidr_el1
  68. * r3: The last cache level to operate on
  69. * and will carry out the operation on each data cache from level 0
  70. * to the level in r3 in sequence
  71. *
  72. * The dcsw_op macro sets up the r2 and r3 parameters based on
  73. * clidr_el1 cache information before invoking the main function
  74. * ----------------------------------------------------------------
  75. */
  76. .macro dcsw_op shift, fw, ls
  77. ldcopr r2, CLIDR
  78. ubfx r3, r2, \shift, \fw
  79. lsl r3, r3, \ls
  80. mov r1, #0
  81. b do_dcsw_op
  82. .endm
  83. func do_dcsw_op
  84. push {r4-r12, lr}
  85. ldcopr r8, ID_MMFR4 // stash FEAT_CCIDX identifier in r8
  86. ubfx r8, r8, #ID_MMFR4_CCIDX_SHIFT, #ID_MMFR4_CCIDX_LENGTH
  87. adr r11, dcsw_loop_table // compute cache op based on the operation type
  88. add r6, r11, r0, lsl #3 // cache op is 2x32-bit instructions
  89. loop1:
  90. add r10, r1, r1, LSR #1 // Work out 3x current cache level
  91. mov r12, r2, LSR r10 // extract cache type bits from clidr
  92. and r12, r12, #7 // mask the bits for current cache only
  93. cmp r12, #2 // see what cache we have at this level
  94. blo level_done // no cache or only instruction cache at this level
  95. stcopr r1, CSSELR // select current cache level in csselr
  96. isb // isb to sych the new cssr&csidr
  97. ldcopr r12, CCSIDR // read the new ccsidr
  98. and r10, r12, #7 // extract the length of the cache lines
  99. add r10, r10, #4 // add 4 (r10 = line length offset)
  100. cmp r8, #0 // check for FEAT_CCIDX for Associativity
  101. beq 1f
  102. ubfx r4, r12, #3, #21 // r4 = associativity CCSIDR[23:3]
  103. b 2f
  104. 1:
  105. ubfx r4, r12, #3, #10 // r4 = associativity CCSIDR[12:3]
  106. 2:
  107. clz r5, r4 // r5 = the bit position of the way size increment
  108. mov r9, r4 // r9 working copy of the aligned max way number
  109. loop2:
  110. cmp r8, #0 // check for FEAT_CCIDX for NumSets
  111. beq 3f
  112. ldcopr r12, CCSIDR2 // FEAT_CCIDX numsets is in CCSIDR2
  113. ubfx r7, r12, #0, #24 // r7 = numsets CCSIDR2[23:0]
  114. b loop3
  115. 3:
  116. ubfx r7, r12, #13, #15 // r7 = numsets CCSIDR[27:13]
  117. loop3:
  118. orr r0, r1, r9, LSL r5 // factor in the way number and cache level into r0
  119. orr r0, r0, r7, LSL r10 // factor in the set number
  120. blx r6
  121. subs r7, r7, #1 // decrement the set number
  122. bhs loop3
  123. subs r9, r9, #1 // decrement the way number
  124. bhs loop2
  125. level_done:
  126. add r1, r1, #2 // increment the cache number
  127. cmp r3, r1
  128. // Ensure completion of previous cache maintenance instruction. Note
  129. // this also mitigates erratum 814220 on Cortex-A7
  130. dsb sy
  131. bhi loop1
  132. mov r6, #0
  133. stcopr r6, CSSELR //select cache level 0 in csselr
  134. dsb sy
  135. isb
  136. pop {r4-r12, pc}
  137. dcsw_loop_table:
  138. stcopr r0, DCISW
  139. bx lr
  140. stcopr r0, DCCISW
  141. bx lr
  142. stcopr r0, DCCSW
  143. bx lr
  144. endfunc do_dcsw_op
  145. /* ---------------------------------------------------------------
  146. * Data cache operations by set/way till PoU.
  147. *
  148. * The function requires :
  149. * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
  150. * as defined in arch.h
  151. * ---------------------------------------------------------------
  152. */
  153. func dcsw_op_louis
  154. dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
  155. endfunc dcsw_op_louis
  156. /* ---------------------------------------------------------------
  157. * Data cache operations by set/way till PoC.
  158. *
  159. * The function requires :
  160. * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
  161. * as defined in arch.h
  162. * ---------------------------------------------------------------
  163. */
  164. func dcsw_op_all
  165. dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
  166. endfunc dcsw_op_all
  167. /* ---------------------------------------------------------------
  168. * Helper macro for data cache operations by set/way for the
  169. * level specified
  170. * ---------------------------------------------------------------
  171. */
  172. .macro dcsw_op_level level
  173. ldcopr r2, CLIDR
  174. mov r3, \level
  175. sub r1, r3, #2
  176. b do_dcsw_op
  177. .endm
  178. /* ---------------------------------------------------------------
  179. * Data cache operations by set/way for level 1 cache
  180. *
  181. * The main function, do_dcsw_op requires:
  182. * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
  183. * as defined in arch.h
  184. * ---------------------------------------------------------------
  185. */
  186. func dcsw_op_level1
  187. dcsw_op_level #(1 << LEVEL_SHIFT)
  188. endfunc dcsw_op_level1
  189. /* ---------------------------------------------------------------
  190. * Data cache operations by set/way for level 2 cache
  191. *
  192. * The main function, do_dcsw_op requires:
  193. * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
  194. * as defined in arch.h
  195. * ---------------------------------------------------------------
  196. */
  197. func dcsw_op_level2
  198. dcsw_op_level #(2 << LEVEL_SHIFT)
  199. endfunc dcsw_op_level2
  200. /* ---------------------------------------------------------------
  201. * Data cache operations by set/way for level 3 cache
  202. *
  203. * The main function, do_dcsw_op requires:
  204. * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
  205. * as defined in arch.h
  206. * ---------------------------------------------------------------
  207. */
  208. func dcsw_op_level3
  209. dcsw_op_level #(3 << LEVEL_SHIFT)
  210. endfunc dcsw_op_level3