162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2015-2020 ARM Limited. 462306a36Sopenharmony_ci * Original author: Dave Martin <Dave.Martin@arm.com> 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci#include <assert.h> 762306a36Sopenharmony_ci#include <errno.h> 862306a36Sopenharmony_ci#include <stdio.h> 962306a36Sopenharmony_ci#include <stdlib.h> 1062306a36Sopenharmony_ci#include <string.h> 1162306a36Sopenharmony_ci#include <sys/auxv.h> 1262306a36Sopenharmony_ci#include <sys/prctl.h> 1362306a36Sopenharmony_ci#include <asm/sigcontext.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include "../../kselftest.h" 1662306a36Sopenharmony_ci#include "rdvl.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ciint main(int argc, char **argv) 1962306a36Sopenharmony_ci{ 2062306a36Sopenharmony_ci unsigned int vq; 2162306a36Sopenharmony_ci int vl; 2262306a36Sopenharmony_ci static unsigned int vqs[SVE_VQ_MAX]; 2362306a36Sopenharmony_ci unsigned int nvqs = 0; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci ksft_print_header(); 2662306a36Sopenharmony_ci ksft_set_plan(2); 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci if (!(getauxval(AT_HWCAP) & HWCAP_SVE)) 2962306a36Sopenharmony_ci ksft_exit_skip("SVE not available\n"); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci /* 3262306a36Sopenharmony_ci * Enumerate up to SVE_VQ_MAX vector lengths 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci for (vq = SVE_VQ_MAX; vq > 0; --vq) { 3562306a36Sopenharmony_ci vl = prctl(PR_SVE_SET_VL, vq * 16); 3662306a36Sopenharmony_ci if (vl == -1) 3762306a36Sopenharmony_ci ksft_exit_fail_msg("PR_SVE_SET_VL failed: %s (%d)\n", 3862306a36Sopenharmony_ci strerror(errno), errno); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci vl &= PR_SVE_VL_LEN_MASK; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci if (rdvl_sve() != vl) 4362306a36Sopenharmony_ci ksft_exit_fail_msg("PR_SVE_SET_VL reports %d, RDVL %d\n", 4462306a36Sopenharmony_ci vl, rdvl_sve()); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci if (!sve_vl_valid(vl)) 4762306a36Sopenharmony_ci ksft_exit_fail_msg("VL %d invalid\n", vl); 4862306a36Sopenharmony_ci vq = sve_vq_from_vl(vl); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci if (!(nvqs < SVE_VQ_MAX)) 5162306a36Sopenharmony_ci ksft_exit_fail_msg("Too many VLs %u >= SVE_VQ_MAX\n", 5262306a36Sopenharmony_ci nvqs); 5362306a36Sopenharmony_ci vqs[nvqs++] = vq; 5462306a36Sopenharmony_ci } 5562306a36Sopenharmony_ci ksft_test_result_pass("Enumerated %d vector lengths\n", nvqs); 5662306a36Sopenharmony_ci ksft_test_result_pass("All vector lengths valid\n"); 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci /* Print out the vector lengths in ascending order: */ 5962306a36Sopenharmony_ci while (nvqs--) 6062306a36Sopenharmony_ci ksft_print_msg("%u\n", 16 * vqs[nvqs]); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci ksft_exit_pass(); 6362306a36Sopenharmony_ci} 64