test(dir_msg) test FFA_MSG_SEND_DIRECT_REQ2

Add tests for basic functionality of FFA_MSG_SEND_DIRECT_REQ2
without use of extended registers.

This patch temporarily uses FFA_MSG_SEND_DIRECT_RESP ABI to test
usage of FFA_MSG_SEND_DIRECT_REQ2. This will be replaced by usage of
FFA_MSG_SEND_DIRECT_RESP2 and this pairing of ABIs will be enforced
by the SPMC.

Signed-off-by: Kathleen Capella <kathleen.capella@arm.com>
Change-Id: I090353d5af76f0666564e554d59d3b16dc65cde4
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index 552dffe..51d8051 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -503,6 +503,30 @@
 	});
 }
 
+/*
+ * TODO edit function to accept more arguments and make use of full range of
+ * registers if needed.
+ */
+static inline struct ffa_value ffa_msg_send_direct_req2(
+	ffa_id_t sender_vm_id, ffa_id_t target_vm_id,
+	const struct ffa_uuid *uuid, uint32_t arg4, uint32_t arg5,
+	uint32_t arg6, uint32_t arg7)
+{
+	uint64_t arg2 = (uint64_t)uuid->uuid[1] << 32 | uuid->uuid[0];
+	uint64_t arg3 = (uint64_t)uuid->uuid[3] << 32 | uuid->uuid[2];
+
+	return ffa_call_ext((struct ffa_value){
+		.func = FFA_MSG_SEND_DIRECT_REQ2_64,
+		.arg1 = ((uint64_t)sender_vm_id << 16) | target_vm_id,
+		.arg2 = arg2,
+		.arg3 = arg3,
+		.arg4 = arg4,
+		.arg5 = arg5,
+		.arg6 = arg6,
+		.arg7 = arg7,
+	});
+}
+
 static inline struct ffa_value ffa_msg_send_direct_resp(
 	ffa_id_t sender_vm_id, ffa_id_t target_vm_id, uint32_t arg3,
 	uint32_t arg4, uint32_t arg5, uint32_t arg6, uint32_t arg7)
diff --git a/test/vmapi/primary_with_secondaries/dir_msg.c b/test/vmapi/primary_with_secondaries/dir_msg.c
index c826347..8c29f1a 100644
--- a/test/vmapi/primary_with_secondaries/dir_msg.c
+++ b/test/vmapi/primary_with_secondaries/dir_msg.c
@@ -314,3 +314,60 @@
 	ASSERT_EQ(ret.func, FFA_SUCCESS_32);
 	EXPECT_EQ(ffa_run(service1_info->vm_id, 0).func, FFA_YIELD_32);
 }
+
+/**
+ * Send direct message via FFA_MSG_SEND_DIRECT_REQ2, verify that sent info is
+ * echoed back.
+ */
+TEST(direct_message, ffa_send_direct_message_req2_echo)
+{
+	const uint32_t msg[] = {0x00001111, 0x22223333, 0x44445555, 0x66667777};
+	struct mailbox_buffers mb = set_up_mailbox();
+	struct ffa_value res;
+	struct ffa_partition_info *service1_info = service1(mb.recv);
+	struct ffa_uuid uuid = SERVICE1;
+
+	SERVICE_SELECT(service1_info->vm_id,
+		       "ffa_direct_message_req2_resp_echo", mb.send);
+	ffa_run(service1_info->vm_id, 0);
+
+	res = ffa_msg_send_direct_req2(HF_PRIMARY_VM_ID, service1_info->vm_id,
+				       &uuid, msg[0], msg[1], msg[2], msg[3]);
+
+	EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
+
+	EXPECT_EQ(res.arg4, msg[0]);
+	EXPECT_EQ(res.arg5, msg[1]);
+	EXPECT_EQ(res.arg6, msg[2]);
+	EXPECT_EQ(res.arg7, msg[3]);
+}
+
+/**
+ * Initiate direct message request between test SPs.
+ * If test services are VMs, test should be skipped.
+ */
+TEST_PRECONDITION(direct_message, ffa_direct_message_req2_services_echo,
+		  service1_and_service2_are_secure)
+{
+	struct mailbox_buffers mb = set_up_mailbox();
+	struct ffa_partition_info *service1_info = service1(mb.recv);
+	struct ffa_partition_info *service2_info = service2(mb.recv);
+	ffa_id_t own_id = hf_vm_get_id();
+	struct ffa_value ret;
+	const struct ffa_uuid service2_uuid = SERVICE2;
+
+	/* Run service2 for it to wait for a request from service1. */
+	SERVICE_SELECT(service2_info->vm_id,
+		       "ffa_direct_message_req2_resp_echo", mb.send);
+	ffa_run(service2_info->vm_id, 0);
+
+	/* Service1 requests echo from service2. */
+	SERVICE_SELECT(service1_info->vm_id,
+		       "ffa_direct_message_req2_echo_services", mb.send);
+
+	/* Send to service1 the uuid of the target for its message. */
+	ret = send_indirect_message(own_id, service1_info->vm_id, mb.send,
+				    &service2_uuid, sizeof(service2_uuid), 0);
+	ASSERT_EQ(ret.func, FFA_SUCCESS_32);
+	ffa_run(service1_info->vm_id, 0);
+}
diff --git a/test/vmapi/primary_with_secondaries/partition_manifest_nwd_primary.dts b/test/vmapi/primary_with_secondaries/partition_manifest_nwd_primary.dts
index 44bd89e..7803e67 100644
--- a/test/vmapi/primary_with_secondaries/partition_manifest_nwd_primary.dts
+++ b/test/vmapi/primary_with_secondaries/partition_manifest_nwd_primary.dts
@@ -21,6 +21,6 @@
 	load-address = <0x90000000>;
 	entrypoint-offset = <0x2000>;
 	xlat-granule = <0>; /* 4KiB */
