blob: 0512789147c78468f2a73c4b2c260782f78e5b20 [file] [log] [blame]
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +01001/*
2 * Copyright (c) 2023, Arm Limited. All rights reserved.
3 * 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>
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010012#include <lib/extensions/sve.h>
13
14#include <host_realm_sve.h>
15#include <host_shared_data.h>
16
Arunachalam Ganapathyc1136a82023-04-12 15:24:44 +010017#define RL_SVE_OP_ARRAYSIZE 512U
18#define SVE_TEST_ITERATIONS 4U
19
20static int rl_sve_op_1[RL_SVE_OP_ARRAYSIZE];
21static int rl_sve_op_2[RL_SVE_OP_ARRAYSIZE];
22
Arunachalam Ganapathy5270d012023-04-19 14:53:42 +010023static sve_vector_t rl_sve_vectors_write[SVE_NUM_VECTORS] __aligned(16);
24
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010025/* Returns the maximum supported VL. This test is called only by sve Realm */
26bool test_realm_sve_rdvl(void)
27{
Shruti Gupta550e3e82023-08-16 13:20:11 +010028 host_shared_data_t *sd = realm_get_my_shared_structure();
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010029 struct sve_cmd_rdvl *output;
30
31 assert(is_armv8_2_sve_present());
32
33 output = (struct sve_cmd_rdvl *)sd->realm_cmd_output_buffer;
34 memset((void *)output, 0, sizeof(struct sve_cmd_rdvl));
35
36 sve_config_vq(SVE_VQ_ARCH_MAX);
37 output->rdvl = sve_vector_length_get();
38
39 return true;
40}
41
42/*
43 * Reads and returns the ID_AA64PFR0_EL1 and ID_AA64ZFR0_EL1 registers
44 * This test could be called from sve or non-sve Realm
45 */
46bool test_realm_sve_read_id_registers(void)
47{
Shruti Gupta550e3e82023-08-16 13:20:11 +010048 host_shared_data_t *sd = realm_get_my_shared_structure();
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010049 struct sve_cmd_id_regs *output;
50
51 output = (struct sve_cmd_id_regs *)sd->realm_cmd_output_buffer;
52 memset((void *)output, 0, sizeof(struct sve_cmd_id_regs));
53
54 realm_printf("Realm: reading ID registers: ID_AA64PFR0_EL1, "
55 " ID_AA64ZFR0_EL1\n");
56 output->id_aa64pfr0_el1 = read_id_aa64pfr0_el1();
57 output->id_aa64zfr0_el1 = read_id_aa64zfr0_el1();
58
59 return true;
60}
61
62/*
63 * Probes all VLs and return the bitmap with the bit set for each corresponding
64 * valid VQ. This test is called only by sve Realm
65 */
66bool test_realm_sve_probe_vl(void)
67{
Shruti Gupta550e3e82023-08-16 13:20:11 +010068 host_shared_data_t *sd = realm_get_my_shared_structure();
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +010069 struct sve_cmd_probe_vl *output;
70
71 assert(is_armv8_2_sve_present());
72
73 output = (struct sve_cmd_probe_vl *)&sd->realm_cmd_output_buffer;
74 memset((void *)output, 0, sizeof(struct sve_cmd_probe_vl));
75
76 /* Probe all VLs */
77 output->vl_bitmap = sve_probe_vl(SVE_VQ_ARCH_MAX);
78
79 return true;
80}
Arunachalam Ganapathyc1136a82023-04-12 15:24:44 +010081
82bool test_realm_sve_ops(void)
83{
84 int val, i;
85
86 assert(is_armv8_2_sve_present());
87
88 /* get at random value to do sve_subtract */
89 val = rand();
90 for (i = 0; i < RL_SVE_OP_ARRAYSIZE; i++) {
91 rl_sve_op_1[i] = val - i;
92 rl_sve_op_2[i] = 1;
93 }
94
95 for (i = 0; i < SVE_TEST_ITERATIONS; i++) {
96 /* Config Realm with random SVE length */
97 sve_config_vq(SVE_GET_RANDOM_VQ);
98
99 /* Perform SVE operations, without world switch */
100 sve_subtract_arrays(rl_sve_op_1, rl_sve_op_1, rl_sve_op_2,
101 RL_SVE_OP_ARRAYSIZE);
102 }
103
104 /* Check result of SVE operations. */
105 for (i = 0; i < RL_SVE_OP_ARRAYSIZE; i++) {
106 if (rl_sve_op_1[i] != (val - i - SVE_TEST_ITERATIONS)) {
107 realm_printf("Realm: SVE ops failed\n");
108 return false;
109 }
110 }
111
112 return true;
113}
Arunachalam Ganapathy5270d012023-04-19 14:53:42 +0100114
115/* Fill SVE Z registers with known pattern */
116bool test_realm_sve_fill_regs(void)
117{
118 uint32_t vl;
119
120 assert(is_armv8_2_sve_present());
121
122 /* Config Realm with max SVE length */
123 sve_config_vq(SVE_VQ_ARCH_MAX);
124 vl = sve_vector_length_get();
125
126 memset((void *)&rl_sve_vectors_write, 0xcd, vl * SVE_NUM_VECTORS);
127 sve_fill_vector_regs(rl_sve_vectors_write);
128
129 return true;
130}