blob: 39c64571b1ba19448afb26783074f48de43d9d98 [file] [log] [blame]
johpow0150ccb552020-11-10 19:22:13 -06001/*
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +00002 * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
johpow0150ccb552020-11-10 19:22:13 -06003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stdbool.h>
8#include <stdio.h>
9#include <stdlib.h>
10
11#include <arch_features.h>
12#include <arch_helpers.h>
13#include <lib/extensions/sme.h>
14#include <test_helpers.h>
15#include <tftf_lib.h>
16
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000017#ifdef __aarch64__
18
19/* Global buffers*/
Olivier Depreza61927e2023-06-01 17:16:00 +020020static __aligned(16) uint64_t ZA_In_vector[8] = {0xaaff, 0xbbff, 0xccff, 0xddff, 0xeeff,
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000021 0xffff, 0xff00, 0xff00};
Olivier Depreza61927e2023-06-01 17:16:00 +020022static __aligned(16) uint64_t ZA_Out_vector[8] = {0};
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000023
24/**
25 * sme_zero_ZA
26 * ZER0 : Zero a list of upto eight 64bit element ZA tiles.
27 * ZERO {<mask>} , where mask=ff, to clear all the 8, 64 bit elements.
28 */
29static void sme_zero_ZA(void)
30{
31 /**
32 * Due to the lack of support from the toolchain, instruction
33 * opcodes are used here.
34 * Manual Encoding Instruction, to Zero all the tiles of ZA array.
35 *
36 * TODO: Further, once the toolchain adds support for SME features
37 * this could be replaced with the actual instruction ZERO { <mask>}.
38 */
39 asm volatile(".inst 0xc008000f" : : : );
40}
41
42/**
43 * This function compares two buffers/vector elements
44 * Inputs: uint64_t *ZA_In_vector, ZA_Out_vector
45 * @return true : If both are equal
46 * @return false : If both are not equal
47 */
48static bool sme_cmp_vector(const uint64_t *ZA_In_vector, const uint64_t *ZA_Out_vector)
49{
50 bool ret = true;
51
52 for (int i = 0; i < (MAX_VL_B/8); i++) {
53 if (ZA_In_vector[i] != ZA_Out_vector[i]) {
54 ret = false;
55 }
56 }
57
58 return ret;
59}
60
61#endif /* __aarch64__ */
62
johpow0150ccb552020-11-10 19:22:13 -060063test_result_t test_sme_support(void)
64{
65 /* SME is an AArch64-only feature.*/
66 SKIP_TEST_IF_AARCH32();
67
68#ifdef __aarch64__
69 u_register_t reg;
70 unsigned int current_vector_len;
71 unsigned int requested_vector_len;
72 unsigned int len_max;
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000073 unsigned int __unused svl_max = 0U;
Arunachalam Ganapathy92f18682023-09-02 01:41:28 +010074 u_register_t saved_smcr;
johpow0150ccb552020-11-10 19:22:13 -060075
76 /* Skip the test if SME is not supported. */
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000077 SKIP_TEST_IF_SME_NOT_SUPPORTED();
johpow0150ccb552020-11-10 19:22:13 -060078
johpow0150ccb552020-11-10 19:22:13 -060079 /* Make sure TPIDR2_EL0 is accessible. */
80 write_tpidr2_el0(0);
81 if (read_tpidr2_el0() != 0) {
82 ERROR("Could not read TPIDR2_EL0.\n");
83 return TEST_RESULT_FAIL;
84 }
85 write_tpidr2_el0(0xb0bafe77);
86 if (read_tpidr2_el0() != 0xb0bafe77) {
87 ERROR("Could not write TPIDR2_EL0.\n");
88 return TEST_RESULT_FAIL;
89 }
90
johpow0150ccb552020-11-10 19:22:13 -060091 /*
92 * Iterate through values for LEN to detect supported vector lengths.
johpow0150ccb552020-11-10 19:22:13 -060093 */
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000094
95 /* Entering Streaming SVE mode */
96 sme_smstart(SMSTART_SM);
johpow0150ccb552020-11-10 19:22:13 -060097
Arunachalam Ganapathy92f18682023-09-02 01:41:28 +010098 saved_smcr = read_smcr_el2();
99
johpow0150ccb552020-11-10 19:22:13 -0600100 /* Write SMCR_EL2 with the LEN max to find implemented width. */
Arunachalam Ganapathy5b68e202023-06-06 16:31:19 +0100101 write_smcr_el2(MASK(SMCR_ELX_RAZ_LEN));
Arunachalam Ganapathy92f18682023-09-02 01:41:28 +0100102 isb();
103
johpow0150ccb552020-11-10 19:22:13 -0600104 len_max = (unsigned int)read_smcr_el2();
105 VERBOSE("Maximum SMCR_EL2.LEN value: 0x%x\n", len_max);
106 VERBOSE("Enumerating supported vector lengths...\n");
107 for (unsigned int i = 0; i <= len_max; i++) {
Arunachalam Ganapathy5b68e202023-06-06 16:31:19 +0100108 /* Load new value into SMCR_EL2.RAZ_LEN */
johpow0150ccb552020-11-10 19:22:13 -0600109 reg = read_smcr_el2();
Arunachalam Ganapathy5b68e202023-06-06 16:31:19 +0100110 reg &= ~(MASK(SMCR_ELX_RAZ_LEN));
111 reg |= INPLACE(SMCR_ELX_RAZ_LEN, i);
johpow0150ccb552020-11-10 19:22:13 -0600112 write_smcr_el2(reg);
Arunachalam Ganapathy92f18682023-09-02 01:41:28 +0100113 isb();
johpow0150ccb552020-11-10 19:22:13 -0600114
115 /* Compute current and requested vector lengths in bits. */
Arunachalam Ganapathy47b702c2023-06-06 13:31:46 +0100116 current_vector_len = ((unsigned int)sme_rdsvl_1() * 8U);
Arunachalam Ganapathy5b68e202023-06-06 16:31:19 +0100117 requested_vector_len = (i + 1U) * 128U;
johpow0150ccb552020-11-10 19:22:13 -0600118
119 /*
120 * We count down from the maximum SMLEN value, so if the values
121 * match, we've found the largest supported value for SMLEN.
122 */
123 if (current_vector_len == requested_vector_len) {
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +0000124 svl_max = current_vector_len;
Arunachalam Ganapathy5b68e202023-06-06 16:31:19 +0100125 VERBOSE("SUPPORTED: %u bits (LEN=%u)\n",
126 requested_vector_len, i);
johpow0150ccb552020-11-10 19:22:13 -0600127 } else {
Arunachalam Ganapathy5b68e202023-06-06 16:31:19 +0100128 VERBOSE("NOT SUPPORTED: %u bits (LEN=%u)\n",
129 requested_vector_len, i);
johpow0150ccb552020-11-10 19:22:13 -0600130 }
131 }
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +0000132
Arunachalam Ganapathy5b68e202023-06-06 16:31:19 +0100133 INFO("Largest Supported Streaming Vector Length(SVL): %u bits\n",
134 svl_max);
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +0000135
136 /* Exiting Streaming SVE mode */
137 sme_smstop(SMSTOP_SM);
138
139 /**
140 * Perform/Execute SME Instructions.
141 * SME Data processing instructions LDR, STR, and ZERO instructions that
142 * access the SME ZA storage are legal only if ZA is enabled.
143 */
144
145 /* Enable SME ZA Array Storage */
146 sme_smstart(SMSTART_ZA);
147
148 /* LDR : Load vector to ZA Array */
149 sme_vector_to_ZA(ZA_In_vector);
150
151 /* STR : Store Vector from ZA Array. */
152 sme_ZA_to_vector(ZA_Out_vector);
153
154 /* Compare both vectors to ensure load and store instructions have
155 * executed precisely.
156 */
157 if (!sme_cmp_vector(ZA_In_vector, ZA_Out_vector)) {
158 return TEST_RESULT_FAIL;
159 }
160
161 /* Zero or clear the entire ZA Array Storage/Tile */
162 sme_zero_ZA();
163
164 /* Disable the SME ZA array storage. */
165 sme_smstop(SMSTOP_ZA);
johpow0150ccb552020-11-10 19:22:13 -0600166
167 /* If FEAT_SME_FA64 then attempt to execute an illegal instruction. */
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +0000168 if (is_feat_sme_fa64_supported()) {
johpow0150ccb552020-11-10 19:22:13 -0600169 VERBOSE("FA64 supported, trying illegal instruction.\n");
170 sme_try_illegal_instruction();
171 }
172
Arunachalam Ganapathy92f18682023-09-02 01:41:28 +0100173 write_smcr_el2(saved_smcr);
174 isb();
175
johpow0150ccb552020-11-10 19:22:13 -0600176 return TEST_RESULT_SUCCESS;
177#endif /* __aarch64__ */
178}