feat(memory sharing): retrieve response v1.0

Prepare retrieve response message depending on retriever's FF-A version.
If FF-A v1.0 prepare message using respective structures, else default
to FF-A v1.1 structures.

Change-Id: I1caeaea2159b054c252e1ec5f1185c7f33e626f4
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/inc/vmapi/hf/ffa.h b/inc/vmapi/hf/ffa.h
index 533dcc4..386d480 100644
--- a/inc/vmapi/hf/ffa.h
+++ b/inc/vmapi/hf/ffa.h
@@ -1031,6 +1031,12 @@
 						      desc->tx_offset);
 }
 
+void ffa_memory_region_init_header(struct ffa_memory_region *memory_region,
+				   ffa_vm_id_t sender,
+				   ffa_memory_attributes_t attributes,
+				   ffa_memory_region_flags_t flags,
+				   ffa_memory_handle_t handle, uint32_t tag,
+				   uint32_t receiver_count);
 void ffa_memory_access_init_permissions(
 	struct ffa_memory_access *receiver, ffa_vm_id_t receiver_id,
 	enum ffa_data_access data_access,
@@ -1072,15 +1078,6 @@
 uint32_t ffa_memory_lender_retrieve_request_init(
 	struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
 	ffa_vm_id_t sender);
-bool ffa_retrieved_memory_region_init(
-	struct ffa_memory_region *response, size_t response_max_size,
-	ffa_vm_id_t sender, ffa_memory_attributes_t attributes,
-	ffa_memory_region_flags_t flags, ffa_memory_handle_t handle,
-	ffa_vm_id_t receiver, ffa_memory_access_permissions_t permissions,
-	uint32_t page_count, uint32_t total_constituent_count,
-	const struct ffa_memory_region_constituent constituents[],
-	uint32_t fragment_constituent_count, uint32_t *total_length,
-	uint32_t *fragment_length);
 uint32_t ffa_memory_fragment_init(
 	struct ffa_memory_region_constituent *fragment,
 	size_t fragment_max_size,
diff --git a/inc/vmapi/hf/ffa_v1_0.h b/inc/vmapi/hf/ffa_v1_0.h
index 2f64202..4029e2b 100644
--- a/inc/vmapi/hf/ffa_v1_0.h
+++ b/inc/vmapi/hf/ffa_v1_0.h
@@ -88,6 +88,11 @@
 						      offset);
 }
 
