refactor(tftf): move SIMD/FPU save/restore routine to common lib

- Move FPU routines to common lib
- FPU/SIMD state consist of the 32 SIMD vectors, FPCR and FPSR registers
- Test that FPU/SIMD state are preserved during a context switch
  between secure/non-secure.

Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
Change-Id: I88f0a9f716aafdd634c4eae5b885f839bb3deb00
diff --git a/include/lib/extensions/fpu.h b/include/lib/extensions/fpu.h
new file mode 100644
index 0000000..c803081
--- /dev/null
+++ b/include/lib/extensions/fpu.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FPU_H
+#define FPU_H
+
+/* The FPU and SIMD register bank is 32 quadword (128 bits) Q registers. */
+#define FPU_Q_SIZE		16U
+#define FPU_Q_COUNT		32U
+
+/* These defines are needed by assembly code to access FPU registers. */
+#define FPU_OFFSET_Q		0U
+#define FPU_OFFSET_FPSR		(FPU_Q_SIZE * FPU_Q_COUNT)
+#define FPU_OFFSET_FPCR		(FPU_OFFSET_FPSR + 8)
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+typedef struct fpu_reg_state {
+	uint8_t q[FPU_Q_COUNT][FPU_Q_SIZE];
+	unsigned long fpsr;
+	unsigned long fpcr;
+} fpu_reg_state_t;
+
+/*
+ * Read and compare FPU state registers with provided template values in parameters.
+ */
+bool fpu_state_compare_template(fpu_reg_state_t *fpu);
+
+/*
+ * Fill the template with random values and copy it to
+ * FPU state registers(SIMD vectors, FPCR, FPSR).
+ */
+void fpu_state_fill_regs_and_template(fpu_reg_state_t *fpu);
+
+/*
+ * This function populates the provided FPU structure with the provided template
+ * regs_val for all the 32 FPU/SMID registers, and the status registers FPCR/FPSR
+ */
+void fpu_state_set(fpu_reg_state_t *vec,
+		uint8_t regs_val);
+
+/*
+ * This function prints the content of the provided FPU structure
+ */
+void fpu_state_print(fpu_reg_state_t *vec);
+
+#endif /* __ASSEMBLER__ */
+#endif /* FPU_H */
diff --git a/include/runtime_services/cactus_test_cmds.h b/include/runtime_services/cactus_test_cmds.h
index e52f333..9dc0d90 100644
--- a/include/runtime_services/cactus_test_cmds.h
+++ b/include/runtime_services/cactus_test_cmds.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -283,6 +283,20 @@
 }
 
 /**
+ * Request to compare FPU state(SIMD vectors, FPCR, FPSR) content
+ * with previous template values to check a save/restore routine during the
+ * context switches between secure world and normal world.
+ */
+#define CACTUS_CMP_SIMD_VALUE_CMD (CACTUS_REQ_SIMD_FILL_CMD + 1)
+
+static inline struct ffa_value cactus_req_simd_compare_send_cmd(
+	ffa_id_t source, ffa_id_t dest)
+{
+	return cactus_send_cmd(source, dest, CACTUS_CMP_SIMD_VALUE_CMD, 0, 0, 0,
+			       0);
+}
+
+/**
  * Command to request cactus to sleep for the given time in ms
  *
  * The command id is the hex representation of string "sleep"
diff --git a/include/runtime_services/spm_common.h b/include/runtime_services/spm_common.h
index 6fe445a..7f47dc7 100644
--- a/include/runtime_services/spm_common.h
+++ b/include/runtime_services/spm_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -97,27 +97,15 @@
 void dump_ffa_value(struct ffa_value ret);
 
 /*
- * Max. vector length:
- * SIMD: 128 bits = 16 bytes
- */
-#define SIMD_VECTOR_LEN_BYTES		16
-
-#define SIMD_NUM_VECTORS		32
-
-typedef uint8_t simd_vector_t[SIMD_VECTOR_LEN_BYTES];
-
-/*
  * Fills SIMD/SVE registers with the content of the container v.
  * Number of vectors is assumed to be SIMD/SVE_NUM_VECTORS.
  */
