Merge changes from topic "od/sme"
* changes:
feat(spm): probe SVL for SME related tests
test(spm): add three SME related tests
refactor(spm): rename FF-A SIMD test suite
refactor(spm): test_sve_vectors_preserved
test(spm): check processor feature regs
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 3c30c9d..c45358e 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -132,46 +132,52 @@
#define ID_AA64PFR0_EL1_SHIFT U(4)
#define ID_AA64PFR0_EL2_SHIFT U(8)
#define ID_AA64PFR0_EL3_SHIFT U(12)
-#define ID_AA64PFR0_AMU_SHIFT U(44)
-#define ID_AA64PFR0_AMU_LENGTH U(4)
-#define ID_AA64PFR0_AMU_MASK ULL(0xf)
-#define ID_AA64PFR0_AMU_NOT_SUPPORTED U(0x0)
-#define ID_AA64PFR0_AMU_V1 U(0x1)
-#define ID_AA64PFR0_AMU_V1P1 U(0x2)
#define ID_AA64PFR0_ELX_MASK ULL(0xf)
-#define ID_AA64PFR0_SVE_SHIFT U(32)
-#define ID_AA64PFR0_SVE_WIDTH U(4)
-#define ID_AA64PFR0_SVE_MASK ULL(0xf)
-#define ID_AA64PFR0_SVE_LENGTH U(4)
-#define ID_AA64PFR0_MPAM_SHIFT U(40)
-#define ID_AA64PFR0_MPAM_MASK ULL(0xf)
-#define ID_AA64PFR0_DIT_SHIFT U(48)
-#define ID_AA64PFR0_DIT_MASK ULL(0xf)
-#define ID_AA64PFR0_DIT_LENGTH U(4)
-#define ID_AA64PFR0_DIT_SUPPORTED U(1)
-#define ID_AA64PFR0_CSV2_SHIFT U(56)
-#define ID_AA64PFR0_CSV2_MASK ULL(0xf)
-#define ID_AA64PFR0_CSV2_WIDTH U(4)
-#define ID_AA64PFR0_CSV2_NOT_SUPPORTED ULL(0x0)
-#define ID_AA64PFR0_CSV2_SUPPORTED ULL(0x1)
-#define ID_AA64PFR0_CSV2_2_SUPPORTED ULL(0x2)
-#define ID_AA64PFR0_FEAT_RME_SHIFT U(52)
-#define ID_AA64PFR0_FEAT_RME_MASK ULL(0xf)
-#define ID_AA64PFR0_FEAT_RME_LENGTH U(4)
-#define ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED U(0)
-#define ID_AA64PFR0_FEAT_RME_V1 U(1)
-#define ID_AA64PFR0_RAS_MASK ULL(0xf)
-#define ID_AA64PFR0_RAS_SHIFT U(28)
-#define ID_AA64PFR0_RAS_WIDTH U(4)
-#define ID_AA64PFR0_RAS_NOT_SUPPORTED ULL(0x0)
-#define ID_AA64PFR0_RAS_SUPPORTED ULL(0x1)
-#define ID_AA64PFR0_RASV1P1_SUPPORTED ULL(0x2)
+#define ID_AA64PFR0_FP_SHIFT U(16)
+#define ID_AA64PFR0_FP_WIDTH U(4)
+#define ID_AA64PFR0_FP_MASK U(0xf)
+#define ID_AA64PFR0_ADVSIMD_SHIFT U(20)
+#define ID_AA64PFR0_ADVSIMD_WIDTH U(4)
+#define ID_AA64PFR0_ADVSIMD_MASK U(0xf)
#define ID_AA64PFR0_GIC_SHIFT U(24)
#define ID_AA64PFR0_GIC_WIDTH U(4)
#define ID_AA64PFR0_GIC_MASK ULL(0xf)
#define ID_AA64PFR0_GIC_NOT_SUPPORTED ULL(0x0)
#define ID_AA64PFR0_GICV3_GICV4_SUPPORTED ULL(0x1)
#define ID_AA64PFR0_GICV4_1_SUPPORTED ULL(0x2)
+#define ID_AA64PFR0_RAS_MASK ULL(0xf)
+#define ID_AA64PFR0_RAS_SHIFT U(28)
+#define ID_AA64PFR0_RAS_WIDTH U(4)
+#define ID_AA64PFR0_RAS_NOT_SUPPORTED ULL(0x0)
+#define ID_AA64PFR0_RAS_SUPPORTED ULL(0x1)
+#define ID_AA64PFR0_RASV1P1_SUPPORTED ULL(0x2)
+#define ID_AA64PFR0_SVE_SHIFT U(32)
+#define ID_AA64PFR0_SVE_WIDTH U(4)
+#define ID_AA64PFR0_SVE_MASK ULL(0xf)
+#define ID_AA64PFR0_SVE_LENGTH U(4)
+#define ID_AA64PFR0_MPAM_SHIFT U(40)
+#define ID_AA64PFR0_MPAM_MASK ULL(0xf)
+#define ID_AA64PFR0_AMU_SHIFT U(44)
+#define ID_AA64PFR0_AMU_LENGTH U(4)
+#define ID_AA64PFR0_AMU_MASK ULL(0xf)
+#define ID_AA64PFR0_AMU_NOT_SUPPORTED U(0x0)
+#define ID_AA64PFR0_AMU_V1 U(0x1)
+#define ID_AA64PFR0_AMU_V1P1 U(0x2)
+#define ID_AA64PFR0_DIT_SHIFT U(48)
+#define ID_AA64PFR0_DIT_MASK ULL(0xf)
+#define ID_AA64PFR0_DIT_LENGTH U(4)
+#define ID_AA64PFR0_DIT_SUPPORTED U(1)
+#define ID_AA64PFR0_FEAT_RME_SHIFT U(52)
+#define ID_AA64PFR0_FEAT_RME_MASK ULL(0xf)
+#define ID_AA64PFR0_FEAT_RME_LENGTH U(4)
+#define ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED U(0)
+#define ID_AA64PFR0_FEAT_RME_V1 U(1)
+#define ID_AA64PFR0_CSV2_SHIFT U(56)
+#define ID_AA64PFR0_CSV2_MASK ULL(0xf)
+#define ID_AA64PFR0_CSV2_WIDTH U(4)
+#define ID_AA64PFR0_CSV2_NOT_SUPPORTED ULL(0x0)
+#define ID_AA64PFR0_CSV2_SUPPORTED ULL(0x1)
+#define ID_AA64PFR0_CSV2_2_SUPPORTED ULL(0x2)
/* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */
#define ID_AA64DFR0_PMS_SHIFT U(32)
diff --git a/include/lib/aarch64/arch_features.h b/include/lib/aarch64/arch_features.h
index c59e405..a2ed5be 100644
--- a/include/lib/aarch64/arch_features.h
+++ b/include/lib/aarch64/arch_features.h
@@ -42,6 +42,20 @@
ID_AA64PFR0_SVE_MASK) == 1U;
}
+static inline bool is_feat_advsimd_present(void)
+{
+ u_register_t id_aa64pfr0_advsimd =
+ EXTRACT(ID_AA64PFR0_ADVSIMD, read_id_aa64pfr0_el1());
+ return (id_aa64pfr0_advsimd == 0 || id_aa64pfr0_advsimd == 1);
+}
+
+static inline bool is_feat_fp_present(void)
+{
+ u_register_t id_aa64pfr0_fp =
+ EXTRACT(ID_AA64PFR0_FP, read_id_aa64pfr0_el1());
+ return (id_aa64pfr0_fp == 0 || id_aa64pfr0_fp == 1);
+}
+
static inline bool is_armv8_2_ttcnp_present(void)
{
return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_CNP_SHIFT) &
diff --git a/include/lib/extensions/sme.h b/include/lib/extensions/sme.h
index 4a7e9b7..7175b71 100644
--- a/include/lib/extensions/sme.h
+++ b/include/lib/extensions/sme.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +13,9 @@
#define MAX_VL_B (MAX_VL / 8)
#define SME_SVQ_ARCH_MAX (MASK(SMCR_ELX_LEN) >> SMCR_ELX_LEN_SHIFT)
+/* convert SME SVL in bytes to SVQ */
+#define SME_SVL_TO_SVQ(svl_bytes) (((svl_bytes) >> 4U) - 1U)
+
/* get a random Streaming SVE VQ b/w 0 to SME_SVQ_ARCH_MAX */
#define SME_GET_RANDOM_SVQ (rand() % (SME_SVQ_ARCH_MAX + 1))
@@ -31,6 +34,7 @@
/* SME feature related prototypes. */
void sme_smstart(smestart_instruction_type_t smstart_type);
void sme_smstop(smestop_instruction_type_t smstop_type);
+uint32_t sme_probe_svl(uint8_t sme_max_svq);
/* Assembly function prototypes. */
uint64_t sme_rdsvl_1(void);
diff --git a/lib/extensions/sme/aarch64/sme.c b/lib/extensions/sme/aarch64/sme.c
index ee21578..a7337ee 100644
--- a/lib/extensions/sme/aarch64/sme.c
+++ b/lib/extensions/sme/aarch64/sme.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -91,7 +91,7 @@
{
u_register_t smcr_el2_val;
- /* cap svq to arch supported max value */
+ /* Cap svq to arch supported max value. */
if (svq > SME_SVQ_ARCH_MAX) {
svq = SME_SVQ_ARCH_MAX;
}
@@ -145,3 +145,25 @@
{
return ((read_smcr_el2() & SMCR_ELX_FA64_BIT) != 0U);
}
+
+uint32_t sme_probe_svl(uint8_t sme_max_svq)
+{
+ uint32_t svl_bitmap = 0;
+ uint8_t svq, rdsvl_vq;
+
+ /* Cap svq to arch supported max value. */
+ if (sme_max_svq > SME_SVQ_ARCH_MAX) {
+ sme_max_svq = SME_SVQ_ARCH_MAX;
+ }
+
+ for (svq = 0; svq <= sme_max_svq; svq++) {
+ sme_config_svq(svq);
+ rdsvl_vq = SME_SVL_TO_SVQ(sme_rdsvl_1());
+ if (svl_bitmap & BIT_32(rdsvl_vq)) {
+ continue;
+ }
+ svl_bitmap |= BIT_32(rdsvl_vq);
+ }
+
+ return svl_bitmap;
+}
diff --git a/plat/xilinx/versal_net/tests_to_skip.txt b/plat/xilinx/versal_net/tests_to_skip.txt
index d5c3a39..80e7cb2 100644
--- a/plat/xilinx/versal_net/tests_to_skip.txt
+++ b/plat/xilinx/versal_net/tests_to_skip.txt
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -38,7 +38,7 @@
FF-A Setup and Discovery/FF-A RXTX unmap SP rxtx buffer
FF-A Setup and Discovery/Test FFA_PARTITION_INFO_GET v1.0
FF-A Memory Sharing/Lend memory, clear flag set
-SIMD,SVE Registers context/Check that SIMD registers context is preserved
+SIMD context switch tests
FF-A Interrupt
FF-A Notifications
diff --git a/plat/xilinx/zynqmp/tests_to_skip.txt b/plat/xilinx/zynqmp/tests_to_skip.txt
index 9c32ae2..271fdc8 100644
--- a/plat/xilinx/zynqmp/tests_to_skip.txt
+++ b/plat/xilinx/zynqmp/tests_to_skip.txt
@@ -53,7 +53,7 @@
EL3 power state parser validation
#TESTS: SIMD
-SIMD,SVE Registers context/Check that SIMD registers context is preserved
+SIMD context switch tests
#TESTS: psci-extensive
PSCI CPU ON OFF Stress Tests/Repeated shutdown of all cores to stress test CPU_ON, CPU_SUSPEND and CPU_OFF
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index 0755749..9557745 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -46,6 +46,7 @@
) \
$(addprefix spm/common/sp_tests/, \
sp_test_ffa.c \
+ sp_test_cpu.c \
) \
$(addprefix spm/cactus/cactus_tests/, \
cactus_message_loop.c \
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index b39f138..1d5cd97 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -327,8 +327,9 @@
discover_managed_exit_interrupt_id();
register_maintenance_interrupt_handlers();
- /* Invoking Tests */
+ /* Invoking self tests */
ffa_tests(&mb);
+ cpu_feature_tests();
msg_loop:
/* End up to message loop */
diff --git a/spm/common/sp_helpers.h b/spm/common/sp_helpers.h
index e0e749d..776cc75 100644
--- a/spm/common/sp_helpers.h
+++ b/spm/common/sp_helpers.h
@@ -8,6 +8,8 @@
#define SP_HELPERS_H
#include <stdint.h>
+
+#include <debug.h>
#include <tftf_lib.h>
#include <spm_common.h>
#include <spinlock.h>
diff --git a/spm/common/sp_tests/sp_test_cpu.c b/spm/common/sp_tests/sp_test_cpu.c
new file mode 100644
index 0000000..a05dbf3
--- /dev/null
+++ b/spm/common/sp_tests/sp_test_cpu.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sp_helpers.h>
+
+#include <arch_features.h>
+
+static void cpu_check_id_regs(void)
+{
+ /* ID_AA64PFR0_EL1 */
+ EXPECT(is_feat_advsimd_present(), true);
+ EXPECT(is_feat_fp_present(), true);
+ EXPECT(is_armv8_2_sve_present(), false);
+
+ /* ID_AA64PFR1_EL1 */
+ EXPECT(is_feat_sme_supported(), false);
+}
+
+void cpu_feature_tests(void)
+{
+ const char *test_cpu_str = "CPU tests";
+
+ announce_test_section_start(test_cpu_str);
+ cpu_check_id_regs();
+ announce_test_section_end(test_cpu_str);
+}
diff --git a/spm/common/sp_tests/sp_test_ffa.c b/spm/common/sp_tests/sp_test_ffa.c
index c3774f9..ba63a0e 100644
--- a/spm/common/sp_tests/sp_test_ffa.c
+++ b/spm/common/sp_tests/sp_test_ffa.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -195,7 +195,7 @@
ffa_partition_info_wrong_test();
}
-void ffa_version_test(void)
+static void ffa_version_test(void)
{
struct ffa_value ret = ffa_version(FFA_VERSION_COMPILED);
@@ -212,7 +212,7 @@
EXPECT((int)compatible, (int)true);
}
-void ffa_spm_id_get_test(void)
+static void ffa_spm_id_get_test(void)
{
if (spm_version >= FFA_VERSION_1_1) {
struct ffa_value ret = ffa_spm_id_get();
@@ -236,9 +236,9 @@
void ffa_tests(struct mailbox_buffers *mb)
{
- const char *test_ffa = "FF-A setup and discovery";
+ const char *test_ffa_str = "FF-A setup and discovery";
- announce_test_section_start(test_ffa);
+ announce_test_section_start(test_ffa_str);
ffa_features_test();
ffa_version_test();
@@ -246,5 +246,5 @@
ffa_partition_info_get_test(mb);
ffa_partition_info_get_regs_test();
- announce_test_section_end(test_ffa);
+ announce_test_section_end(test_ffa_str);
}
diff --git a/spm/common/sp_tests/sp_tests.h b/spm/common/sp_tests/sp_tests.h
index 10d3b9b..007c2ca 100644
--- a/spm/common/sp_tests/sp_tests.h
+++ b/spm/common/sp_tests/sp_tests.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,9 +10,10 @@
#include <spm_common.h>
/*
- * Test functions
+ * Self test functions
*/
void ffa_tests(struct mailbox_buffers *mb);
+void cpu_feature_tests(void);
#endif /* CACTUS_TESTS_H */
diff --git a/tftf/tests/aarch32_tests_to_skip.txt b/tftf/tests/aarch32_tests_to_skip.txt
index 6913cb1..f05235d 100644
--- a/tftf/tests/aarch32_tests_to_skip.txt
+++ b/tftf/tests/aarch32_tests_to_skip.txt
@@ -1,10 +1,9 @@
#
-# Copyright (c) 2023, Arm Limited. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
Realm payload at EL1
-SIMD,SVE Registers context
Invalid memory access with RME extension
FF-A Setup and Discovery
SP exceptions
@@ -12,7 +11,7 @@
FF-A Group0 interrupts
FF-A Power management
FF-A Memory Sharing
-SIMD,SVE Registers context
+SIMD context switch tests
FF-A Interrupt
SMMUv3 tests
FF-A Notifications
diff --git a/tftf/tests/runtime_services/secure_service/test_spm_simd.c b/tftf/tests/runtime_services/secure_service/test_spm_simd.c
index cfc931f..baec1ac 100644
--- a/tftf/tests/runtime_services/secure_service/test_spm_simd.c
+++ b/tftf/tests/runtime_services/secure_service/test_spm_simd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,6 +21,10 @@
static sve_z_regs_t sve_vectors_input;
static sve_z_regs_t sve_vectors_output;
+static sve_p_regs_t sve_predicates_input;
+static sve_p_regs_t sve_predicates_output;
+static sve_ffr_regs_t sve_ffr_input;
+static sve_ffr_regs_t sve_ffr_output;
static int sve_op_1[NS_SVE_OP_ARRAYSIZE];
static int sve_op_2[NS_SVE_OP_ARRAYSIZE];
static fpu_state_t g_fpu_state_write;
@@ -38,7 +42,7 @@
/**********************************************************************
* Verify that FF-A is there and that it has the correct version.
**********************************************************************/
- CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
fpu_state_write_rand(&g_fpu_state_write);
struct ffa_value ret = cactus_req_simd_fill_send_cmd(SENDER, RECEIVER);
@@ -70,23 +74,13 @@
return TEST_RESULT_SUCCESS;
}
-/*
- * Tests that SVE vectors are preserved during the context switches between
- * normal world and the secure world.
- * Fills the SVE vectors with known values, requests SP to fill the vectors
- * with a different values, checks that the context is restored on return.
- */
-test_result_t test_sve_vectors_preserved(void)
+static test_result_t test_sve_vectors_preserved_impl(uint8_t vq)
{
- uint64_t vl;
uint8_t *sve_vector;
+ uint64_t vl;
- SKIP_TEST_IF_SVE_NOT_SUPPORTED();
-
- /**********************************************************************
- * Verify that FF-A is there and that it has the correct version.
- **********************************************************************/
- CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ /* Configure requested VL. */
+ sve_config_vq(vq);
/*
* Clear SVE vectors buffers used to compare the SVE state before calling
@@ -95,15 +89,12 @@
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_rdvl_1();
+ /* Vector length in bytes from vq. */
+ vl = SVE_VQ_TO_BYTES(vq);
/* Fill each vector for the VL size with a fixed pattern. */
sve_vector = (uint8_t *) sve_vectors_input;
+
for (uint32_t vector_num = 0U; vector_num < SVE_NUM_VECTORS; vector_num++) {
memset(sve_vector, 0x11 * (vector_num + 1), vl);
sve_vector += vl;
@@ -126,6 +117,11 @@
return TEST_RESULT_FAIL;
}
+ /* Check ZCR_EL2 was preserved. */
+ if (sve_read_zcr_elx() != vq) {
+ return TEST_RESULT_FAIL;
+ }
+
/* Get the SVE vectors state after returning to normal world. */
sve_z_regs_read(&sve_vectors_output);
@@ -137,13 +133,59 @@
return TEST_RESULT_SUCCESS;
}
+static test_result_t helper_test_sve(test_result_t (*func)(uint8_t vq))
+{
+ uint32_t bitmap, vl_bitmap;
+ uint32_t vq = 0;
+ test_result_t ret;
+
+ SKIP_TEST_IF_SVE_NOT_SUPPORTED();
+
+ /**********************************************************************
+ * Verify that FF-A is there and that it has the correct version.
+ **********************************************************************/
+ CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
+
+ /*
+ * Check SVE state is preserved normal/secure accross world switches for
+ * the discovered vector lengths.
+ */
+ vl_bitmap = sve_probe_vl(SVE_VQ_ARCH_MAX);
+ for (bitmap = vl_bitmap; bitmap != 0U; bitmap >>= 1) {
+ if ((bitmap & 1) != 0) {
+ VERBOSE("Test VL %u bits.\n", SVE_VQ_TO_BITS(vq));
+
+ ret = func(vq);
+ if (ret != TEST_RESULT_SUCCESS) {
+ return ret;
+ }
+ }
+ vq++;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * Tests that SVE vectors are preserved during the context switches between
+ * normal world and the secure world.
+ * Probe all possible vector length that the platform implements.
+ * For each vector length value:
+ * -Fill SVE vectors with known values.
+ * -Request SP to fill NEON vectors with different values.
+ * -Check the SVE context is restored on return.
+ */
+test_result_t test_sve_vectors_preserved(void)
+{
+ return helper_test_sve(test_sve_vectors_preserved_impl);
+}
+
/*
* Sends SIMD fill command to Cactus SP
* Returns:
* false - On success
* true - On failure
*/
-#ifdef __aarch64__
static bool callback_enter_cactus_sp(void)
{
struct ffa_value ret = cactus_req_simd_fill_send_cmd(SENDER, RECEIVER);
@@ -158,7 +200,6 @@
return false;
}
-#endif /* __aarch64__ */
/*
* Tests that SVE vector operations in normal world are not affected by context
@@ -174,7 +215,7 @@
/**********************************************************************
* Verify that FF-A is there and that it has the correct version.
**********************************************************************/
- CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
val = 2 * SVE_TEST_ITERATIONS;
@@ -184,7 +225,7 @@
}
/* Set ZCR_EL2.LEN to implemented VL (constrained by EL3). */
- write_zcr_el2(0xf);
+ write_zcr_el2(SVE_VQ_ARCH_MAX);
isb();
for (unsigned int i = 0; i < SVE_TEST_ITERATIONS; i++) {
@@ -209,3 +250,298 @@
return TEST_RESULT_SUCCESS;
}
+
+/*
+ * This base function probes all possible Streaming SVE vector length
+ * values and calls the function passed as parameter with each discovered
+ * value.
+ */
+static test_result_t helper_test_sme(test_result_t (*func)(uint8_t svq))
+{
+ uint32_t svl_bitmap;
+ uint8_t svq;
+ test_result_t ret;
+
+ SKIP_TEST_IF_AARCH32();
+
+ /* Skip the test if SME is not supported. */
+ SKIP_TEST_IF_SME_NOT_SUPPORTED();
+
+ CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
+
+ svl_bitmap = sme_probe_svl(SME_SVQ_ARCH_MAX);
+ svq = 0;
+ for (uint32_t bitmap = svl_bitmap; bitmap != 0U; bitmap >>= 1) {
+ if ((bitmap & 1) != 0) {
+ VERBOSE("Test SVL %u bits.\n", SVE_VQ_TO_BITS(svq));
+ ret = func(svq);
+ if (ret != TEST_RESULT_SUCCESS) {
+ return ret;
+ }
+ }
+
+ svq++;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+static test_result_t do_test_sme_streaming_sve(uint8_t svq)
+{
+ struct ffa_value ret;
+
+ /* Enable SME FA64 if implemented. */
+ if (is_feat_sme_fa64_supported()) {
+ sme_enable_fa64();
+ }
+
+ /* Enter Streaming SVE mode. */
+ sme_smstart(SMSTART_SM);
+
+ /* Configure SVQ. */
+ sme_config_svq((uint32_t)svq);
+
+ sve_z_regs_write_rand(&sve_vectors_input);
+ sve_p_regs_write_rand(&sve_predicates_input);
+ fpu_cs_regs_write_rand(&g_fpu_state_write.cs_regs);
+
+ if (is_feat_sme_fa64_supported()) {
+ sve_ffr_regs_write_rand(&sve_ffr_input);
+ }
+
+ ret = cactus_req_simd_fill_send_cmd(SENDER, RECEIVER);
+
+ if (!is_expected_cactus_response(ret, CACTUS_SUCCESS, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (is_feat_sme_fa64_supported()) {
+ if (!sme_feat_fa64_enabled()) {
+ ERROR("FA64 trap bit disabled, expected enabled.\n");
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ /* Expect Streaming SVE to be active. */
+ if (!sme_smstat_sm()) {
+ ERROR("Streaming SVE disabled, expected enabled.\n");
+ return TEST_RESULT_FAIL;
+ }
+
+ sve_z_regs_read(&sve_vectors_output);
+ if (sve_z_regs_compare(&sve_vectors_input, &sve_vectors_output) != 0) {
+ ERROR("SME Z vectors compare failed.");
+ return TEST_RESULT_FAIL;
+ }
+
+ sve_p_regs_read(&sve_predicates_output);
+ if (sve_p_regs_compare(&sve_predicates_input, &sve_predicates_output) != 0) {
+ ERROR("SME predicates compare failed.");
+ return TEST_RESULT_FAIL;
+ }
+
+ fpu_cs_regs_read(&g_fpu_state_read.cs_regs);
+ if (fpu_cs_regs_compare(&g_fpu_state_write.cs_regs, &g_fpu_state_read.cs_regs) != 0) {
+ ERROR("FPU control/status compare failed.");
+ return TEST_RESULT_FAIL;
+ }
+
+ if (is_feat_sme_fa64_supported()) {
+ sve_ffr_regs_read(&sve_ffr_output);
+ if (sve_ffr_regs_compare(&sve_ffr_input, &sve_ffr_output) != 0) {
+ ERROR("SVE FFR register compare failed.");
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ /* Exit Streaming SVE mode. */
+ sme_smstop(SMSTOP_SM);
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * SME enter SPMC with SSVE enabled.
+ *
+ * Check Streaming SVE is preserved on a normal/secure world switch.
+ *
+ */
+test_result_t test_sme_streaming_sve(void)
+{
+ return helper_test_sme(do_test_sme_streaming_sve);
+}
+
+static test_result_t do_test_sme_za(uint8_t vq)
+{
+ struct ffa_value ret;
+
+ /* Enable SME FA64 if implemented. */
+ if (is_feat_sme_fa64_supported()) {
+ sme_enable_fa64();
+ }
+
+ /* Enable SME ZA Array Storage */
+ sme_smstart(SMSTART_ZA);
+
+ /* Configure VQ. */
+ sve_config_vq(vq);
+
+ sve_z_regs_write_rand(&sve_vectors_input);
+ sve_p_regs_write_rand(&sve_predicates_input);
+ fpu_cs_regs_write_rand(&g_fpu_state_write.cs_regs);
+ sve_ffr_regs_write_rand(&sve_ffr_input);
+
+ ret = cactus_req_simd_fill_send_cmd(SENDER, RECEIVER);
+ if (!is_ffa_direct_response(ret)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (cactus_get_response(ret) == CACTUS_ERROR) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (is_feat_sme_fa64_supported()) {
+ if (!sme_feat_fa64_enabled()) {
+ ERROR("FA64 trap bit disabled, expected enabled.\n");
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ /* Expect Streaming SVE to be inactive. */
+ if (sme_smstat_sm()) {
+ ERROR("Streaming SVE enabled, expected disabled.\n");
+ return TEST_RESULT_FAIL;
+ }
+
+
+ sve_z_regs_read(&sve_vectors_output);
+ if (sve_z_regs_compare(&sve_vectors_input, &sve_vectors_output) != 0) {
+ ERROR("SME Z vectors compare failed.");
+ return TEST_RESULT_FAIL;
+ }
+
+ sve_p_regs_read(&sve_predicates_output);
+ if (sve_p_regs_compare(&sve_predicates_input, &sve_predicates_output) != 0) {
+ ERROR("SME predicates compare failed.");
+ return TEST_RESULT_FAIL;
+ }
+
+ fpu_cs_regs_read(&g_fpu_state_read.cs_regs);
+ if (fpu_cs_regs_compare(&g_fpu_state_write.cs_regs, &g_fpu_state_read.cs_regs) != 0) {
+ ERROR("FPU control/status compare failed.");
+ return TEST_RESULT_FAIL;
+ }
+
+ sve_ffr_regs_read(&sve_ffr_output);
+ if (sve_ffr_regs_compare(&sve_ffr_input, &sve_ffr_output) != 0) {
+ ERROR("SVE FFR register compare failed.");
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Disable SME ZA array storage. */
+ sme_smstop(SMSTOP_ZA);
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * SME enter SPMC with ZA enabled.
+ *
+ * Check ZA array enabled is preserved on a normal/secure world switch.
+ */
+test_result_t test_sme_za(void)
+{
+ SKIP_TEST_IF_AARCH32();
+
+ /* Skip the test if SME is not supported. */
+ SKIP_TEST_IF_SME_NOT_SUPPORTED();
+
+ return helper_test_sve(do_test_sme_za);
+}
+
+static test_result_t do_test_sme_streaming_sve_za(uint8_t svq)
+{
+ struct ffa_value ret;
+
+ /* Enable SME FA64 if implemented. */
+ if (is_feat_sme_fa64_supported()) {
+ sme_enable_fa64();
+ }
+
+ /* Enable SME SSVE + ZA. */
+ sme_smstart(SMSTART);
+
+ /* Configure SVQ. */
+ sme_config_svq((uint32_t)svq);
+
+ sve_z_regs_write_rand(&sve_vectors_input);
+ sve_p_regs_write_rand(&sve_predicates_input);
+ fpu_cs_regs_write_rand(&g_fpu_state_write.cs_regs);
+
+ if (is_feat_sme_fa64_supported()) {
+ sve_ffr_regs_write_rand(&sve_ffr_input);
+ }
+
+ ret = cactus_req_simd_fill_send_cmd(SENDER, RECEIVER);
+ if (!is_ffa_direct_response(ret)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (cactus_get_response(ret) == CACTUS_ERROR) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (is_feat_sme_fa64_supported()) {
+ if (!sme_feat_fa64_enabled()) {
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ /* Expect Streaming SVE to be active. */
+ if (!sme_smstat_sm()) {
+ ERROR("Streaming SVE disabled, expected enabled.\n");
+ return TEST_RESULT_FAIL;
+ }
+
+ sve_z_regs_read(&sve_vectors_output);
+ if (sve_z_regs_compare(&sve_vectors_input, &sve_vectors_output) != 0) {
+ ERROR("SME Z vectors compare failed.");
+ return TEST_RESULT_FAIL;
+ }
+
+ sve_p_regs_read(&sve_predicates_output);
+ if (sve_p_regs_compare(&sve_predicates_input, &sve_predicates_output) != 0) {
+ ERROR("SME predicates compare failed.");
+ return TEST_RESULT_FAIL;
+ }
+
+ fpu_cs_regs_read(&g_fpu_state_read.cs_regs);
+ if (fpu_cs_regs_compare(&g_fpu_state_write.cs_regs, &g_fpu_state_read.cs_regs) != 0) {
+ ERROR("FPU control/status compare failed.");
+ return TEST_RESULT_FAIL;
+ }
+
+ if (is_feat_sme_fa64_supported()) {
+ sve_ffr_regs_read(&sve_ffr_output);
+ if (sve_ffr_regs_compare(&sve_ffr_input, &sve_ffr_output) != 0) {
+ ERROR("SVE FFR register compare failed.");
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ /* Disable SSVE + ZA. */
+ sme_smstop(SMSTOP);
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * SME enter SPMC with SSVE+ZA enabled.
+ *
+ * Check Streaming SVE and ZA array enabled are preserved on a
+ * normal/secure world switch.
+ */
+test_result_t test_sme_streaming_sve_za(void)
+{
+ return helper_test_sme(do_test_sme_streaming_sve_za);
+}
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index 5658d62..7c5a8c3 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ Copyright (c) 2018-2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
-->
@@ -143,14 +143,20 @@
function="test_ffa_memory_retrieve_request_from_vm" />
</testsuite>
- <testsuite name="SIMD,SVE Registers context"
+ <testsuite name="SIMD context switch tests"
description="Validate context switch between NWd and SWd" >
- <testcase name="Check that SIMD registers context is preserved"
+ <testcase name="Check that Adv. SIMD registers context is preserved"
function="test_simd_vectors_preserved" />
<testcase name="Check that SVE registers context is preserved"
function="test_sve_vectors_preserved" />
<testcase name="Check that SVE operations in NWd are unaffected by SWd"
function="test_sve_vectors_operations" />
+ <testcase name="Enter SPMC with SME SSVE enabled"
+ function="test_sme_streaming_sve" />
+ <testcase name="Enter SPMC with SME ZA enabled"
+ function="test_sme_za" />
+ <testcase name="Enter SPMC with SME SM+ZA enabled"
+ function="test_sme_streaming_sve_za" />
</testsuite>
<testsuite name="FF-A Interrupt"