feat(hftest): drive test execution via FF-A v1.1 indirect message

FF-A v1.1 indirect messaging is implemented for both SPs and VMs.
This allows the hftest framework to drive tests to NWd VMs as well
as SPs.
Change mostly impacts 'SELECT_SERVICE' macro and 'hftest_service_main'
function:
- The macro SELECT_SERVICE is used to drive the tests from the Primary
VM, by sending indirect messages to Secondary VMs/SPs.
- The function hftest_service_main handles the indirect message requests
in the target partition.

Change-Id: If8874f434ad598444222403c6d8450ad283f1b95
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/test/hftest/BUILD.gn b/test/hftest/BUILD.gn
index 57db19f..5394561 100644
--- a/test/hftest/BUILD.gn
+++ b/test/hftest/BUILD.gn
@@ -274,6 +274,7 @@
     "//src:memiter",
     "//src:panic",
     "//src:std",
+    "//test/vmapi/common:common",
   ]
 }
 
diff --git a/test/hftest/service_common.c b/test/hftest/service_common.c
index 25df466..43455f1 100644
--- a/test/hftest/service_common.c
+++ b/test/hftest/service_common.c
@@ -19,18 +19,13 @@
 
 #include "test/hftest.h"
 #include "test/hftest_impl.h"
+#include "test/vmapi/ffa.h"
 
 HFTEST_ENABLE();
 
 extern struct hftest_test hftest_begin[];
 extern struct hftest_test hftest_end[];
 
-static alignas(HF_MAILBOX_SIZE) uint8_t send[HF_MAILBOX_SIZE];
-static alignas(HF_MAILBOX_SIZE) uint8_t recv[HF_MAILBOX_SIZE];
-
-static hf_ipaddr_t send_addr = (hf_ipaddr_t)send;
-static hf_ipaddr_t recv_addr = (hf_ipaddr_t)recv;
-
 static struct hftest_context global_context;
 
 struct hftest_context *hftest_get_context(void)
@@ -76,16 +71,29 @@
 	struct hftest_context *ctx;
 	struct ffa_value ret;
 	struct fdt fdt;
-
-	/* Prepare the context. */
-
-	/* Set up the mailbox. */
-	ffa_rxtx_map(send_addr, recv_addr);
+	ffa_vm_id_t own_id = hf_vm_get_id();
+	struct mailbox_buffers mb = set_up_mailbox();
+	ffa_notifications_bitmap_t bitmap;
+	struct ffa_partition_msg *message = (struct ffa_partition_msg *)mb.recv;
 
 	/* Receive the name of the service to run. */
-	ret = ffa_msg_wait();
-	ASSERT_EQ(ret.func, FFA_MSG_SEND_32);
-	memiter_init(&args, recv, ffa_msg_send_size(ret));
+	ffa_msg_wait();
+
+	/*
+	 * Expect to wake up with indirect message related to the next service
+	 * to be executed.
+	 */
+	ret = ffa_notification_get(own_id, 0,
+				   FFA_NOTIFICATION_FLAG_BITMAP_SPM |
+					   FFA_NOTIFICATION_FLAG_BITMAP_HYP);
+	ASSERT_EQ(ret.func, FFA_SUCCESS_32);
+	bitmap = ffa_notification_get_from_framework(ret);
+	ASSERT_TRUE(is_ffa_spm_buffer_full_notification(bitmap) ||
+		    is_ffa_hyp_buffer_full_notification(bitmap));
+	ASSERT_EQ(own_id, ffa_rxtx_header_receiver(&message->header));
+	memiter_init(&args, message->payload, message->header.size);
+
+	/* Find service handler. */
 	service = find_service(&args);
 	EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
 
@@ -106,9 +114,16 @@
 	ctx = hftest_get_context();
 	memset_s(ctx, sizeof(*ctx), 0, sizeof(*ctx));
 	ctx->abort = abort;