-void fill_simd_vector_regs(const simd_vector_t v[SIMD_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_simd_vector_regs(simd_vector_t v[SIMD_NUM_VECTORS]);
 void read_sve_vector_regs(sve_vector_t v[SVE_NUM_VECTORS]);
 
 bool check_spmc_execution_level(void);
diff --git a/lib/extensions/fpu/fpu.c b/lib/extensions/fpu/fpu.c
new file mode 100644
index 0000000..da887b3
--- /dev/null
+++ b/lib/extensions/fpu/fpu.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <debug.h>
+#include <lib/extensions/fpu.h>
+
+#define __STR(x) #x
+#define STR(x) __STR(x)
+
+#define fill_simd_helper(num1, num2) "ldp q"#num1", q"#num2",\
+	[%0], #"STR(2 * FPU_Q_SIZE)";"
+#define read_simd_helper(num1, num2) "stp q"#num1", q"#num2",\
+	[%0], #"STR(2 * FPU_Q_SIZE)";"
+
+static fpu_reg_state_t g_fpu_read;
+
+static void read_fpu_state_registers(fpu_reg_state_t *fpu_template_in)
+{
+#ifdef __aarch64__
+
+	u_register_t fpsr;
+	u_register_t fpcr;
+
+	/* Read current FPCR FPSR and write to template. */
+	__asm__ volatile ("mrs %0, fpsr\n" : "=r" (fpsr));
+	__asm__ volatile ("mrs %0, fpcr\n" : "=r" (fpcr));
+	fpu_template_in->fpsr = fpsr;
+	fpu_template_in->fpcr = fpcr;
+
+	__asm__ volatile(
+			read_simd_helper(0, 1)
+			read_simd_helper(2, 3)
+			read_simd_helper(4, 5)
+			read_simd_helper(6, 7)
+			read_simd_helper(8, 9)
+			read_simd_helper(10, 11)
+			read_simd_helper(12, 13)
+			read_simd_helper(14, 15)
+			read_simd_helper(16, 17)
+			read_simd_helper(18, 19)
+			read_simd_helper(20, 21)
+			read_simd_helper(22, 23)
+			read_simd_helper(24, 25)
+			read_simd_helper(26, 27)
+			read_simd_helper(28, 29)
+			read_simd_helper(30, 31)
+			"sub %0, %0, #" STR(FPU_Q_COUNT * FPU_Q_SIZE) ";"
+			: : "r" (fpu_template_in->q));
+#endif
+}
+
+void fpu_state_fill_regs_and_template(fpu_reg_state_t *fpu_template_in)
+{
+	u_register_t fpsr;
+	u_register_t fpcr;
+	u_register_t temp;
+
+	temp = rand();
+	(void)memset((void *)fpu_template_in, 0, sizeof(fpu_reg_state_t));
+
+	/*
+	 * Write random value to FPCR FPSR.
+	 * Note write will be ignored for reserved bits.
+	 */
+	__asm__ volatile ("mrs %0, fpsr\n" : "=r" (temp));
+	__asm__ volatile ("mrs %0, fpcr\n" : "=r" (temp));
+
+	/*
+	 * Read back current FPCR FPSR and write to template,
+	 */
+	__asm__ volatile ("mrs %0, fpsr\n" : "=r" (fpsr));
+	__asm__ volatile ("mrs %0, fpcr\n" : "=r" (fpcr));
+	fpu_template_in->fpsr = fpsr;
+	fpu_template_in->fpcr = fpcr;
+
+	for (unsigned int num = 0U; num < FPU_Q_COUNT; num++) {
+		memset((uint8_t *)fpu_template_in->q[num], temp * num,
+				sizeof(fpu_template_in->q[0]));
+	}
+	__asm__ volatile(
+			fill_simd_helper(0, 1)
+			fill_simd_helper(2, 3)
+			fill_simd_helper(4, 5)
+			fill_simd_helper(6, 7)
+			fill_simd_helper(8, 9)
+			fill_simd_helper(10, 11)
+			fill_simd_helper(12, 13)
+			fill_simd_helper(14, 15)
+			fill_simd_helper(16, 17)
+			fill_simd_helper(18, 19)
+			fill_simd_helper(20, 21)
+			fill_simd_helper(22, 23)
+			fill_simd_helper(24, 25)
+			fill_simd_helper(26, 27)
+			fill_simd_helper(28, 29)
+			fill_simd_helper(30, 31)
+			"sub %0, %0, #" STR(FPU_Q_COUNT * FPU_Q_SIZE) ";"
+			: : "r" (fpu_template_in->q));
+}
+
+void fpu_state_print(fpu_reg_state_t *vec)
+{
+	INFO("dumping FPU registers :\n");
+	for (unsigned int num = 0U; num < FPU_Q_COUNT; num++) {
+		INFO("Q[%u]=0x%llx%llx\n", num, (uint64_t)vec->q[num * FPU_Q_SIZE],
+				(uint64_t)(vec->q[num * FPU_Q_SIZE + 1]));
+	}
+	INFO("FPCR=0x%lx FPSR=0x%lx\n", vec->fpcr, vec->fpsr);
+}
+
+bool fpu_state_compare_template(fpu_reg_state_t *fpu_template_in)
+{
+	(void)memset((void *)&g_fpu_read, 0, sizeof(fpu_reg_state_t));
+	read_fpu_state_registers(&g_fpu_read);
+
+	if (memcmp((uint8_t *)fpu_template_in,
+			(uint8_t *)&g_fpu_read,
+			sizeof(fpu_reg_state_t)) != 0U) {
+		ERROR("%s failed\n", __func__);
+		ERROR("Read values\n");
+		fpu_state_print(&g_fpu_read);
+		ERROR("Template values\n");
+		fpu_state_print(fpu_template_in);
+		return false;
+	} else {
+		return true;
+	}
+}
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index c3bbe59..be8997e 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -22,6 +22,7 @@
 	-Iinclude/common				\
 	-Iinclude/common/${ARCH}			\
 	-Iinclude/lib					\
+	-Iinclude/lib/extensions			\
 	-Iinclude/lib/${ARCH}				\
 	-Iinclude/lib/utils				\
 	-Iinclude/lib/xlat_tables			\
@@ -75,6 +76,7 @@
 			lib/exceptions/${ARCH}/sync.c			\
 			lib/locks/${ARCH}/spinlock.S			\
 			lib/utils/mp_printf.c				\
+			lib/extensions/fpu/fpu.c			\
 			${XLAT_TABLES_LIB_SRCS}
 
 CACTUS_LINKERFILE	:=	spm/cactus/cactus.ld.S
diff --git a/spm/cactus/cactus_tests/cactus_test_cpu_features.c b/spm/cactus/cactus_tests/cactus_test_cpu_features.c
index 7bf6e83..78b89ac 100644
--- a/spm/cactus/cactus_tests/cactus_test_cpu_features.c
+++ b/spm/cactus/cactus_tests/cactus_test_cpu_features.c
@@ -1,29 +1,45 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include "cactus_message_loop.h"
 #include "cactus_test_cmds.h"
+#include <fpu.h>
 #include "spm_common.h"
 
 /*
+ * Note Test must exercise FILL and COMPARE command in
+ * sequence and on same CPU.
+ */
+static fpu_reg_state_t g_fpu_temp;
+static unsigned int core_pos;
+/*
  * Fill SIMD vectors from secure world side with a unique value.
- * 0x22 is just a dummy value to be distinguished from the value
- * in the normal world.
  */
 CACTUS_CMD_HANDLER(req_simd_fill, CACTUS_REQ_SIMD_FILL_CMD)
 {
-	simd_vector_t simd_vectors[SIMD_NUM_VECTORS];
-
-	for (unsigned int num = 0U; num < SIMD_NUM_VECTORS; num++) {
-		memset(simd_vectors[num], 0x22 * num, sizeof(simd_vector_t));
-	}
-
-	fill_simd_vector_regs(simd_vectors);
-
+	core_pos = platform_get_core_pos(read_mpidr_el1());
+	fpu_state_fill_regs_and_template(&g_fpu_temp);
 	return cactus_response(ffa_dir_msg_dest(*args),
 			       ffa_dir_msg_source(*args),
 			       CACTUS_SUCCESS);
 }
+
+/*
+ * compare FPU state(SIMD vectors, FPCR, FPSR) from secure world side with the previous
+ * SIMD_SECURE_VALUE unique value.
+ */
+CACTUS_CMD_HANDLER(req_simd_compare, CACTUS_CMP_SIMD_VALUE_CMD)
+{
+	bool test_succeed = false;
+
+	unsigned int core_pos1 = platform_get_core_pos(read_mpidr_el1());
+	if (core_pos1 == core_pos) {
+		test_succeed = fpu_state_compare_template(&g_fpu_temp);
+	}
+	return cactus_response(ffa_dir_msg_dest(*args),
+			ffa_dir_msg_source(*args),
+			test_succeed ? CACTUS_SUCCESS : CACTUS_ERROR);
+}
diff --git a/tftf/tests/aarch32_tests_to_skip.txt b/tftf/tests/aarch32_tests_to_skip.txt
index cdc298d..9ccc1b5 100644
--- a/tftf/tests/aarch32_tests_to_skip.txt
+++ b/tftf/tests/aarch32_tests_to_skip.txt
@@ -4,4 +4,4 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 Realm payload at EL1
-
+SIMD,SVE Registers context
diff --git a/tftf/tests/runtime_services/secure_service/spm_common.c b/tftf/tests/runtime_services/secure_service/spm_common.c
index ae30ebc..60b77b8 100644
--- a/tftf/tests/runtime_services/secure_service/spm_common.c
+++ b/tftf/tests/runtime_services/secure_service/spm_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,14 +12,6 @@
 #include <spm_common.h>
 #include <xlat_tables_v2.h>
 
-#define __STR(x) #x
-#define STR(x) __STR(x)
-
-#define fill_simd_helper(num1, num2) "ldp q"#num1", q"#num2",\
-	[%0], #"STR(2 * SIMD_VECTOR_LEN_BYTES)";"
-#define read_simd_helper(num1, num2) "stp q"#num1", q"#num2",\
-	[%0], #"STR(2 * SIMD_VECTOR_LEN_BYTES)";"
-
 /**
  * Helper to log errors after FF-A calls.
  */
@@ -111,57 +103,6 @@
 		ret.arg7);
 }
 
