Merge changes from topic "ja/fix_ffa_feat"

* changes:
  fix(ff-a): tests for FFA_FEATURES
  fix(ff-a): check for presence of SPMC
diff --git a/include/runtime_services/spm_common.h b/include/runtime_services/spm_common.h
index fb1f61e..6c01751 100644
--- a/include/runtime_services/spm_common.h
+++ b/include/runtime_services/spm_common.h
@@ -101,7 +101,10 @@
 
 bool check_spmc_execution_level(void);
 
-unsigned int get_ffa_feature_test_target(const struct ffa_features_test **test_target);
+unsigned int get_ffa_feature_test_target(
+		const struct ffa_features_test **test_target);
+bool ffa_features_test_targets(const struct ffa_features_test *targets,
+			       uint32_t test_target_size);
 
 /**
  * Helper to conduct a memory retrieve. This is to be called by the receiver
diff --git a/spm/common/sp_tests/sp_test_ffa.c b/spm/common/sp_tests/sp_test_ffa.c
index 63bf131..9a32891 100644
--- a/spm/common/sp_tests/sp_test_ffa.c
+++ b/spm/common/sp_tests/sp_test_ffa.c
@@ -80,43 +80,25 @@
  */
 static void ffa_features_test(void)
 {
-	struct ffa_value ffa_ret;
-	unsigned int expected_ret;
-	const struct ffa_features_test *ffa_feature_test_target;
-	unsigned int i, test_target_size =
-		get_ffa_feature_test_target(&ffa_feature_test_target);
-	struct ffa_features_test test_target;
+	const struct ffa_features_test *func_id_targets;
+	/* Get common features between tftf and cactus. */
+	unsigned int test_target_size =
+		get_ffa_feature_test_target(&func_id_targets);
+	const struct ffa_features_test feature_id_targets[] = {
+		{"FFA_FEATURE_MEI", FFA_FEATURE_MEI, FFA_SUCCESS_SMC32, 0,
+			MAKE_FFA_VERSION(1, 1)},
+		{"FFA_FEATURE_SRI", FFA_FEATURE_SRI, FFA_ERROR, 0,
+			MAKE_FFA_VERSION(1, 1)},
+		{"FFA_FEATURE_NPI", FFA_FEATURE_NPI, FFA_SUCCESS_SMC32, 0,
+			MAKE_FFA_VERSION(1, 1)},
+	};
 
 	INFO("Test FFA_FEATURES.\n");
+	ffa_features_test_targets(func_id_targets, test_target_size);
 
-	for (i = 0U; i < test_target_size; i++) {
-		test_target = ffa_feature_test_target[i];
-
-		ffa_ret = ffa_features_with_input_property(test_target.feature,
-							   test_target.param);
-		expected_ret = FFA_VERSION_COMPILED
-				>= test_target.version_added ?
-				test_target.expected_ret : FFA_ERROR;
-
-		if (ffa_func_id(ffa_ret) != expected_ret) {
-			ERROR("Unexpected return: %s (expected %s)."
-			      " FFA_FEATURES test: %s.\n",
-			      ffa_func_name(ffa_func_id(ffa_ret)),
-			      ffa_func_name(expected_ret),
-			      test_target.test_name);
-		}
-
-		if (expected_ret == FFA_ERROR) {
-			if (ffa_error_code(ffa_ret) !=
-			    FFA_ERROR_NOT_SUPPORTED) {
-				ERROR("Unexpected error code: %s (expected %s)."
-				      " FFA_FEATURES test: %s.\n",
-				      ffa_error_name(ffa_error_code(ffa_ret)),
-				      ffa_error_name(expected_ret),
-				      test_target.test_name);
-			}
-		}
-	}
+	/* Features are expected to be different to tftf. */
+	ffa_features_test_targets(feature_id_targets,
+			ARRAY_SIZE(feature_id_targets));
 }
 
 static void ffa_partition_info_wrong_test(void)