+void ffa_memory_region_init_header_v1_0(
+	struct ffa_memory_region_v1_0 *memory_region, ffa_vm_id_t sender,
+	ffa_memory_attributes_t attributes, ffa_memory_region_flags_t flags,
+	ffa_memory_handle_t handle, uint32_t tag, uint32_t receiver_count);
+
 uint32_t ffa_memory_region_init_v1_0(
 	struct ffa_memory_region_v1_0 *memory_region,
 	size_t memory_region_max_size, ffa_vm_id_t sender,
diff --git a/src/ffa_memory.c b/src/ffa_memory.c
index 6ef64e1..a17000d 100644
--- a/src/ffa_memory.c
+++ b/src/ffa_memory.c
@@ -22,6 +22,8 @@
 #include "hf/std.h"
 #include "hf/vm.h"
 
+#include "vmapi/hf/ffa_v1_0.h"
+
 /**
  * All access to members of a `struct ffa_memory_share_state` must be guarded
  * by this lock.
@@ -1666,6 +1668,121 @@
 	}
 }
 
+/**
+ * Initialises the given memory region descriptor to be used for an
+ * `FFA_MEM_RETRIEVE_RESP`, including the given constituents for the first
+ * fragment.
+ * The memory region descriptor is initialized according to retriever's
+ * FF-A version.
+ *
+ * Returns true on success, or false if the given constituents won't all fit in
+ * the first fragment.
+ */
+static bool ffa_retrieved_memory_region_init(
+	void *response, uint32_t ffa_version, size_t response_max_size,
+	ffa_vm_id_t sender, ffa_memory_attributes_t attributes,
+	ffa_memory_region_flags_t flags, ffa_memory_handle_t handle,
+	ffa_vm_id_t receiver_id, ffa_memory_access_permissions_t permissions,
+	uint32_t page_count, uint32_t total_constituent_count,
+	const struct ffa_memory_region_constituent constituents[],
+	uint32_t fragment_constituent_count, uint32_t *total_length,
+	uint32_t *fragment_length)
+{
+	struct ffa_composite_memory_region *composite_memory_region;
+	struct ffa_memory_access *receiver;
+	uint32_t i;
+	uint32_t constituents_offset;
+	uint32_t receiver_count;
+
+	assert(response != NULL);
+
+	if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+		struct ffa_memory_region_v1_0 *retrieve_response =
+			(struct ffa_memory_region_v1_0 *)response;
+
+		ffa_memory_region_init_header_v1_0(retrieve_response, sender,
+						   attributes, flags, handle, 0,
+						   1);
+
+		receiver = &retrieve_response->receivers[0];
+		receiver_count = retrieve_response->receiver_count;
+
+		receiver->composite_memory_region_offset =
+			sizeof(struct ffa_memory_region_v1_0) +
+			receiver_count * sizeof(struct ffa_memory_access);
+
+		composite_memory_region = ffa_memory_region_get_composite_v1_0(
+			retrieve_response, 0);
+	} else {
+		/* Default to FF-A v1.1 version. */
+		struct ffa_memory_region *retrieve_response =
+			(struct ffa_memory_region *)response;
+
+		ffa_memory_region_init_header(retrieve_response, sender,
+					      attributes, flags, handle, 0, 1);
+
+		receiver = &retrieve_response->receivers[0];
+		receiver_count = retrieve_response->receiver_count;
+
+		/*
+		 * Note that `sizeof(struct_ffa_memory_region)` and
+		 * `sizeof(struct ffa_memory_access)` must both be multiples of
+		 * 16 (as verified by the asserts in `ffa_memory.c`, so it is
+		 * guaranteed that the offset we calculate here is aligned to a
+		 * 64-bit boundary and so 64-bit values can be copied without
+		 * alignment faults.
+		 */
+		receiver->composite_memory_region_offset =
+			sizeof(struct ffa_memory_region) +
+			receiver_count * sizeof(struct ffa_memory_access);
+
+		composite_memory_region =
+			ffa_memory_region_get_composite(retrieve_response, 0);
+	}
+
+	assert(receiver != NULL);
+	assert(composite_memory_region != NULL);
+
+	/*
+	 * Initialized here as in memory retrieve responses we currently expect
+	 * one borrower to be specified.
+	 */
+	ffa_memory_access_init_permissions(receiver, receiver_id, 0, 0, flags);
+	receiver->receiver_permissions.permissions = permissions;
+
+	composite_memory_region->page_count = page_count;
+	composite_memory_region->constituent_count = total_constituent_count;
+	composite_memory_region->reserved_0 = 0;
+
+	constituents_offset = receiver->composite_memory_region_offset +
+			      sizeof(struct ffa_composite_memory_region);
+	if (constituents_offset +
+		    fragment_constituent_count *
+			    sizeof(struct ffa_memory_region_constituent) >
+	    response_max_size) {
+		return false;
+	}
+
+	for (i = 0; i < fragment_constituent_count; ++i) {
+		composite_memory_region->constituents[i] = constituents[i];
+	}
+
+	if (total_length != NULL) {
+		*total_length =
+			constituents_offset +
+			composite_memory_region->constituent_count *
+				sizeof(struct ffa_memory_region_constituent);
+	}
+	if (fragment_length != NULL) {
+		*fragment_length =
+			constituents_offset +
+			fragment_constituent_count *
+				sizeof(struct ffa_memory_region_constituent);
+	}
+
+	return true;
+}
+
 /*
  * Gets the receiver's access permissions from 'struct ffa_memory_region' and
  * returns its index in the receiver's array. If receiver's ID doesn't exist
@@ -2236,11 +2353,11 @@
 	 * should never fail.
 	 */
 	CHECK(ffa_retrieved_memory_region_init(
-		to_locked.vm->mailbox.recv, HF_MAILBOX_SIZE,
-		memory_region->sender, memory_region->attributes,
-		memory_region->flags, handle, receiver_id, permissions,
-		composite->page_count, composite->constituent_count,
-		share_state->fragments[0],
+		to_locked.vm->mailbox.recv, to_locked.vm->ffa_version,
+		HF_MAILBOX_SIZE, memory_region->sender,
+		memory_region->attributes, memory_region->flags, handle,
+		receiver_id, permissions, composite->page_count,
+		composite->constituent_count, share_state->fragments[0],
 		share_state->fragment_constituent_counts[0], &total_length,
 		&fragment_length));
 
diff --git a/vmlib/ffa.c b/vmlib/ffa.c
index c0c4d91..40122c5 100644
--- a/vmlib/ffa.c
+++ b/vmlib/ffa.c
@@ -61,10 +61,12 @@
  * Initialises the header of the given `ffa_memory_region`, not
  * including the composite memory region offset.
  */
