Add RSS Communication Protocol components

The Corstone-1000 platform uses RSS Communication Protocol
to communicate between the Secure Enclave and the Host processor.

This uses the previously copied RSS Comm Protocol-related files
and has minor modifications to make them work correctly in
Trusted Services. Currently, only the Embed Protocol is supported
from the RSS Comms.

A new messaging and RPC component was made, and both of them follows the
previous OpenAMP and psa_ipc components' structures.

Modified the SE-Proxy deployment to use this new protocol instead of
the OpenAMP.

Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Change-Id: Ia0d2c71396006404f28b8f1338dbbb939237cf62
diff --git a/components/rpc/rss_comms/rss_comms.c b/components/rpc/rss_comms/rss_comms.c
index 332105f..267d134 100644
--- a/components/rpc/rss_comms/rss_comms.c
+++ b/components/rpc/rss_comms/rss_comms.c
@@ -7,24 +7,23 @@
 #include <stdint.h>
 #include <string.h>
 
-#include <common/debug.h>
-#include <drivers/arm/mhu.h>
-#include <drivers/arm/rss_comms.h>
-#include <psa/client.h>
-#include <rss_comms_protocol.h>
+#include "protocols/rpc/common/packed-c/status.h"
+#include "psa/client.h"
+#include "rss_comms_caller.h"
+#include "rss_comms_protocol.h"
+#include "trace.h"
 
-/* Union as message space and reply space are never used at the same time, and this saves space as
- * we can overlap them.
+/* This value should be set according to the implemented channels
+ * in the MHU. As only the Embed protocol is supported at the moment,
+ * it is set big enough to fit even the largest messages.
  */
-union __packed __attribute__((aligned(4))) rss_comms_io_buffer_t {
-	struct serialized_rss_comms_msg_t msg;
-	struct serialized_rss_comms_reply_t reply;
-};
+#ifndef COMMS_MHU_MSG_SIZE
+#define COMMS_MHU_MSG_SIZE 0x2200
+#endif
 
-static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len,
-				       const psa_outvec *out_vec, size_t out_len)
+static uint8_t select_protocol_version(const struct psa_invec *in_vec, size_t in_len,
+				       const struct psa_outvec *out_vec, size_t out_len)
 {
-	size_t comms_mhu_msg_size;
 	size_t comms_embed_msg_min_size;
 	size_t comms_embed_reply_min_size;
 	size_t in_size_total = 0;
@@ -38,11 +37,8 @@
 		out_size_total += out_vec[i].len;
 	}
 
-	comms_mhu_msg_size = mhu_get_max_message_size();
-
 	comms_embed_msg_min_size = sizeof(struct serialized_rss_comms_header_t) +
-				   sizeof(struct rss_embed_msg_t) -
-				   PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE;
+				   sizeof(struct rss_embed_msg_t) - PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE;
 
 	comms_embed_reply_min_size = sizeof(struct serialized_rss_comms_header_t) +
 				     sizeof(struct rss_embed_reply_t) -
@@ -60,121 +56,100 @@
 	 * pointers.
 	 */
 	if ((comms_embed_msg_min_size + in_size_total >
-	     comms_mhu_msg_size - sizeof(uint32_t)) ||
+	     COMMS_MHU_MSG_SIZE - sizeof(uint32_t)) ||
 	    (comms_embed_reply_min_size + out_size_total >
-	     comms_mhu_msg_size - sizeof(uint32_t))) {
+	     COMMS_MHU_MSG_SIZE - sizeof(uint32_t))) {
 		return RSS_COMMS_PROTOCOL_POINTER_ACCESS;
 	} else {
 		return RSS_COMMS_PROTOCOL_EMBED;
 	}
 }
 
-psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec, size_t in_len,
-		      psa_outvec *out_vec, size_t out_len)
+psa_status_t __psa_call(struct rpc_caller_interface *caller, psa_handle_t handle, int32_t client_id,
+			int32_t type, const struct psa_invec *in_vec, size_t in_len,
+			struct psa_outvec *out_vec, size_t out_len)
 {
-	/* Declared statically to avoid using huge amounts of stack space. Maybe revisit if
-	 * functions not being reentrant becomes a problem.
-	 */
-	static union rss_comms_io_buffer_t io_buf;
-	enum mhu_error_t err;
-	psa_status_t status;
 	static uint8_t seq_num = 1U;
-	size_t msg_size;
-	size_t reply_size = sizeof(io_buf.reply);
-	psa_status_t return_val;
-	size_t idx;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	psa_status_t psa_status = PSA_ERROR_INVALID_ARGUMENT;
+	psa_status_t return_val = PSA_ERROR_INVALID_ARGUMENT;
+	rss_comms_call_handle rpc_handle = (rss_comms_call_handle)caller;
+	size_t req_len = 0;
+	size_t resp_len = 0;
+	struct serialized_rss_comms_msg_t *req = NULL;
+	struct serialized_rss_comms_reply_t *reply = NULL;
+	uint8_t protocol_ver = 0;
 
-	if (type > PSA_CALL_TYPE_MAX || type < PSA_CALL_TYPE_MIN ||
-	    in_len > PSA_MAX_IOVEC   || out_len > PSA_MAX_IOVEC) {
-		return PSA_ERROR_INVALID_ARGUMENT;
+	protocol_ver = select_protocol_version(in_vec, in_len, out_vec, out_len);
+
+	psa_status = rss_protocol_calculate_msg_len(handle, protocol_ver, in_vec, in_len, &req_len);
+	if (psa_status != PSA_SUCCESS) {
+		EMSG("Message size calculation failed: %d", psa_status);
+		return psa_status;
 	}
 
-	io_buf.msg.header.seq_num = seq_num,
+	rpc_handle = rss_comms_caller_begin(caller, (uint8_t **)&req, req_len);
+	if (!rpc_handle) {
+		EMSG("Could not get handle");
+		return PSA_ERROR_GENERIC_ERROR;
+	}
+
+	req->header.seq_num = seq_num;
 	/* No need to distinguish callers (currently concurrent calls are not supported). */
-	io_buf.msg.header.client_id = 1U,
-	io_buf.msg.header.protocol_ver = select_protocol_version(in_vec, in_len, out_vec, out_len);
+	req->header.client_id = client_id;
+	req->header.protocol_ver = protocol_ver;
 
-	status = rss_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec,
-					    out_len, &io_buf.msg, &msg_size);
-	if (status != PSA_SUCCESS) {
-		return status;
+	psa_status = rss_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec, out_len, req,
+						&req_len);
+	if (psa_status != PSA_SUCCESS) {
+		EMSG("Serialize msg failed: %d", psa_status);
+		return psa_status;
 	}
 
-	VERBOSE("[RSS-COMMS] Sending message\n");
-	VERBOSE("protocol_ver=%u\n", io_buf.msg.header.protocol_ver);
-	VERBOSE("seq_num=%u\n", io_buf.msg.header.seq_num);
-	VERBOSE("client_id=%u\n", io_buf.msg.header.client_id);
-	for (idx = 0; idx < in_len; idx++) {
-		VERBOSE("in_vec[%lu].len=%lu\n", idx, in_vec[idx].len);
-		VERBOSE("in_vec[%lu].buf=%p\n", idx, (void *)in_vec[idx].base);
+	DMSG("Sending rss_comms message");
+	DMSG("protocol_ver=%u", req->header.protocol_ver);
+	DMSG("seq_num=%u", req->header.seq_num);
+	DMSG("client_id=%u", req->header.client_id);
+
+	resp_len = sizeof(*reply);
+
+	rpc_status = rss_comms_caller_invoke(rpc_handle, 0, (uint8_t **)&reply, &resp_len);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Invoke failed: %d", rpc_status);
+		return PSA_ERROR_GENERIC_ERROR;
 	}
 
-	err = mhu_send_data((uint8_t *)&io_buf.msg, msg_size);
-	if (err != MHU_ERR_NONE) {
-		return PSA_ERROR_COMMUNICATION_FAILURE;
+	DMSG("Received rss_comms reply");
+	DMSG("protocol_ver=%u", reply->header.protocol_ver);
+	DMSG("seq_num=%u", reply->header.seq_num);
+	DMSG("client_id=%u", reply->header.client_id);
+	DMSG("resp_len=%lu", resp_len);
+
+	psa_status = rss_protocol_deserialize_reply(out_vec, out_len, &return_val, reply, resp_len);
+	if (psa_status != PSA_SUCCESS) {
+		EMSG("Protocol deserialize reply failed: %d", psa_status);
+		return psa_status;
 	}
 
-#if DEBUG
-	/*
-	 * Poisoning the message buffer (with a known pattern).
-	 * Helps in detecting hypothetical RSS communication bugs.
-	 */
-	memset(&io_buf.msg, 0xA5, msg_size);
-#endif
+	DMSG("Return_val=%d", return_val);
 
-	err = mhu_receive_data((uint8_t *)&io_buf.reply, &reply_size);
-	if (err != MHU_ERR_NONE) {
-		return PSA_ERROR_COMMUNICATION_FAILURE;
-	}
-
-	VERBOSE("[RSS-COMMS] Received reply\n");
-	VERBOSE("protocol_ver=%u\n", io_buf.reply.header.protocol_ver);
-	VERBOSE("seq_num=%u\n", io_buf.reply.header.seq_num);
-	VERBOSE("client_id=%u\n", io_buf.reply.header.client_id);
-
-	status = rss_protocol_deserialize_reply(out_vec, out_len, &return_val,
-						&io_buf.reply, reply_size);
-	if (status != PSA_SUCCESS) {
-		return status;
-	}
-
-	VERBOSE("return_val=%d\n", return_val);
-	for (idx = 0U; idx < out_len; idx++) {
-		VERBOSE("out_vec[%lu].len=%lu\n", idx, out_vec[idx].len);
-		VERBOSE("out_vec[%lu].buf=%p\n", idx, (void *)out_vec[idx].base);
-	}
-
-	/* Clear the MHU message buffer to remove assets from memory */
-	memset(&io_buf, 0x0, sizeof(io_buf));
+	rss_comms_caller_end(rpc_handle);
 
 	seq_num++;
 
 	return return_val;
 }
 
-int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base)
+psa_status_t psa_call_client_id(struct rpc_caller_interface *caller, psa_handle_t psa_handle,
+				int32_t client_id, int32_t type, const struct psa_invec *in_vec,
+				size_t in_len, struct psa_outvec *out_vec, size_t out_len)
 {
-	enum mhu_error_t err;
+	return __psa_call(caller, psa_handle, client_id, type, in_vec, in_len, out_vec, out_len);
+}
 
-	err = mhu_init_sender(mhu_sender_base);
-	if (err != MHU_ERR_NONE) {
-		if (err == MHU_ERR_ALREADY_INIT) {
-			INFO("[RSS-COMMS] Host to RSS MHU driver already initialized\n");
-		} else {
-			ERROR("[RSS-COMMS] Host to RSS MHU driver initialization failed: %d\n", err);
-			return -1;
-		}
-	}
-
-	err = mhu_init_receiver(mhu_receiver_base);
-	if (err != MHU_ERR_NONE) {
-		if (err == MHU_ERR_ALREADY_INIT) {
-			INFO("[RSS-COMMS] RSS to Host MHU driver already initialized\n");
-		} else {
-			ERROR("[RSS-COMMS] RSS to Host MHU driver initialization failed: %d\n", err);
-			return -1;
-		}
-	}
-
-	return 0;
+psa_status_t psa_call(struct rpc_caller_interface *caller, psa_handle_t psa_handle, int32_t type,
+		      const struct psa_invec *in_vec, size_t in_len, struct psa_outvec *out_vec,
+		      size_t out_len)
+{
+	return __psa_call(caller, psa_handle, 0, type, in_vec, in_len, out_vec, out_len);
 }