feat(ff-a): add helpers for indirect message

Add the header structures for the rxtx buffers, other
helper macros, and the FFA_MSG_SEND2 ABI caller.

Signed-off-by: J-Alves <joao.alves@arm.com>
Change-Id: Ie5c735aa0b33dbf0288b6494362b6e7dc84c6db7
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index 12120e7..d086f91 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -11,6 +11,8 @@
 #include <tftf_lib.h>
 #include <utils_def.h>
 
+#include <xlat_tables_defs.h>
+
 /* This error code must be different to the ones used by FFA */
 #define FFA_TFTF_ERROR		-42
 
@@ -294,6 +296,48 @@
 
 typedef uint64_t ffa_notification_bitmap_t;
 
+/**
+ * Partition message header as specified by table 6.2 from FF-A v1.1 EAC0
+ * specification.
+ */
+struct ffa_partition_rxtx_header {
+	uint32_t flags;
+	/* MBZ */
+	uint32_t reserved;
+	/* Offset from the beginning of the buffer to the message payload. */
+	uint32_t offset;
+	/* Sender(Bits[31:16]) and Receiver(Bits[15:0]) endpoint IDs. */
+	ffa_id_t receiver;
+	ffa_id_t sender;
+	/* Size of message in buffer. */
+	uint32_t size;
+};
+
+#define FFA_RXTX_HEADER_SIZE sizeof(struct ffa_partition_rxtx_header)
+
+static inline void ffa_rxtx_header_init(
+	ffa_id_t sender, ffa_id_t receiver, uint32_t size,
+	struct ffa_partition_rxtx_header *header)
+{
+	header->flags = 0;
+	header->reserved = 0;
+	header->offset = FFA_RXTX_HEADER_SIZE;
+	header->sender = sender;
+	header->receiver = receiver;
+	header->size = size;
+}
+
+/* The maximum length possible for a single message. */
+#define FFA_PARTITION_MSG_PAYLOAD_MAX (PAGE_SIZE - FFA_RXTX_HEADER_SIZE)
+
+struct ffa_partition_msg {
+	struct ffa_partition_rxtx_header header;
+	char payload[FFA_PARTITION_MSG_PAYLOAD_MAX];
+};
+
+/* The maximum length possible for a single message. */
+#define FFA_MSG_PAYLOAD_MAX PAGE_SIZE
+
 #define FFA_NOTIFICATION(ID)		(UINT64_C(1) << ID)
 
 #define MAX_FFA_NOTIFICATIONS		UINT32_C(64)
@@ -794,6 +838,7 @@
 struct ffa_value ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages);
 struct ffa_value ffa_rxtx_unmap_with_id(uint32_t id);
 struct ffa_value ffa_rxtx_unmap(void);
+struct ffa_value ffa_msg_send2(uint32_t flags);
 struct ffa_value ffa_mem_donate(uint32_t descriptor_length,
 				uint32_t fragment_length);
 struct ffa_value ffa_mem_lend(uint32_t descriptor_length,
diff --git a/include/runtime_services/ffa_svc.h b/include/runtime_services/ffa_svc.h
index 0e6081e..577e8cf 100644
--- a/include/runtime_services/ffa_svc.h
+++ b/include/runtime_services/ffa_svc.h
@@ -150,6 +150,7 @@
 #define FFA_RX_RELEASE		FFA_FID(SMC_32, FFA_FNUM_RX_RELEASE)
 #define FFA_RXTX_MAP_SMC32	FFA_FID(SMC_32, FFA_FNUM_RXTX_MAP)
 #define FFA_RXTX_UNMAP		FFA_FID(SMC_32, FFA_FNUM_RXTX_UNMAP)
+#define FFA_MSG_SEND2		FFA_FID(SMC_32, FFA_FNUM_MSG_SEND2)
 #define FFA_PARTITION_INFO_GET	FFA_FID(SMC_32, FFA_FNUM_PARTITION_INFO_GET)
 #define FFA_ID_GET		FFA_FID(SMC_32, FFA_FNUM_ID_GET)
 #define FFA_MSG_POLL		FFA_FID(SMC_32, FFA_FNUM_MSG_POLL)
diff --git a/tftf/tests/runtime_services/secure_service/ffa_helpers.c b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
index a8e732f..6fe8905 100644
--- a/tftf/tests/runtime_services/secure_service/ffa_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
@@ -521,6 +521,34 @@
 	return ffa_service_call(&args);
 }
 
+/**
+ * Copies data from the sender's send buffer to the recipient's receive buffer
+ * and notifies the receiver.
+ *
+ * `flags` may include a 'Delay Schedule Receiver interrupt'.
+ *
+ * Returns FFA_SUCCESS if the message is sent, or an error code otherwise:
+ *  - INVALID_PARAMETERS: one or more of the parameters do not conform.
+ *  - BUSY: receiver's mailbox was full.
+ *  - DENIED: receiver is not in a state to handle the request or doesn't
+ *    support indirect messages.
+ */
+struct ffa_value ffa_msg_send2(uint32_t flags)
+{
+	struct ffa_value args = {
+		.fid = FFA_MSG_SEND2,
+		.arg1 = 0,
+		.arg2 = flags,
+		.arg3 = FFA_PARAM_MBZ,
+		.arg4 = FFA_PARAM_MBZ,
+		.arg5 = FFA_PARAM_MBZ,
+		.arg6 = FFA_PARAM_MBZ,
+		.arg7 = FFA_PARAM_MBZ
+	};
+
+	return ffa_service_call(&args);
+}
+
 /* Donate memory to another partition */
 struct ffa_value ffa_mem_donate(uint32_t descriptor_length,
 				uint32_t fragment_length)