diff options
Diffstat (limited to 'tools/testing/selftests/arm64/abi/syscall-abi-asm.S')
| -rw-r--r-- | tools/testing/selftests/arm64/abi/syscall-abi-asm.S | 83 |
1 files changed, 63 insertions, 20 deletions
diff --git a/tools/testing/selftests/arm64/abi/syscall-abi-asm.S b/tools/testing/selftests/arm64/abi/syscall-abi-asm.S index acd5e9f3bc0b..66ab2e0bae5f 100644 --- a/tools/testing/selftests/arm64/abi/syscall-abi-asm.S +++ b/tools/testing/selftests/arm64/abi/syscall-abi-asm.S @@ -23,6 +23,9 @@ .arch_extension sve +#define ID_AA64SMFR0_EL1_SMEver_SHIFT 56 +#define ID_AA64SMFR0_EL1_SMEver_WIDTH 4 + /* * LDR (vector to ZA array): * LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL] @@ -45,6 +48,26 @@ | ((\offset) & 7) .endm +/* + * LDR (ZT0) + * + * LDR ZT0, nx + */ +.macro _ldr_zt nx + .inst 0xe11f8000 \ + | (((\nx) & 0x1f) << 5) +.endm + +/* + * STR (ZT0) + * + * STR ZT0, nx + */ +.macro _str_zt nx + .inst 0xe13f8000 \ + | (((\nx) & 0x1f) << 5) +.endm + .globl do_syscall do_syscall: // Store callee saved registers x19-x29 (80 bytes) plus x0 and x1 @@ -58,23 +81,31 @@ do_syscall: stp x27, x28, [sp, #96] // Set SVCR if we're doing SME - cbz x1, 1f + cbz x1, load_gpr adrp x2, svcr_in ldr x2, [x2, :lo12:svcr_in] msr S3_3_C4_C2_2, x2 -1: - // Load ZA if it's enabled - uses x12 as scratch due to SME LDR - tbz x2, #SVCR_ZA_SHIFT, 1f + // Load ZA and ZT0 if enabled - uses x12 as scratch due to SME LDR + tbz x2, #SVCR_ZA_SHIFT, load_gpr mov w12, #0 ldr x2, =za_in -2: _ldr_za 12, 2 +1: _ldr_za 12, 2 add x2, x2, x1 add x12, x12, #1 cmp x1, x12 - bne 2b -1: + bne 1b + + // ZT0 + mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1 + ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \ + #ID_AA64SMFR0_EL1_SMEver_WIDTH + cbz x2, load_gpr + adrp x2, zt_in + add x2, x2, :lo12:zt_in + _ldr_zt 2 +load_gpr: // Load GPRs x8-x28, and save our SP/FP for later comparison ldr x2, =gpr_in add x2, x2, #64 @@ -92,8 +123,11 @@ do_syscall: str x29, [x2], #8 // FP str x30, [x2], #8 // LR - // Load FPRs if we're not doing SVE - cbnz x0, 1f + // Load FPRs if we're not doing neither SVE nor streaming SVE + cbnz x0, check_sve_in + ldr x2, =svcr_in + tbnz x2, #SVCR_SM_SHIFT, check_sve_in + ldr x2, =fpr_in ldp q0, q1, [x2] ldp q2, q3, [x2, #16 * 2] @@ -111,10 +145,11 @@ do_syscall: ldp q26, q27, [x2, #16 * 26] ldp q28, q29, [x2, #16 * 28] ldp q30, q31, [x2, #16 * 30] -1: + b 2f + +check_sve_in: // Load the SVE registers if we're doing SVE/SME - cbz x0, 1f ldr x2, =z_in ldr z0, [x2, #0, MUL VL] @@ -155,9 +190,9 @@ do_syscall: ldr x2, =ffr_in ldr p0, [x2] ldr x2, [x2, #0] - cbz x2, 2f + cbz x2, 1f wrffr p0.b -2: +1: ldr x2, =p_in ldr p0, [x2, #0, MUL VL] @@ -176,7 +211,7 @@ do_syscall: ldr p13, [x2, #13, MUL VL] ldr p14, [x2, #14, MUL VL] ldr p15, [x2, #15, MUL VL] -1: +2: // Do the syscall svc #0 @@ -220,23 +255,31 @@ do_syscall: stp q30, q31, [x2, #16 * 30] // Save SVCR if we're doing SME - cbz x1, 1f + cbz x1, check_sve_out mrs x2, S3_3_C4_C2_2 adrp x3, svcr_out str x2, [x3, :lo12:svcr_out] -1: // Save ZA if it's enabled - uses x12 as scratch due to SME STR - tbz x2, #SVCR_ZA_SHIFT, 1f + tbz x2, #SVCR_ZA_SHIFT, check_sve_out mov w12, #0 ldr x2, =za_out -2: _str_za 12, 2 +1: _str_za 12, 2 add x2, x2, x1 add x12, x12, #1 cmp x1, x12 - bne 2b -1: + bne 1b + + // ZT0 + mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1 + ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \ + #ID_AA64SMFR0_EL1_SMEver_WIDTH + cbz x2, check_sve_out + adrp x2, zt_out + add x2, x2, :lo12:zt_out + _str_zt 2 +check_sve_out: // Save the SVE state if we have some cbz x0, 1f |
