1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright (C) 2021 ARM Limited.
3 // Original author: Mark Brown <broonie@kernel.org>
5 // Scalable Matrix Extension ZA context switch test
6 // Repeatedly writes unique test patterns into each ZA tile
7 // and reads them back to verify integrity.
9 // for x in `seq 1 NR_CPUS`; do sve-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"
21 #define MAXVL_B (MAXVL / 8)
23 // Declare some storage space to shadow ZA register contents and a
24 // scratch buffer for a vector.
29 .space MAXVL_B * MAXVL_B
34 // Trivial memory copy: copy x2 bytes, starting at address x1, to address x0.
46 // Generate a test pattern for storage in ZA
51 // These values are used to constuct a 32-bit pattern that is repeated in the
52 // scratch buffer as many times as will fit:
53 // bits 31:28 generation number (increments once per test_loop)
55 // bits 15: 8 row number
56 // bits 7: 0 32-bit lane index
60 bfi w3, w0, #16, #12 // PID
61 bfi w3, w1, #8, #8 // Row
62 bfi w3, w2, #28, #4 // Generation
68 add w3, w3, #1 // Lane
75 // Get the address of shadow data for ZA horizontal vector xn
76 .macro _adrza xd, xn, nrtmp
79 madd \xd, x\nrtmp, \xn, \xd
82 // Set up test pattern in a ZA horizontal vector
88 mov x12, x1 // Use x12 for vector select
90 bl pattern // Get pattern in scratch buffer
91 _adrza x0, x12, 2 // Shadow buffer pointer to x0 and x5
94 bl memcpy // length set up in x2 by _adrza
96 _ldr_za 12, 5 // load vector w12 from pointer x5
101 // Trivial memory compare: compare x2 bytes starting at address x0 with
102 // bytes starting at address x1.
103 // Returns only if all bytes match; otherwise, the program is aborted.
108 stp x0, x1, [sp, #-0x20]!
120 1: ldr x2, [sp, #0x10]
121 ldp x0, x1, [sp], #0x20
127 // Verify that a ZA vector matches its shadow in memory, else abort
129 // Clobbers x0-x7 and x12.
134 _adrza x5, x0, 6 // pointer to expected value in x5
136 ldr x7, =scratch // x7 is scratch
138 mov x0, x7 // Poison scratch
142 _str_za 12, 7 // save vector w12 to pointer x7
151 // Modify the live SME register state, signal return will undo our changes
152 function irritator_handler
153 // Increment the irritation signal count (x23):
154 ldr x0, [x2, #ucontext_regs + 8 * 23]
156 str x0, [x2, #ucontext_regs + 8 * 23]
158 // This will reset ZA to all bits 0
165 function tickle_handler
166 // Increment the signal count (x23):
167 ldr x0, [x2, #ucontext_regs + 8 * 23]
169 str x0, [x2, #ucontext_regs + 8 * 23]
174 function terminate_handler
178 puts "Terminated by signal "
181 puts ", no error, iterations="
182 ldr x0, [x20, #ucontext_regs + 8 * 22]
185 ldr x0, [x20, #ucontext_regs + 8 * 23]
198 str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
210 str w6, [x1, #sa_flags]
211 str x5, [x1, #sa_handler]
214 mov x8, #__NR_rt_sigaction
219 puts "sigaction failure\n"
222 1: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
226 // Main program entry point
231 mov x23, #0 // signal count
234 adr x1, terminate_handler
239 adr x1, terminate_handler
244 adr x1, irritator_handler
246 orr w2, w2, #SA_NODEFER
250 adr x1, tickle_handler
252 orr w2, w2, #SA_NODEFER
255 puts "Streaming mode "
258 // Sanity-check and report the vector length
268 1: puts "bad vector length: "
273 2: puts "vector length:\t"
278 // Obtain our PID, to ensure test pattern uniqueness between processes
287 mov x22, #0 // generation number, increments per iteration
293 rdsvl 21, 1 // Set up ZA & shadow with test pattern
301 mov x8, #__NR_sched_yield // encourage preemption
305 mrs x0, S3_3_C4_C2_2 // SVCR should have ZA=1,SM=0
310 rdsvl 21, 1 // Verify that the data made it through
311 rdsvl 24, 1 // Verify that the data made it through
317 add x22, x22, #1 // Everything still working
328 // fpsimd.c acitivty log dump hack
329 // ldr w0, =0xdeadc0de
330 // mov w8, #__NR_exit
334 mrs x13, S3_3_C4_C2_2
337 mov x10, x0 // expected data
338 mov x11, x1 // actual data
339 mov x12, x2 // data size
341 puts "Mismatch: PID="
365 // fpsimd.c acitivty log dump hack
366 // ldr w0, =0xdeadc0de
367 // mov w8, #__NR_exit
373 // mov x8, #__NR_exit
381 puts "Bad active VL: "