Add 64 bit direct message handling to libsp

* Change direct message struct to allow 64 bit arguments
* Add 64 bit direct message req/resp functions to FF-A layer
* Distinguish 32/64 bit messages on SP layer by field in sp_msg
* Update tests and mocks

The FF-A direct message response must match the request's 32/64bit mode
which is the responsibility of the callee and it should be validated by
the SPMC.

Signed-off-by: Imre Kis <imre.kis@arm.com>
Change-Id: Ibbd64ca0291dfe142a23471a649a07ba1a036824
diff --git a/components/messaging/ffa/libsp/ffa.c b/components/messaging/ffa/libsp/ffa.c
index 374e940..caacc79 100644
--- a/components/messaging/ffa/libsp/ffa.c
+++ b/components/messaging/ffa/libsp/ffa.c
@@ -33,11 +33,20 @@
 	msg->function_id = svc_result->a0;
 	msg->source_id = (svc_result->a1 >> 16);
 	msg->destination_id = svc_result->a1;
-	msg->args[0] = svc_result->a3;
-	msg->args[1] = svc_result->a4;
-	msg->args[2] = svc_result->a5;
-	msg->args[3] = svc_result->a6;
-	msg->args[4] = svc_result->a7;
+
+	if (FFA_IS_32_BIT_FUNC(msg->function_id)) {
+		msg->args.args32[0] = svc_result->a3;
+		msg->args.args32[1] = svc_result->a4;
+		msg->args.args32[2] = svc_result->a5;
+		msg->args.args32[3] = svc_result->a6;
+		msg->args.args32[4] = svc_result->a7;
+	} else {
+		msg->args.args64[0] = svc_result->a3;
+		msg->args.args64[1] = svc_result->a4;
+		msg->args.args64[2] = svc_result->a5;
+		msg->args.args64[3] = svc_result->a6;
+		msg->args.args64[4] = svc_result->a7;
+	}
 }
 
 /*
@@ -217,7 +226,7 @@
 
 	if (result.a0 == FFA_ERROR) {
 		return ffa_get_errorcode(&result);
-	} else if (result.a0 == FFA_MSG_SEND_DIRECT_REQ_32) {
+	} else if (FFA_TO_32_BIT_FUNC(result.a0) == FFA_MSG_SEND_DIRECT_REQ_32) {
 		ffa_unpack_direct_msg(&result, msg);
 	} else {
 		assert(result.a0 == FFA_SUCCESS_32);
@@ -227,13 +236,15 @@
 	return FFA_OK;
 }
 
-ffa_result ffa_msg_send_direct_req(uint16_t source, uint16_t dest, uint32_t a0,
-				   uint32_t a1, uint32_t a2, uint32_t a3,
-				   uint32_t a4, struct ffa_direct_msg *msg)
+static ffa_result ffa_msg_send_direct_req(uint32_t function_id, uint32_t resp_id,
+					  uint16_t source, uint16_t dest,
+					  uint64_t a0, uint64_t a1, uint64_t a2,
+					  uint64_t a3, uint64_t a4,
+					  struct ffa_direct_msg *msg)
 {
 	struct ffa_params result = {0};
 
-	ffa_svc(FFA_MSG_SEND_DIRECT_REQ_32,
+	ffa_svc(function_id,
 		SHIFT_U32(source, FFA_MSG_SEND_DIRECT_REQ_SOURCE_ID_SHIFT) |
 		dest, FFA_PARAM_MBZ, a0, a1, a2, a3, a4, &result);
 
@@ -244,7 +255,7 @@
 
 	if (result.a0 == FFA_ERROR) {
 		return ffa_get_errorcode(&result);
-	} else if (result.a0 == FFA_MSG_SEND_DIRECT_RESP_32) {
+	} else if (result.a0 == resp_id) {
 		ffa_unpack_direct_msg(&result, msg);
 	} else {
 		assert(result.a0 == FFA_SUCCESS_32);
@@ -254,13 +265,36 @@
 	return FFA_OK;
 }
 
-ffa_result ffa_msg_send_direct_resp(uint16_t source, uint16_t dest, uint32_t a0,
-				    uint32_t a1, uint32_t a2, uint32_t a3,
-				    uint32_t a4, struct ffa_direct_msg *msg)
+ffa_result ffa_msg_send_direct_req_32(uint16_t source, uint16_t dest,
+				      uint32_t a0, uint32_t a1, uint32_t a2,
+				      uint32_t a3, uint32_t a4,
+				      struct ffa_direct_msg *msg)
+{
+	return ffa_msg_send_direct_req(FFA_MSG_SEND_DIRECT_REQ_32,
+				       FFA_MSG_SEND_DIRECT_RESP_32,
+				       source, dest, a0, a1, a2, a3, a4, msg);
+}
+
+ffa_result ffa_msg_send_direct_req_64(uint16_t source, uint16_t dest,
+				      uint64_t a0, uint64_t a1, uint64_t a2,
+				      uint64_t a3, uint64_t a4,
+				      struct ffa_direct_msg *msg)
+{
+	return ffa_msg_send_direct_req(FFA_MSG_SEND_DIRECT_REQ_64,
+				       FFA_MSG_SEND_DIRECT_RESP_64,
+				       source, dest, a0, a1, a2, a3, a4, msg);
+}
+
+static ffa_result ffa_msg_send_direct_resp(uint32_t function_id,
+					   uint16_t source, uint16_t dest,
+					   uint64_t a0, uint64_t a1,
+					   uint64_t a2, uint64_t a3,
+					   uint64_t a4,
+					   struct ffa_direct_msg *msg)
 {
 	struct ffa_params result = {0};
 
-	ffa_svc(FFA_MSG_SEND_DIRECT_RESP_32,
+	ffa_svc(function_id,
 		SHIFT_U32(source, FFA_MSG_SEND_DIRECT_RESP_SOURCE_ID_SHIFT) |
 		dest, FFA_PARAM_MBZ, a0, a1, a2, a3, a4, &result);
 
@@ -271,7 +305,7 @@
 
 	if (result.a0 == FFA_ERROR) {
 		return ffa_get_errorcode(&result);
-	} else if (result.a0 == FFA_MSG_SEND_DIRECT_REQ_32) {
+	} else if (FFA_TO_32_BIT_FUNC(result.a0) == FFA_MSG_SEND_DIRECT_REQ_32) {
 		ffa_unpack_direct_msg(&result, msg);
 	} else {
 		assert(result.a0 == FFA_SUCCESS_32);
@@ -281,6 +315,24 @@
 	return FFA_OK;
 }
 
+ffa_result ffa_msg_send_direct_resp_32(uint16_t source, uint16_t dest,
+				       uint32_t a0, uint32_t a1, uint32_t a2,
+				       uint32_t a3, uint32_t a4,
+				       struct ffa_direct_msg *msg)
+{
+	return ffa_msg_send_direct_resp(FFA_MSG_SEND_DIRECT_RESP_32, source,
+					dest, a0, a1, a2, a3, a4, msg);
+}
+
+ffa_result ffa_msg_send_direct_resp_64(uint16_t source, uint16_t dest,
+				      uint64_t a0, uint64_t a1, uint64_t a2,
+				      uint64_t a3, uint64_t a4,
+				      struct ffa_direct_msg *msg)
+{
+	return ffa_msg_send_direct_resp(FFA_MSG_SEND_DIRECT_RESP_64, source,
+					dest, a0, a1, a2, a3, a4, msg);
+}
+
 ffa_result ffa_mem_donate(uint32_t total_length, uint32_t fragment_length,
 			  void *buffer_address, uint32_t page_count,
 			  uint64_t *handle)