fp-ptrace-asm.S 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. // Copyright (C) 2021-3 ARM Limited.
  3. //
  4. // Assembly portion of the FP ptrace test
  5. //
  6. // Load values from memory into registers, break on a breakpoint, then
  7. // break on a further breakpoint
  8. //
  9. #include "fp-ptrace.h"
  10. #include "sme-inst.h"
  11. .arch_extension sve
  12. // Load and save register values with pauses for ptrace
  13. //
  14. // x0 - SVE in use
  15. // x1 - SME in use
  16. // x2 - SME2 in use
  17. // x3 - FA64 supported
  18. .globl load_and_save
  19. load_and_save:
  20. stp x11, x12, [sp, #-0x10]!
  21. // This should be redundant in the SVE case
  22. ldr x7, =v_in
  23. ldp q0, q1, [x7]
  24. ldp q2, q3, [x7, #16 * 2]
  25. ldp q4, q5, [x7, #16 * 4]
  26. ldp q6, q7, [x7, #16 * 6]
  27. ldp q8, q9, [x7, #16 * 8]
  28. ldp q10, q11, [x7, #16 * 10]
  29. ldp q12, q13, [x7, #16 * 12]
  30. ldp q14, q15, [x7, #16 * 14]
  31. ldp q16, q17, [x7, #16 * 16]
  32. ldp q18, q19, [x7, #16 * 18]
  33. ldp q20, q21, [x7, #16 * 20]
  34. ldp q22, q23, [x7, #16 * 22]
  35. ldp q24, q25, [x7, #16 * 24]
  36. ldp q26, q27, [x7, #16 * 26]
  37. ldp q28, q29, [x7, #16 * 28]
  38. ldp q30, q31, [x7, #16 * 30]
  39. // SME?
  40. cbz x1, check_sve_in
  41. adrp x7, svcr_in
  42. ldr x7, [x7, :lo12:svcr_in]
  43. // SVCR is 0 by default, avoid triggering SME if not in use
  44. cbz x7, check_sve_in
  45. msr S3_3_C4_C2_2, x7
  46. // ZA?
  47. tbz x7, #SVCR_ZA_SHIFT, check_sm_in
  48. rdsvl 11, 1
  49. mov w12, #0
  50. ldr x6, =za_in
  51. 1: _ldr_za 12, 6
  52. add x6, x6, x11
  53. add x12, x12, #1
  54. cmp x11, x12
  55. bne 1b
  56. // ZT?
  57. cbz x2, check_sm_in
  58. adrp x6, zt_in
  59. add x6, x6, :lo12:zt_in
  60. _ldr_zt 6
  61. // In streaming mode?
  62. check_sm_in:
  63. tbz x7, #SVCR_SM_SHIFT, check_sve_in
  64. mov x4, x3 // Load FFR if we have FA64
  65. b load_sve
  66. // SVE?
  67. check_sve_in:
  68. cbz x0, wait_for_writes
  69. mov x4, #1
  70. load_sve:
  71. ldr x7, =z_in
  72. ldr z0, [x7, #0, MUL VL]
  73. ldr z1, [x7, #1, MUL VL]
  74. ldr z2, [x7, #2, MUL VL]
  75. ldr z3, [x7, #3, MUL VL]
  76. ldr z4, [x7, #4, MUL VL]
  77. ldr z5, [x7, #5, MUL VL]
  78. ldr z6, [x7, #6, MUL VL]
  79. ldr z7, [x7, #7, MUL VL]
  80. ldr z8, [x7, #8, MUL VL]
  81. ldr z9, [x7, #9, MUL VL]
  82. ldr z10, [x7, #10, MUL VL]
  83. ldr z11, [x7, #11, MUL VL]
  84. ldr z12, [x7, #12, MUL VL]
  85. ldr z13, [x7, #13, MUL VL]
  86. ldr z14, [x7, #14, MUL VL]
  87. ldr z15, [x7, #15, MUL VL]
  88. ldr z16, [x7, #16, MUL VL]
  89. ldr z17, [x7, #17, MUL VL]
  90. ldr z18, [x7, #18, MUL VL]
  91. ldr z19, [x7, #19, MUL VL]
  92. ldr z20, [x7, #20, MUL VL]
  93. ldr z21, [x7, #21, MUL VL]
  94. ldr z22, [x7, #22, MUL VL]
  95. ldr z23, [x7, #23, MUL VL]
  96. ldr z24, [x7, #24, MUL VL]
  97. ldr z25, [x7, #25, MUL VL]
  98. ldr z26, [x7, #26, MUL VL]
  99. ldr z27, [x7, #27, MUL VL]
  100. ldr z28, [x7, #28, MUL VL]
  101. ldr z29, [x7, #29, MUL VL]
  102. ldr z30, [x7, #30, MUL VL]
  103. ldr z31, [x7, #31, MUL VL]
  104. // FFR is not present in base SME
  105. cbz x4, 1f
  106. ldr x7, =ffr_in
  107. ldr p0, [x7]
  108. ldr x7, [x7, #0]
  109. cbz x7, 1f
  110. wrffr p0.b
  111. 1:
  112. ldr x7, =p_in
  113. ldr p0, [x7, #0, MUL VL]
  114. ldr p1, [x7, #1, MUL VL]
  115. ldr p2, [x7, #2, MUL VL]
  116. ldr p3, [x7, #3, MUL VL]
  117. ldr p4, [x7, #4, MUL VL]
  118. ldr p5, [x7, #5, MUL VL]
  119. ldr p6, [x7, #6, MUL VL]
  120. ldr p7, [x7, #7, MUL VL]
  121. ldr p8, [x7, #8, MUL VL]
  122. ldr p9, [x7, #9, MUL VL]
  123. ldr p10, [x7, #10, MUL VL]
  124. ldr p11, [x7, #11, MUL VL]
  125. ldr p12, [x7, #12, MUL VL]
  126. ldr p13, [x7, #13, MUL VL]
  127. ldr p14, [x7, #14, MUL VL]
  128. ldr p15, [x7, #15, MUL VL]
  129. wait_for_writes:
  130. // Wait for the parent
  131. brk #0
  132. // Save values
  133. ldr x7, =v_out
  134. stp q0, q1, [x7]
  135. stp q2, q3, [x7, #16 * 2]
  136. stp q4, q5, [x7, #16 * 4]
  137. stp q6, q7, [x7, #16 * 6]
  138. stp q8, q9, [x7, #16 * 8]
  139. stp q10, q11, [x7, #16 * 10]
  140. stp q12, q13, [x7, #16 * 12]
  141. stp q14, q15, [x7, #16 * 14]
  142. stp q16, q17, [x7, #16 * 16]
  143. stp q18, q19, [x7, #16 * 18]
  144. stp q20, q21, [x7, #16 * 20]
  145. stp q22, q23, [x7, #16 * 22]
  146. stp q24, q25, [x7, #16 * 24]
  147. stp q26, q27, [x7, #16 * 26]
  148. stp q28, q29, [x7, #16 * 28]
  149. stp q30, q31, [x7, #16 * 30]
  150. // SME?
  151. cbz x1, check_sve_out
  152. rdsvl 11, 1
  153. adrp x6, sme_vl_out
  154. str x11, [x6, :lo12:sme_vl_out]
  155. mrs x7, S3_3_C4_C2_2
  156. adrp x6, svcr_out
  157. str x7, [x6, :lo12:svcr_out]
  158. // ZA?
  159. tbz x7, #SVCR_ZA_SHIFT, check_sm_out
  160. mov w12, #0
  161. ldr x6, =za_out
  162. 1: _str_za 12, 6
  163. add x6, x6, x11
  164. add x12, x12, #1
  165. cmp x11, x12
  166. bne 1b
  167. // ZT?
  168. cbz x2, check_sm_out
  169. adrp x6, zt_out
  170. add x6, x6, :lo12:zt_out
  171. _str_zt 6
  172. // In streaming mode?
  173. check_sm_out:
  174. tbz x7, #SVCR_SM_SHIFT, check_sve_out
  175. mov x4, x3 // FFR?
  176. b read_sve
  177. // SVE?
  178. check_sve_out:
  179. cbz x0, wait_for_reads
  180. mov x4, #1
  181. rdvl x7, #1
  182. adrp x6, sve_vl_out
  183. str x7, [x6, :lo12:sve_vl_out]
  184. read_sve:
  185. ldr x7, =z_out
  186. str z0, [x7, #0, MUL VL]
  187. str z1, [x7, #1, MUL VL]
  188. str z2, [x7, #2, MUL VL]
  189. str z3, [x7, #3, MUL VL]
  190. str z4, [x7, #4, MUL VL]
  191. str z5, [x7, #5, MUL VL]
  192. str z6, [x7, #6, MUL VL]
  193. str z7, [x7, #7, MUL VL]
  194. str z8, [x7, #8, MUL VL]
  195. str z9, [x7, #9, MUL VL]
  196. str z10, [x7, #10, MUL VL]
  197. str z11, [x7, #11, MUL VL]
  198. str z12, [x7, #12, MUL VL]
  199. str z13, [x7, #13, MUL VL]
  200. str z14, [x7, #14, MUL VL]
  201. str z15, [x7, #15, MUL VL]
  202. str z16, [x7, #16, MUL VL]
  203. str z17, [x7, #17, MUL VL]
  204. str z18, [x7, #18, MUL VL]
  205. str z19, [x7, #19, MUL VL]
  206. str z20, [x7, #20, MUL VL]
  207. str z21, [x7, #21, MUL VL]
  208. str z22, [x7, #22, MUL VL]
  209. str z23, [x7, #23, MUL VL]
  210. str z24, [x7, #24, MUL VL]
  211. str z25, [x7, #25, MUL VL]
  212. str z26, [x7, #26, MUL VL]
  213. str z27, [x7, #27, MUL VL]
  214. str z28, [x7, #28, MUL VL]
  215. str z29, [x7, #29, MUL VL]
  216. str z30, [x7, #30, MUL VL]
  217. str z31, [x7, #31, MUL VL]
  218. ldr x7, =p_out
  219. str p0, [x7, #0, MUL VL]
  220. str p1, [x7, #1, MUL VL]
  221. str p2, [x7, #2, MUL VL]
  222. str p3, [x7, #3, MUL VL]
  223. str p4, [x7, #4, MUL VL]
  224. str p5, [x7, #5, MUL VL]
  225. str p6, [x7, #6, MUL VL]
  226. str p7, [x7, #7, MUL VL]
  227. str p8, [x7, #8, MUL VL]
  228. str p9, [x7, #9, MUL VL]
  229. str p10, [x7, #10, MUL VL]
  230. str p11, [x7, #11, MUL VL]
  231. str p12, [x7, #12, MUL VL]
  232. str p13, [x7, #13, MUL VL]
  233. str p14, [x7, #14, MUL VL]
  234. str p15, [x7, #15, MUL VL]
  235. // Only save FFR if it exists
  236. cbz x4, wait_for_reads
  237. ldr x7, =ffr_out
  238. rdffr p0.b
  239. str p0, [x7]
  240. wait_for_reads:
  241. // Wait for the parent
  242. brk #0
  243. // Ensure we don't leave ourselves in streaming mode
  244. cbz x1, out
  245. msr S3_3_C4_C2_2, xzr
  246. out:
  247. ldp x11, x12, [sp, #-0x10]
  248. ret