Add tests for FFA function FFA_SPM_ID_GET

Also add the ability for ffa_features_test to only use the expected
return if the minimum FF-A version for the feature is met.

Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
Change-Id: I276500c666365c563a117aa7b250b18f51dcace7
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index cc2072c..73606bd 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -182,7 +182,7 @@
 
 	/* Get current FFA id */
 	smc_ret_values ffa_id_ret = ffa_id_get();
-	ffa_id_t ffa_id = (ffa_id_t)(ffa_id_ret.ret2 & 0xffff);
+	ffa_id_t ffa_id = ffa_endpoint_id(ffa_id_ret);
 	if (ffa_func_id(ffa_id_ret) != FFA_SUCCESS_SMC32) {
 		ERROR("FFA_ID_GET failed.\n");
 		panic();
diff --git a/spm/cactus/cactus_tests/cactus_test_ffa.c b/spm/cactus/cactus_tests/cactus_test_ffa.c
index 2ade7bd..93f0403 100644
--- a/spm/cactus/cactus_tests/cactus_test_ffa.c
+++ b/spm/cactus/cactus_tests/cactus_test_ffa.c
@@ -20,6 +20,8 @@
 #define FFA_MAJOR 1U
 #define FFA_MINOR 0U
 
+static uint32_t spm_version;
+
 static const uint32_t primary_uuid[4] = PRIMARY_UUID;
 static const uint32_t secondary_uuid[4] = SECONDARY_UUID;
 static const uint32_t tertiary_uuid[4] = TERTIARY_UUID;
@@ -32,23 +34,31 @@
 {
 	const char *test_features = "FFA Features interface";
 	smc_ret_values 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;
 
 
 	announce_test_section_start(test_features);
 
 	for (i = 0U; i < test_target_size; i++) {
-		announce_test_start(ffa_feature_test_target[i].test_name);
+		test_target = ffa_feature_test_target[i];
 
-		ffa_ret = ffa_features(ffa_feature_test_target[i].feature);
-		expect(ffa_func_id(ffa_ret), ffa_feature_test_target[i].expected_ret);
-		if (ffa_feature_test_target[i].expected_ret == FFA_ERROR) {
+		announce_test_start(test_target.test_name);
+
+		ffa_ret = ffa_features(test_target.feature);
+		expected_ret = FFA_VERSION_COMPILED
+				>= test_target.version_added ?
+				test_target.expected_ret : FFA_ERROR;
+
+		expect(ffa_func_id(ffa_ret), expected_ret);
+		if (expected_ret == FFA_ERROR) {
 			expect(ffa_error_code(ffa_ret), FFA_ERROR_NOT_SUPPORTED);
 		}
 
-		announce_test_end(ffa_feature_test_target[i].test_name);
+		announce_test_end(test_target.test_name);
 	}
 
 	announce_test_section_end(test_features);
@@ -147,7 +157,7 @@
 	announce_test_start(test_ffa_version);
 
 	smc_ret_values ret = ffa_version(MAKE_FFA_VERSION(FFA_MAJOR, FFA_MINOR));
-	uint32_t spm_version = (uint32_t)ret.ret0;
+	spm_version = (uint32_t)ret.ret0;
 
 	bool ffa_version_compatible =
 		((spm_version >> FFA_VERSION_MAJOR_SHIFT) == FFA_MAJOR &&
@@ -163,6 +173,32 @@
 	announce_test_end(test_ffa_version);
 }
 
+void ffa_spm_id_get_test(void)
+{
+	const char *test_spm_id_get = "FFA_SPM_ID_GET SMC Function";
+
+	announce_test_start(test_spm_id_get);
+
+	if (spm_version >= MAKE_FFA_VERSION(1, 1)) {
+		smc_ret_values ret = ffa_spm_id_get();
+
+		expect(ffa_func_id(ret), FFA_SUCCESS_SMC32);
+
+		ffa_id_t spm_id = ffa_endpoint_id(ret);
+
+		VERBOSE("SPM ID = 0x%x\n", spm_id);
+		/*
+		 * Check the SPMC value given in the fvp_spmc_manifest
+		 * is returned.
+		 */
+		expect(spm_id, SPMC_ID);
+	} else {
+		NOTICE("FFA_SPM_ID_GET not supported in this version of FF-A."
+			" Test skipped.\n");
+	}
+	announce_test_end(test_spm_id_get);
+}
+
 void ffa_tests(struct mailbox_buffers *mb)
 {
 	const char *test_ffa = "FFA Interfaces";
@@ -171,6 +207,7 @@
 
 	ffa_features_test();
 	ffa_version_test();
+	ffa_spm_id_get_test();
 	ffa_partition_info_get_test(mb);
 
 	announce_test_section_end(test_ffa);