Support fragmented memory sharing messages.

Bug: 132420445
Change-Id: I638f7fece9a8f83976c0e9ff2fd3ad66dac3ad25
diff --git a/inc/hf/api.h b/inc/hf/api.h
index bfeed7c..be825fd 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -71,3 +71,11 @@
 struct ffa_value api_ffa_mem_reclaim(ffa_memory_handle_t handle,
 				     ffa_memory_region_flags_t flags,
 				     struct vcpu *current);
+struct ffa_value api_ffa_mem_frag_rx(ffa_memory_handle_t handle,
+				     uint32_t fragment_offset,
+				     ffa_vm_id_t sender_vm_id,
+				     struct vcpu *current);
+struct ffa_value api_ffa_mem_frag_tx(ffa_memory_handle_t handle,
+				     uint32_t fragment_length,
+				     ffa_vm_id_t sender_vm_id,
+				     struct vcpu *current);
diff --git a/inc/hf/ffa_memory.h b/inc/hf/ffa_memory.h
index 9715918..3637980 100644
--- a/inc/hf/ffa_memory.h
+++ b/inc/hf/ffa_memory.h
@@ -30,17 +30,34 @@
 	struct vm_locked from_locked, struct vm_locked to_locked,
 	struct ffa_memory_region *memory_region, uint32_t memory_share_length,
 	uint32_t fragment_length, uint32_t share_func, struct mpool *page_pool);
+struct ffa_value ffa_memory_send_continue(struct vm_locked from_locked,
+					  void *fragment,
+					  uint32_t fragment_length,
+					  ffa_memory_handle_t handle,
+					  struct mpool *page_pool);
+struct ffa_value ffa_memory_tee_send_continue(struct vm_locked from_locked,
+					      struct vm_locked to_locked,
+					      void *fragment,
+					      uint32_t fragment_length,
+					      ffa_memory_handle_t handle,
+					      struct mpool *page_pool);
 struct ffa_value ffa_memory_retrieve(struct vm_locked to_locked,
 				     struct ffa_memory_region *retrieve_request,
 				     uint32_t retrieve_request_length,
 				     struct mpool *page_pool);
+struct ffa_value ffa_memory_retrieve_continue(struct vm_locked to_locked,
+					      ffa_memory_handle_t handle,
+					      uint32_t fragment_offset,
+					      struct mpool *page_pool);
 struct ffa_value ffa_memory_relinquish(
 	struct vm_locked from_locked,
 	struct ffa_mem_relinquish *relinquish_request, struct mpool *page_pool);
 struct ffa_value ffa_memory_reclaim(struct vm_locked to_locked,
-				    ffa_memory_handle_t handle, bool clear,
+				    ffa_memory_handle_t handle,
+				    ffa_memory_region_flags_t flags,
 				    struct mpool *page_pool);
 struct ffa_value ffa_memory_tee_reclaim(struct vm_locked to_locked,
+					struct vm_locked from_locked,
 					ffa_memory_handle_t handle,
-					struct ffa_memory_region *memory_region,
-					bool clear, struct mpool *page_pool);
+					ffa_memory_region_flags_t flags,
+					struct mpool *page_pool);
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index 1416f77..204a248 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -175,6 +175,26 @@
 					   .arg3 = flags});
 }
 
+static inline struct ffa_value ffa_mem_frag_rx(ffa_memory_handle_t handle,
+					       uint32_t fragment_offset)
+{
+	/* Note that sender MBZ at virtual instance. */
+	return ffa_call((struct ffa_value){.func = FFA_MEM_FRAG_RX_32,
+					   .arg1 = (uint32_t)handle,
+					   .arg2 = (uint32_t)(handle >> 32),
+					   .arg3 = fragment_offset});
+}
+
+static inline struct ffa_value ffa_mem_frag_tx(ffa_memory_handle_t handle,
+					       uint32_t fragment_length)
+{
+	/* Note that sender MBZ at virtual instance. */
+	return ffa_call((struct ffa_value){.func = FFA_MEM_FRAG_TX_32,
+					   .arg1 = (uint32_t)handle,
+					   .arg2 = (uint32_t)(handle >> 32),
+					   .arg3 = fragment_length});
+}
+
 /**
  * Called by secondary VMs to receive a message. This will block until a message
  * is received.
diff --git a/inc/vmapi/hf/ffa.h b/inc/vmapi/hf/ffa.h
index f7d7356..e6a3015 100644
--- a/inc/vmapi/hf/ffa.h
+++ b/inc/vmapi/hf/ffa.h
@@ -56,6 +56,8 @@
 #define FFA_MEM_RETRIEVE_RESP_32     0x84000075
 #define FFA_MEM_RELINQUISH_32        0x84000076
 #define FFA_MEM_RECLAIM_32           0x84000077
+#define FFA_MEM_FRAG_RX_32           0x8400007A
+#define FFA_MEM_FRAG_TX_32           0x8400007B
 
 /* FF-A error codes. */
 #define FFA_NOT_SUPPORTED      INT32_C(-1)
@@ -194,6 +196,7 @@
 	((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_INVALID (~UINT64_C(0))
 
 /** The ID of a VM. These are assigned sequentially starting with an offset. */
 typedef uint16_t ffa_vm_id_t;
@@ -261,6 +264,11 @@
 	return ffa_assemble_handle(args.arg2, args.arg3);
 }
 
+static inline ffa_memory_handle_t ffa_frag_handle(struct ffa_value args)
+{
+	return ffa_assemble_handle(args.arg1, args.arg2);
+}
+
 static inline struct ffa_value ffa_mem_success(ffa_memory_handle_t handle)
 {
 	return (struct ffa_value){.func = FFA_SUCCESS_32,
@@ -284,6 +292,11 @@
 	return ((uint32_t)vm_id << 16) | vcpu_index;
 }
 
+static inline ffa_vm_id_t ffa_frag_sender(struct ffa_value args)
+{
+	return (args.arg4 >> 16) & 0xffff;
+}
+
 /**
  * A set of contiguous pages which is part of a memory region. This corresponds
  * to table 40 of the FF-A 1.0 EAC specification, "Constituent memory region
@@ -469,14 +482,15 @@
 }
 
 uint32_t ffa_memory_region_init(
-	struct ffa_memory_region *memory_region, ffa_vm_id_t sender,
-	ffa_vm_id_t receiver,
+	struct ffa_memory_region *memory_region, size_t memory_region_max_size,
+	ffa_vm_id_t sender, ffa_vm_id_t receiver,
 	const struct ffa_memory_region_constituent constituents[],
 	uint32_t constituent_count, uint32_t tag,
 	ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
 	enum ffa_instruction_access instruction_access,
 	enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
-	enum ffa_memory_shareability shareability);
+	enum ffa_memory_shareability shareability, uint32_t *fragment_length,
+	uint32_t *total_length);
 uint32_t ffa_memory_retrieve_request_init(
 	struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
 	ffa_vm_id_t sender, ffa_vm_id_t receiver, uint32_t tag,
@@ -487,10 +501,17 @@
 uint32_t ffa_memory_lender_retrieve_request_init(
 	struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
 	ffa_vm_id_t sender);
-uint32_t ffa_retrieved_memory_region_init(
+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 constituent_count);
+	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,
+	const struct ffa_memory_region_constituent constituents[],
+	uint32_t constituent_count, uint32_t *fragment_length);