293 lines
6.2 KiB
ArmAsm
293 lines
6.2 KiB
ArmAsm
// SPDX-License-Identifier: GPL-2.0-only
|
|
// Copyright (C) 2021-3 ARM Limited.
|
|
//
|
|
// Assembly portion of the FP ptrace test
|
|
|
|
//
|
|
// Load values from memory into registers, break on a breakpoint, then
|
|
// break on a further breakpoint
|
|
//
|
|
|
|
#include "fp-ptrace.h"
|
|
#include "sme-inst.h"
|
|
|
|
.arch_extension sve
|
|
|
|
// Load and save register values with pauses for ptrace
|
|
//
|
|
// x0 - HAVE_ flags indicating which features are in use
|
|
|
|
.globl load_and_save
|
|
load_and_save:
|
|
stp x11, x12, [sp, #-0x10]!
|
|
|
|
// This should be redundant in the SVE case
|
|
ldr x7, =v_in
|
|
ldp q0, q1, [x7]
|
|
ldp q2, q3, [x7, #16 * 2]
|
|
ldp q4, q5, [x7, #16 * 4]
|
|
ldp q6, q7, [x7, #16 * 6]
|
|
ldp q8, q9, [x7, #16 * 8]
|
|
ldp q10, q11, [x7, #16 * 10]
|
|
ldp q12, q13, [x7, #16 * 12]
|
|
ldp q14, q15, [x7, #16 * 14]
|
|
ldp q16, q17, [x7, #16 * 16]
|
|
ldp q18, q19, [x7, #16 * 18]
|
|
ldp q20, q21, [x7, #16 * 20]
|
|
ldp q22, q23, [x7, #16 * 22]
|
|
ldp q24, q25, [x7, #16 * 24]
|
|
ldp q26, q27, [x7, #16 * 26]
|
|
ldp q28, q29, [x7, #16 * 28]
|
|
ldp q30, q31, [x7, #16 * 30]
|
|
|
|
// SME?
|
|
tbz x0, #HAVE_SME_SHIFT, check_sve_in
|
|
|
|
adrp x7, svcr_in
|
|
ldr x7, [x7, :lo12:svcr_in]
|
|
// SVCR is 0 by default, avoid triggering SME if not in use
|
|
cbz x7, check_sve_in
|
|
msr S3_3_C4_C2_2, x7
|
|
|
|
// ZA?
|
|
tbz x7, #SVCR_ZA_SHIFT, check_sm_in
|
|
rdsvl 11, 1
|
|
mov w12, #0
|
|
ldr x6, =za_in
|
|
1: _ldr_za 12, 6
|
|
add x6, x6, x11
|
|
add x12, x12, #1
|
|
cmp x11, x12
|
|
bne 1b
|
|
|
|
// ZT?
|
|
tbz x0, #HAVE_SME2_SHIFT, check_sm_in
|
|
adrp x6, zt_in
|
|
add x6, x6, :lo12:zt_in
|
|
_ldr_zt 6
|
|
|
|
// In streaming mode?
|
|
check_sm_in:
|
|
tbz x7, #SVCR_SM_SHIFT, check_sve_in
|
|
|
|
// Load FFR if we have FA64
|
|
ubfx x4, x0, #HAVE_FA64_SHIFT, #1
|
|
b load_sve
|
|
|
|
// SVE?
|
|
check_sve_in:
|
|
tbz x0, #HAVE_SVE_SHIFT, check_fpmr_in
|
|
mov x4, #1
|
|
|
|
load_sve:
|
|
ldr x7, =z_in
|
|
ldr z0, [x7, #0, MUL VL]
|
|
ldr z1, [x7, #1, MUL VL]
|
|
ldr z2, [x7, #2, MUL VL]
|
|
ldr z3, [x7, #3, MUL VL]
|
|
ldr z4, [x7, #4, MUL VL]
|
|
ldr z5, [x7, #5, MUL VL]
|
|
ldr z6, [x7, #6, MUL VL]
|
|
ldr z7, [x7, #7, MUL VL]
|
|
ldr z8, [x7, #8, MUL VL]
|
|
ldr z9, [x7, #9, MUL VL]
|
|
ldr z10, [x7, #10, MUL VL]
|
|
ldr z11, [x7, #11, MUL VL]
|
|
ldr z12, [x7, #12, MUL VL]
|
|
ldr z13, [x7, #13, MUL VL]
|
|
ldr z14, [x7, #14, MUL VL]
|
|
ldr z15, [x7, #15, MUL VL]
|
|
ldr z16, [x7, #16, MUL VL]
|
|
ldr z17, [x7, #17, MUL VL]
|
|
ldr z18, [x7, #18, MUL VL]
|
|
ldr z19, [x7, #19, MUL VL]
|
|
ldr z20, [x7, #20, MUL VL]
|
|
ldr z21, [x7, #21, MUL VL]
|
|
ldr z22, [x7, #22, MUL VL]
|
|
ldr z23, [x7, #23, MUL VL]
|
|
ldr z24, [x7, #24, MUL VL]
|
|
ldr z25, [x7, #25, MUL VL]
|
|
ldr z26, [x7, #26, MUL VL]
|
|
ldr z27, [x7, #27, MUL VL]
|
|
ldr z28, [x7, #28, MUL VL]
|
|
ldr z29, [x7, #29, MUL VL]
|
|
ldr z30, [x7, #30, MUL VL]
|
|
ldr z31, [x7, #31, MUL VL]
|
|
|
|
// FFR is not present in base SME
|
|
cbz x4, 1f
|
|
ldr x7, =ffr_in
|
|
ldr p0, [x7]
|
|
ldr x7, [x7, #0]
|
|
cbz x7, 1f
|
|
wrffr p0.b
|
|
1:
|
|
|
|
ldr x7, =p_in
|
|
ldr p0, [x7, #0, MUL VL]
|
|
ldr p1, [x7, #1, MUL VL]
|
|
ldr p2, [x7, #2, MUL VL]
|
|
ldr p3, [x7, #3, MUL VL]
|
|
ldr p4, [x7, #4, MUL VL]
|
|
ldr p5, [x7, #5, MUL VL]
|
|
ldr p6, [x7, #6, MUL VL]
|
|
ldr p7, [x7, #7, MUL VL]
|
|
ldr p8, [x7, #8, MUL VL]
|
|
ldr p9, [x7, #9, MUL VL]
|
|
ldr p10, [x7, #10, MUL VL]
|
|
ldr p11, [x7, #11, MUL VL]
|
|
ldr p12, [x7, #12, MUL VL]
|
|
ldr p13, [x7, #13, MUL VL]
|
|
ldr p14, [x7, #14, MUL VL]
|
|
ldr p15, [x7, #15, MUL VL]
|
|
|
|
// This has to come after we set PSTATE.SM
|
|
check_fpmr_in:
|
|
tbz x0, #HAVE_FPMR_SHIFT, wait_for_writes
|
|
adrp x7, fpmr_in
|
|
ldr x7, [x7, :lo12:fpmr_in]
|
|
msr REG_FPMR, x7
|
|
|
|
wait_for_writes:
|
|
// Wait for the parent
|
|
brk #0
|
|
|
|
// Save values
|
|
ldr x7, =v_out
|
|
stp q0, q1, [x7]
|
|
stp q2, q3, [x7, #16 * 2]
|
|
stp q4, q5, [x7, #16 * 4]
|
|
stp q6, q7, [x7, #16 * 6]
|
|
stp q8, q9, [x7, #16 * 8]
|
|
stp q10, q11, [x7, #16 * 10]
|
|
stp q12, q13, [x7, #16 * 12]
|
|
stp q14, q15, [x7, #16 * 14]
|
|
stp q16, q17, [x7, #16 * 16]
|
|
stp q18, q19, [x7, #16 * 18]
|
|
stp q20, q21, [x7, #16 * 20]
|
|
stp q22, q23, [x7, #16 * 22]
|
|
stp q24, q25, [x7, #16 * 24]
|
|
stp q26, q27, [x7, #16 * 26]
|
|
stp q28, q29, [x7, #16 * 28]
|
|
stp q30, q31, [x7, #16 * 30]
|
|
|
|
tbz x0, #HAVE_FPMR_SHIFT, check_sme_out
|
|
mrs x7, REG_FPMR
|
|
adrp x6, fpmr_out
|
|
str x7, [x6, :lo12:fpmr_out]
|
|
|
|
check_sme_out:
|
|
tbz x0, #HAVE_SME_SHIFT, check_sve_out
|
|
|
|
rdsvl 11, 1
|
|
adrp x6, sme_vl_out
|
|
str x11, [x6, :lo12:sme_vl_out]
|
|
|
|
mrs x7, S3_3_C4_C2_2
|
|
adrp x6, svcr_out
|
|
str x7, [x6, :lo12:svcr_out]
|
|
|
|
// ZA?
|
|
tbz x7, #SVCR_ZA_SHIFT, check_sm_out
|
|
mov w12, #0
|
|
ldr x6, =za_out
|
|
1: _str_za 12, 6
|
|
add x6, x6, x11
|
|
add x12, x12, #1
|
|
cmp x11, x12
|
|
bne 1b
|
|
|
|
// ZT?
|
|
tbz x0, #HAVE_SME2_SHIFT, check_sm_out
|
|
adrp x6, zt_out
|
|
add x6, x6, :lo12:zt_out
|
|
_str_zt 6
|
|
|
|
// In streaming mode?
|
|
check_sm_out:
|
|
tbz x7, #SVCR_SM_SHIFT, check_sve_out
|
|
|
|
// Do we have FA64 and FFR?
|
|
ubfx x4, x0, #HAVE_FA64_SHIFT, #1
|
|
b read_sve
|
|
|
|
// SVE?
|
|
check_sve_out:
|
|
tbz x0, #HAVE_SVE_SHIFT, wait_for_reads
|
|
mov x4, #1
|
|
|
|
rdvl x7, #1
|
|
adrp x6, sve_vl_out
|
|
str x7, [x6, :lo12:sve_vl_out]
|
|
|
|
read_sve:
|
|
ldr x7, =z_out
|
|
str z0, [x7, #0, MUL VL]
|
|
str z1, [x7, #1, MUL VL]
|
|
str z2, [x7, #2, MUL VL]
|
|
str z3, [x7, #3, MUL VL]
|
|
str z4, [x7, #4, MUL VL]
|
|
str z5, [x7, #5, MUL VL]
|
|
str z6, [x7, #6, MUL VL]
|
|
str z7, [x7, #7, MUL VL]
|
|
str z8, [x7, #8, MUL VL]
|
|
str z9, [x7, #9, MUL VL]
|
|
str z10, [x7, #10, MUL VL]
|
|
str z11, [x7, #11, MUL VL]
|
|
str z12, [x7, #12, MUL VL]
|
|
str z13, [x7, #13, MUL VL]
|
|
str z14, [x7, #14, MUL VL]
|
|
str z15, [x7, #15, MUL VL]
|
|
str z16, [x7, #16, MUL VL]
|
|
str z17, [x7, #17, MUL VL]
|
|
str z18, [x7, #18, MUL VL]
|
|
str z19, [x7, #19, MUL VL]
|
|
str z20, [x7, #20, MUL VL]
|
|
str z21, [x7, #21, MUL VL]
|
|
str z22, [x7, #22, MUL VL]
|
|
str z23, [x7, #23, MUL VL]
|
|
str z24, [x7, #24, MUL VL]
|
|
str z25, [x7, #25, MUL VL]
|
|
str z26, [x7, #26, MUL VL]
|
|
str z27, [x7, #27, MUL VL]
|
|
str z28, [x7, #28, MUL VL]
|
|
str z29, [x7, #29, MUL VL]
|
|
str z30, [x7, #30, MUL VL]
|
|
str z31, [x7, #31, MUL VL]
|
|
|
|
ldr x7, =p_out
|
|
str p0, [x7, #0, MUL VL]
|
|
str p1, [x7, #1, MUL VL]
|
|
str p2, [x7, #2, MUL VL]
|
|
str p3, [x7, #3, MUL VL]
|
|
str p4, [x7, #4, MUL VL]
|
|
str p5, [x7, #5, MUL VL]
|
|
str p6, [x7, #6, MUL VL]
|
|
str p7, [x7, #7, MUL VL]
|
|
str p8, [x7, #8, MUL VL]
|
|
str p9, [x7, #9, MUL VL]
|
|
str p10, [x7, #10, MUL VL]
|
|
str p11, [x7, #11, MUL VL]
|
|
str p12, [x7, #12, MUL VL]
|
|
str p13, [x7, #13, MUL VL]
|
|
str p14, [x7, #14, MUL VL]
|
|
str p15, [x7, #15, MUL VL]
|
|
|
|
// Only save FFR if it exists
|
|
cbz x4, wait_for_reads
|
|
ldr x7, =ffr_out
|
|
rdffr p0.b
|
|
str p0, [x7]
|
|
|
|
wait_for_reads:
|
|
// Wait for the parent
|
|
brk #0
|
|
|
|
// Ensure we don't leave ourselves in streaming mode
|
|
tbz x0, #HAVE_SME_SHIFT, out
|
|
msr S3_3_C4_C2_2, xzr
|
|
|
|
out:
|
|
ldp x11, x12, [sp, #-0x10]
|
|
ret
|