refactor: report secondary EP register supported

Report `FFA_SECONDARY_EP_REGISTER_64` argument to `FFA_FEATURES`
supported when caller is SP with more than 1 vCPU.

Change-Id: If6247746d6f52c95e893d4978981693638897cf7
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/src/api.c b/src/api.c
index b519845..23af32e 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2619,6 +2619,21 @@
 		}
 		return api_ffa_feature_success(0);
 
+	case FFA_SECONDARY_EP_REGISTER_64:
+		if (FFA_VERSION_COMPILED < FFA_VERSION_1_1) {
+			return ffa_error(FFA_NOT_SUPPORTED);
+		}
+
+		if (!(vm_id_is_current_world(current->vm->id) &&
+		      current->vm->vcpu_count > 1)) {
+			dlog_verbose(
+				"FFA_FEATURE: %s is only supported on SPs with "
+				"more than 1 vCPU\n",
+				ffa_func_name(function_or_feature_id));
+			return ffa_error(FFA_NOT_SUPPORTED);
+		}
+		return api_ffa_feature_success(0);
+
 	case FFA_RXTX_MAP_64: {
 		if (FFA_VERSION_1_2 > FFA_VERSION_COMPILED) {
 			return ffa_error(FFA_NOT_SUPPORTED);
diff --git a/test/vmapi/ffa_secure_partitions/ffa_secure_partitions.c b/test/vmapi/ffa_secure_partitions/ffa_secure_partitions.c
index 2728f8d..96fc76c 100644
--- a/test/vmapi/ffa_secure_partitions/ffa_secure_partitions.c
+++ b/test/vmapi/ffa_secure_partitions/ffa_secure_partitions.c
@@ -39,6 +39,18 @@
 }
 
 /*
+ * The following is a precondition function, for the current system set-up.
+ * Check that service1 partition is an MP SP.
+ */
+bool service2_is_mp_sp(void)
+{
+	struct mailbox_buffers mb = get_precondition_mailbox();
+	struct ffa_partition_info *service2_info = service2(mb.recv);
+
+	return (service2_info->vcpu_count > 1);
+}
+
+/*
  * Currently we are using the vCPU count set to 0 for service 2 as being an
  * indication it is S-EL0 partition.
  */
diff --git a/test/vmapi/ffa_secure_partitions/inc/ffa_secure_partitions.h b/test/vmapi/ffa_secure_partitions/inc/ffa_secure_partitions.h
index 7e0d428..8247c1c 100644
--- a/test/vmapi/ffa_secure_partitions/inc/ffa_secure_partitions.h
+++ b/test/vmapi/ffa_secure_partitions/inc/ffa_secure_partitions.h
@@ -70,4 +70,5 @@
 bool sp1_fail_at_boot(void);
 bool sp2_fail_at_boot(void);
 bool sp3_fail_at_boot(void);
+bool service2_is_mp_sp(void);
 bool service2_is_el0(void);
diff --git a/test/vmapi/ffa_secure_partitions/setup_and_discovery.c b/test/vmapi/ffa_secure_partitions/setup_and_discovery.c
index 74f7cee..a833e4d 100644
--- a/test/vmapi/ffa_secure_partitions/setup_and_discovery.c
+++ b/test/vmapi/ffa_secure_partitions/setup_and_discovery.c
@@ -353,3 +353,30 @@
 	EXPECT_EQ(res.arg3, FFA_ERROR_32);
 	EXPECT_EQ((int32_t)res.arg4, FFA_NOT_SUPPORTED);
 }
+
+TEST_PRECONDITION(ffa, secondary_ep_register_supported, service2_is_mp_sp)
+{
+	const ffa_id_t own_id = hf_vm_get_id();
+	/* SP is expected to be S-EL0 partition */
+	const ffa_id_t receiver_id = SP_ID(2);
+	struct ffa_value res;
+
+	res = sp_ffa_features_cmd_send(own_id, receiver_id,
+				       FFA_SECONDARY_EP_REGISTER_64);
+	EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
+	EXPECT_EQ(res.arg3, FFA_SUCCESS_32);
+}
+
+TEST_PRECONDITION(ffa, secondary_ep_register_not_supported, service2_is_up_sp)
+{
+	const ffa_id_t own_id = hf_vm_get_id();
+	/* SP is expected to be S-EL0 partition */
+	const ffa_id_t receiver_id = SP_ID(2);
+	struct ffa_value res;
+
+	res = sp_ffa_features_cmd_send(own_id, receiver_id,
+				       FFA_SECONDARY_EP_REGISTER_64);
+	EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
+	EXPECT_EQ(res.arg3, FFA_ERROR_32);
+	EXPECT_EQ((int32_t)res.arg4, FFA_NOT_SUPPORTED);
+}
diff --git a/test/vmapi/primary_only/primary_only.c b/test/vmapi/primary_only/primary_only.c
index f180fb2..8500f70 100644
--- a/test/vmapi/primary_only/primary_only.c
+++ b/test/vmapi/primary_only/primary_only.c
@@ -285,6 +285,9 @@
 
 	ret = ffa_features(FFA_MSG_SEND_DIRECT_RESP_32);
 	EXPECT_EQ(ret.func, FFA_SUCCESS_32);
+
+	ret = ffa_features(FFA_SECONDARY_EP_REGISTER_64);
+	EXPECT_EQ(ret.func, FFA_SUCCESS_32);
 }
 
 static bool v1_1_or_later(void)