1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright (C) 2015-2019 ARM Limited.
3 // Original author: Dave Martin <Dave.Martin@arm.com>
5 // Simple FPSIMD context switch test
6 // Repeatedly writes unique test patterns into each FPSIMD register
7 // and reads them back to verify integrity.
9 // for x in `seq 1 NR_CPUS`; do fpsimd-test & pids=$pids\ $! ; done
10 // (leave it running for as long as you want...)
13 #include <asm/unistd.h>
14 #include "assembler.h"
15 #include "asm-offsets.h"
18 #define MAXVL_B (128 / 8)
20 .macro _vldr Vn:req, Xt:req
21 ld1 {v\Vn\().2d}, [x\Xt]
24 .macro _vstr Vn:req, Xt:req
25 st1 {v\Vn\().2d}, [x\Xt]
28 // Generate accessor functions to read/write programmatically selected
30 // x0 is the register index to access
31 // x1 is the memory address to read from (getv,setp) or store to (setv,setp)
33 define_accessor setv, NVR, _vldr
34 define_accessor getv, NVR, _vstr
36 // Declare some storate space to shadow the SVE register contents:
46 // Generate a test pattern for storage in SVE registers
48 // x1: register number (6 bits)
49 // x2: generation (4 bits)
51 orr w1, w0, w1, lsl #16
52 orr w2, w1, w2, lsl #28
58 add w2, w2, #(1 << 22)
65 // Get the address of shadow data for FPSIMD V-register V<xn>
66 .macro _adrv xd, xn, nrtmp
69 madd \xd, x\nrtmp, \xn, \xd
72 // Set up test pattern in a FPSIMD V-register
74 // x1: register number
93 // Trivial memory compare: compare x2 bytes starting at address x0 with
94 // bytes starting at address x1.
95 // Returns only if all bytes match; otherwise, the program is aborted.
112 // Verify that a FPSIMD V-register matches its shadow in memory, else abort
137 // Modify live register state, the signal return will undo our changes
138 function irritator_handler
139 // Increment the irritation signal count (x23):
140 ldr x0, [x2, #ucontext_regs + 8 * 23]
142 str x0, [x2, #ucontext_regs + 8 * 23]
144 // Corrupt some random V-regs
152 function tickle_handler
153 // Increment the signal count (x23):
154 ldr x0, [x2, #ucontext_regs + 8 * 23]
156 str x0, [x2, #ucontext_regs + 8 * 23]
161 function terminate_handler
165 puts "Terminated by signal "
168 puts ", no error, iterations="
169 ldr x0, [x20, #ucontext_regs + 8 * 22]
172 ldr x0, [x20, #ucontext_regs + 8 * 23]
185 str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
197 str w6, [x1, #sa_flags]
198 str x5, [x1, #sa_handler]
201 mov x8, #__NR_rt_sigaction
206 puts "sigaction failure\n"
209 1: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
213 // Main program entry point
218 mov x23, #0 // signal count
221 adr x1, terminate_handler
226 adr x1, terminate_handler
231 adr x1, irritator_handler
233 orr w2, w2, #SA_NODEFER
237 adr x1, tickle_handler
239 orr w2, w2, #SA_NODEFER
242 // Sanity-check and report the vector length
252 1: puts "Bad vector length: "
257 2: puts "Vector length:\t"
262 // Obtain our PID, to ensure test pattern uniqueness between processes
272 mov x22, #0 // generation number, increments per iteration
275 mov x21, #0 // Set up V-regs & shadow with test pattern
284 // Can't do this when SVE state is volatile across SVC:
285 mov x8, #__NR_sched_yield // Encourage preemption
306 mov x10, x0 // expected data
307 mov x11, x1 // actual data
308 mov x12, x2 // data size
310 puts "Mismatch: PID="