Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
26289 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
// Copyright (C) 2021 ARM Limited.
3
//
4
// Assembly portion of the syscall ABI test
5
6
//
7
// Load values from memory into registers, invoke a syscall and save the
8
// register values back to memory for later checking. The syscall to be
9
// invoked is configured in x8 of the input GPR data.
10
//
11
// x0: SVE VL, 0 for FP only
12
// x1: SME VL
13
//
14
// GPRs: gpr_in, gpr_out
15
// FPRs: fpr_in, fpr_out
16
// Zn: z_in, z_out
17
// Pn: p_in, p_out
18
// FFR: ffr_in, ffr_out
19
// ZA: za_in, za_out
20
// SVCR: svcr_in, svcr_out
21
22
#include "syscall-abi.h"
23
24
.arch_extension sve
25
26
#define ID_AA64SMFR0_EL1_SMEver_SHIFT 56
27
#define ID_AA64SMFR0_EL1_SMEver_WIDTH 4
28
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=0
34
.inst 0xe1000000 \
35
| (((\nw) & 3) << 13) \
36
| ((\nxbase) << 5) \
37
| ((\offset) & 7)
38
.endm
39
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=0
45
.inst 0xe1200000 \
46
| (((\nw) & 3) << 13) \
47
| ((\nxbase) << 5) \
48
| ((\offset) & 7)
49
.endm
50
51
/*
52
* LDR (ZT0)
53
*
54
* LDR ZT0, nx
55
*/
56
.macro _ldr_zt nx
57
.inst 0xe11f8000 \
58
| (((\nx) & 0x1f) << 5)
59
.endm
60
61
/*
62
* STR (ZT0)
63
*
64
* STR ZT0, nx
65
*/
66
.macro _str_zt nx
67
.inst 0xe13f8000 \
68
| (((\nx) & 0x1f) << 5)
69
.endm
70
71
.globl do_syscall
72
do_syscall:
73
// Store callee saved registers x19-x29 (80 bytes) plus x0 and x1
74
stp x29, x30, [sp, #-112]!
75
mov x29, sp
76
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 SME
84
cbz x1, load_gpr
85
adrp x2, svcr_in
86
ldr x2, [x2, :lo12:svcr_in]
87
msr S3_3_C4_C2_2, x2
88
89
// Load ZA and ZT0 if enabled - uses x12 as scratch due to SME LDR
90
tbz x2, #SVCR_ZA_SHIFT, load_gpr
91
mov w12, #0
92
ldr x2, =za_in
93
1: _ldr_za 12, 2
94
add x2, x2, x1
95
add x12, x12, #1
96
cmp x1, x12
97
bne 1b
98
99
// ZT0
100
mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1
101
ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \
102
#ID_AA64SMFR0_EL1_SMEver_WIDTH
103
cbz x2, load_gpr
104
adrp x2, zt_in
105
add x2, x2, :lo12:zt_in
106
_ldr_zt 2
107
108
load_gpr:
109
// Load GPRs x8-x28, and save our SP/FP for later comparison
110
ldr x2, =gpr_in
111
add x2, x2, #64
112
ldp x8, x9, [x2], #16
113
ldp x10, x11, [x2], #16
114
ldp x12, x13, [x2], #16
115
ldp x14, x15, [x2], #16
116
ldp x16, x17, [x2], #16
117
ldp x18, x19, [x2], #16
118
ldp x20, x21, [x2], #16
119
ldp x22, x23, [x2], #16
120
ldp x24, x25, [x2], #16
121
ldp x26, x27, [x2], #16
122
ldr x28, [x2], #8
123
str x29, [x2], #8 // FP
124
str x30, [x2], #8 // LR
125
126
// Load FPRs if we're not doing neither SVE nor streaming SVE
127
cbnz x0, check_sve_in
128
ldr x2, =svcr_in
129
tbnz x2, #SVCR_SM_SHIFT, check_sve_in
130
131
ldr x2, =fpr_in
132
ldp q0, q1, [x2]
133
ldp q2, q3, [x2, #16 * 2]
134
ldp q4, q5, [x2, #16 * 4]
135
ldp q6, q7, [x2, #16 * 6]
136
ldp q8, q9, [x2, #16 * 8]
137
ldp q10, q11, [x2, #16 * 10]
138
ldp q12, q13, [x2, #16 * 12]
139
ldp q14, q15, [x2, #16 * 14]
140
ldp q16, q17, [x2, #16 * 16]
141
ldp q18, q19, [x2, #16 * 18]
142
ldp q20, q21, [x2, #16 * 20]
143
ldp q22, q23, [x2, #16 * 22]
144
ldp q24, q25, [x2, #16 * 24]
145
ldp q26, q27, [x2, #16 * 26]
146
ldp q28, q29, [x2, #16 * 28]
147
ldp q30, q31, [x2, #16 * 30]
148
149
b 2f
150
151
check_sve_in:
152
// Load the SVE registers if we're doing SVE/SME
153
154
ldr x2, =z_in
155
ldr z0, [x2, #0, MUL VL]
156
ldr z1, [x2, #1, MUL VL]
157
ldr z2, [x2, #2, MUL VL]
158
ldr z3, [x2, #3, MUL VL]
159
ldr z4, [x2, #4, MUL VL]
160
ldr z5, [x2, #5, MUL VL]
161
ldr z6, [x2, #6, MUL VL]
162
ldr z7, [x2, #7, MUL VL]
163
ldr z8, [x2, #8, MUL VL]
164
ldr z9, [x2, #9, MUL VL]
165
ldr z10, [x2, #10, MUL VL]
166
ldr z11, [x2, #11, MUL VL]
167
ldr z12, [x2, #12, MUL VL]
168
ldr z13, [x2, #13, MUL VL]
169
ldr z14, [x2, #14, MUL VL]
170
ldr z15, [x2, #15, MUL VL]
171
ldr z16, [x2, #16, MUL VL]
172
ldr z17, [x2, #17, MUL VL]
173
ldr z18, [x2, #18, MUL VL]
174
ldr z19, [x2, #19, MUL VL]
175
ldr z20, [x2, #20, MUL VL]
176
ldr z21, [x2, #21, MUL VL]
177
ldr z22, [x2, #22, MUL VL]
178
ldr z23, [x2, #23, MUL VL]
179
ldr z24, [x2, #24, MUL VL]
180
ldr z25, [x2, #25, MUL VL]
181
ldr z26, [x2, #26, MUL VL]
182
ldr z27, [x2, #27, MUL VL]
183
ldr z28, [x2, #28, MUL VL]
184
ldr z29, [x2, #29, MUL VL]
185
ldr z30, [x2, #30, MUL VL]
186
ldr z31, [x2, #31, MUL VL]
187
188
// Only set a non-zero FFR, test patterns must be zero since the
189
// syscall should clear it - this lets us handle FA64.
190
ldr x2, =ffr_in
191
ldr p0, [x2]
192
ldr x2, [x2, #0]
193
cbz x2, 1f
194
wrffr p0.b
195
1:
196
197
ldr x2, =p_in
198
ldr p0, [x2, #0, MUL VL]
199
ldr p1, [x2, #1, MUL VL]
200
ldr p2, [x2, #2, MUL VL]
201
ldr p3, [x2, #3, MUL VL]
202
ldr p4, [x2, #4, MUL VL]
203
ldr p5, [x2, #5, MUL VL]
204
ldr p6, [x2, #6, MUL VL]
205
ldr p7, [x2, #7, MUL VL]
206
ldr p8, [x2, #8, MUL VL]
207
ldr p9, [x2, #9, MUL VL]
208
ldr p10, [x2, #10, MUL VL]
209
ldr p11, [x2, #11, MUL VL]
210
ldr p12, [x2, #12, MUL VL]
211
ldr p13, [x2, #13, MUL VL]
212
ldr p14, [x2, #14, MUL VL]
213
ldr p15, [x2, #15, MUL VL]
214
2:
215
216
// Do the syscall
217
svc #0
218
219
// Save GPRs x8-x30
220
ldr x2, =gpr_out
221
add x2, x2, #64
222
stp x8, x9, [x2], #16
223
stp x10, x11, [x2], #16
224
stp x12, x13, [x2], #16
225
stp x14, x15, [x2], #16
226
stp x16, x17, [x2], #16
227
stp x18, x19, [x2], #16
228
stp x20, x21, [x2], #16
229
stp x22, x23, [x2], #16
230
stp x24, x25, [x2], #16
231
stp x26, x27, [x2], #16
232
stp x28, x29, [x2], #16
233
str x30, [x2]
234
235
// Restore x0 and x1 for feature checks
236
ldp x0, x1, [sp, #16]
237
238
// Save FPSIMD state
239
ldr x2, =fpr_out
240
stp q0, q1, [x2]
241
stp q2, q3, [x2, #16 * 2]
242
stp q4, q5, [x2, #16 * 4]
243
stp q6, q7, [x2, #16 * 6]
244
stp q8, q9, [x2, #16 * 8]
245
stp q10, q11, [x2, #16 * 10]
246
stp q12, q13, [x2, #16 * 12]
247
stp q14, q15, [x2, #16 * 14]
248
stp q16, q17, [x2, #16 * 16]
249
stp q18, q19, [x2, #16 * 18]
250
stp q20, q21, [x2, #16 * 20]
251
stp q22, q23, [x2, #16 * 22]
252
stp q24, q25, [x2, #16 * 24]
253
stp q26, q27, [x2, #16 * 26]
254
stp q28, q29, [x2, #16 * 28]
255
stp q30, q31, [x2, #16 * 30]
256
257
// Save SVCR if we're doing SME
258
cbz x1, check_sve_out
259
mrs x2, S3_3_C4_C2_2
260
adrp x3, svcr_out
261
str x2, [x3, :lo12:svcr_out]
262
263
// Save ZA if it's enabled - uses x12 as scratch due to SME STR
264
tbz x2, #SVCR_ZA_SHIFT, check_sve_out
265
mov w12, #0
266
ldr x2, =za_out
267
1: _str_za 12, 2
268
add x2, x2, x1
269
add x12, x12, #1
270
cmp x1, x12
271
bne 1b
272
273
// ZT0
274
mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1
275
ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \
276
#ID_AA64SMFR0_EL1_SMEver_WIDTH
277
cbz x2, check_sve_out
278
adrp x2, zt_out
279
add x2, x2, :lo12:zt_out
280
_str_zt 2
281
282
check_sve_out:
283
// Save the SVE state if we have some
284
cbz x0, 1f
285
286
ldr x2, =z_out
287
str z0, [x2, #0, MUL VL]
288
str z1, [x2, #1, MUL VL]
289
str z2, [x2, #2, MUL VL]
290
str z3, [x2, #3, MUL VL]
291
str z4, [x2, #4, MUL VL]
292
str z5, [x2, #5, MUL VL]
293
str z6, [x2, #6, MUL VL]
294
str z7, [x2, #7, MUL VL]
295
str z8, [x2, #8, MUL VL]
296
str z9, [x2, #9, MUL VL]
297
str z10, [x2, #10, MUL VL]
298
str z11, [x2, #11, MUL VL]
299
str z12, [x2, #12, MUL VL]
300
str z13, [x2, #13, MUL VL]
301
str z14, [x2, #14, MUL VL]
302
str z15, [x2, #15, MUL VL]
303
str z16, [x2, #16, MUL VL]
304
str z17, [x2, #17, MUL VL]
305
str z18, [x2, #18, MUL VL]
306
str z19, [x2, #19, MUL VL]
307
str z20, [x2, #20, MUL VL]
308
str z21, [x2, #21, MUL VL]
309
str z22, [x2, #22, MUL VL]
310
str z23, [x2, #23, MUL VL]
311
str z24, [x2, #24, MUL VL]
312
str z25, [x2, #25, MUL VL]
313
str z26, [x2, #26, MUL VL]
314
str z27, [x2, #27, MUL VL]
315
str z28, [x2, #28, MUL VL]
316
str z29, [x2, #29, MUL VL]
317
str z30, [x2, #30, MUL VL]
318
str z31, [x2, #31, MUL VL]
319
320
ldr x2, =p_out
321
str p0, [x2, #0, MUL VL]
322
str p1, [x2, #1, MUL VL]
323
str p2, [x2, #2, MUL VL]
324
str p3, [x2, #3, MUL VL]
325
str p4, [x2, #4, MUL VL]
326
str p5, [x2, #5, MUL VL]
327
str p6, [x2, #6, MUL VL]
328
str p7, [x2, #7, MUL VL]
329
str p8, [x2, #8, MUL VL]
330
str p9, [x2, #9, MUL VL]
331
str p10, [x2, #10, MUL VL]
332
str p11, [x2, #11, MUL VL]
333
str p12, [x2, #12, MUL VL]
334
str p13, [x2, #13, MUL VL]
335
str p14, [x2, #14, MUL VL]
336
str p15, [x2, #15, MUL VL]
337
338
// Only save FFR if we wrote a value for SME
339
ldr x2, =ffr_in
340
ldr x2, [x2, #0]
341
cbz x2, 1f
342
ldr x2, =ffr_out
343
rdffr p0.b
344
str p0, [x2]
345
1:
346
347
// Restore callee saved registers x19-x30
348
ldp x19, x20, [sp, #32]
349
ldp x21, x22, [sp, #48]
350
ldp x23, x24, [sp, #64]
351
ldp x25, x26, [sp, #80]
352
ldp x27, x28, [sp, #96]
353
ldp x29, x30, [sp], #112
354
355
// Clear SVCR if we were doing SME so future tests don't have ZA
356
cbz x1, 1f
357
msr S3_3_C4_C2_2, xzr
358
1:
359
360
ret
361
362