feat(memory share): support sending fragmented messages.

Updates `memory_init_and_send` to allow sending memory share messages
across multiple fragments.
Tests for this functionality will be added in the next commit.

Change-Id: I6a47735415a8fed1d15322499f1d08cc3e1fd6a2
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index f265fe8..3f760fa 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -433,10 +433,10 @@
 _Static_assert(sizeof(ffa_memory_attributes_t) == sizeof(uint16_t),
 	       "ffa_memory_attributes_t must be 2 bytes wide");
 
-#define FFA_MEMORY_HANDLE_ALLOCATOR_MASK \
-	((ffa_memory_handle_t)(UINT64_C(1) << 63))
-#define FFA_MEMORY_HANDLE_ALLOCATOR_HYPERVISOR \
-	((ffa_memory_handle_t)(UINT64_C(1) << 63))
+#define FFA_MEMORY_HANDLE_ALLOCATOR_MASK UINT64_C(1)
+#define FFA_MEMORY_HANDLE_ALLOCATOR_SHIFT 63U
+#define FFA_MEMORY_HANDLE_ALLOCATOR_HYPERVISOR UINT64_C(1)
+#define FFA_MEMORY_HANDLE_ALLOCATOR_SPMC UINT64_C(0)
 #define FFA_MEMORY_HANDLE_INVALID (~UINT64_C(0))
 
 /**
@@ -608,6 +608,16 @@
 	return ffa_assemble_handle(r.arg2, r.arg3);
 }
 
+static inline ffa_memory_handle_t ffa_frag_handle(struct ffa_value r)
+{
+	return ffa_assemble_handle(r.arg1, r.arg2);
+}
+
+static inline ffa_id_t ffa_frag_sender(struct ffa_value args)
+{
+	return (args.arg4 >> 16) & 0xffff;
+}
+
 /**
  * Gets the `ffa_composite_memory_region` for the given receiver from an
  * `ffa_memory_region`, or NULL if it is not valid.
@@ -660,6 +670,12 @@
 	enum ffa_memory_shareability shareability, 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,
+	const struct ffa_memory_region_constituent constituents[],
+	uint32_t constituent_count, uint32_t *fragment_length);
+
 static inline ffa_id_t ffa_dir_msg_dest(struct ffa_value val) {
 	return (ffa_id_t)val.arg1 & U(0xFFFF);
 }
@@ -711,6 +727,10 @@
 				      uint32_t fragment_length);
 struct ffa_value ffa_mem_relinquish(void);
 struct ffa_value ffa_mem_reclaim(uint64_t handle, uint32_t flags);
+struct ffa_value ffa_mem_frag_rx(ffa_memory_handle_t handle,
+				 uint32_t fragment_length);
+struct ffa_value ffa_mem_frag_tx(ffa_memory_handle_t handle,
+				 uint32_t fragment_length);
 struct ffa_value ffa_notification_bitmap_create(ffa_id_t vm_id,
 						ffa_vcpu_count_t vcpu_count);
 struct ffa_value ffa_notification_bitmap_destroy(ffa_id_t vm_id);
diff --git a/include/runtime_services/ffa_svc.h b/include/runtime_services/ffa_svc.h
index 3abd21f..226bbd1 100644
--- a/include/runtime_services/ffa_svc.h
+++ b/include/runtime_services/ffa_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -86,6 +86,8 @@
 #define FFA_FNUM_MEM_RETRIEVE_RESP		U(0x75)
 #define FFA_FNUM_MEM_RELINQUISH			U(0x76)
 #define FFA_FNUM_MEM_RECLAIM			U(0x77)
+#define FFA_FNUM_MEM_FRAG_RX 			U(0x7A)
+#define FFA_FNUM_MEM_FRAG_TX 			U(0x7B)
 #define FFA_FNUM_NORMAL_WORLD_RESUME		U(0x7C)
 
 /* FF-A v1.1 */
@@ -134,6 +136,8 @@
 #define FFA_MEM_RETRIEVE_RESP	FFA_FID(SMC_32, FFA_FNUM_MEM_RETRIEVE_RESP)
 #define FFA_MEM_RELINQUISH	FFA_FID(SMC_32, FFA_FNUM_MEM_RELINQUISH)
 #define FFA_MEM_RECLAIM		FFA_FID(SMC_32, FFA_FNUM_MEM_RECLAIM)
+#define FFA_MEM_FRAG_RX 	FFA_FID(SMC_32, FFA_FNUM_MEM_FRAG_RX)
+#define FFA_MEM_FRAG_TX 	FFA_FID(SMC_32, FFA_FNUM_MEM_FRAG_TX)
 #define FFA_NOTIFICATION_BITMAP_CREATE	\
 	FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_BITMAP_CREATE)
 #define FFA_NOTIFICATION_BITMAP_DESTROY	\
diff --git a/include/runtime_services/spm_common.h b/include/runtime_services/spm_common.h
index 6494947..ad2ba08 100644
--- a/include/runtime_services/spm_common.h
+++ b/include/runtime_services/spm_common.h
@@ -110,8 +110,7 @@
 bool memory_retrieve(struct mailbox_buffers *mb,
 		     struct ffa_memory_region **retrieved, uint64_t handle,
 		     ffa_id_t sender, struct ffa_memory_access receivers[],
-		     uint32_t receiver_count, ffa_memory_region_flags_t flags,
-		     uint32_t mem_func);
+		     uint32_t receiver_count, ffa_memory_region_flags_t flags);
 
 bool hypervisor_retrieve_request(struct mailbox_buffers *mb, uint64_t handle,
 				 void *out, uint32_t out_size);
@@ -124,20 +123,22 @@
 		       ffa_id_t id);
 
 ffa_memory_handle_t memory_send(
-	struct ffa_memory_region *memory_region, uint32_t mem_func,
-	uint32_t fragment_length, uint32_t total_length, struct ffa_value *ret);
+	void *send_buffer, uint32_t mem_func,
+	const struct ffa_memory_region_constituent *constituents,
+	uint32_t constituent_count, uint32_t remaining_constituent_count,
+	uint32_t fragment_length, uint32_t total_length,
+	struct ffa_value *ret);
 
 ffa_memory_handle_t memory_init_and_send(
-	struct ffa_memory_region *memory_region, size_t memory_region_max_size,
-	ffa_id_t sender, struct ffa_memory_access receivers[],
-	uint32_t receiver_count,
+	void *send_buffer, size_t memory_region_max_size, ffa_id_t sender,
+	struct ffa_memory_access receivers[], uint32_t receiver_count,
 	const struct ffa_memory_region_constituent *constituents,
 	uint32_t constituents_count, uint32_t mem_func, struct ffa_value *ret);
 
 bool ffa_partition_info_helper(struct mailbox_buffers *mb,
-			const struct ffa_uuid uuid,
-			const struct ffa_partition_info *expected,
-			const uint16_t expected_size);
+			       const struct ffa_uuid uuid,
+			       const struct ffa_partition_info *expected,
+			       const uint16_t expected_size);
 bool enable_trusted_wdog_interrupt(ffa_id_t source, ffa_id_t dest);
 bool disable_trusted_wdog_interrupt(ffa_id_t source, ffa_id_t dest);