test: FFA_MSG_SEND_DIRECT_RESP2 intercepted

This test helps to validate the functionality of the SPMC to intercept a
direct response sent via FFA_MSG_SEND_DIRECT_RESP2 if there are pending
virtual secure interrupts and reschedule the partition to handle the
pending interrupt.

Upgrade `SP Service Second EL0` partition in ffa_secure_partitions test
setup to FF-A v1.2 to be able to receive direct messages sent via
FFA_MSG_SEND_DIRECT_REQ2. Also enable recv/send messaging methods for
FFA_MSG_SEND_DIRECT_REQ2 for this partition and for `SP Service Second
EL1` partition.

Signed-off-by: Kathleen Capella <kathleen.capella@arm.com>
Change-Id: I8def860eb14e35e01b964aa0d751e37efefbb18c
diff --git a/test/vmapi/ffa_secure_partitions/secure_interrupts.c b/test/vmapi/ffa_secure_partitions/secure_interrupts.c
index 51e6c52..50d06da 100644
--- a/test/vmapi/ffa_secure_partitions/secure_interrupts.c
+++ b/test/vmapi/ffa_secure_partitions/secure_interrupts.c
@@ -128,12 +128,12 @@
 	check_and_disable_trusted_wdog_timer(own_id, receiver_id);
 }
 
-/*
+/**
  * Test secure interrupt handling while the Secure Partition runs with
  * interrupts potentially masked. This test helps to validate the functionality
- * of the SPMC to intercept a direct response message if there are pending
- * virtual secure interrupts and reschedule the partition to handle the pending
- * interrupt.
+ * of the SPMC to intercept a direct response message sent via
+ * FFA_MSG_SEND_DIRECT_RESP_32 if there are pending virtual secure interrupts
+ * and reschedule the partition to handle the pending interrupt.
  */
 TEST(secure_interrupts, sp_direct_response_intercepted)
 {
@@ -162,6 +162,43 @@
 	check_and_disable_trusted_wdog_timer(own_id, receiver_id);
 }
 
+/**
+ * Test secure interrupt handling while the Secure Partition runs with
+ * interrupts potentially masked. This test helps to validate the functionality
+ * of the SPMC to intercept a direct response message sent via
+ * FFA_MSG_SEND_DIRECT_RESP2_64 if there are pending virtual secure interrupts
+ * and reschedule the partition to handle the pending interrupt.
+ */
+TEST(secure_interrupts, sp_direct_response2_intercepted)
+{
+	struct ffa_value res;
+	ffa_id_t own_id = hf_vm_get_id();
+	struct mailbox_buffers mb = set_up_mailbox();
+	struct ffa_partition_info *service2_info = service2(mb.recv);
+	const ffa_id_t receiver_id = service2_info->vm_id;
+	const uint64_t msg[] = {SP_SLEEP_CMD, SP_SLEEP_TIME, 1};
+	struct ffa_uuid uuid;
+
+	enable_trigger_trusted_wdog_timer(own_id, receiver_id, 400);
+
+	/* Send request to the SP to sleep uninterrupted. */
+	ffa_uuid_init(0, 0, 0, 0, &uuid);
+	res = ffa_msg_send_direct_req2(own_id, receiver_id, &uuid,
+				       (const uint64_t *)&msg, ARRAY_SIZE(msg));
+
+	/*
+	 * Secure interrupt should trigger during this time, SP will handle the
+	 * trusted watchdog timer interrupt.
+	 */
+	EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP2_64);
+	EXPECT_EQ(sp_resp(res), SP_SUCCESS);
+
+	/* Make sure elapsed time not less than sleep time. */
+	EXPECT_GE(res.arg5, SP_SLEEP_TIME);
+
+	check_and_disable_trusted_wdog_timer(own_id, receiver_id);
+}
+
 /*
  * This test is an extension of the 'sp_direct_response_intercepted' test. It
  * creates a scenario where a direct response message between two Secure
diff --git a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/el0/partition_manifest_service_sp_second.dts b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/el0/partition_manifest_service_sp_second.dts
index 58a38c2..bd4435b 100644
--- a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/el0/partition_manifest_service_sp_second.dts
+++ b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/el0/partition_manifest_service_sp_second.dts
@@ -13,7 +13,7 @@
   debug_name = "SP Service Second EL0";
 
   /* Properties */
-  ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+  ffa-version = <0x00010002>; /* 31:16 - Major, 15:0 - Minor */
   uuid = <0xa609f132 0x6b4f 0x4c14 0x9489>;
   execution-ctx-count = <1>;
   exception-level = <1>; /* S-EL0 */
@@ -21,7 +21,7 @@
   load-address = <0x6380000>;
   entrypoint-offset = <0x2000>;
   xlat-granule = <0>; /* 4KiB */
-  messaging-method = <0x7>; /* Support direct and indirect messaging. */
+  messaging-method = <0x607>; /* Support direct (both APIs) and indirect messaging. */
   ns-interrupts-action = <2>; /* NS interrupts are signaled */
   boot-order = <4>;
   notification-support; /* Receipt of notifications. */
