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 26*49886aa9SMark Brown#define ID_AA64SMFR0_EL1_SMEver_SHIFT 56 27*49886aa9SMark Brown#define ID_AA64SMFR0_EL1_SMEver_WIDTH 4 28*49886aa9SMark 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 51*49886aa9SMark Brown/* 52*49886aa9SMark Brown * LDR (ZT0) 53*49886aa9SMark Brown * 54*49886aa9SMark Brown * LDR ZT0, nx 55*49886aa9SMark Brown */ 56*49886aa9SMark Brown.macro _ldr_zt nx 57*49886aa9SMark Brown .inst 0xe11f8000 \ 58*49886aa9SMark Brown | (((\nx) & 0x1f) << 5) 59*49886aa9SMark Brown.endm 60*49886aa9SMark Brown 61*49886aa9SMark Brown/* 62*49886aa9SMark Brown * STR (ZT0) 63*49886aa9SMark Brown * 64*49886aa9SMark Brown * STR ZT0, nx 65*49886aa9SMark Brown */ 66*49886aa9SMark Brown.macro _str_zt nx 67*49886aa9SMark Brown .inst 0xe13f8000 \ 68*49886aa9SMark Brown | (((\nx) & 0x1f) << 5) 69*49886aa9SMark Brown.endm 70*49886aa9SMark 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 8443e3f855SMark Brown cbz x1, 1f 8543e3f855SMark Brown adrp x2, svcr_in 8643e3f855SMark Brown ldr x2, [x2, :lo12:svcr_in] 8743e3f855SMark Brown msr S3_3_C4_C2_2, x2 8843e3f855SMark Brown1: 8943e3f855SMark Brown 90*49886aa9SMark Brown // Load ZA and ZT0 if enabled - uses x12 as scratch due to SME LDR 9143e3f855SMark Brown tbz x2, #SVCR_ZA_SHIFT, 1f 9243e3f855SMark Brown mov w12, #0 9343e3f855SMark Brown ldr x2, =za_in 9443e3f855SMark Brown2: _ldr_za 12, 2 9543e3f855SMark Brown add x2, x2, x1 9643e3f855SMark Brown add x12, x12, #1 9743e3f855SMark Brown cmp x1, x12 9843e3f855SMark Brown bne 2b 99*49886aa9SMark Brown 100*49886aa9SMark Brown // ZT0 101*49886aa9SMark Brown mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1 102*49886aa9SMark Brown ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \ 103*49886aa9SMark Brown #ID_AA64SMFR0_EL1_SMEver_WIDTH 104*49886aa9SMark Brown cbz x2, 1f 105*49886aa9SMark Brown adrp x2, zt_in 106*49886aa9SMark Brown add x2, x2, :lo12:zt_in 107*49886aa9SMark Brown _ldr_zt 2 10843e3f855SMark Brown1: 10943e3f855SMark Brown 110b77e995eSMark Brown // Load GPRs x8-x28, and save our SP/FP for later comparison 111b77e995eSMark Brown ldr x2, =gpr_in 112b77e995eSMark Brown add x2, x2, #64 113b77e995eSMark Brown ldp x8, x9, [x2], #16 114b77e995eSMark Brown ldp x10, x11, [x2], #16 115b77e995eSMark Brown ldp x12, x13, [x2], #16 116b77e995eSMark Brown ldp x14, x15, [x2], #16 117b77e995eSMark Brown ldp x16, x17, [x2], #16 118b77e995eSMark Brown ldp x18, x19, [x2], #16 119b77e995eSMark Brown ldp x20, x21, [x2], #16 120b77e995eSMark Brown ldp x22, x23, [x2], #16 121b77e995eSMark Brown ldp x24, x25, [x2], #16 122b77e995eSMark Brown ldp x26, x27, [x2], #16 123b77e995eSMark Brown ldr x28, [x2], #8 124b77e995eSMark Brown str x29, [x2], #8 // FP 125b77e995eSMark Brown str x30, [x2], #8 // LR 126b77e995eSMark Brown 127b77e995eSMark Brown // Load FPRs if we're not doing neither SVE nor streaming SVE 128b77e995eSMark Brown cbnz x0, 1f 129b77e995eSMark Brown ldr x2, =svcr_in 130b77e995eSMark Brown tbnz x2, #SVCR_SM_SHIFT, 1f 131b77e995eSMark Brown 132b77e995eSMark Brown ldr x2, =fpr_in 133b77e995eSMark Brown ldp q0, q1, [x2] 134b77e995eSMark Brown ldp q2, q3, [x2, #16 * 2] 135b77e995eSMark Brown ldp q4, q5, [x2, #16 * 4] 136b77e995eSMark Brown ldp q6, q7, [x2, #16 * 6] 137b77e995eSMark Brown ldp q8, q9, [x2, #16 * 8] 138b77e995eSMark Brown ldp q10, q11, [x2, #16 * 10] 139b77e995eSMark Brown ldp q12, q13, [x2, #16 * 12] 140b77e995eSMark Brown ldp q14, q15, [x2, #16 * 14] 141b77e995eSMark Brown ldp q16, q17, [x2, #16 * 16] 142b77e995eSMark Brown ldp q18, q19, [x2, #16 * 18] 143b77e995eSMark Brown ldp q20, q21, [x2, #16 * 20] 144b77e995eSMark Brown ldp q22, q23, [x2, #16 * 22] 145b77e995eSMark Brown ldp q24, q25, [x2, #16 * 24] 146b77e995eSMark Brown ldp q26, q27, [x2, #16 * 26] 147b77e995eSMark Brown ldp q28, q29, [x2, #16 * 28] 14843e3f855SMark Brown ldp q30, q31, [x2, #16 * 30] 149b77e995eSMark Brown 150b77e995eSMark Brown b 2f 151b77e995eSMark Brown1: 152b77e995eSMark Brown 153b77e995eSMark Brown // Load the SVE registers if we're doing SVE/SME 154b77e995eSMark Brown 155b77e995eSMark Brown ldr x2, =z_in 156b77e995eSMark Brown ldr z0, [x2, #0, MUL VL] 157b77e995eSMark Brown ldr z1, [x2, #1, MUL VL] 158b77e995eSMark Brown ldr z2, [x2, #2, MUL VL] 159b77e995eSMark Brown ldr z3, [x2, #3, MUL VL] 160b77e995eSMark Brown ldr z4, [x2, #4, MUL VL] 161b77e995eSMark Brown ldr z5, [x2, #5, MUL VL] 162b77e995eSMark Brown ldr z6, [x2, #6, MUL VL] 163b77e995eSMark Brown ldr z7, [x2, #7, MUL VL] 164b77e995eSMark Brown ldr z8, [x2, #8, MUL VL] 165b77e995eSMark Brown ldr z9, [x2, #9, MUL VL] 166b77e995eSMark Brown ldr z10, [x2, #10, MUL VL] 167b77e995eSMark Brown ldr z11, [x2, #11, MUL VL] 168b77e995eSMark Brown ldr z12, [x2, #12, MUL VL] 169b77e995eSMark Brown ldr z13, [x2, #13, MUL VL] 170b77e995eSMark Brown ldr z14, [x2, #14, MUL VL] 171b77e995eSMark Brown ldr z15, [x2, #15, MUL VL] 172b77e995eSMark Brown ldr z16, [x2, #16, MUL VL] 173b77e995eSMark Brown ldr z17, [x2, #17, MUL VL] 174b77e995eSMark Brown ldr z18, [x2, #18, MUL VL] 175b77e995eSMark Brown ldr z19, [x2, #19, MUL VL] 176b77e995eSMark Brown ldr z20, [x2, #20, MUL VL] 177b77e995eSMark Brown ldr z21, [x2, #21, MUL VL] 178b77e995eSMark Brown ldr z22, [x2, #22, MUL VL] 179b77e995eSMark Brown ldr z23, [x2, #23, MUL VL] 180b77e995eSMark Brown ldr z24, [x2, #24, MUL VL] 181b77e995eSMark Brown ldr z25, [x2, #25, MUL VL] 182b77e995eSMark Brown ldr z26, [x2, #26, MUL VL] 183b77e995eSMark Brown ldr z27, [x2, #27, MUL VL] 184b77e995eSMark Brown ldr z28, [x2, #28, MUL VL] 18543e3f855SMark Brown ldr z29, [x2, #29, MUL VL] 18643e3f855SMark Brown ldr z30, [x2, #30, MUL VL] 187b77e995eSMark Brown ldr z31, [x2, #31, MUL VL] 188284d2b44SMark Brown 18943e3f855SMark Brown // Only set a non-zero FFR, test patterns must be zero since the 19043e3f855SMark Brown // syscall should clear it - this lets us handle FA64. 191b77e995eSMark Brown ldr x2, =ffr_in 19243e3f855SMark Brown ldr p0, [x2] 193b77e995eSMark Brown ldr x2, [x2, #0] 194b77e995eSMark Brown cbz x2, 1f 195b77e995eSMark Brown wrffr p0.b 196b77e995eSMark Brown1: 197b77e995eSMark Brown 198b77e995eSMark Brown ldr x2, =p_in 199b77e995eSMark Brown ldr p0, [x2, #0, MUL VL] 200b77e995eSMark Brown ldr p1, [x2, #1, MUL VL] 201b77e995eSMark Brown ldr p2, [x2, #2, MUL VL] 202b77e995eSMark Brown ldr p3, [x2, #3, MUL VL] 203b77e995eSMark Brown ldr p4, [x2, #4, MUL VL] 204b77e995eSMark Brown ldr p5, [x2, #5, MUL VL] 205b77e995eSMark Brown ldr p6, [x2, #6, MUL VL] 206b77e995eSMark Brown ldr p7, [x2, #7, MUL VL] 207b77e995eSMark Brown ldr p8, [x2, #8, MUL VL] 208b77e995eSMark Brown ldr p9, [x2, #9, MUL VL] 209b77e995eSMark Brown ldr p10, [x2, #10, MUL VL] 210b77e995eSMark Brown ldr p11, [x2, #11, MUL VL] 211b77e995eSMark Brown ldr p12, [x2, #12, MUL VL] 212b77e995eSMark Brown ldr p13, [x2, #13, MUL VL] 213b77e995eSMark Brown ldr p14, [x2, #14, MUL VL] 214b77e995eSMark Brown ldr p15, [x2, #15, MUL VL] 215b77e995eSMark Brown2: 216b77e995eSMark Brown 217b77e995eSMark Brown // Do the syscall 218b77e995eSMark Brown svc #0 219b77e995eSMark Brown 220b77e995eSMark Brown // Save GPRs x8-x30 221b77e995eSMark Brown ldr x2, =gpr_out 222b77e995eSMark Brown add x2, x2, #64 223b77e995eSMark Brown stp x8, x9, [x2], #16 224b77e995eSMark Brown stp x10, x11, [x2], #16 225b77e995eSMark Brown stp x12, x13, [x2], #16 226b77e995eSMark Brown stp x14, x15, [x2], #16 227b77e995eSMark Brown stp x16, x17, [x2], #16 228b77e995eSMark Brown stp x18, x19, [x2], #16 229b77e995eSMark Brown stp x20, x21, [x2], #16 230b77e995eSMark Brown stp x22, x23, [x2], #16 231b77e995eSMark Brown stp x24, x25, [x2], #16 232b77e995eSMark Brown stp x26, x27, [x2], #16 233b77e995eSMark Brown stp x28, x29, [x2], #16 234b77e995eSMark Brown str x30, [x2] 235b77e995eSMark Brown 236b77e995eSMark Brown // Restore x0 and x1 for feature checks 237b77e995eSMark Brown ldp x0, x1, [sp, #16] 238b77e995eSMark Brown 239b77e995eSMark Brown // Save FPSIMD state 240b77e995eSMark Brown ldr x2, =fpr_out 241b77e995eSMark Brown stp q0, q1, [x2] 242b77e995eSMark Brown stp q2, q3, [x2, #16 * 2] 243b77e995eSMark Brown stp q4, q5, [x2, #16 * 4] 244b77e995eSMark Brown stp q6, q7, [x2, #16 * 6] 245b77e995eSMark Brown stp q8, q9, [x2, #16 * 8] 246b77e995eSMark Brown stp q10, q11, [x2, #16 * 10] 247b77e995eSMark Brown stp q12, q13, [x2, #16 * 12] 248b77e995eSMark Brown stp q14, q15, [x2, #16 * 14] 249b77e995eSMark Brown stp q16, q17, [x2, #16 * 16] 250b77e995eSMark Brown stp q18, q19, [x2, #16 * 18] 251b77e995eSMark Brown stp q20, q21, [x2, #16 * 20] 252b77e995eSMark Brown stp q22, q23, [x2, #16 * 22] 253b77e995eSMark Brown stp q24, q25, [x2, #16 * 24] 25443e3f855SMark Brown stp q26, q27, [x2, #16 * 26] 25543e3f855SMark Brown stp q28, q29, [x2, #16 * 28] 25643e3f855SMark Brown stp q30, q31, [x2, #16 * 30] 25743e3f855SMark Brown 25843e3f855SMark Brown // Save SVCR if we're doing SME 25943e3f855SMark Brown cbz x1, 1f 26043e3f855SMark Brown mrs x2, S3_3_C4_C2_2 26143e3f855SMark Brown adrp x3, svcr_out 26243e3f855SMark Brown str x2, [x3, :lo12:svcr_out] 26343e3f855SMark Brown1: 26443e3f855SMark Brown 26543e3f855SMark Brown // Save ZA if it's enabled - uses x12 as scratch due to SME STR 26643e3f855SMark Brown tbz x2, #SVCR_ZA_SHIFT, 1f 26743e3f855SMark Brown mov w12, #0 26843e3f855SMark Brown ldr x2, =za_out 26943e3f855SMark Brown2: _str_za 12, 2 270*49886aa9SMark Brown add x2, x2, x1 271*49886aa9SMark Brown add x12, x12, #1 272*49886aa9SMark Brown cmp x1, x12 273*49886aa9SMark Brown bne 2b 274*49886aa9SMark Brown 275*49886aa9SMark Brown // ZT0 276*49886aa9SMark Brown mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1 277*49886aa9SMark Brown ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \ 278*49886aa9SMark Brown #ID_AA64SMFR0_EL1_SMEver_WIDTH 27943e3f855SMark Brown cbz x2, 1f 28043e3f855SMark Brown adrp x2, zt_out 281b77e995eSMark Brown add x2, x2, :lo12:zt_out 282b77e995eSMark Brown _str_zt 2 283b77e995eSMark Brown1: 284b77e995eSMark Brown 285b77e995eSMark Brown // Save the SVE state if we have some 286b77e995eSMark Brown cbz x0, 1f 287b77e995eSMark Brown 288b77e995eSMark Brown ldr x2, =z_out 289b77e995eSMark Brown str z0, [x2, #0, MUL VL] 290b77e995eSMark Brown str z1, [x2, #1, MUL VL] 291b77e995eSMark Brown str z2, [x2, #2, MUL VL] 292b77e995eSMark Brown str z3, [x2, #3, MUL VL] 293b77e995eSMark Brown str z4, [x2, #4, MUL VL] 294b77e995eSMark Brown str z5, [x2, #5, MUL VL] 295b77e995eSMark Brown str z6, [x2, #6, MUL VL] 296b77e995eSMark Brown str z7, [x2, #7, MUL VL] 297b77e995eSMark Brown str z8, [x2, #8, MUL VL] 298b77e995eSMark Brown str z9, [x2, #9, MUL VL] 299b77e995eSMark Brown str z10, [x2, #10, MUL VL] 300b77e995eSMark Brown str z11, [x2, #11, MUL VL] 301b77e995eSMark Brown str z12, [x2, #12, MUL VL] 302b77e995eSMark Brown str z13, [x2, #13, MUL VL] 303b77e995eSMark Brown str z14, [x2, #14, MUL VL] 304b77e995eSMark Brown str z15, [x2, #15, MUL VL] 305b77e995eSMark Brown str z16, [x2, #16, MUL VL] 306b77e995eSMark Brown str z17, [x2, #17, MUL VL] 307b77e995eSMark Brown str z18, [x2, #18, MUL VL] 308b77e995eSMark Brown str z19, [x2, #19, MUL VL] 309b77e995eSMark Brown str z20, [x2, #20, MUL VL] 310b77e995eSMark Brown str z21, [x2, #21, MUL VL] 311b77e995eSMark Brown str z22, [x2, #22, MUL VL] 312b77e995eSMark Brown str z23, [x2, #23, MUL VL] 313b77e995eSMark Brown str z24, [x2, #24, MUL VL] 314b77e995eSMark Brown str z25, [x2, #25, MUL VL] 315b77e995eSMark Brown str z26, [x2, #26, MUL VL] 316b77e995eSMark Brown str z27, [x2, #27, MUL VL] 317b77e995eSMark Brown str z28, [x2, #28, MUL VL] 318b77e995eSMark Brown str z29, [x2, #29, MUL VL] 319b77e995eSMark Brown str z30, [x2, #30, MUL VL] 320b77e995eSMark Brown str z31, [x2, #31, MUL VL] 321b77e995eSMark Brown 322b77e995eSMark Brown ldr x2, =p_out 323b77e995eSMark Brown str p0, [x2, #0, MUL VL] 324b77e995eSMark Brown str p1, [x2, #1, MUL VL] 325b77e995eSMark Brown str p2, [x2, #2, MUL VL] 326b77e995eSMark Brown str p3, [x2, #3, MUL VL] 327b77e995eSMark Brown str p4, [x2, #4, MUL VL] 328b77e995eSMark Brown str p5, [x2, #5, MUL VL] 329b77e995eSMark Brown str p6, [x2, #6, MUL VL] 330b77e995eSMark Brown str p7, [x2, #7, MUL VL] 331b77e995eSMark Brown str p8, [x2, #8, MUL VL] 332b77e995eSMark Brown str p9, [x2, #9, MUL VL] 333b77e995eSMark Brown str p10, [x2, #10, MUL VL] 334b77e995eSMark Brown str p11, [x2, #11, MUL VL] 335b77e995eSMark Brown str p12, [x2, #12, MUL VL] 33643e3f855SMark Brown str p13, [x2, #13, MUL VL] 33743e3f855SMark Brown str p14, [x2, #14, MUL VL] 33843e3f855SMark Brown str p15, [x2, #15, MUL VL] 33943e3f855SMark Brown 340b77e995eSMark Brown // Only save FFR if we wrote a value for SME 341b77e995eSMark Brown ldr x2, =ffr_in 342284d2b44SMark Brown ldr x2, [x2, #0] 343b77e995eSMark Brown cbz x2, 1f 344b77e995eSMark Brown ldr x2, =ffr_out 345b77e995eSMark Brown rdffr p0.b 346b77e995eSMark Brown str p0, [x2] 347b77e995eSMark Brown1: 348b77e995eSMark Brown 349b77e995eSMark Brown // Restore callee saved registers x19-x30 350b77e995eSMark Brown ldp x19, x20, [sp, #32] 351b77e995eSMark Brown ldp x21, x22, [sp, #48] 352b77e995eSMark Brown ldp x23, x24, [sp, #64] 35343e3f855SMark Brown ldp x25, x26, [sp, #80] 35443e3f855SMark Brown ldp x27, x28, [sp, #96] 35543e3f855SMark Brown ldp x29, x30, [sp], #112 35643e3f855SMark Brown 35743e3f855SMark Brown // Clear SVCR if we were doing SME so future tests don't have ZA 358b77e995eSMark Brown cbz x1, 1f 359 msr S3_3_C4_C2_2, xzr 3601: 361 362 ret 363