-	messaging-method = <0x7>; /* Supports direct and indirect requests. */
+	messaging-method = <0x607>; /* Supports direct and indirect requests. */
 	notification-support; /* Receipt of notifications. */
 };
diff --git a/test/vmapi/primary_with_secondaries/service1.dts b/test/vmapi/primary_with_secondaries/service1.dts
index 997e450..01148b6 100644
--- a/test/vmapi/primary_with_secondaries/service1.dts
+++ b/test/vmapi/primary_with_secondaries/service1.dts
@@ -21,6 +21,6 @@
         load-address = <0x90000000>; /* To make parsing of manifest happy. it is not yet used. */
         entrypoint-offset = <0x0>;
         xlat-granule = <0>; /* 4KiB */
-        messaging-method = <0x7>; /* Supports direct and indirect requests. */
+        messaging-method = <0x607>; /* Supports direct and indirect requests. */
         notification-support; /* Receipt of notifications. */
 };
diff --git a/test/vmapi/primary_with_secondaries/service2.dts b/test/vmapi/primary_with_secondaries/service2.dts
index 9294b7c..1e5ea17 100644
--- a/test/vmapi/primary_with_secondaries/service2.dts
+++ b/test/vmapi/primary_with_secondaries/service2.dts
@@ -21,7 +21,7 @@
         load-address = <0x90000000>; /* To make parsing of manifest happy. it is not yet used. */
         entrypoint-offset = <0x0>;
         xlat-granule = <0>; /* 4KiB */
-        messaging-method = <0x7>; /* Supports direct and indirect requests. */
+        messaging-method = <0x607>; /* Supports direct and indirect requests. */
         notification-support; /* Receipt of notifications. */
 
 };
diff --git a/test/vmapi/primary_with_secondaries/service3.dts b/test/vmapi/primary_with_secondaries/service3.dts
index 44bd793..f32832f 100644
--- a/test/vmapi/primary_with_secondaries/service3.dts
+++ b/test/vmapi/primary_with_secondaries/service3.dts
@@ -21,7 +21,7 @@
         load-address = <0x90000000>; /* To make parsing of manifest happy. it is not yet used. */
         entrypoint-offset = <0x0>;
         xlat-granule = <0>; /* 4KiB */
-        messaging-method = <0x7>; /* Supports direct and indirect requests. */
+        messaging-method = <0x607>; /* Supports direct and indirect requests. */
         notification-support; /* Receipt of notifications. */
 
 };
diff --git a/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/el0/partition_manifest_service_sp1.dts b/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/el0/partition_manifest_service_sp1.dts
index 978dc13..3f8c5ea 100644
--- a/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/el0/partition_manifest_service_sp1.dts
+++ b/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/el0/partition_manifest_service_sp1.dts
@@ -21,7 +21,7 @@
 	load-address = <0x6480000>;
 	entrypoint-offset = <0x2000>;
 	xlat-granule = <0>; /* 4KiB */
-	messaging-method = <0x7>; /* Supports direct and indirect requests. */
+	messaging-method = <0x607>; /* Supports direct (both APIs) and indirect requests. */
 	boot-order = <1>;
 	notification-support; /* Receipt of notifications. */
 	gp-register-num = <0>;
diff --git a/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/el0/partition_manifest_service_sp2.dts b/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/el0/partition_manifest_service_sp2.dts
index 90f3ee3..d03c323 100644
--- a/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/el0/partition_manifest_service_sp2.dts
+++ b/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/el0/partition_manifest_service_sp2.dts
@@ -21,7 +21,7 @@
 	load-address = <0x6380000>;
 	entrypoint-offset = <0x2000>;
 	xlat-granule = <0>; /* 4KiB */
-	messaging-method = <0x7>; /* Supports direct and indirect requests. */
+	messaging-method = <0x607>; /* Supports direct (both APIs) and indirect requests. */
 	boot-order = <2>;
 	notification-support; /* Receipt of notifications. */
 	gp-register-num = <0>;
