xref: /linux/tools/testing/selftests/arm64/fp/fp-ptrace-asm.S (revision 60675d4ca1ef0857e44eba5849b74a3a998d0c0f)
1c745b15cSMark Brown// SPDX-License-Identifier: GPL-2.0-only
2c745b15cSMark Brown// Copyright (C) 2021-3 ARM Limited.
3c745b15cSMark Brown//
4c745b15cSMark Brown// Assembly portion of the FP ptrace test
5c745b15cSMark Brown
6c745b15cSMark Brown//
7c745b15cSMark Brown// Load values from memory into registers, break on a breakpoint, then
8c745b15cSMark Brown// break on a further breakpoint
9c745b15cSMark Brown//
10c745b15cSMark Brown
11c745b15cSMark Brown#include "fp-ptrace.h"
12c745b15cSMark Brown#include "sme-inst.h"
13c745b15cSMark Brown
14c745b15cSMark Brown.arch_extension sve
15c745b15cSMark Brown
16c745b15cSMark Brown// Load and save register values with pauses for ptrace
17c745b15cSMark Brown//
18c0350076SMark Brown// x0 - HAVE_ flags indicating which features are in use
19c745b15cSMark Brown
20c745b15cSMark Brown.globl load_and_save
21c745b15cSMark Brownload_and_save:
22c745b15cSMark Brown	stp	x11, x12, [sp, #-0x10]!
23c745b15cSMark Brown
24c745b15cSMark Brown	// This should be redundant in the SVE case
25c745b15cSMark Brown	ldr	x7, =v_in
26c745b15cSMark Brown	ldp	q0, q1, [x7]
27c745b15cSMark Brown	ldp	q2, q3, [x7, #16 * 2]
28c745b15cSMark Brown	ldp	q4, q5, [x7, #16 * 4]
29c745b15cSMark Brown	ldp	q6, q7, [x7, #16 * 6]
30c745b15cSMark Brown	ldp	q8, q9, [x7, #16 * 8]
31c745b15cSMark Brown	ldp	q10, q11, [x7, #16 * 10]
32c745b15cSMark Brown	ldp	q12, q13, [x7, #16 * 12]
33c745b15cSMark Brown	ldp	q14, q15, [x7, #16 * 14]
34c745b15cSMark Brown	ldp	q16, q17, [x7, #16 * 16]
35c745b15cSMark Brown	ldp	q18, q19, [x7, #16 * 18]
36c745b15cSMark Brown	ldp	q20, q21, [x7, #16 * 20]
37c745b15cSMark Brown	ldp	q22, q23, [x7, #16 * 22]
38c745b15cSMark Brown	ldp	q24, q25, [x7, #16 * 24]
39c745b15cSMark Brown	ldp	q26, q27, [x7, #16 * 26]
40c745b15cSMark Brown	ldp	q28, q29, [x7, #16 * 28]
41c745b15cSMark Brown	ldp	q30, q31, [x7, #16 * 30]
42c745b15cSMark Brown
43c745b15cSMark Brown	// SME?
44c0350076SMark Brown	tbz	x0, #HAVE_SME_SHIFT, check_sve_in
45c745b15cSMark Brown
46c745b15cSMark Brown	adrp	x7, svcr_in
47c745b15cSMark Brown	ldr	x7, [x7, :lo12:svcr_in]
48c745b15cSMark Brown	// SVCR is 0 by default, avoid triggering SME if not in use
49c745b15cSMark Brown	cbz	x7, check_sve_in
50c745b15cSMark Brown	msr	S3_3_C4_C2_2, x7
51c745b15cSMark Brown
52c745b15cSMark Brown	// ZA?
53c745b15cSMark Brown	tbz	x7, #SVCR_ZA_SHIFT, check_sm_in
54c745b15cSMark Brown	rdsvl	11, 1
55c745b15cSMark Brown	mov	w12, #0
56c745b15cSMark Brown	ldr	x6, =za_in
57c745b15cSMark Brown1:	_ldr_za 12, 6
58c745b15cSMark Brown	add	x6, x6, x11
59c745b15cSMark Brown	add	x12, x12, #1
60c745b15cSMark Brown	cmp	x11, x12
61c745b15cSMark Brown	bne	1b
62c745b15cSMark Brown
63c745b15cSMark Brown	// ZT?
64c0350076SMark Brown	tbz	x0, #HAVE_SME2_SHIFT, check_sm_in
65c745b15cSMark Brown	adrp	x6, zt_in
66c745b15cSMark Brown	add	x6, x6, :lo12:zt_in
67c745b15cSMark Brown	_ldr_zt 6
68c745b15cSMark Brown
69c745b15cSMark Brown	// In streaming mode?
70c745b15cSMark Browncheck_sm_in:
71c745b15cSMark Brown	tbz	x7, #SVCR_SM_SHIFT, check_sve_in
72c0350076SMark Brown
73c0350076SMark Brown	// Load FFR if we have FA64
74*7dbd26d0SMark Brown	ubfx	x4, x0, #HAVE_FA64_SHIFT, #1
75c745b15cSMark Brown	b	load_sve
76c745b15cSMark Brown
77c745b15cSMark Brown	// SVE?
78c745b15cSMark Browncheck_sve_in:
79*7dbd26d0SMark Brown	tbz	x0, #HAVE_SVE_SHIFT, check_fpmr_in
80c745b15cSMark Brown	mov	x4, #1
81c745b15cSMark Brown
82c745b15cSMark Brownload_sve:
83c745b15cSMark Brown	ldr	x7, =z_in
84c745b15cSMark Brown	ldr	z0, [x7, #0, MUL VL]
85c745b15cSMark Brown	ldr	z1, [x7, #1, MUL VL]
86c745b15cSMark Brown	ldr	z2, [x7, #2, MUL VL]
87c745b15cSMark Brown	ldr	z3, [x7, #3, MUL VL]
88c745b15cSMark Brown	ldr	z4, [x7, #4, MUL VL]
89c745b15cSMark Brown	ldr	z5, [x7, #5, MUL VL]
90c745b15cSMark Brown	ldr	z6, [x7, #6, MUL VL]
91c745b15cSMark Brown	ldr	z7, [x7, #7, MUL VL]
92c745b15cSMark Brown	ldr	z8, [x7, #8, MUL VL]
93c745b15cSMark Brown	ldr	z9, [x7, #9, MUL VL]
94c745b15cSMark Brown	ldr	z10, [x7, #10, MUL VL]
95c745b15cSMark Brown	ldr	z11, [x7, #11, MUL VL]
96c745b15cSMark Brown	ldr	z12, [x7, #12, MUL VL]
97c745b15cSMark Brown	ldr	z13, [x7, #13, MUL VL]
98c745b15cSMark Brown	ldr	z14, [x7, #14, MUL VL]
99c745b15cSMark Brown	ldr	z15, [x7, #15, MUL VL]
100c745b15cSMark Brown	ldr	z16, [x7, #16, MUL VL]
101c745b15cSMark Brown	ldr	z17, [x7, #17, MUL VL]
102c745b15cSMark Brown	ldr	z18, [x7, #18, MUL VL]
103c745b15cSMark Brown	ldr	z19, [x7, #19, MUL VL]
104c745b15cSMark Brown	ldr	z20, [x7, #20, MUL VL]
105c745b15cSMark Brown	ldr	z21, [x7, #21, MUL VL]
106c745b15cSMark Brown	ldr	z22, [x7, #22, MUL VL]
107c745b15cSMark Brown	ldr	z23, [x7, #23, MUL VL]
108c745b15cSMark Brown	ldr	z24, [x7, #24, MUL VL]
109c745b15cSMark Brown	ldr	z25, [x7, #25, MUL VL]
110c745b15cSMark Brown	ldr	z26, [x7, #26, MUL VL]
111c745b15cSMark Brown	ldr	z27, [x7, #27, MUL VL]
112c745b15cSMark Brown	ldr	z28, [x7, #28, MUL VL]
113c745b15cSMark Brown	ldr	z29, [x7, #29, MUL VL]
114c745b15cSMark Brown	ldr	z30, [x7, #30, MUL VL]
115c745b15cSMark Brown	ldr	z31, [x7, #31, MUL VL]
116c745b15cSMark Brown
117c745b15cSMark Brown	// FFR is not present in base SME
118c745b15cSMark Brown	cbz	x4, 1f
119c745b15cSMark Brown	ldr	x7, =ffr_in
120c745b15cSMark Brown	ldr	p0, [x7]
121c745b15cSMark Brown	ldr	x7, [x7, #0]
122c745b15cSMark Brown	cbz	x7, 1f
123c745b15cSMark Brown	wrffr	p0.b
124c745b15cSMark Brown1:
125c745b15cSMark Brown
126c745b15cSMark Brown	ldr	x7, =p_in
127c745b15cSMark Brown	ldr	p0, [x7, #0, MUL VL]
128c745b15cSMark Brown	ldr	p1, [x7, #1, MUL VL]
129c745b15cSMark Brown	ldr	p2, [x7, #2, MUL VL]
130c745b15cSMark Brown	ldr	p3, [x7, #3, MUL VL]
131c745b15cSMark Brown	ldr	p4, [x7, #4, MUL VL]
132c745b15cSMark Brown	ldr	p5, [x7, #5, MUL VL]
133c745b15cSMark Brown	ldr	p6, [x7, #6, MUL VL]
134c745b15cSMark Brown	ldr	p7, [x7, #7, MUL VL]
135c745b15cSMark Brown	ldr	p8, [x7, #8, MUL VL]
136c745b15cSMark Brown	ldr	p9, [x7, #9, MUL VL]
137c745b15cSMark Brown	ldr	p10, [x7, #10, MUL VL]
138c745b15cSMark Brown	ldr	p11, [x7, #11, MUL VL]
139c745b15cSMark Brown	ldr	p12, [x7, #12, MUL VL]
140c745b15cSMark Brown	ldr	p13, [x7, #13, MUL VL]
141c745b15cSMark Brown	ldr	p14, [x7, #14, MUL VL]
142c745b15cSMark Brown	ldr	p15, [x7, #15, MUL VL]
143c745b15cSMark Brown
144*7dbd26d0SMark Brown	// This has to come after we set PSTATE.SM
145*7dbd26d0SMark Browncheck_fpmr_in:
146*7dbd26d0SMark Brown	tbz	x0, #HAVE_FPMR_SHIFT, wait_for_writes
147*7dbd26d0SMark Brown	adrp	x7, fpmr_in
148*7dbd26d0SMark Brown	ldr	x7, [x7, :lo12:fpmr_in]
149*7dbd26d0SMark Brown	msr	REG_FPMR, x7
150*7dbd26d0SMark Brown
151c745b15cSMark Brownwait_for_writes:
152c745b15cSMark Brown	// Wait for the parent
153c745b15cSMark Brown	brk #0
154c745b15cSMark Brown
155c745b15cSMark Brown	// Save values
156c745b15cSMark Brown	ldr	x7, =v_out
157c745b15cSMark Brown	stp	q0, q1, [x7]
158c745b15cSMark Brown	stp	q2, q3, [x7, #16 * 2]
159c745b15cSMark Brown	stp	q4, q5, [x7, #16 * 4]
160c745b15cSMark Brown	stp	q6, q7, [x7, #16 * 6]
161c745b15cSMark Brown	stp	q8, q9, [x7, #16 * 8]
162c745b15cSMark Brown	stp	q10, q11, [x7, #16 * 10]
163c745b15cSMark Brown	stp	q12, q13, [x7, #16 * 12]
164c745b15cSMark Brown	stp	q14, q15, [x7, #16 * 14]
165c745b15cSMark Brown	stp	q16, q17, [x7, #16 * 16]
166c745b15cSMark Brown	stp	q18, q19, [x7, #16 * 18]
167c745b15cSMark Brown	stp	q20, q21, [x7, #16 * 20]
168c745b15cSMark Brown	stp	q22, q23, [x7, #16 * 22]
169c745b15cSMark Brown	stp	q24, q25, [x7, #16 * 24]
170c745b15cSMark Brown	stp	q26, q27, [x7, #16 * 26]
171c745b15cSMark Brown	stp	q28, q29, [x7, #16 * 28]
172c745b15cSMark Brown	stp	q30, q31, [x7, #16 * 30]
173c745b15cSMark Brown
174*7dbd26d0SMark Brown	tbz	x0, #HAVE_FPMR_SHIFT, check_sme_out
175*7dbd26d0SMark Brown	mrs	x7, REG_FPMR
176*7dbd26d0SMark Brown	adrp	x6, fpmr_out
177*7dbd26d0SMark Brown	str	x7, [x6, :lo12:fpmr_out]
178*7dbd26d0SMark Brown
179*7dbd26d0SMark Browncheck_sme_out:
180c0350076SMark Brown	tbz	x0, #HAVE_SME_SHIFT, check_sve_out
181c745b15cSMark Brown
182c745b15cSMark Brown	rdsvl	11, 1
183c745b15cSMark Brown	adrp	x6, sme_vl_out
184c745b15cSMark Brown	str	x11, [x6, :lo12:sme_vl_out]
185c745b15cSMark Brown
186c745b15cSMark Brown	mrs	x7, S3_3_C4_C2_2
187c745b15cSMark Brown	adrp	x6, svcr_out
188c745b15cSMark Brown	str	x7, [x6, :lo12:svcr_out]
189c745b15cSMark Brown
190c745b15cSMark Brown	// ZA?
191c745b15cSMark Brown	tbz	x7, #SVCR_ZA_SHIFT, check_sm_out
192c745b15cSMark Brown	mov	w12, #0
193c745b15cSMark Brown	ldr	x6, =za_out
194c745b15cSMark Brown1:	_str_za 12, 6
195c745b15cSMark Brown	add	x6, x6, x11
196c745b15cSMark Brown	add	x12, x12, #1
197c745b15cSMark Brown	cmp	x11, x12
198c745b15cSMark Brown	bne	1b
199c745b15cSMark Brown
200c745b15cSMark Brown	// ZT?
201c0350076SMark Brown	tbz	x0, #HAVE_SME2_SHIFT, check_sm_out
202c745b15cSMark Brown	adrp	x6, zt_out
203c745b15cSMark Brown	add	x6, x6, :lo12:zt_out
204c745b15cSMark Brown	_str_zt 6
205c745b15cSMark Brown
206c745b15cSMark Brown	// In streaming mode?
207c745b15cSMark Browncheck_sm_out:
208c745b15cSMark Brown	tbz	x7, #SVCR_SM_SHIFT, check_sve_out
209c0350076SMark Brown
210c0350076SMark Brown	// Do we have FA64 and FFR?
211*7dbd26d0SMark Brown	ubfx	x4, x0, #HAVE_FA64_SHIFT, #1
212c745b15cSMark Brown	b	read_sve
213c745b15cSMark Brown
214c745b15cSMark Brown	// SVE?
215c745b15cSMark Browncheck_sve_out:
216c0350076SMark Brown	tbz	x0, #HAVE_SVE_SHIFT, wait_for_reads
217c745b15cSMark Brown	mov	x4, #1
218c745b15cSMark Brown
219c745b15cSMark Brown	rdvl	x7, #1
220c745b15cSMark Brown	adrp	x6, sve_vl_out
221c745b15cSMark Brown	str	x7, [x6, :lo12:sve_vl_out]
222c745b15cSMark Brown
223c745b15cSMark Brownread_sve:
224c745b15cSMark Brown	ldr	x7, =z_out
225c745b15cSMark Brown	str	z0, [x7, #0, MUL VL]
226c745b15cSMark Brown	str	z1, [x7, #1, MUL VL]
227c745b15cSMark Brown	str	z2, [x7, #2, MUL VL]
228c745b15cSMark Brown	str	z3, [x7, #3, MUL VL]
229c745b15cSMark Brown	str	z4, [x7, #4, MUL VL]
230c745b15cSMark Brown	str	z5, [x7, #5, MUL VL]
231c745b15cSMark Brown	str	z6, [x7, #6, MUL VL]
232c745b15cSMark Brown	str	z7, [x7, #7, MUL VL]
233c745b15cSMark Brown	str	z8, [x7, #8, MUL VL]
234c745b15cSMark Brown	str	z9, [x7, #9, MUL VL]
235c745b15cSMark Brown	str	z10, [x7, #10, MUL VL]
236c745b15cSMark Brown	str	z11, [x7, #11, MUL VL]
237c745b15cSMark Brown	str	z12, [x7, #12, MUL VL]
238c745b15cSMark Brown	str	z13, [x7, #13, MUL VL]
239c745b15cSMark Brown	str	z14, [x7, #14, MUL VL]
240c745b15cSMark Brown	str	z15, [x7, #15, MUL VL]
241c745b15cSMark Brown	str	z16, [x7, #16, MUL VL]
242c745b15cSMark Brown	str	z17, [x7, #17, MUL VL]
243c745b15cSMark Brown	str	z18, [x7, #18, MUL VL]
244c745b15cSMark Brown	str	z19, [x7, #19, MUL VL]
245c745b15cSMark Brown	str	z20, [x7, #20, MUL VL]
246c745b15cSMark Brown	str	z21, [x7, #21, MUL VL]
247c745b15cSMark Brown	str	z22, [x7, #22, MUL VL]
248c745b15cSMark Brown	str	z23, [x7, #23, MUL VL]
249c745b15cSMark Brown	str	z24, [x7, #24, MUL VL]
250c745b15cSMark Brown	str	z25, [x7, #25, MUL VL]
251c745b15cSMark Brown	str	z26, [x7, #26, MUL VL]
252c745b15cSMark Brown	str	z27, [x7, #27, MUL VL]
253c745b15cSMark Brown	str	z28, [x7, #28, MUL VL]
254c745b15cSMark Brown	str	z29, [x7, #29, MUL VL]
255c745b15cSMark Brown	str	z30, [x7, #30, MUL VL]
256c745b15cSMark Brown	str	z31, [x7, #31, MUL VL]
257c745b15cSMark Brown
258c745b15cSMark Brown	ldr	x7, =p_out
259c745b15cSMark Brown	str	p0, [x7, #0, MUL VL]
260c745b15cSMark Brown	str	p1, [x7, #1, MUL VL]
261c745b15cSMark Brown	str	p2, [x7, #2, MUL VL]
262c745b15cSMark Brown	str	p3, [x7, #3, MUL VL]
263c745b15cSMark Brown	str	p4, [x7, #4, MUL VL]
264c745b15cSMark Brown	str	p5, [x7, #5, MUL VL]
265c745b15cSMark Brown	str	p6, [x7, #6, MUL VL]
266c745b15cSMark Brown	str	p7, [x7, #7, MUL VL]
267c745b15cSMark Brown	str	p8, [x7, #8, MUL VL]
268c745b15cSMark Brown	str	p9, [x7, #9, MUL VL]
269c745b15cSMark Brown	str	p10, [x7, #10, MUL VL]
270c745b15cSMark Brown	str	p11, [x7, #11, MUL VL]
271c745b15cSMark Brown	str	p12, [x7, #12, MUL VL]
272c745b15cSMark Brown	str	p13, [x7, #13, MUL VL]
273c745b15cSMark Brown	str	p14, [x7, #14, MUL VL]
274c745b15cSMark Brown	str	p15, [x7, #15, MUL VL]
275c745b15cSMark Brown
276c745b15cSMark Brown	// Only save FFR if it exists
277c745b15cSMark Brown	cbz	x4, wait_for_reads
278c745b15cSMark Brown	ldr	x7, =ffr_out
279c745b15cSMark Brown	rdffr	p0.b
280c745b15cSMark Brown	str	p0, [x7]
281c745b15cSMark Brown
282c745b15cSMark Brownwait_for_reads:
283c745b15cSMark Brown	// Wait for the parent
284c745b15cSMark Brown	brk #0
285c745b15cSMark Brown
286c745b15cSMark Brown	// Ensure we don't leave ourselves in streaming mode
287c0350076SMark Brown	tbz	x0, #HAVE_SME_SHIFT, out
288c745b15cSMark Brown	msr	S3_3_C4_C2_2, xzr
289c745b15cSMark Brown
290c745b15cSMark Brownout:
291c745b15cSMark Brown	ldp	x11, x12, [sp, #-0x10]
292c745b15cSMark Brown	ret
293