-void fill_simd_vector_regs(const simd_vector_t v[SIMD_NUM_VECTORS])
-{
-#ifdef __aarch64__
-	__asm__ volatile(
-		fill_simd_helper(0, 1)
-		fill_simd_helper(2, 3)
-		fill_simd_helper(4, 5)
-		fill_simd_helper(6, 7)
-		fill_simd_helper(8, 9)
-		fill_simd_helper(10, 11)
-		fill_simd_helper(12, 13)
-		fill_simd_helper(14, 15)
-		fill_simd_helper(16, 17)
-		fill_simd_helper(18, 19)
-		fill_simd_helper(20, 21)
-		fill_simd_helper(22, 23)
-		fill_simd_helper(24, 25)
-		fill_simd_helper(26, 27)
-		fill_simd_helper(28, 29)
-		fill_simd_helper(30, 31)
-		"sub %0, %0, #" STR(SIMD_NUM_VECTORS * SIMD_VECTOR_LEN_BYTES) ";"
-		: : "r" (v));
-#endif
-}
-
-void read_simd_vector_regs(simd_vector_t v[SIMD_NUM_VECTORS])
-{
-#ifdef __aarch64__
-	memset(v, 0, sizeof(simd_vector_t) * SIMD_NUM_VECTORS);
-	__asm__ volatile(
-		read_simd_helper(0, 1)
-		read_simd_helper(2, 3)
-		read_simd_helper(4, 5)
-		read_simd_helper(6, 7)
-		read_simd_helper(8, 9)
-		read_simd_helper(10, 11)
-		read_simd_helper(12, 13)
-		read_simd_helper(14, 15)
-		read_simd_helper(16, 17)
-		read_simd_helper(18, 19)
-		read_simd_helper(20, 21)
-		read_simd_helper(22, 23)
-		read_simd_helper(24, 25)
-		read_simd_helper(26, 27)
-		read_simd_helper(28, 29)
-		read_simd_helper(30, 31)
-		"sub %0, %0, #" STR(SIMD_NUM_VECTORS * SIMD_VECTOR_LEN_BYTES) ";"
-		: : "r" (v));
-#endif
-}
-
 void fill_sve_vector_regs(const sve_vector_t v[SVE_NUM_VECTORS])
 {
 #ifdef __aarch64__
@@ -642,4 +583,4 @@
 bool disable_trusted_wdog_interrupt(ffa_id_t source, ffa_id_t dest)
 {
 	return configure_trusted_wdog_interrupt(source, dest, false);
-}
\ No newline at end of file
+}
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 a230d56..8cb54f7 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #include <cactus_test_cmds.h>
 #include <ffa_endpoints.h>
 #include <ffa_helpers.h>