diff --git a/tftf/tests/runtime_services/secure_service/spm_common.c b/tftf/tests/runtime_services/secure_service/spm_common.c
index 8fb3a72..2f68914 100644
--- a/tftf/tests/runtime_services/secure_service/spm_common.c
+++ b/tftf/tests/runtime_services/secure_service/spm_common.c
@@ -197,13 +197,7 @@
 		FFA_SUCCESS_SMC32},
 	{"FFA_NOTIFICATION_INFO_GET_64", FFA_NOTIFICATION_INFO_GET_SMC64,
 		FFA_SUCCESS_SMC32},
-	/* Indirect messaging is only supported in Nwd */
 	{"FFA_YIELD_32", FFA_MSG_YIELD, FFA_ERROR},
-	{"FFA_MSG_SEND_32", FFA_MSG_SEND, FFA_ERROR},
-	{"FFA_MSG_POLL_32", FFA_MSG_POLL, FFA_ERROR},
-	{"FFA_FEATURE_MEI", FFA_FEATURE_MEI, FFA_ERROR, 0, MAKE_FFA_VERSION(1, 1)},
-	{"FFA_FEATURE_SRI", FFA_FEATURE_SRI, FFA_SUCCESS_SMC32, 0, MAKE_FFA_VERSION(1, 1)},
-	{"FFA_FEATURE_NPI", FFA_FEATURE_NPI, FFA_ERROR, 0, MAKE_FFA_VERSION(1, 1)},
 	{"Check non-existent command", 0xFFFF, FFA_ERROR},
 };
 
@@ -223,6 +217,51 @@
 	       sizeof(struct ffa_features_test);
 }
 
+/**
+ * Leverages the struct ffa_feature_test and validates the result of
+ * FFA_FEATURES calls.
+ */
+bool ffa_features_test_targets(const struct ffa_features_test *targets,
+			       uint32_t test_target_size)
+{
+	bool ret = true;
+
+	for (size_t i = 0U; i < test_target_size; i++) {
+		struct ffa_value ffa_ret;
+		uint32_t expected_ret;
+		const struct ffa_features_test *test_target = &targets[i];
+
+		ffa_ret = ffa_features_with_input_property(test_target->feature,
+							   test_target->param);
+		expected_ret = FFA_VERSION_COMPILED
+				>= test_target->version_added ?
+				test_target->expected_ret : FFA_ERROR;
+
+		if (ffa_func_id(ffa_ret) != expected_ret) {
+			ERROR("Unexpected return: %s (expected %s)."
+			      " FFA_FEATURES test: %s.\n",
+			      ffa_func_name(ffa_func_id(ffa_ret)),
+			      ffa_func_name(expected_ret),
+			      test_target->test_name);
+			ret = false;
+		}
+
+		if (expected_ret == FFA_ERROR) {
+			if (ffa_error_code(ffa_ret) !=
+			    FFA_ERROR_NOT_SUPPORTED) {
+				ERROR("Unexpected error code: %s (expected %s)."
+				      " FFA_FEATURES test: %s.\n",
+				      ffa_error_name(ffa_error_code(ffa_ret)),
+				      ffa_error_name(expected_ret),
+				      test_target->test_name);
+				ret = false;
+			}
+		}
+	}
+
+	return ret;
+}
+
 bool memory_retrieve(struct mailbox_buffers *mb,
 		     struct ffa_memory_region **retrieved, uint64_t handle,
 		     ffa_id_t sender, struct ffa_memory_access receivers[],
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
index bd0df07..588c8d0 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
@@ -135,6 +135,11 @@
 		return TEST_RESULT_SKIPPED;
 	}
 