-	ctx->send = send;
-	ctx->recv = recv;
-	if (!fdt_get_memory_size(&fdt, &ctx->memory_size)) {
+	ctx->send = mb.send;
+	ctx->recv = mb.recv;
+
+	/*
+	 * The memory size argument is to be used only by VMs. It is part of
+	 * the dt provided by the Hypervisor. SPs expect to receive their
+	 * FF-A manifest which doesn't have a memory size field.
+	 */
+	if (!IS_SP_ID(own_id) &&
+	    !fdt_get_memory_size(&fdt, &ctx->memory_size)) {
 		HFTEST_LOG_FAILURE();
 		HFTEST_LOG(HFTEST_LOG_INDENT
 			   "No entry in the FDT on memory size details");
diff --git a/test/inc/test/hftest_impl.h b/test/inc/test/hftest_impl.h
index ff388e9..8b83488 100644
--- a/test/inc/test/hftest_impl.h
+++ b/test/inc/test/hftest_impl.h
@@ -274,29 +274,35 @@
 /**
  * Select the service to run in a service VM.
  */
-#define HFTEST_SERVICE_SELECT(vm_id, service, send_buffer)                    \
-	do {                                                                  \
-		struct ffa_value run_res;                                     \
-		uint32_t msg_length =                                         \
-			strnlen_s(service, SERVICE_NAME_MAX_LENGTH);          \
-                                                                              \
-		/*                                                            \
-		 * Let the service configure its mailbox and wait for a       \
-		 * message.                                                   \
-		 */                                                           \
-		run_res = ffa_run(vm_id, 0);                                  \
-		ASSERT_EQ(run_res.func, FFA_MSG_WAIT_32);                     \
-		ASSERT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);                \
-                                                                              \
-		/* Send the selected service to run and let it be handled. */ \
-		memcpy_s(send_buffer, FFA_MSG_PAYLOAD_MAX, service,           \
-			 msg_length);                                         \
-                                                                              \
-		ASSERT_EQ(ffa_msg_send(hf_vm_get_id(), vm_id, msg_length, 0)  \
-				  .func,                                      \
-			  FFA_SUCCESS_32);                                    \
-		run_res = ffa_run(vm_id, 0);                                  \
-		ASSERT_EQ(run_res.func, FFA_YIELD_32);                        \
+#define HFTEST_SERVICE_SELECT(vm_id, service, send_buffer)                 \
+	do {                                                               \
+		struct ffa_value res;                                      \
+		uint32_t msg_length =                                      \
+			strnlen_s(service, SERVICE_NAME_MAX_LENGTH);       \
+		struct ffa_partition_msg *message =                        \
+			(struct ffa_partition_msg *)send_buffer;           \
+                                                                           \
+		/*                                                         \
+		 * If service is a Secondary VM, let the service configure \
+		 * its mailbox and wait for a message.                     \
+		 */                                                        \
+		res = ffa_run(vm_id, 0);                                   \
+		ASSERT_EQ(res.func, FFA_MSG_WAIT_32);                      \
+		ASSERT_EQ(res.arg2, FFA_SLEEP_INDEFINITE);                 \
+                                                                           \
+		/*                                                         \
+		 * Send the selected service to run and let it be          \
+		 * handled.                                                \
+		 */                                                        \
+		ffa_rxtx_header_init(hf_vm_get_id(), vm_id, msg_length,    \
+				     &message->header);                    \
+		memcpy_s(message->payload, FFA_PARTITION_MSG_PAYLOAD_MAX,  \
+			 service, msg_length);                             \
+		res = ffa_msg_send2(0);                                    \
+                                                                           \
+		ASSERT_EQ(res.func, FFA_SUCCESS_32);                       \
+		res = ffa_run(vm_id, 0);                                   \
+		ASSERT_EQ(res.func, FFA_YIELD_32);                         \
 	} while (0)
 
 #define HFTEST_SERVICE_SEND_BUFFER() hftest_get_context()->send