+#include <fpu.h>
 #include <test_helpers.h>
 
 #define SENDER HYP_ID
@@ -28,18 +29,18 @@
 	return TEST_RESULT_SUCCESS;
 }
 
-#ifdef __aarch64__
 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 int sve_op_1[SVE_ARRAYSIZE];
 static int sve_op_2[SVE_ARRAYSIZE];
-#endif
+static fpu_reg_state_t g_fpu_template;
 
 /*
- * Tests that SIMD vectors are preserved during the context switches between
+ * Tests that SIMD vectors and FPU state are preserved during the context switches between
  * normal world and the secure world.
- * Fills the SIMD vectors with known values, requests SP to fill the vectors
- * with a different values, checks that the context is restored on return.
+ * Fills the SIMD vectors, FPCR and FPSR with random values, requests SP to fill the vectors
+ * with a different values, request SP to check if secure SIMD context is restored.
+ * Checks that the NS context is restored on return.
  */
 test_result_t test_simd_vectors_preserved(void)
 {
@@ -48,16 +49,7 @@
 	 **********************************************************************/
 	CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
 
-	simd_vector_t simd_vectors_send[SIMD_NUM_VECTORS],
-		      simd_vectors_receive[SIMD_NUM_VECTORS];
-
-	/* 0x11 is just a dummy value to be distinguished from the value in the
-	 * secure world. */
-	for (unsigned int num = 0U; num < SIMD_NUM_VECTORS; num++) {
-		memset(simd_vectors_send[num], 0x11 * (num+1), sizeof(simd_vector_t));
-	}
-	fill_simd_vector_regs(simd_vectors_send);
-
+	fpu_state_fill_regs_and_template(&g_fpu_template);
 	struct ffa_value ret = cactus_req_simd_fill_send_cmd(SENDER, RECEIVER);
 
 	if (!is_ffa_direct_response(ret)) {
@@ -68,11 +60,18 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	read_simd_vector_regs(simd_vectors_receive);
+	ret = cactus_req_simd_compare_send_cmd(SENDER, RECEIVER);
 
-	return fp_vector_compare((uint8_t *)simd_vectors_send,
-				 (uint8_t *)simd_vectors_receive,
-				 sizeof(simd_vector_t), SIMD_NUM_VECTORS);
+	if (!is_ffa_direct_response(ret)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	if (cactus_get_response(ret) == CACTUS_ERROR) {
+		return TEST_RESULT_FAIL;
+	}
+	/* Normal world verify its FPU/SIMD state registers data */
+	return fpu_state_compare_template(&g_fpu_template) ? TEST_RESULT_SUCCESS :
+		TEST_RESULT_FAIL;
 }
 
 /*
@@ -83,7 +82,6 @@
  */
 test_result_t test_sve_vectors_preserved(void)
 {
-#ifdef __aarch64__
 	uint64_t vl;
 	uint8_t *sve_vector;
 
@@ -139,9 +137,6 @@
 	return fp_vector_compare((uint8_t *)sve_vectors_input,
 				 (uint8_t *)sve_vectors_output,
 				 vl, SVE_NUM_VECTORS);
-#else
-	return TEST_RESULT_SKIPPED;
-#endif /* __aarch64__ */
 }
 
 /*
@@ -150,7 +145,6 @@
  */
 test_result_t test_sve_vectors_operations(void)
 {
-#ifdef __aarch64__
 	unsigned int val;
 
 	SKIP_TEST_IF_SVE_NOT_SUPPORTED();
@@ -184,7 +178,4 @@
 	}
 
 	return TEST_RESULT_SUCCESS;
-#else
-	return TEST_RESULT_SKIPPED;
-#endif /* __aarch64__ */
 }
diff --git a/tftf/tests/tests-spm.mk b/tftf/tests/tests-spm.mk
index 8f44f14..fccddb4 100644
--- a/tftf/tests/tests-spm.mk
+++ b/tftf/tests/tests-spm.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -18,14 +18,22 @@
 		test_ffa_memory_sharing.c				\
 		test_ffa_setup_and_discovery.c				\
 		test_ffa_notifications.c				\
-		test_spm_cpu_features.c					\
 		test_spm_smmu.c						\
 		test_ffa_exceptions.c					\
-		sve_operations_cactus.S					\
 	)
 
+ifeq (${ARCH},aarch64)
+TESTS_SOURCES   +=                                                      \
+        $(addprefix tftf/tests/runtime_services/secure_service/,        \
+	  test_spm_cpu_features.c					\
+	  sve_operations_cactus.S					\
+	 )
+
 TESTS_SOURCES	+=							\
 	$(addprefix tftf/tests/runtime_services/host_realm_managment/,	\
 		host_realm_rmi.c					\
 		host_realm_helper.c					\
 	)
+
+TESTS_SOURCES   += lib/extensions/fpu/fpu.c
+endif