1b77e995eSMark Brown// SPDX-License-Identifier: GPL-2.0-only 2b77e995eSMark Brown// Copyright (C) 2021 ARM Limited. 3b77e995eSMark Brown// 4b77e995eSMark Brown// Assembly portion of the syscall ABI test 5b77e995eSMark Brown 6b77e995eSMark Brown// 7b77e995eSMark Brown// Load values from memory into registers, invoke a syscall and save the 8b77e995eSMark Brown// register values back to memory for later checking. The syscall to be 9b77e995eSMark Brown// invoked is configured in x8 of the input GPR data. 10b77e995eSMark Brown// 11b77e995eSMark Brown// x0: SVE VL, 0 for FP only 1243e3f855SMark Brown// x1: SME VL 13b77e995eSMark Brown// 14b77e995eSMark Brown// GPRs: gpr_in, gpr_out 15b77e995eSMark Brown// FPRs: fpr_in, fpr_out 16b77e995eSMark Brown// Zn: z_in, z_out 17b77e995eSMark Brown// Pn: p_in, p_out 18b77e995eSMark Brown// FFR: ffr_in, ffr_out 1943e3f855SMark Brown// ZA: za_in, za_out 2043e3f855SMark Brown// SVCR: svcr_in, svcr_out 2143e3f855SMark Brown 2243e3f855SMark Brown#include "syscall-abi.h" 23b77e995eSMark Brown 24b77e995eSMark Brown.arch_extension sve 25b77e995eSMark Brown 2649886aa9SMark Brown#define ID_AA64SMFR0_EL1_SMEver_SHIFT 56 2749886aa9SMark Brown#define ID_AA64SMFR0_EL1_SMEver_WIDTH 4 2849886aa9SMark Brown 2943e3f855SMark Brown/* 3043e3f855SMark Brown * LDR (vector to ZA array): 3143e3f855SMark Brown * LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL] 3243e3f855SMark Brown */ 3343e3f855SMark Brown.macro _ldr_za nw, nxbase, offset=0 3443e3f855SMark Brown .inst 0xe1000000 \ 3543e3f855SMark Brown | (((\nw) & 3) << 13) \ 3643e3f855SMark Brown | ((\nxbase) << 5) \ 3743e3f855SMark Brown | ((\offset) & 7) 3843e3f855SMark Brown.endm 3943e3f855SMark Brown 4043e3f855SMark Brown/* 4143e3f855SMark Brown * STR (vector from ZA array): 4243e3f855SMark Brown * STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL] 4343e3f855SMark Brown */ 4443e3f855SMark Brown.macro _str_za nw, nxbase, offset=0 4543e3f855SMark Brown .inst 0xe1200000 \ 4643e3f855SMark Brown | (((\nw) & 3) << 13) \ 4743e3f855SMark Brown | ((\nxbase) << 5) \ 4843e3f855SMark Brown | ((\offset) & 7) 4943e3f855SMark Brown.endm 5043e3f855SMark Brown 5149886aa9SMark Brown/* 5249886aa9SMark Brown * LDR (ZT0) 5349886aa9SMark Brown * 5449886aa9SMark Brown * LDR ZT0, nx 5549886aa9SMark Brown */ 5649886aa9SMark Brown.macro _ldr_zt nx 5749886aa9SMark Brown .inst 0xe11f8000 \ 5849886aa9SMark Brown | (((\nx) & 0x1f) << 5) 5949886aa9SMark Brown.endm 6049886aa9SMark Brown 6149886aa9SMark Brown/* 6249886aa9SMark Brown * STR (ZT0) 6349886aa9SMark Brown * 6449886aa9SMark Brown * STR ZT0, nx 6549886aa9SMark Brown */ 6649886aa9SMark Brown.macro _str_zt nx 6749886aa9SMark Brown .inst 0xe13f8000 \ 6849886aa9SMark Brown | (((\nx) & 0x1f) << 5) 6949886aa9SMark Brown.endm 7049886aa9SMark Brown 71b77e995eSMark Brown.globl do_syscall 72b77e995eSMark Browndo_syscall: 73b77e995eSMark Brown // Store callee saved registers x19-x29 (80 bytes) plus x0 and x1 74b77e995eSMark Brown stp x29, x30, [sp, #-112]! 75b77e995eSMark Brown mov x29, sp 76b77e995eSMark Brown stp x0, x1, [sp, #16] 77b77e995eSMark Brown stp x19, x20, [sp, #32] 78b77e995eSMark Brown stp x21, x22, [sp, #48] 79b77e995eSMark Brown stp x23, x24, [sp, #64] 80b77e995eSMark Brown stp x25, x26, [sp, #80] 81b77e995eSMark Brown stp x27, x28, [sp, #96] 82b77e995eSMark Brown 8343e3f855SMark Brown // Set SVCR if we're doing SME 84*e2ccaf2dSWeizhao Ouyang cbz x1, load_gpr 8543e3f855SMark Brown adrp x2, svcr_in 8643e3f855SMark Brown ldr x2, [x2, :lo12:svcr_in] 8743e3f855SMark Brown msr S3_3_C4_C2_2, x2 8843e3f855SMark Brown 8949886aa9SMark Brown // Load ZA and ZT0 if enabled - uses x12 as scratch due to SME LDR 90*e2ccaf2dSWeizhao Ouyang tbz x2, #SVCR_ZA_SHIFT, load_gpr 9143e3f855SMark Brown mov w12, #0 9243e3f855SMark Brown ldr x2, =za_in 93*e2ccaf2dSWeizhao Ouyang1: _ldr_za 12, 2 9443e3f855SMark Brown add x2, x2, x1 9543e3f855SMark Brown add x12, x12, #1 9643e3f855SMark Brown cmp x1, x12 97*e2ccaf2dSWeizhao Ouyang bne 1b 9849886aa9SMark Brown 9949886aa9SMark Brown // ZT0 10049886aa9SMark Brown mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1 10149886aa9SMark Brown ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \ 10249886aa9SMark Brown #ID_AA64SMFR0_EL1_SMEver_WIDTH 103*e2ccaf2dSWeizhao Ouyang cbz x2, load_gpr 10449886aa9SMark Brown adrp x2, zt_in 10549886aa9SMark Brown add x2, x2, :lo12:zt_in 10649886aa9SMark Brown _ldr_zt 2 10743e3f855SMark Brown 108*e2ccaf2dSWeizhao Ouyangload_gpr: 109b77e995eSMark Brown // Load GPRs x8-x28, and save our SP/FP for later comparison 110b77e995eSMark Brown ldr x2, =gpr_in 111b77e995eSMark Brown add x2, x2, #64 112b77e995eSMark Brown ldp x8, x9, [x2], #16 113b77e995eSMark Brown ldp x10, x11, [x2], #16 114b77e995eSMark Brown ldp x12, x13, [x2], #16 115b77e995eSMark Brown ldp x14, x15, [x2], #16 116b77e995eSMark Brown ldp x16, x17, [x2], #16 117b77e995eSMark Brown ldp x18, x19, [x2], #16 118b77e995eSMark Brown ldp x20, x21, [x2], #16 119b77e995eSMark Brown ldp x22, x23, [x2], #16 120b77e995eSMark Brown ldp x24, x25, [x2], #16 121b77e995eSMark Brown ldp x26, x27, [x2], #16 122b77e995eSMark Brown ldr x28, [x2], #8 123b77e995eSMark Brown str x29, [x2], #8 // FP 124b77e995eSMark Brown str x30, [x2], #8 // LR 125b77e995eSMark Brown 126024e4a15SMark Brown // Load FPRs if we're not doing neither SVE nor streaming SVE 127*e2ccaf2dSWeizhao Ouyang cbnz x0, check_sve_in 128024e4a15SMark Brown ldr x2, =svcr_in 129*e2ccaf2dSWeizhao Ouyang tbnz x2, #SVCR_SM_SHIFT, check_sve_in 130024e4a15SMark Brown 131b77e995eSMark Brown ldr x2, =fpr_in 132b77e995eSMark Brown ldp q0, q1, [x2] 133b77e995eSMark Brown ldp q2, q3, [x2, #16 * 2] 134b77e995eSMark Brown ldp q4, q5, [x2, #16 * 4] 135b77e995eSMark Brown ldp q6, q7, [x2, #16 * 6] 136b77e995eSMark Brown ldp q8, q9, [x2, #16 * 8] 137b77e995eSMark Brown ldp q10, q11, [x2, #16 * 10] 138b77e995eSMark Brown ldp q12, q13, [x2, #16 * 12] 139b77e995eSMark Brown ldp q14, q15, [x2, #16 * 14] 140b77e995eSMark Brown ldp q16, q17, [x2, #16 * 16] 141b77e995eSMark Brown ldp q18, q19, [x2, #16 * 18] 142b77e995eSMark Brown ldp q20, q21, [x2, #16 * 20] 143b77e995eSMark Brown ldp q22, q23, [x2, #16 * 22] 144b77e995eSMark Brown ldp q24, q25, [x2, #16 * 24] 145b77e995eSMark Brown ldp q26, q27, [x2, #16 * 26] 146b77e995eSMark Brown ldp q28, q29, [x2, #16 * 28] 147b77e995eSMark Brown ldp q30, q31, [x2, #16 * 30] 148024e4a15SMark Brown 149024e4a15SMark Brown b 2f 150b77e995eSMark Brown 151*e2ccaf2dSWeizhao Ouyangcheck_sve_in: 15243e3f855SMark Brown // Load the SVE registers if we're doing SVE/SME 153b77e995eSMark Brown 154b77e995eSMark Brown ldr x2, =z_in 155b77e995eSMark Brown ldr z0, [x2, #0, MUL VL] 156b77e995eSMark Brown ldr z1, [x2, #1, MUL VL] 157b77e995eSMark Brown ldr z2, [x2, #2, MUL VL] 158b77e995eSMark Brown ldr z3, [x2, #3, MUL VL] 159b77e995eSMark Brown ldr z4, [x2, #4, MUL VL] 160b77e995eSMark Brown ldr z5, [x2, #5, MUL VL] 161b77e995eSMark Brown ldr z6, [x2, #6, MUL VL] 162b77e995eSMark Brown ldr z7, [x2, #7, MUL VL] 163b77e995eSMark Brown ldr z8, [x2, #8, MUL VL] 164b77e995eSMark Brown ldr z9, [x2, #9, MUL VL] 165b77e995eSMark Brown ldr z10, [x2, #10, MUL VL] 166b77e995eSMark Brown ldr z11, [x2, #11, MUL VL] 167b77e995eSMark Brown ldr z12, [x2, #12, MUL VL] 168b77e995eSMark Brown ldr z13, [x2, #13, MUL VL] 169b77e995eSMark Brown ldr z14, [x2, #14, MUL VL] 170b77e995eSMark Brown ldr z15, [x2, #15, MUL VL] 171b77e995eSMark Brown ldr z16, [x2, #16, MUL VL] 172b77e995eSMark Brown ldr z17, [x2, #17, MUL VL] 173b77e995eSMark Brown ldr z18, [x2, #18, MUL VL] 174b77e995eSMark Brown ldr z19, [x2, #19, MUL VL] 175b77e995eSMark Brown ldr z20, [x2, #20, MUL VL] 176b77e995eSMark Brown ldr z21, [x2, #21, MUL VL] 177b77e995eSMark Brown ldr z22, [x2, #22, MUL VL] 178b77e995eSMark Brown ldr z23, [x2, #23, MUL VL] 179b77e995eSMark Brown ldr z24, [x2, #24, MUL VL] 180b77e995eSMark Brown ldr z25, [x2, #25, MUL VL] 181b77e995eSMark Brown ldr z26, [x2, #26, MUL VL] 182b77e995eSMark Brown ldr z27, [x2, #27, MUL VL] 183b77e995eSMark Brown ldr z28, [x2, #28, MUL VL] 184b77e995eSMark Brown ldr z29, [x2, #29, MUL VL] 185b77e995eSMark Brown ldr z30, [x2, #30, MUL VL] 186b77e995eSMark Brown ldr z31, [x2, #31, MUL VL] 187b77e995eSMark Brown 18843e3f855SMark Brown // Only set a non-zero FFR, test patterns must be zero since the 18943e3f855SMark Brown // syscall should clear it - this lets us handle FA64. 190b77e995eSMark Brown ldr x2, =ffr_in 191284d2b44SMark Brown ldr p0, [x2] 19243e3f855SMark Brown ldr x2, [x2, #0] 193024e4a15SMark Brown cbz x2, 1f 194b77e995eSMark Brown wrffr p0.b 195024e4a15SMark Brown1: 196b77e995eSMark Brown 197b77e995eSMark Brown ldr x2, =p_in 198b77e995eSMark Brown ldr p0, [x2, #0, MUL VL] 199b77e995eSMark Brown ldr p1, [x2, #1, MUL VL] 200b77e995eSMark Brown ldr p2, [x2, #2, MUL VL] 201b77e995eSMark Brown ldr p3, [x2, #3, MUL VL] 202b77e995eSMark Brown ldr p4, [x2, #4, MUL VL] 203b77e995eSMark Brown ldr p5, [x2, #5, MUL VL] 204b77e995eSMark Brown ldr p6, [x2, #6, MUL VL] 205b77e995eSMark Brown ldr p7, [x2, #7, MUL VL] 206b77e995eSMark Brown ldr p8, [x2, #8, MUL VL] 207b77e995eSMark Brown ldr p9, [x2, #9, MUL VL] 208b77e995eSMark Brown ldr p10, [x2, #10, MUL VL] 209b77e995eSMark Brown ldr p11, [x2, #11, MUL VL] 210b77e995eSMark Brown ldr p12, [x2, #12, MUL VL] 211b77e995eSMark Brown ldr p13, [x2, #13, MUL VL] 212b77e995eSMark Brown ldr p14, [x2, #14, MUL VL] 213b77e995eSMark Brown ldr p15, [x2, #15, MUL VL] 214024e4a15SMark Brown2: 215b77e995eSMark Brown 216b77e995eSMark Brown // Do the syscall 217b77e995eSMark Brown svc #0 218b77e995eSMark Brown 219b77e995eSMark Brown // Save GPRs x8-x30 220b77e995eSMark Brown ldr x2, =gpr_out 221b77e995eSMark Brown add x2, x2, #64 222b77e995eSMark Brown stp x8, x9, [x2], #16 223b77e995eSMark Brown stp x10, x11, [x2], #16 224b77e995eSMark Brown stp x12, x13, [x2], #16 225b77e995eSMark Brown stp x14, x15, [x2], #16 226b77e995eSMark Brown stp x16, x17, [x2], #16 227b77e995eSMark Brown stp x18, x19, [x2], #16 228b77e995eSMark Brown stp x20, x21, [x2], #16 229b77e995eSMark Brown stp x22, x23, [x2], #16 230b77e995eSMark Brown stp x24, x25, [x2], #16 231b77e995eSMark Brown stp x26, x27, [x2], #16 232b77e995eSMark Brown stp x28, x29, [x2], #16 233b77e995eSMark Brown str x30, [x2] 234b77e995eSMark Brown 235b77e995eSMark Brown // Restore x0 and x1 for feature checks 236b77e995eSMark Brown ldp x0, x1, [sp, #16] 237b77e995eSMark Brown 238b77e995eSMark Brown // Save FPSIMD state 239b77e995eSMark Brown ldr x2, =fpr_out 240b77e995eSMark Brown stp q0, q1, [x2] 241b77e995eSMark Brown stp q2, q3, [x2, #16 * 2] 242b77e995eSMark Brown stp q4, q5, [x2, #16 * 4] 243b77e995eSMark Brown stp q6, q7, [x2, #16 * 6] 244b77e995eSMark Brown stp q8, q9, [x2, #16 * 8] 245b77e995eSMark Brown stp q10, q11, [x2, #16 * 10] 246b77e995eSMark Brown stp q12, q13, [x2, #16 * 12] 247b77e995eSMark Brown stp q14, q15, [x2, #16 * 14] 248b77e995eSMark Brown stp q16, q17, [x2, #16 * 16] 249b77e995eSMark Brown stp q18, q19, [x2, #16 * 18] 250b77e995eSMark Brown stp q20, q21, [x2, #16 * 20] 251b77e995eSMark Brown stp q22, q23, [x2, #16 * 22] 252b77e995eSMark Brown stp q24, q25, [x2, #16 * 24] 253b77e995eSMark Brown stp q26, q27, [x2, #16 * 26] 254b77e995eSMark Brown stp q28, q29, [x2, #16 * 28] 255b77e995eSMark Brown stp q30, q31, [x2, #16 * 30] 256b77e995eSMark Brown 25743e3f855SMark Brown // Save SVCR if we're doing SME 258*e2ccaf2dSWeizhao Ouyang cbz x1, check_sve_out 25943e3f855SMark Brown mrs x2, S3_3_C4_C2_2 26043e3f855SMark Brown adrp x3, svcr_out 26143e3f855SMark Brown str x2, [x3, :lo12:svcr_out] 26243e3f855SMark Brown 26343e3f855SMark Brown // Save ZA if it's enabled - uses x12 as scratch due to SME STR 264*e2ccaf2dSWeizhao Ouyang tbz x2, #SVCR_ZA_SHIFT, check_sve_out 26543e3f855SMark Brown mov w12, #0 26643e3f855SMark Brown ldr x2, =za_out 267*e2ccaf2dSWeizhao Ouyang1: _str_za 12, 2 26843e3f855SMark Brown add x2, x2, x1 26943e3f855SMark Brown add x12, x12, #1 27043e3f855SMark Brown cmp x1, x12 271*e2ccaf2dSWeizhao Ouyang bne 1b 27249886aa9SMark Brown 27349886aa9SMark Brown // ZT0 27449886aa9SMark Brown mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1 27549886aa9SMark Brown ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \ 27649886aa9SMark Brown #ID_AA64SMFR0_EL1_SMEver_WIDTH 277*e2ccaf2dSWeizhao Ouyang cbz x2, check_sve_out 27849886aa9SMark Brown adrp x2, zt_out 27949886aa9SMark Brown add x2, x2, :lo12:zt_out 28049886aa9SMark Brown _str_zt 2 28143e3f855SMark Brown 282*e2ccaf2dSWeizhao Ouyangcheck_sve_out: 283b77e995eSMark Brown // Save the SVE state if we have some 284b77e995eSMark Brown cbz x0, 1f 285b77e995eSMark Brown 286b77e995eSMark Brown ldr x2, =z_out 287b77e995eSMark Brown str z0, [x2, #0, MUL VL] 288b77e995eSMark Brown str z1, [x2, #1, MUL VL] 289b77e995eSMark Brown str z2, [x2, #2, MUL VL] 290b77e995eSMark Brown str z3, [x2, #3, MUL VL] 291b77e995eSMark Brown str z4, [x2, #4, MUL VL] 292b77e995eSMark Brown str z5, [x2, #5, MUL VL] 293b77e995eSMark Brown str z6, [x2, #6, MUL VL] 294b77e995eSMark Brown str z7, [x2, #7, MUL VL] 295b77e995eSMark Brown str z8, [x2, #8, MUL VL] 296b77e995eSMark Brown str z9, [x2, #9, MUL VL] 297b77e995eSMark Brown str z10, [x2, #10, MUL VL] 298b77e995eSMark Brown str z11, [x2, #11, MUL VL] 299b77e995eSMark Brown str z12, [x2, #12, MUL VL] 300b77e995eSMark Brown str z13, [x2, #13, MUL VL] 301b77e995eSMark Brown str z14, [x2, #14, MUL VL] 302b77e995eSMark Brown str z15, [x2, #15, MUL VL] 303b77e995eSMark Brown str z16, [x2, #16, MUL VL] 304b77e995eSMark Brown str z17, [x2, #17, MUL VL] 305b77e995eSMark Brown str z18, [x2, #18, MUL VL] 306b77e995eSMark Brown str z19, [x2, #19, MUL VL] 307b77e995eSMark Brown str z20, [x2, #20, MUL VL] 308b77e995eSMark Brown str z21, [x2, #21, MUL VL] 309b77e995eSMark Brown str z22, [x2, #22, MUL VL] 310b77e995eSMark Brown str z23, [x2, #23, MUL VL] 311b77e995eSMark Brown str z24, [x2, #24, MUL VL] 312b77e995eSMark Brown str z25, [x2, #25, MUL VL] 313b77e995eSMark Brown str z26, [x2, #26, MUL VL] 314b77e995eSMark Brown str z27, [x2, #27, MUL VL] 315b77e995eSMark Brown str z28, [x2, #28, MUL VL] 316b77e995eSMark Brown str z29, [x2, #29, MUL VL] 317b77e995eSMark Brown str z30, [x2, #30, MUL VL] 318b77e995eSMark Brown str z31, [x2, #31, MUL VL] 319b77e995eSMark Brown 320b77e995eSMark Brown ldr x2, =p_out 321b77e995eSMark Brown str p0, [x2, #0, MUL VL] 322b77e995eSMark Brown str p1, [x2, #1, MUL VL] 323b77e995eSMark Brown str p2, [x2, #2, MUL VL] 324b77e995eSMark Brown str p3, [x2, #3, MUL VL] 325b77e995eSMark Brown str p4, [x2, #4, MUL VL] 326b77e995eSMark Brown str p5, [x2, #5, MUL VL] 327b77e995eSMark Brown str p6, [x2, #6, MUL VL] 328b77e995eSMark Brown str p7, [x2, #7, MUL VL] 329b77e995eSMark Brown str p8, [x2, #8, MUL VL] 330b77e995eSMark Brown str p9, [x2, #9, MUL VL] 331b77e995eSMark Brown str p10, [x2, #10, MUL VL] 332b77e995eSMark Brown str p11, [x2, #11, MUL VL] 333b77e995eSMark Brown str p12, [x2, #12, MUL VL] 334b77e995eSMark Brown str p13, [x2, #13, MUL VL] 335b77e995eSMark Brown str p14, [x2, #14, MUL VL] 336b77e995eSMark Brown str p15, [x2, #15, MUL VL] 337b77e995eSMark Brown 33843e3f855SMark Brown // Only save FFR if we wrote a value for SME 33943e3f855SMark Brown ldr x2, =ffr_in 34043e3f855SMark Brown ldr x2, [x2, #0] 34143e3f855SMark Brown cbz x2, 1f 342b77e995eSMark Brown ldr x2, =ffr_out 343b77e995eSMark Brown rdffr p0.b 344284d2b44SMark Brown str p0, [x2] 345b77e995eSMark Brown1: 346b77e995eSMark Brown 347b77e995eSMark Brown // Restore callee saved registers x19-x30 348b77e995eSMark Brown ldp x19, x20, [sp, #32] 349b77e995eSMark Brown ldp x21, x22, [sp, #48] 350b77e995eSMark Brown ldp x23, x24, [sp, #64] 351b77e995eSMark Brown ldp x25, x26, [sp, #80] 352b77e995eSMark Brown ldp x27, x28, [sp, #96] 353b77e995eSMark Brown ldp x29, x30, [sp], #112 354b77e995eSMark Brown 35543e3f855SMark Brown // Clear SVCR if we were doing SME so future tests don't have ZA 35643e3f855SMark Brown cbz x1, 1f 35743e3f855SMark Brown msr S3_3_C4_C2_2, xzr 35843e3f855SMark Brown1: 35943e3f855SMark Brown 360b77e995eSMark Brown ret 361