363 lines · plain
1// SPDX-License-Identifier: GPL-2.0-only2// Copyright (C) 2021 ARM Limited.3//4// Assembly portion of the syscall ABI test5 6//7// Load values from memory into registers, invoke a syscall and save the8// register values back to memory for later checking. The syscall to be9// invoked is configured in x8 of the input GPR data.10//11// x0: SVE VL, 0 for FP only12// x1: SME VL13//14// GPRs: gpr_in, gpr_out15// FPRs: fpr_in, fpr_out16// Zn: z_in, z_out17// Pn: p_in, p_out18// FFR: ffr_in, ffr_out19// ZA: za_in, za_out20// SVCR: svcr_in, svcr_out21 22#include "syscall-abi.h"23 24.arch_extension sve25 26#define ID_AA64SMFR0_EL1_SMEver_SHIFT 5627#define ID_AA64SMFR0_EL1_SMEver_WIDTH 428 29/*30 * LDR (vector to ZA array):31 * LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]32 */33.macro _ldr_za nw, nxbase, offset=034 .inst 0xe1000000 \35 | (((\nw) & 3) << 13) \36 | ((\nxbase) << 5) \37 | ((\offset) & 7)38.endm39 40/*41 * STR (vector from ZA array):42 * STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]43 */44.macro _str_za nw, nxbase, offset=045 .inst 0xe1200000 \46 | (((\nw) & 3) << 13) \47 | ((\nxbase) << 5) \48 | ((\offset) & 7)49.endm50 51/*52 * LDR (ZT0)53 *54 * LDR ZT0, nx55 */56.macro _ldr_zt nx57 .inst 0xe11f8000 \58 | (((\nx) & 0x1f) << 5)59.endm60 61/*62 * STR (ZT0)63 *64 * STR ZT0, nx65 */66.macro _str_zt nx67 .inst 0xe13f8000 \68 | (((\nx) & 0x1f) << 5)69.endm70 71.globl do_syscall72do_syscall:73 // Store callee saved registers x19-x29 (80 bytes) plus x0 and x174 stp x29, x30, [sp, #-112]!75 mov x29, sp76 stp x0, x1, [sp, #16]77 stp x19, x20, [sp, #32]78 stp x21, x22, [sp, #48]79 stp x23, x24, [sp, #64]80 stp x25, x26, [sp, #80]81 stp x27, x28, [sp, #96]82 83 // Set SVCR if we're doing SME84 cbz x1, 1f85 adrp x2, svcr_in86 ldr x2, [x2, :lo12:svcr_in]87 msr S3_3_C4_C2_2, x2881:89 90 // Load ZA and ZT0 if enabled - uses x12 as scratch due to SME LDR91 tbz x2, #SVCR_ZA_SHIFT, 1f92 mov w12, #093 ldr x2, =za_in942: _ldr_za 12, 295 add x2, x2, x196 add x12, x12, #197 cmp x1, x1298 bne 2b99 100 // ZT0101 mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1102 ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \103 #ID_AA64SMFR0_EL1_SMEver_WIDTH104 cbz x2, 1f105 adrp x2, zt_in106 add x2, x2, :lo12:zt_in107 _ldr_zt 21081:109 110 // Load GPRs x8-x28, and save our SP/FP for later comparison111 ldr x2, =gpr_in112 add x2, x2, #64113 ldp x8, x9, [x2], #16114 ldp x10, x11, [x2], #16115 ldp x12, x13, [x2], #16116 ldp x14, x15, [x2], #16117 ldp x16, x17, [x2], #16118 ldp x18, x19, [x2], #16119 ldp x20, x21, [x2], #16120 ldp x22, x23, [x2], #16121 ldp x24, x25, [x2], #16122 ldp x26, x27, [x2], #16123 ldr x28, [x2], #8124 str x29, [x2], #8 // FP125 str x30, [x2], #8 // LR126 127 // Load FPRs if we're not doing neither SVE nor streaming SVE128 cbnz x0, 1f129 ldr x2, =svcr_in130 tbnz x2, #SVCR_SM_SHIFT, 1f131 132 ldr x2, =fpr_in133 ldp q0, q1, [x2]134 ldp q2, q3, [x2, #16 * 2]135 ldp q4, q5, [x2, #16 * 4]136 ldp q6, q7, [x2, #16 * 6]137 ldp q8, q9, [x2, #16 * 8]138 ldp q10, q11, [x2, #16 * 10]139 ldp q12, q13, [x2, #16 * 12]140 ldp q14, q15, [x2, #16 * 14]141 ldp q16, q17, [x2, #16 * 16]142 ldp q18, q19, [x2, #16 * 18]143 ldp q20, q21, [x2, #16 * 20]144 ldp q22, q23, [x2, #16 * 22]145 ldp q24, q25, [x2, #16 * 24]146 ldp q26, q27, [x2, #16 * 26]147 ldp q28, q29, [x2, #16 * 28]148 ldp q30, q31, [x2, #16 * 30]149 150 b 2f1511:152 153 // Load the SVE registers if we're doing SVE/SME154 155 ldr x2, =z_in156 ldr z0, [x2, #0, MUL VL]157 ldr z1, [x2, #1, MUL VL]158 ldr z2, [x2, #2, MUL VL]159 ldr z3, [x2, #3, MUL VL]160 ldr z4, [x2, #4, MUL VL]161 ldr z5, [x2, #5, MUL VL]162 ldr z6, [x2, #6, MUL VL]163 ldr z7, [x2, #7, MUL VL]164 ldr z8, [x2, #8, MUL VL]165 ldr z9, [x2, #9, MUL VL]166 ldr z10, [x2, #10, MUL VL]167 ldr z11, [x2, #11, MUL VL]168 ldr z12, [x2, #12, MUL VL]169 ldr z13, [x2, #13, MUL VL]170 ldr z14, [x2, #14, MUL VL]171 ldr z15, [x2, #15, MUL VL]172 ldr z16, [x2, #16, MUL VL]173 ldr z17, [x2, #17, MUL VL]174 ldr z18, [x2, #18, MUL VL]175 ldr z19, [x2, #19, MUL VL]176 ldr z20, [x2, #20, MUL VL]177 ldr z21, [x2, #21, MUL VL]178 ldr z22, [x2, #22, MUL VL]179 ldr z23, [x2, #23, MUL VL]180 ldr z24, [x2, #24, MUL VL]181 ldr z25, [x2, #25, MUL VL]182 ldr z26, [x2, #26, MUL VL]183 ldr z27, [x2, #27, MUL VL]184 ldr z28, [x2, #28, MUL VL]185 ldr z29, [x2, #29, MUL VL]186 ldr z30, [x2, #30, MUL VL]187 ldr z31, [x2, #31, MUL VL]188 189 // Only set a non-zero FFR, test patterns must be zero since the190 // syscall should clear it - this lets us handle FA64.191 ldr x2, =ffr_in192 ldr p0, [x2]193 ldr x2, [x2, #0]194 cbz x2, 1f195 wrffr p0.b1961:197 198 ldr x2, =p_in199 ldr p0, [x2, #0, MUL VL]200 ldr p1, [x2, #1, MUL VL]201 ldr p2, [x2, #2, MUL VL]202 ldr p3, [x2, #3, MUL VL]203 ldr p4, [x2, #4, MUL VL]204 ldr p5, [x2, #5, MUL VL]205 ldr p6, [x2, #6, MUL VL]206 ldr p7, [x2, #7, MUL VL]207 ldr p8, [x2, #8, MUL VL]208 ldr p9, [x2, #9, MUL VL]209 ldr p10, [x2, #10, MUL VL]210 ldr p11, [x2, #11, MUL VL]211 ldr p12, [x2, #12, MUL VL]212 ldr p13, [x2, #13, MUL VL]213 ldr p14, [x2, #14, MUL VL]214 ldr p15, [x2, #15, MUL VL]2152:216 217 // Do the syscall218 svc #0219 220 // Save GPRs x8-x30221 ldr x2, =gpr_out222 add x2, x2, #64223 stp x8, x9, [x2], #16224 stp x10, x11, [x2], #16225 stp x12, x13, [x2], #16226 stp x14, x15, [x2], #16227 stp x16, x17, [x2], #16228 stp x18, x19, [x2], #16229 stp x20, x21, [x2], #16230 stp x22, x23, [x2], #16231 stp x24, x25, [x2], #16232 stp x26, x27, [x2], #16233 stp x28, x29, [x2], #16234 str x30, [x2]235 236 // Restore x0 and x1 for feature checks237 ldp x0, x1, [sp, #16]238 239 // Save FPSIMD state240 ldr x2, =fpr_out241 stp q0, q1, [x2]242 stp q2, q3, [x2, #16 * 2]243 stp q4, q5, [x2, #16 * 4]244 stp q6, q7, [x2, #16 * 6]245 stp q8, q9, [x2, #16 * 8]246 stp q10, q11, [x2, #16 * 10]247 stp q12, q13, [x2, #16 * 12]248 stp q14, q15, [x2, #16 * 14]249 stp q16, q17, [x2, #16 * 16]250 stp q18, q19, [x2, #16 * 18]251 stp q20, q21, [x2, #16 * 20]252 stp q22, q23, [x2, #16 * 22]253 stp q24, q25, [x2, #16 * 24]254 stp q26, q27, [x2, #16 * 26]255 stp q28, q29, [x2, #16 * 28]256 stp q30, q31, [x2, #16 * 30]257 258 // Save SVCR if we're doing SME259 cbz x1, 1f260 mrs x2, S3_3_C4_C2_2261 adrp x3, svcr_out262 str x2, [x3, :lo12:svcr_out]2631:264 265 // Save ZA if it's enabled - uses x12 as scratch due to SME STR266 tbz x2, #SVCR_ZA_SHIFT, 1f267 mov w12, #0268 ldr x2, =za_out2692: _str_za 12, 2270 add x2, x2, x1271 add x12, x12, #1272 cmp x1, x12273 bne 2b274 275 // ZT0276 mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1277 ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \278 #ID_AA64SMFR0_EL1_SMEver_WIDTH279 cbz x2, 1f280 adrp x2, zt_out281 add x2, x2, :lo12:zt_out282 _str_zt 22831:284 285 // Save the SVE state if we have some286 cbz x0, 1f287 288 ldr x2, =z_out289 str z0, [x2, #0, MUL VL]290 str z1, [x2, #1, MUL VL]291 str z2, [x2, #2, MUL VL]292 str z3, [x2, #3, MUL VL]293 str z4, [x2, #4, MUL VL]294 str z5, [x2, #5, MUL VL]295 str z6, [x2, #6, MUL VL]296 str z7, [x2, #7, MUL VL]297 str z8, [x2, #8, MUL VL]298 str z9, [x2, #9, MUL VL]299 str z10, [x2, #10, MUL VL]300 str z11, [x2, #11, MUL VL]301 str z12, [x2, #12, MUL VL]302 str z13, [x2, #13, MUL VL]303 str z14, [x2, #14, MUL VL]304 str z15, [x2, #15, MUL VL]305 str z16, [x2, #16, MUL VL]306 str z17, [x2, #17, MUL VL]307 str z18, [x2, #18, MUL VL]308 str z19, [x2, #19, MUL VL]309 str z20, [x2, #20, MUL VL]310 str z21, [x2, #21, MUL VL]311 str z22, [x2, #22, MUL VL]312 str z23, [x2, #23, MUL VL]313 str z24, [x2, #24, MUL VL]314 str z25, [x2, #25, MUL VL]315 str z26, [x2, #26, MUL VL]316 str z27, [x2, #27, MUL VL]317 str z28, [x2, #28, MUL VL]318 str z29, [x2, #29, MUL VL]319 str z30, [x2, #30, MUL VL]320 str z31, [x2, #31, MUL VL]321 322 ldr x2, =p_out323 str p0, [x2, #0, MUL VL]324 str p1, [x2, #1, MUL VL]325 str p2, [x2, #2, MUL VL]326 str p3, [x2, #3, MUL VL]327 str p4, [x2, #4, MUL VL]328 str p5, [x2, #5, MUL VL]329 str p6, [x2, #6, MUL VL]330 str p7, [x2, #7, MUL VL]331 str p8, [x2, #8, MUL VL]332 str p9, [x2, #9, MUL VL]333 str p10, [x2, #10, MUL VL]334 str p11, [x2, #11, MUL VL]335 str p12, [x2, #12, MUL VL]336 str p13, [x2, #13, MUL VL]337 str p14, [x2, #14, MUL VL]338 str p15, [x2, #15, MUL VL]339 340 // Only save FFR if we wrote a value for SME341 ldr x2, =ffr_in342 ldr x2, [x2, #0]343 cbz x2, 1f344 ldr x2, =ffr_out345 rdffr p0.b346 str p0, [x2]3471:348 349 // Restore callee saved registers x19-x30350 ldp x19, x20, [sp, #32]351 ldp x21, x22, [sp, #48]352 ldp x23, x24, [sp, #64]353 ldp x25, x26, [sp, #80]354 ldp x27, x28, [sp, #96]355 ldp x29, x30, [sp], #112356 357 // Clear SVCR if we were doing SME so future tests don't have ZA358 cbz x1, 1f359 msr S3_3_C4_C2_2, xzr3601:361 362 ret363