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);