fix(ff-a): Fix FFA_FEATURES for indirect message ABIs

Indirect messaging has not been implemented and tested for SPMC,
this patch makes it so that FFA_FEATURES reflects this by returning
FFA_ERROR NOT_SUPPORTED for calls to FFA_FEATURES querying indirect
messaging ABIs in the SPMC.
Also add ffa_features tests to the secure partition tests.

Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
Change-Id: I0e8976979192a94765d88bf9a7eec67d50aaadb6
diff --git a/src/api.c b/src/api.c
index a32fae0..ddbde0f 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1798,11 +1798,8 @@
 	case FFA_RXTX_UNMAP_32:
 	case FFA_PARTITION_INFO_GET_32:
 	case FFA_ID_GET_32:
-	case FFA_MSG_POLL_32:
 	case FFA_MSG_WAIT_32:
-	case FFA_YIELD_32:
 	case FFA_RUN_32:
-	case FFA_MSG_SEND_32:
 	case FFA_MEM_DONATE_32:
 	case FFA_MEM_LEND_32:
 	case FFA_MEM_SHARE_32:
@@ -1820,7 +1817,7 @@
 #endif
 		return (struct ffa_value){.func = FFA_SUCCESS_32};
 	default:
-		return ffa_error(FFA_NOT_SUPPORTED);
+		return arch_ffa_features(function_id);
 	}
 }
 
diff --git a/src/arch/aarch64/hypervisor/ffa.c b/src/arch/aarch64/hypervisor/ffa.c
index f0606d2..363ac85 100644
--- a/src/arch/aarch64/hypervisor/ffa.c
+++ b/src/arch/aarch64/hypervisor/ffa.c
@@ -18,6 +18,14 @@
 static ffa_vm_id_t spmc_id = HF_INVALID_VM_ID;
 
 /**
+ * Returns information for features with arch specific implementation.
+ */
+struct ffa_value arch_ffa_features(uint32_t function_id)
+{
+	return plat_ffa_features(function_id);
+}
+
+/**
  * Returns the SPMC ID returned from the SPMD.
  */
 ffa_vm_id_t arch_ffa_spmc_id_get(void)
diff --git a/src/arch/aarch64/plat/ffa/absent.c b/src/arch/aarch64/plat/ffa/absent.c
index 999e169..1bfa115 100644
--- a/src/arch/aarch64/plat/ffa/absent.c
+++ b/src/arch/aarch64/plat/ffa/absent.c
@@ -11,6 +11,12 @@
 #include "hf/vcpu.h"
 #include "hf/vm.h"
 
+struct ffa_value plat_ffa_features(uint32_t function_id)
+{
+	(void)function_id;
+	return ffa_error(FFA_NOT_SUPPORTED);
+}
+
 struct ffa_value plat_ffa_spmc_id_get(void)
 {
 	return (struct ffa_value){.func = FFA_ERROR_32,
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
index 2625954..14a057e 100644
--- a/src/arch/aarch64/plat/ffa/hypervisor.c
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -22,6 +22,19 @@
 alignas(FFA_PAGE_SIZE) static uint8_t other_world_send_buffer[HF_MAILBOX_SIZE];
 alignas(FFA_PAGE_SIZE) static uint8_t other_world_recv_buffer[HF_MAILBOX_SIZE];
 
+/** Returns information on features specific to the NWd. */
+struct ffa_value plat_ffa_features(uint32_t function_id)
+{
+	switch (function_id) {
+	case FFA_MSG_POLL_32:
+	case FFA_YIELD_32:
+	case FFA_MSG_SEND_32:
+		return (struct ffa_value){.func = FFA_SUCCESS_32};
+	default:
+		return ffa_error(FFA_NOT_SUPPORTED);
+	}
+}
+
 struct ffa_value plat_ffa_spmc_id_get(void)
 {
 	if (ffa_tee_enabled) {
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index f382399..531af10 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -65,6 +65,14 @@
 	dlog_info("Initializing Hafnium (SPMC)\n");
 }
 
+/** Returns information on features specific to the SWd. */
+struct ffa_value plat_ffa_features(uint32_t function_id)
+{
+	(void)function_id;
+	/* There are no features only supported in the SWd */
+	return ffa_error(FFA_NOT_SUPPORTED);
+}
+
 struct ffa_value plat_ffa_spmc_id_get(void)
 {
 	/*
diff --git a/src/arch/fake/hypervisor/ffa.c b/src/arch/fake/hypervisor/ffa.c
index d372636..c423748 100644
--- a/src/arch/fake/hypervisor/ffa.c
+++ b/src/arch/fake/hypervisor/ffa.c
@@ -12,6 +12,12 @@
 #include "hf/vcpu.h"
 #include "hf/vm.h"
 
+struct ffa_value arch_ffa_features(uint32_t function_id)
+{
+	(void)function_id;
+	return ffa_error(FFA_NOT_SUPPORTED);
+}
+
 ffa_vm_id_t arch_ffa_spmc_id_get(void)
 {
 	return HF_SPMC_VM_ID;