-static void ffa_memory_region_init_header(
-	struct ffa_memory_region *memory_region, ffa_vm_id_t sender,
-	ffa_memory_attributes_t attributes, ffa_memory_region_flags_t flags,
-	ffa_memory_handle_t handle, uint32_t tag, uint32_t receiver_count)
+void ffa_memory_region_init_header(struct ffa_memory_region *memory_region,
+				   ffa_vm_id_t sender,
+				   ffa_memory_attributes_t attributes,
+				   ffa_memory_region_flags_t flags,
+				   ffa_memory_handle_t handle, uint32_t tag,
+				   uint32_t receiver_count)
 {
 	memory_region->sender = sender;
 	memory_region->attributes = attributes;
@@ -315,84 +317,6 @@
 	return sizeof(struct ffa_memory_region);
 }
 
-/**
- * Initialises the given `ffa_memory_region` to be used for an
- * `FFA_MEM_RETRIEVE_RESP`, including the given constituents for the first
- * fragment.
- *
- * Returns true on success, or false if the given constituents won't all fit in
- * the first fragment.
- */
-bool ffa_retrieved_memory_region_init(
-	struct ffa_memory_region *response, size_t response_max_size,
-	ffa_vm_id_t sender, ffa_memory_attributes_t attributes,
-	ffa_memory_region_flags_t flags, ffa_memory_handle_t handle,
-	ffa_vm_id_t receiver, ffa_memory_access_permissions_t permissions,
-	uint32_t page_count, uint32_t total_constituent_count,
-	const struct ffa_memory_region_constituent constituents[],
-	uint32_t fragment_constituent_count, uint32_t *total_length,
-	uint32_t *fragment_length)
-{
-	struct ffa_composite_memory_region *composite_memory_region;
-	uint32_t i;
-	uint32_t constituents_offset;
-
-	ffa_memory_region_init_header(response, sender, attributes, flags,
-				      handle, 0, 1);
-	/*
-	 * Initialized here as in memory retrieve responses we currently expect
-	 * one borrower to be specified.
-	 */
-	ffa_memory_access_init_permissions(&response->receivers[0], receiver, 0,
-					   0, flags);
-	response->receivers[0].receiver_permissions.permissions = permissions;
-
-	/*
-	 * Note that `sizeof(struct_ffa_memory_region)` and `sizeof(struct
-	 * ffa_memory_access)` must both be multiples of 16 (as verified by the
-	 * asserts in `ffa_memory.c`, so it is guaranteed that the offset we
-	 * calculate here is aligned to a 64-bit boundary and so 64-bit values
-	 * can be copied without alignment faults.
-	 */
-	response->receivers[0].composite_memory_region_offset =
-		sizeof(struct ffa_memory_region) +
-		response->receiver_count * sizeof(struct ffa_memory_access);
-
-	composite_memory_region = ffa_memory_region_get_composite(response, 0);
-	composite_memory_region->page_count = page_count;
-	composite_memory_region->constituent_count = total_constituent_count;
-	composite_memory_region->reserved_0 = 0;
-
-	constituents_offset =
-		response->receivers[0].composite_memory_region_offset +
-		sizeof(struct ffa_composite_memory_region);
-	if (constituents_offset +
-		    fragment_constituent_count *
-			    sizeof(struct ffa_memory_region_constituent) >
-	    response_max_size) {
-		return false;
-	}
-
-	for (i = 0; i < fragment_constituent_count; ++i) {
-		composite_memory_region->constituents[i] = constituents[i];
-	}
-
-	if (total_length != NULL) {
-		*total_length =
-			constituents_offset +
-			composite_memory_region->constituent_count *
-				sizeof(struct ffa_memory_region_constituent);
-	}
-	if (fragment_length != NULL) {
-		*fragment_length =
-			constituents_offset +
-			fragment_constituent_count *
-				sizeof(struct ffa_memory_region_constituent);
-	}
-
-	return true;
-}
-
 uint32_t ffa_memory_fragment_init(
 	struct ffa_memory_region_constituent *fragment,
 	size_t fragment_max_size,
diff --git a/vmlib/ffa_v1_0.c b/vmlib/ffa_v1_0.c
index d6b6b14..eccf307 100644
--- a/vmlib/ffa_v1_0.c
+++ b/vmlib/ffa_v1_0.c
@@ -26,7 +26,7 @@
  * Initialises the header of the given `ffa_memory_region_v1_0`, not
  * including the composite memory region offset.
  */
-static void ffa_memory_region_init_header_v1_0(
+void ffa_memory_region_init_header_v1_0(
 	struct ffa_memory_region_v1_0 *memory_region, ffa_vm_id_t sender,
 	ffa_memory_attributes_t attributes, ffa_memory_region_flags_t flags,
 	ffa_memory_handle_t handle, uint32_t tag, uint32_t receiver_count)