diff --git a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/inc/partition_services.h b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/inc/partition_services.h
index 75b682c..95c1ba5 100644
--- a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/inc/partition_services.h
+++ b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/inc/partition_services.h
@@ -387,7 +387,7 @@
 }
 
 struct ffa_value sp_sleep_cmd(ffa_id_t source, uint32_t sleep_ms,
-			      uint32_t options);
+			      uint32_t options, uint64_t func);
 
 static inline uint32_t sp_get_sleep_options(struct ffa_value ret)
 {
diff --git a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/message_loop.c b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/message_loop.c
index 194e842..7698be2 100644
--- a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/message_loop.c
+++ b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/message_loop.c
@@ -14,6 +14,29 @@
 #include "test/hftest.h"
 #include "test/vmapi/ffa.h"
 
+static struct ffa_value handle_direct_req2_cmd(struct ffa_value res)
+{
+	uint32_t options = res.arg6;
+
+	hftest_set_dir_req_source_id(ffa_sender(res));
+
+	if (res.arg4 == SP_SLEEP_CMD) {
+		res = sp_sleep_cmd(ffa_sender(res), res.arg5, options,
+				   FFA_MSG_SEND_DIRECT_REQ2_64);
+	} else {
+		HFTEST_LOG_FAILURE();
+		HFTEST_LOG(HFTEST_LOG_INDENT
+			   "0x%x is not a valid command from %x\n",
+			   res.arg4, ffa_sender(res));
+		abort();
+	}
+
+	/* Reset the field tracking the source of direct request message. */
+	hftest_set_dir_req_source_id(HF_INVALID_VM_ID);
+
+	return res;
+}
+
 static struct ffa_value handle_direct_req_cmd(struct ffa_value res)
 {
 	hftest_set_dir_req_source_id(ffa_sender(res));
@@ -80,7 +103,8 @@
 		break;
 	case SP_SLEEP_CMD:
 		res = sp_sleep_cmd(ffa_sender(res), sp_get_sleep_time(res),
-				   sp_get_sleep_options(res));
+				   sp_get_sleep_options(res),
+				   FFA_MSG_SEND_DIRECT_REQ_32);
 		break;
 	case SP_FWD_SLEEP_CMD:
 		res = sp_fwd_sleep_cmd(ffa_sender(res), sp_get_sleep_time(res),
@@ -135,11 +159,11 @@
 
 	while (1) {
 		if (res.func == FFA_MSG_SEND_DIRECT_REQ_32) {
-			if (is_boot_vcpu) {
-				/* TODO: can only print from boot vCPU. */
-				HFTEST_LOG("Received direct message request");
-			}
+			HFTEST_LOG("Received direct message request");
 			res = handle_direct_req_cmd(res);
+		} else if (res.func == FFA_MSG_SEND_DIRECT_REQ2_64) {
+			HFTEST_LOG("Received direct message request2");
+			res = handle_direct_req2_cmd(res);
 		} else if (res.func == FFA_INTERRUPT_32) {
 			res = handle_ffa_interrupt(res);
 		} else if (res.func == FFA_RUN_32) {
diff --git a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/partition_manifest_service_sp_second.dts b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/partition_manifest_service_sp_second.dts
index 71a4ccd..114aa57 100644
--- a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/partition_manifest_service_sp_second.dts
+++ b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/partition_manifest_service_sp_second.dts
@@ -21,7 +21,7 @@
 	load-address = <0x6380000>;
 	entrypoint-offset = <0x2000>;
 	xlat-granule = <0>; /* 4KiB */
-	messaging-method = <0x7>; /* Supports direct and indirect messages. */
+	messaging-method = <0x607>; /* Supports direct (both APIs) and indirect messages. */
 	ns-interrupts-action = <2>; /* Non secure interrupts are signaled. */
 	boot-order = <2>;
 	notification-support; /* Receipt of notifications. */
diff --git a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/secure_interrupts.c b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/secure_interrupts.c
index 329f586..9c8b718 100644
--- a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/secure_interrupts.c
+++ b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/secure_interrupts.c
@@ -132,7 +132,7 @@
 	ffa_id_t own_id = hf_vm_get_id();
 
 	/* Map peripheral(such as secure watchdog timer) address space. */
-	hftest_mm_identity_map((void*)PLAT_ARM_TWDOG_BASE, PLAT_ARM_TWDOG_SIZE,
+	hftest_mm_identity_map((void *)PLAT_ARM_TWDOG_BASE, PLAT_ARM_TWDOG_SIZE,
 			       MM_MODE_R | MM_MODE_W | MM_MODE_D);
 
 	return sp_success(own_id, test_source, 0);
@@ -179,7 +179,7 @@
 }
 
 struct ffa_value sp_sleep_cmd(ffa_id_t source, uint32_t sleep_ms,
-			      uint32_t options)
+			      uint32_t options, uint64_t func)
 {
 	uint64_t time_lapsed;
 	ffa_id_t own_id = hf_vm_get_id();
@@ -196,6 +196,12 @@
 	/* Lapsed time should be at least equal to sleep time. */
 	HFTEST_LOG("Sleep complete: %u", time_lapsed);
 
+	if (func == FFA_MSG_SEND_DIRECT_REQ2_64) {
+		uint64_t msg[] = {0, time_lapsed};
+		return ffa_msg_send_direct_resp2(own_id, source,
+						 (const uint64_t *)&msg,
+						 ARRAY_SIZE(msg));
+	}
 	return sp_success(own_id, source, time_lapsed);
 }