fix(sve): represent sve Z0-31 registers as array of bytes
Currently each Z register is type defined as sve_vector_t but the helper
routine to write or read Z registers works based on current vector
length.
If test case defines 'sve_vector_t zregs[32]' and reads all Z registers
using sve_read_vector_regs() then zregs[n] might not corresponds to Zn
register unless the vector length is set to max value.
This patch also renames sve_vector_length_get() to sve_rdvl_1()
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: I42955f8009bdd7f40d74c5a8d21d7c16ce6d761e
diff --git a/include/lib/extensions/sve.h b/include/lib/extensions/sve.h
index 60432a5..ed5678e 100644
--- a/include/lib/extensions/sve.h
+++ b/include/lib/extensions/sve.h
@@ -37,12 +37,14 @@
#ifndef __ASSEMBLY__
-typedef uint8_t sve_vector_t[SVE_VECTOR_LEN_BYTES];
+typedef uint8_t sve_z_regs_t[SVE_NUM_VECTORS * SVE_VECTOR_LEN_BYTES]
+ __aligned(16);
void sve_config_vq(uint8_t sve_vq);
uint32_t sve_probe_vl(uint8_t sve_max_vq);
-void sve_fill_vector_regs(const sve_vector_t v[SVE_NUM_VECTORS]);
-void sve_read_vector_regs(sve_vector_t v[SVE_NUM_VECTORS]);
+
+void sve_z_regs_write(const sve_z_regs_t *z_regs);
+void sve_z_regs_read(sve_z_regs_t *z_regs);
/* Assembly routines */
bool sve_subtract_arrays_interleaved(int *dst_array, int *src_array1,
@@ -55,7 +57,7 @@
#ifdef __aarch64__
/* Returns the SVE implemented VL in bytes (constrained by ZCR_EL3.LEN) */
-static inline uint64_t sve_vector_length_get(void)
+static inline uint64_t sve_rdvl_1(void)
{
uint64_t vl;
diff --git a/include/runtime_services/spm_common.h b/include/runtime_services/spm_common.h
index 48471bc..0c8ade1 100644
--- a/include/runtime_services/spm_common.h
+++ b/include/runtime_services/spm_common.h
@@ -99,18 +99,6 @@
uint32_t arg);
void dump_ffa_value(struct ffa_value ret);
-/*
- * Fills SIMD/SVE registers with the content of the container v.
- * Number of vectors is assumed to be SIMD/SVE_NUM_VECTORS.
- */
-void fill_sve_vector_regs(const sve_vector_t v[SVE_NUM_VECTORS]);
-
-/*
- * Reads contents of SIMD/SVE registers into the provided container v.
- * Number of vectors is assumed to be SIMD/SVE_NUM_VECTORS.
- */
-void read_sve_vector_regs(sve_vector_t v[SVE_NUM_VECTORS]);
-
bool check_spmc_execution_level(void);
unsigned int get_ffa_feature_test_target(const struct ffa_features_test **test_target);
diff --git a/lib/extensions/sve/aarch64/sve.c b/lib/extensions/sve/aarch64/sve.c
index 83f61fe..10e1b3b 100644
--- a/lib/extensions/sve/aarch64/sve.c
+++ b/lib/extensions/sve/aarch64/sve.c
@@ -74,7 +74,7 @@
for (vq = 0; vq <= sve_max_vq; vq++) {
_sve_config_vq(vq);
- rdvl_vq = SVE_VL_TO_VQ(sve_vector_length_get());
+ rdvl_vq = SVE_VL_TO_VQ(sve_rdvl_1());
if (vl_bitmap & BIT_32(rdvl_vq)) {
continue;
}
@@ -84,7 +84,7 @@
return vl_bitmap;
}
-void sve_fill_vector_regs(const sve_vector_t v[SVE_NUM_VECTORS])
+void sve_z_regs_write(const sve_z_regs_t *z_regs)
{
assert(is_armv8_2_sve_present());
@@ -123,10 +123,10 @@
fill_sve_helper(30)
fill_sve_helper(31)
".arch_extension nosve\n"
- : : "r" (v));
+ : : "r" (z_regs));
}
-void sve_read_vector_regs(sve_vector_t v[SVE_NUM_VECTORS])
+void sve_z_regs_read(sve_z_regs_t *z_regs)
{
assert(is_armv8_2_sve_present());
@@ -165,5 +165,5 @@
read_sve_helper(30)
read_sve_helper(31)
".arch_extension nosve\n"
- : : "r" (v));
+ : : "r" (z_regs));
}
diff --git a/realm/realm_sve.c b/realm/realm_sve.c
index b41e23d..098cf4c 100644
--- a/realm/realm_sve.c
+++ b/realm/realm_sve.c
@@ -21,7 +21,7 @@
static int rl_sve_op_1[RL_SVE_OP_ARRAYSIZE];
static int rl_sve_op_2[RL_SVE_OP_ARRAYSIZE];
-static sve_vector_t rl_sve_vectors_write[SVE_NUM_VECTORS] __aligned(16);
+static sve_z_regs_t rl_sve_z_regs_write;
static int volatile realm_got_undef_abort;
@@ -37,7 +37,7 @@
memset((void *)output, 0, sizeof(struct sve_cmd_rdvl));
sve_config_vq(SVE_VQ_ARCH_MAX);
- output->rdvl = sve_vector_length_get();
+ output->rdvl = sve_rdvl_1();
return true;
}
@@ -124,10 +124,10 @@
/* Config Realm with max SVE length */
sve_config_vq(SVE_VQ_ARCH_MAX);
- vl = sve_vector_length_get();
+ vl = sve_rdvl_1();
- memset((void *)&rl_sve_vectors_write, 0xcd, vl * SVE_NUM_VECTORS);
- sve_fill_vector_regs(rl_sve_vectors_write);
+ memset((void *)&rl_sve_z_regs_write, 0xcd, vl * SVE_NUM_VECTORS);
+ sve_z_regs_write(&rl_sve_z_regs_write);
return true;
}
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c
index 93dfbfd..5e9d4fd 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c
@@ -22,8 +22,8 @@
static int ns_sve_op_1[NS_SVE_OP_ARRAYSIZE];
static int ns_sve_op_2[NS_SVE_OP_ARRAYSIZE];
-static sve_vector_t ns_sve_vectors_write[SVE_NUM_VECTORS] __aligned(16);
-static sve_vector_t ns_sve_vectors_read[SVE_NUM_VECTORS] __aligned(16);
+static sve_z_regs_t ns_sve_z_regs_write;
+static sve_z_regs_t ns_sve_z_regs_read;
/* Skip test if SVE is not supported in H/W or in RMI features */
#define CHECK_SVE_SUPPORT_IN_HW_AND_IN_RMI(_reg0) \
@@ -95,7 +95,7 @@
* by rdvl
*/
sve_config_vq(SVE_VQ_ARCH_MAX);
- ns_sve_vq = SVE_VL_TO_VQ(sve_vector_length_get());
+ ns_sve_vq = SVE_VL_TO_VQ(sve_rdvl_1());
if (rmi_sve_vq != ns_sve_vq) {
ERROR("RMI max SVE VL %u bits don't match NS max "
@@ -490,9 +490,9 @@
/* 1. Set NS SVE VQ to max and write known pattern */
sve_config_vq(sve_vq);
- (void)memset((void *)&ns_sve_vectors_write, 0xAA,
+ (void)memset((void *)&ns_sve_z_regs_write, 0xAA,
SVE_VQ_TO_BYTES(sve_vq) * SVE_NUM_VECTORS);
- sve_fill_vector_regs(ns_sve_vectors_write);
+ sve_z_regs_write(&ns_sve_z_regs_write);
/* 2. NS programs ZCR_EL2 with VQ as 0 */
sve_config_vq(SVE_VQ_ARCH_MIN);
@@ -513,15 +513,15 @@
/* 5. NS sets ZCR_EL2 with max VQ and reads the Z registers */
sve_config_vq(sve_vq);
- sve_read_vector_regs(ns_sve_vectors_read);
+ sve_z_regs_read(&ns_sve_z_regs_read);
/*
* 6. The upper bits in Z vectors (sve_vq - SVE_VQ_ARCH_MIN) must
* be either 0 or the old values filled by NS world.
* TODO: check if upper bits are zero
*/
- regs_base_wr = (uint8_t *)&ns_sve_vectors_write;
- regs_base_rd = (uint8_t *)&ns_sve_vectors_read;
+ regs_base_wr = (uint8_t *)&ns_sve_z_regs_write;
+ regs_base_rd = (uint8_t *)&ns_sve_z_regs_read;
rc = TEST_RESULT_SUCCESS;
for (int i = 0U; i < SVE_NUM_VECTORS; i++) {
diff --git a/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c b/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c
index efd6c8a..2e1f1d7 100644
--- a/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c
+++ b/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c
@@ -28,8 +28,8 @@
return TEST_RESULT_SUCCESS;
}
-static sve_vector_t sve_vectors_input[SVE_NUM_VECTORS] __aligned(16);
-static sve_vector_t sve_vectors_output[SVE_NUM_VECTORS] __aligned(16);
+static sve_z_regs_t sve_vectors_input;
+static sve_z_regs_t sve_vectors_output;
static int sve_op_1[NS_SVE_OP_ARRAYSIZE];
static int sve_op_2[NS_SVE_OP_ARRAYSIZE];
static fpu_reg_state_t g_fpu_template;
@@ -95,15 +95,15 @@
* Clear SVE vectors buffers used to compare the SVE state before calling
* into the Swd compared to SVE state restored after returning to NWd.
*/
- memset(sve_vectors_input, sizeof(sve_vector_t) * SVE_NUM_VECTORS, 0);
- memset(sve_vectors_output, sizeof(sve_vector_t) * SVE_NUM_VECTORS, 0);
+ memset(sve_vectors_input, 0, sizeof(sve_vectors_input));
+ memset(sve_vectors_output, 0, sizeof(sve_vectors_output));
/* Set ZCR_EL2.LEN to implemented VL (constrained by EL3). */
write_zcr_el2(0xf);
isb();
/* Get the implemented VL. */
- vl = sve_vector_length_get();
+ vl = sve_rdvl_1();
/* Fill each vector for the VL size with a fixed pattern. */
sve_vector = (uint8_t *) sve_vectors_input;
@@ -113,7 +113,7 @@
}
/* Fill SVE vector registers with the buffer contents prepared above. */
- sve_fill_vector_regs(sve_vectors_input);
+ sve_z_regs_write(&sve_vectors_input);
/*
* Call cactus secure partition which uses SIMD (and expect it doesn't
@@ -130,7 +130,7 @@
}
/* Get the SVE vectors state after returning to normal world. */
- sve_read_vector_regs(sve_vectors_output);
+ sve_z_regs_read(&sve_vectors_output);
/* Compare to state before calling into secure world. */
return fp_vector_compare((uint8_t *)sve_vectors_input,