diff --git a/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp1.dts b/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp1.dts
index 964f792..15c7dde 100644
--- a/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp1.dts
+++ b/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp1.dts
@@ -21,7 +21,7 @@
 	load-address = <0x6480000>;
 	entrypoint-offset = <0x2000>;
 	xlat-granule = <0>; /* 4KiB */
-	messaging-method = <0x7>; /* Supports direct and indirect requests. */
+	messaging-method = <0x607>; /* Supports direct (both APIs) and indirect requests. */
 	boot-order = <1>;
 	notification-support; /* Receipt of notifications. */
 	gp-register-num = <0>;
diff --git a/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp2.dts b/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp2.dts
index d8642cd..77bd260 100644
--- a/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp2.dts
+++ b/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp2.dts
@@ -21,7 +21,7 @@
 	load-address = <0x6380000>;
 	entrypoint-offset = <0x2000>;
 	xlat-granule = <0>; /* 4KiB */
-	messaging-method = <0x7>; /* Supports direct and indirect requests. */
+	messaging-method = <0x607>; /* Supports direct (both APIs) and indirect requests. */
 	boot-order = <2>;
 	notification-support; /* Receipt of notifications. */
 	gp-register-num = <0>;
diff --git a/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp3.dts b/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp3.dts
index 5d461d3..15f5019 100644
--- a/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp3.dts
+++ b/test/vmapi/primary_with_secondaries/services/arch/aarch64/secure/partition_manifest_service_sp3.dts
@@ -21,7 +21,7 @@
 	load-address = <0x6280000>;
 	entrypoint-offset = <0x2000>;
 	xlat-granule = <0>; /* 4KiB */
-	messaging-method = <0x7>; /* Supports direct and indirect requests. */
+	messaging-method = <0x7>; /* Supports direct (both APIs) and indirect requests. */
 	boot-order = <3>;
 	notification-support; /* Receipt of notifications. */
 	gp-register-num = <0>;
diff --git a/test/vmapi/primary_with_secondaries/services/dir_msg.c b/test/vmapi/primary_with_secondaries/services/dir_msg.c
index 41e57fd..b536c22 100644
--- a/test/vmapi/primary_with_secondaries/services/dir_msg.c
+++ b/test/vmapi/primary_with_secondaries/services/dir_msg.c
@@ -27,6 +27,23 @@
 	FAIL("Direct response not expected to return");
 }
 
+TEST_SERVICE(ffa_direct_message_req2_resp_echo)
+{
+	struct ffa_value args = ffa_msg_wait();
+
+	EXPECT_EQ(args.func, FFA_MSG_SEND_DIRECT_REQ2_64);
+
+	/*
+	 * TODO: replace with FFA_MSG_SEND_DIRECT_RESP2 abi once
+	 * extended register support is added.
+	 */
+	ffa_msg_send_direct_resp(ffa_receiver(args), ffa_sender(args),
+				 args.arg3, args.arg4, args.arg5, args.arg6,
+				 args.arg7);
+
+	FAIL("Direct response not expected to return");
+}
+
 TEST_SERVICE(ffa_yield_direct_message_resp_echo)
 {
 	struct ffa_value args = ffa_msg_wait();
@@ -75,6 +92,43 @@
 	ffa_yield();
 }
 
+TEST_SERVICE(ffa_direct_message_req2_echo_services)
+{
+	const uint32_t msg[] = {0x00001111, 0x22223333, 0x44445555, 0x66667777};
+	void *recv_buf = SERVICE_RECV_BUFFER();
+	struct ffa_value res;
+	struct ffa_partition_info target_info;
+	struct ffa_uuid target_uuid;
+
+	/* Retrieve uuid of target endpoint. */
+	receive_indirect_message((void *)&target_uuid, sizeof(target_uuid),
+				 recv_buf, NULL);
+
+	HFTEST_LOG("Target UUID: %X-%X-%X-%X", target_uuid.uuid[0],
+		   target_uuid.uuid[1], target_uuid.uuid[2],
+		   target_uuid.uuid[3]);
+
+	/* From uuid to respective partition info. */
+	ASSERT_EQ(get_ffa_partition_info(&target_uuid, &target_info,
+					 sizeof(target_info), recv_buf),
+		  1);
+
+	HFTEST_LOG("Echo test with: %x", target_info.vm_id);
+
+	res = ffa_msg_send_direct_req2(hf_vm_get_id(), target_info.vm_id,
+				       &target_uuid, msg[0], msg[1], msg[2],
+				       msg[3]);
+
+	EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
+
+	EXPECT_EQ(res.arg4, msg[0]);
+	EXPECT_EQ(res.arg5, msg[1]);
+	EXPECT_EQ(res.arg6, msg[2]);
+	EXPECT_EQ(res.arg7, msg[3]);
+
+	ffa_yield();
+}
+
 TEST_SERVICE(ffa_yield_direct_message_echo_services)
 {
 	const uint32_t msg[] = {0x00001111, 0x22223333, 0x44445555, 0x66667777,