Path: blob/master/tools/testing/selftests/arm64/fp/za-test.S
26295 views
// SPDX-License-Identifier: GPL-2.0-only1// Copyright (C) 2021 ARM Limited.2// Original author: Mark Brown <broonie@kernel.org>3//4// Scalable Matrix Extension ZA context switch test5// Repeatedly writes unique test patterns into each ZA tile6// and reads them back to verify integrity.7//8// for x in `seq 1 NR_CPUS`; do sve-test & pids=$pids\ $! ; done9// (leave it running for as long as you want...)10// kill $pids1112#include <asm/unistd.h>13#include "assembler.h"14#include "asm-offsets.h"15#include "sme-inst.h"1617.arch_extension sve1819#define MAXVL 204820#define MAXVL_B (MAXVL / 8)2122// Declare some storage space to shadow ZA register contents and a23// scratch buffer for a vector.24.pushsection .text25.data26.align 427zaref:28.space MAXVL_B * MAXVL_B29scratch:30.space MAXVL_B31.popsection3233// Trivial memory copy: copy x2 bytes, starting at address x1, to address x0.34// Clobbers x0-x335function memcpy36cmp x2, #037b.eq 1f380: ldrb w3, [x1], #139strb w3, [x0], #140subs x2, x2, #141b.ne 0b421: ret43endfunction4445// Generate a test pattern for storage in ZA46// x0: pid47// x1: row in ZA48// x2: generation4950// These values are used to constuct a 32-bit pattern that is repeated in the51// scratch buffer as many times as will fit:52// bits 31:28 generation number (increments once per test_loop)53// bits 27:16 pid54// bits 15: 8 row number55// bits 7: 0 32-bit lane index5657function pattern58mov w3, wzr59bfi w3, w0, #16, #12 // PID60bfi w3, w1, #8, #8 // Row61bfi w3, w2, #28, #4 // Generation6263ldr x0, =scratch64mov w1, #MAXVL_B / 465660: str w3, [x0], #467add w3, w3, #1 // Lane68subs w1, w1, #169b.ne 0b7071ret72endfunction7374// Get the address of shadow data for ZA horizontal vector xn75.macro _adrza xd, xn, nrtmp76ldr \xd, =zaref77rdsvl \nrtmp, 178madd \xd, x\nrtmp, \xn, \xd79.endm8081// Set up test pattern in a ZA horizontal vector82// x0: pid83// x1: row number84// x2: generation85function setup_za86mov x4, x3087mov x12, x1 // Use x12 for vector select8889bl pattern // Get pattern in scratch buffer90_adrza x0, x12, 2 // Shadow buffer pointer to x0 and x591mov x5, x092ldr x1, =scratch93bl memcpy // length set up in x2 by _adrza9495_ldr_za 12, 5 // load vector w12 from pointer x59697ret x498endfunction99100// Trivial memory compare: compare x2 bytes starting at address x0 with101// bytes starting at address x1.102// Returns only if all bytes match; otherwise, the program is aborted.103// Clobbers x0-x5.104function memcmp105cbz x2, 2f106107stp x0, x1, [sp, #-0x20]!108str x2, [sp, #0x10]109110mov x5, #01110: ldrb w3, [x0, x5]112ldrb w4, [x1, x5]113add x5, x5, #1114cmp w3, w4115b.ne 1f116subs x2, x2, #1117b.ne 0b1181191: ldr x2, [sp, #0x10]120ldp x0, x1, [sp], #0x20121b.ne barf1221232: ret124endfunction125126// Verify that a ZA vector matches its shadow in memory, else abort127// x0: row number128// Clobbers x0-x7 and x12.129function check_za130mov x3, x30131132mov x12, x0133_adrza x5, x0, 6 // pointer to expected value in x5134mov x4, x0135ldr x7, =scratch // x7 is scratch136137mov x0, x7 // Poison scratch138mov x1, x6139bl memfill_ae140141_str_za 12, 7 // save vector w12 to pointer x7142143mov x0, x5144mov x1, x7145mov x2, x6146mov x30, x3147b memcmp148endfunction149150// Modify the live SME register state, signal return will undo our changes151function irritator_handler152// Increment the irritation signal count (x23):153ldr x0, [x2, #ucontext_regs + 8 * 23]154add x0, x0, #1155str x0, [x2, #ucontext_regs + 8 * 23]156157// This will reset ZA to all bits 0158smstop159smstart_za160161ret162endfunction163164function tickle_handler165// Increment the signal count (x23):166ldr x0, [x2, #ucontext_regs + 8 * 23]167add x0, x0, #1168str x0, [x2, #ucontext_regs + 8 * 23]169170ret171endfunction172173function terminate_handler174mov w21, w0175mov x20, x2176177puts "Terminated by signal "178mov w0, w21179bl putdec180puts ", no error, iterations="181ldr x0, [x20, #ucontext_regs + 8 * 22]182bl putdec183puts ", signals="184ldr x0, [x20, #ucontext_regs + 8 * 23]185bl putdecn186187mov x0, #0188mov x8, #__NR_exit189svc #0190endfunction191192// w0: signal number193// x1: sa_action194// w2: sa_flags195// Clobbers x0-x6,x8196function setsignal197str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!198199mov w4, w0200mov x5, x1201mov w6, w2202203add x0, sp, #16204mov x1, #sa_sz205bl memclr206207mov w0, w4208add x1, sp, #16209str w6, [x1, #sa_flags]210str x5, [x1, #sa_handler]211mov x2, #0212mov x3, #sa_mask_sz213mov x8, #__NR_rt_sigaction214svc #0215216cbz w0, 1f217218puts "sigaction failure\n"219b .Labort2202211: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)222ret223endfunction224225// Main program entry point226.globl _start227function _start228enable_gcs229230mov x23, #0 // signal count231232mov w0, #SIGINT233adr x1, terminate_handler234mov w2, #SA_SIGINFO235bl setsignal236237mov w0, #SIGTERM238adr x1, terminate_handler239mov w2, #SA_SIGINFO240bl setsignal241242mov w0, #SIGUSR1243adr x1, irritator_handler244mov w2, #SA_SIGINFO245orr w2, w2, #SA_NODEFER246bl setsignal247248mov w0, #SIGUSR2249adr x1, tickle_handler250mov w2, #SA_SIGINFO251orr w2, w2, #SA_NODEFER252bl setsignal253254puts "Streaming mode "255smstart_za256257// Sanity-check and report the vector length258259rdsvl 19, 8260cmp x19, #128261b.lo 1f262cmp x19, #2048263b.hi 1f264tst x19, #(8 - 1)265b.eq 2f2662671: puts "bad vector length: "268mov x0, x19269bl putdecn270b .Labort2712722: puts "vector length:\t"273mov x0, x19274bl putdec275puts " bits\n"276277// Obtain our PID, to ensure test pattern uniqueness between processes278mov x8, #__NR_getpid279svc #0280mov x20, x0281282puts "PID:\t"283mov x0, x20284bl putdecn285286mov x22, #0 // generation number, increments per iteration287.Ltest_loop:288rdsvl 0, 8289cmp x0, x19290b.ne vl_barf291292rdsvl 21, 1 // Set up ZA & shadow with test pattern2930: mov x0, x20294sub x1, x21, #1295mov x2, x22296bl setup_za297subs x21, x21, #1298b.ne 0b299300mov x8, #__NR_sched_yield // encourage preemption3011:302svc #0303304mrs x0, S3_3_C4_C2_2 // SVCR should have ZA=1,SM=0305and x1, x0, #3306cmp x1, #2307b.ne svcr_barf308309rdsvl 21, 1 // Verify that the data made it through310rdsvl 24, 1 // Verify that the data made it through3110: sub x0, x24, x21312bl check_za313subs x21, x21, #1314bne 0b315316add x22, x22, #1 // Everything still working317b .Ltest_loop318319.Labort:320mov x0, #0321mov x1, #SIGABRT322mov x8, #__NR_kill323svc #0324endfunction325326function barf327// fpsimd.c acitivty log dump hack328// ldr w0, =0xdeadc0de329// mov w8, #__NR_exit330// svc #0331// end hack332333mrs x13, S3_3_C4_C2_2334335smstop336mov x10, x0 // expected data337mov x11, x1 // actual data338mov x12, x2 // data size339340puts "Mismatch: PID="341mov x0, x20342bl putdec343puts ", iteration="344mov x0, x22345bl putdec346puts ", row="347mov x0, x21348bl putdecn349puts "\tExpected ["350mov x0, x10351mov x1, x12352bl dumphex353puts "]\n\tGot ["354mov x0, x11355mov x1, x12356bl dumphex357puts "]\n"358puts "\tSVCR: "359mov x0, x13360bl putdecn361362mov x8, #__NR_getpid363svc #0364// fpsimd.c acitivty log dump hack365// ldr w0, =0xdeadc0de366// mov w8, #__NR_exit367// svc #0368// ^ end of hack369mov x1, #SIGABRT370mov x8, #__NR_kill371svc #0372// mov x8, #__NR_exit373// mov x1, #1374// svc #0375endfunction376377function vl_barf378mov x10, x0379380puts "Bad active VL: "381mov x0, x10382bl putdecn383384mov x8, #__NR_exit385mov x1, #1386svc #0387endfunction388389function svcr_barf390mov x10, x0391392puts "Bad SVCR: "393mov x0, x10394bl putdecn395396mov x8, #__NR_exit397mov x1, #1398svc #0399endfunction400401402