blob: 0ff171038ae726797082f83b1bd0f6e4cacd6d5d [file] [log] [blame]
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +01001/*
Javier Almansa Sobrino82cd82e2025-01-17 17:37:42 +00002 * Copyright (c) 2023-2025, Arm Limited. All rights reserved.
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +01003 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#include <arch.h>
7#include <arch_features.h>
8#include <arch_helpers.h>
9#include <assert.h>
10#include <debug.h>
Arunachalam Ganapathyc1136a82023-04-12 15:24:44 +010011#include <stdlib.h>
Javier Almansa Sobrino82cd82e2025-01-17 17:37:42 +000012
Arunachalam Ganapathy73949a22023-06-05 12:01:05 +010013#include <sync.h>
Arunachalam Ganapathyf3697172023-09-04 15:04:46 +010014#include <lib/extensions/fpu.h>
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010015#include <lib/extensions/sve.h>
Javier Almansa Sobrino82cd82e2025-01-17 17:37:42 +000016#include <realm_helpers.h>
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010017
Arunachalam Ganapathy1768e592023-05-23 13:28:38 +010018#include <host_realm_simd.h>
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010019#include <host_shared_data.h>
20
Arunachalam Ganapathyc1136a82023-04-12 15:24:44 +010021#define RL_SVE_OP_ARRAYSIZE 512U
22#define SVE_TEST_ITERATIONS 4U
23
24static int rl_sve_op_1[RL_SVE_OP_ARRAYSIZE];
25static int rl_sve_op_2[RL_SVE_OP_ARRAYSIZE];
26
Arunachalam Ganapathy03589972023-08-30 11:04:51 +010027static sve_z_regs_t rl_sve_z_regs_write;
Arunachalam Ganapathyf3697172023-09-04 15:04:46 +010028static sve_z_regs_t rl_sve_z_regs_read;
29
30static sve_p_regs_t rl_sve_p_regs_write;
31static sve_p_regs_t rl_sve_p_regs_read;
32
33static sve_ffr_regs_t rl_sve_ffr_regs_write;
34static sve_ffr_regs_t rl_sve_ffr_regs_read;
35
36static fpu_cs_regs_t rl_fpu_cs_regs_write;
37static fpu_cs_regs_t rl_fpu_cs_regs_read;
Arunachalam Ganapathy5270d012023-04-19 14:53:42 +010038
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010039/* Returns the maximum supported VL. This test is called only by sve Realm */
40bool test_realm_sve_rdvl(void)
41{
Shruti Gupta550e3e82023-08-16 13:20:11 +010042 host_shared_data_t *sd = realm_get_my_shared_structure();
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010043 struct sve_cmd_rdvl *output;
44
45 assert(is_armv8_2_sve_present());
46
47 output = (struct sve_cmd_rdvl *)sd->realm_cmd_output_buffer;
48 memset((void *)output, 0, sizeof(struct sve_cmd_rdvl));
49
50 sve_config_vq(SVE_VQ_ARCH_MAX);
Arunachalam Ganapathy03589972023-08-30 11:04:51 +010051 output->rdvl = sve_rdvl_1();
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010052
53 return true;
54}
55
56/*
57 * Reads and returns the ID_AA64PFR0_EL1 and ID_AA64ZFR0_EL1 registers
58 * This test could be called from sve or non-sve Realm
59 */
60bool test_realm_sve_read_id_registers(void)
61{
Shruti Gupta550e3e82023-08-16 13:20:11 +010062 host_shared_data_t *sd = realm_get_my_shared_structure();
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010063 struct sve_cmd_id_regs *output;
64
65 output = (struct sve_cmd_id_regs *)sd->realm_cmd_output_buffer;
66 memset((void *)output, 0, sizeof(struct sve_cmd_id_regs));
67
Shruti Guptaa276b202023-12-18 10:07:43 +000068 realm_printf("reading ID registers: ID_AA64PFR0_EL1, "
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010069 " ID_AA64ZFR0_EL1\n");
70 output->id_aa64pfr0_el1 = read_id_aa64pfr0_el1();
71 output->id_aa64zfr0_el1 = read_id_aa64zfr0_el1();
72
73 return true;
74}
75
76/*
77 * Probes all VLs and return the bitmap with the bit set for each corresponding
78 * valid VQ. This test is called only by sve Realm
79 */
80bool test_realm_sve_probe_vl(void)
81{
Shruti Gupta550e3e82023-08-16 13:20:11 +010082 host_shared_data_t *sd = realm_get_my_shared_structure();
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010083 struct sve_cmd_probe_vl *output;
84
85 assert(is_armv8_2_sve_present());
86
87 output = (struct sve_cmd_probe_vl *)&sd->realm_cmd_output_buffer;
88 memset((void *)output, 0, sizeof(struct sve_cmd_probe_vl));
89
90 /* Probe all VLs */
91 output->vl_bitmap = sve_probe_vl(SVE_VQ_ARCH_MAX);
92
93 return true;
94}
Arunachalam Ganapathyc1136a82023-04-12 15:24:44 +010095
96bool test_realm_sve_ops(void)
97{
98 int val, i;
99
100 assert(is_armv8_2_sve_present());
101
102 /* get at random value to do sve_subtract */
103 val = rand();
104 for (i = 0; i < RL_SVE_OP_ARRAYSIZE; i++) {
105 rl_sve_op_1[i] = val - i;
106 rl_sve_op_2[i] = 1;
107 }
108
109 for (i = 0; i < SVE_TEST_ITERATIONS; i++) {
110 /* Config Realm with random SVE length */
111 sve_config_vq(SVE_GET_RANDOM_VQ);
112
113 /* Perform SVE operations, without world switch */
114 sve_subtract_arrays(rl_sve_op_1, rl_sve_op_1, rl_sve_op_2,
115 RL_SVE_OP_ARRAYSIZE);
116 }
117
118 /* Check result of SVE operations. */
119 for (i = 0; i < RL_SVE_OP_ARRAYSIZE; i++) {
120 if (rl_sve_op_1[i] != (val - i - SVE_TEST_ITERATIONS)) {
Shruti Guptaa276b202023-12-18 10:07:43 +0000121 realm_printf("SVE ops failed\n");
Arunachalam Ganapathyc1136a82023-04-12 15:24:44 +0100122 return false;
123 }
124 }
125
126 return true;
127}
Arunachalam Ganapathy5270d012023-04-19 14:53:42 +0100128
129/* Fill SVE Z registers with known pattern */
130bool test_realm_sve_fill_regs(void)
131{
Arunachalam Ganapathy5270d012023-04-19 14:53:42 +0100132 assert(is_armv8_2_sve_present());
133
134 /* Config Realm with max SVE length */
135 sve_config_vq(SVE_VQ_ARCH_MAX);
Arunachalam Ganapathy5270d012023-04-19 14:53:42 +0100136
Arunachalam Ganapathyf3697172023-09-04 15:04:46 +0100137 sve_z_regs_write_rand(&rl_sve_z_regs_write);
138 sve_p_regs_write_rand(&rl_sve_p_regs_write);
139 sve_ffr_regs_write_rand(&rl_sve_ffr_regs_write);
140
141 /* fpcr, fpsr common registers */
142 fpu_cs_regs_write_rand(&rl_fpu_cs_regs_write);
Arunachalam Ganapathy5270d012023-04-19 14:53:42 +0100143
144 return true;
145}
Arunachalam Ganapathy73949a22023-06-05 12:01:05 +0100146
Arunachalam Ganapathyf3697172023-09-04 15:04:46 +0100147/* Compare SVE Z registers with last filled in values */
148bool test_realm_sve_cmp_regs(void)
149{
150 bool rc = true;
151 uint64_t bit_map;
152
153 assert(is_armv8_2_sve_present());
154
155 memset(&rl_sve_z_regs_read, 0, sizeof(rl_sve_z_regs_read));
156 memset(&rl_sve_p_regs_read, 0, sizeof(rl_sve_p_regs_read));
157 memset(&rl_sve_ffr_regs_read, 0, sizeof(rl_sve_ffr_regs_read));
158
159 /* Read all SVE registers */
160 sve_z_regs_read(&rl_sve_z_regs_read);
161 sve_p_regs_read(&rl_sve_p_regs_read);
162 sve_ffr_regs_read(&rl_sve_ffr_regs_read);
163
164 /* Compare the read values with last written values */
165 bit_map = sve_z_regs_compare(&rl_sve_z_regs_write, &rl_sve_z_regs_read);
166 if (bit_map) {
167 rc = false;
168 }
169
170 bit_map = sve_p_regs_compare(&rl_sve_p_regs_write, &rl_sve_p_regs_read);
171 if (bit_map) {
172 rc = false;
173 }
174
175 bit_map = sve_ffr_regs_compare(&rl_sve_ffr_regs_write,
176 &rl_sve_ffr_regs_read);
177 if (bit_map) {
178 rc = false;
179 }
180
181 /* fpcr, fpsr common registers */
182 fpu_cs_regs_read(&rl_fpu_cs_regs_read);
183 if (fpu_cs_regs_compare(&rl_fpu_cs_regs_write, &rl_fpu_cs_regs_read)) {
Shruti Guptaa276b202023-12-18 10:07:43 +0000184 ERROR("FPCR/FPSR mismatch\n");
Arunachalam Ganapathyf3697172023-09-04 15:04:46 +0100185 rc = false;
186 }
187
188 return rc;
189}
190
Arunachalam Ganapathy73949a22023-06-05 12:01:05 +0100191/* Check if Realm gets undefined abort when it accesses SVE functionality */
192bool test_realm_sve_undef_abort(void)
193{
Javier Almansa Sobrino82cd82e2025-01-17 17:37:42 +0000194 realm_reset_undef_abort_count();
Arunachalam Ganapathy73949a22023-06-05 12:01:05 +0100195
Javier Almansa Sobrino82cd82e2025-01-17 17:37:42 +0000196 /* Install exception handler to catch undefined abort */
Arunachalam Ganapathy73949a22023-06-05 12:01:05 +0100197 register_custom_sync_exception_handler(&realm_sync_exception_handler);
198 (void)sve_rdvl_1();
199 unregister_custom_sync_exception_handler();
200
Javier Almansa Sobrino82cd82e2025-01-17 17:37:42 +0000201 return (realm_get_undef_abort_count() != 0U);
Arunachalam Ganapathy73949a22023-06-05 12:01:05 +0100202}
Arunachalam Ganapathy1768e592023-05-23 13:28:38 +0100203
204/* Reads and returns the ID_AA64PFR1_EL1 and ID_AA64SMFR0_EL1 registers */
205bool test_realm_sme_read_id_registers(void)
206{
207 host_shared_data_t *sd = realm_get_my_shared_structure();
208 struct sme_cmd_id_regs *output;
209
210 output = (struct sme_cmd_id_regs *)sd->realm_cmd_output_buffer;
211 memset((void *)output, 0, sizeof(struct sme_cmd_id_regs));
212
Shruti Guptaa276b202023-12-18 10:07:43 +0000213 realm_printf("reading ID registers: ID_AA64PFR1_EL1, "
Arunachalam Ganapathy1768e592023-05-23 13:28:38 +0100214 " ID_AA64SMFR0_EL1\n");
215
216 output->id_aa64pfr1_el1 = read_id_aa64pfr1_el1();
217 output->id_aa64smfr0_el1 = read_id_aa64smfr0_el1();
218
219 return true;
220}
221
222/* Check if Realm gets undefined abort when it access SME functionality */
223bool test_realm_sme_undef_abort(void)
224{
Javier Almansa Sobrino82cd82e2025-01-17 17:37:42 +0000225 realm_reset_undef_abort_count();
Arunachalam Ganapathy1768e592023-05-23 13:28:38 +0100226
Javier Almansa Sobrino82cd82e2025-01-17 17:37:42 +0000227 /* Install exception handler to catch undefined abort */
Arunachalam Ganapathy1768e592023-05-23 13:28:38 +0100228 register_custom_sync_exception_handler(&realm_sync_exception_handler);
229 (void)read_svcr();
230 unregister_custom_sync_exception_handler();
231
Javier Almansa Sobrino82cd82e2025-01-17 17:37:42 +0000232 return (realm_get_undef_abort_count() != 0U);
Arunachalam Ganapathy1768e592023-05-23 13:28:38 +0100233}