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"