+	/***********************************************************************
+	 * Check if SPMC has ffa_version and expected FFA endpoints are deployed.
+	 **********************************************************************/
+	CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
+
 	/* Delegate the shared page to Realm. */
 	retmm = host_rmi_granule_delegate((u_register_t)mb.recv);
 	if (retmm != 0UL) {
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c b/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
index af5a077..507e0cb 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
@@ -1106,6 +1106,11 @@
 	const uint32_t constituents_count = sizeof(constituents) /
 				sizeof(struct ffa_memory_region_constituent);
 
+	/***********************************************************************
+	 * Check if SPMC has ffa_version and expected FFA endpoints are deployed.
+	 **********************************************************************/
+	CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
+
 	for (unsigned j = 0; j < ARRAY_SIZE(mem_func); j++) {
 		for (unsigned int i = 0; i < 4; i++) {
 			/* Address to be delegated to Realm PAS. */
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
index 621fc69..3813503 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include "utils_def.h"
 #include <debug.h>
 
 #include <ffa_endpoints.h>
@@ -86,44 +87,33 @@
 
 test_result_t test_ffa_features(void)
 {
+	const struct ffa_features_test *func_ids_target;
+	const struct ffa_features_test feature_ids_target[] = {
+		{"FFA_FEATURE_MEI", FFA_FEATURE_MEI, FFA_ERROR, 0,
+			MAKE_FFA_VERSION(1, 1)},
+		{"FFA_FEATURE_SRI", FFA_FEATURE_SRI, FFA_SUCCESS_SMC32, 0,
+			MAKE_FFA_VERSION(1, 1)},
+		{"FFA_FEATURE_NPI", FFA_FEATURE_NPI, FFA_ERROR, 0,
+			MAKE_FFA_VERSION(1, 1)},
+	};
+	unsigned int test_target_size =
+		get_ffa_feature_test_target(&func_ids_target);
+
 	SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 0);
 
 	/* Check if SPMC is OP-TEE at S-EL1 */
 	if (check_spmc_execution_level()) {
 		/* FFA_FEATURES is not yet supported in OP-TEE */
-		return TEST_RESULT_SUCCESS;
+		return TEST_RESULT_SKIPPED;
 	}
 
-	struct ffa_value ffa_ret;
-	unsigned int expected_ret;
-	const struct ffa_features_test *ffa_feature_test_target;
-	unsigned int i, test_target_size =
-		get_ffa_feature_test_target(&ffa_feature_test_target);
-	struct ffa_features_test test_target;
+	if (!ffa_features_test_targets(func_ids_target, test_target_size)) {
+		return TEST_RESULT_FAIL;
+	}
 
-	for (i = 0U; i < test_target_size; i++) {
-		test_target = ffa_feature_test_target[i];
-		ffa_ret = ffa_features_with_input_property(test_target.feature, test_target.param);
-		expected_ret = FFA_VERSION_COMPILED
-			>= test_target.version_added ?
-			test_target.expected_ret : FFA_ERROR;
-		if (ffa_func_id(ffa_ret) != expected_ret) {
-			tftf_testcase_printf(
-				"%s returned %s, expected %s\n",
-				test_target.test_name,
-				ffa_func_name(ffa_func_id(ffa_ret)),
-				ffa_func_name(expected_ret));
-			return TEST_RESULT_FAIL;
-		}
-		if ((expected_ret == FFA_ERROR) &&
-				(ffa_error_code(ffa_ret) != FFA_ERROR_NOT_SUPPORTED)) {
-			tftf_testcase_printf(
-				"%s failed for the wrong reason: returned %s, expected %s\n",
-				test_target.test_name,
-				ffa_error_name(ffa_error_code(ffa_ret)),
-				ffa_error_name(FFA_ERROR_NOT_SUPPORTED));
-			return TEST_RESULT_FAIL;
-		}
+	if (!ffa_features_test_targets(feature_ids_target,
+				ARRAY_SIZE(feature_ids_target))) {
+		return TEST_RESULT_FAIL;
 	}
 
 	return TEST_RESULT_SUCCESS;