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