/*
 * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#include <assert.h>
#include <errno.h>

#include <common/debug.h>
#include <common/runtime_svc.h>
#include <lib/object_pool.h>
#include <lib/spinlock.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <services/ffa_svc.h>
#include "spmc.h"
#include "spmc_shared_mem.h"

#include <platform_def.h>

/**
 * struct spmc_shmem_obj - Shared memory object.
 * @desc_size:      Size of @desc.
 * @desc_filled:    Size of @desc already received.
 * @in_use:         Number of clients that have called ffa_mem_retrieve_req
 *                  without a matching ffa_mem_relinquish call.
 * @desc:           FF-A memory region descriptor passed in ffa_mem_share.
 */
struct spmc_shmem_obj {
	size_t desc_size;
	size_t desc_filled;
	size_t in_use;
	struct ffa_mtd desc;
};

/*
 * Declare our data structure to store the metadata of memory share requests.
 * The main datastore is allocated on a per platform basis to ensure enough
 * storage can be made available.
 * The address of the data store will be populated by the SPMC during its
 * initialization.
 */

struct spmc_shmem_obj_state spmc_shmem_obj_state = {
	/* Set start value for handle so top 32 bits are needed quickly. */
	.next_handle = 0xffffffc0U,
};

/**
 * spmc_shmem_obj_size - Convert from descriptor size to object size.
 * @desc_size:  Size of struct ffa_memory_region_descriptor object.
 *
 * Return: Size of struct spmc_shmem_obj object.
 */
static size_t spmc_shmem_obj_size(size_t desc_size)
{
	return desc_size + offsetof(struct spmc_shmem_obj, desc);
}

/**
 * spmc_shmem_obj_alloc - Allocate struct spmc_shmem_obj.
 * @state:      Global state.
 * @desc_size:  Size of struct ffa_memory_region_descriptor object that
 *              allocated object will hold.
 *
 * Return: Pointer to newly allocated object, or %NULL if there not enough space
 *         left. The returned pointer is only valid while @state is locked, to
 *         used it again after unlocking @state, spmc_shmem_obj_lookup must be
 *         called.
 */
static struct spmc_shmem_obj *
spmc_shmem_obj_alloc(struct spmc_shmem_obj_state *state, size_t desc_size)
{
	struct spmc_shmem_obj *obj;
	size_t free = state->data_size - state->allocated;

	if (state->data == NULL) {
		ERROR("Missing shmem datastore!\n");
		return NULL;
	}

	if (spmc_shmem_obj_size(desc_size) > free) {
		WARN("%s(0x%zx) failed, free 0x%zx\n",
		     __func__, desc_size, free);
		return NULL;
	}
	obj = (struct spmc_shmem_obj *)(state->data + state->allocated);
	obj->desc = (struct ffa_mtd) {0};
	obj->desc_size = desc_size;
	obj->desc_filled = 0;
	obj->in_use = 0;
	state->allocated += spmc_shmem_obj_size(desc_size);
	return obj;
}

/**
 * spmc_shmem_obj_free - Free struct spmc_shmem_obj.
 * @state:      Global state.
 * @obj:        Object to free.
 *
 * Release memory used by @obj. Other objects may move, so on return all
 * pointers to struct spmc_shmem_obj object should be considered invalid, not
 * just @obj.
 *
 * The current implementation always compacts the remaining objects to simplify
 * the allocator and to avoid fragmentation.
 */

static void spmc_shmem_obj_free(struct spmc_shmem_obj_state *state,
				  struct spmc_shmem_obj *obj)
{
	size_t free_size = spmc_shmem_obj_size(obj->desc_size);
	uint8_t *shift_dest = (uint8_t *)obj;
	uint8_t *shift_src = shift_dest + free_size;
	size_t shift_size = state->allocated - (shift_src - state->data);

	if (shift_size != 0U) {
		memmove(shift_dest, shift_src, shift_size);
	}
	state->allocated -= free_size;
}

/**
 * spmc_shmem_obj_lookup - Lookup struct spmc_shmem_obj by handle.
 * @state:      Global state.
 * @handle:     Unique handle of object to return.
 *
 * Return: struct spmc_shmem_obj_state object with handle matching @handle.
 *         %NULL, if not object in @state->data has a matching handle.
 */
static struct spmc_shmem_obj *
spmc_shmem_obj_lookup(struct spmc_shmem_obj_state *state, uint64_t handle)
{
	uint8_t *curr = state->data;

	while (curr - state->data < state->allocated) {
		struct spmc_shmem_obj *obj = (struct spmc_shmem_obj *)curr;

		if (obj->desc.handle == handle) {
			return obj;
		}
		curr += spmc_shmem_obj_size(obj->desc_size);
	}
	return NULL;
}

/**
 * spmc_shmem_obj_get_next - Get the next memory object from an offset.
 * @offset:     Offset used to track which objects have previously been
 *              returned.
 *
 * Return: the next struct spmc_shmem_obj_state object from the provided
 *	   offset.
 *	   %NULL, if there are no more objects.
 */
static struct spmc_shmem_obj *
spmc_shmem_obj_get_next(struct spmc_shmem_obj_state *state, size_t *offset)
{
	uint8_t *curr = state->data + *offset;

	if (curr - state->data < state->allocated) {
		struct spmc_shmem_obj *obj = (struct spmc_shmem_obj *)curr;

		*offset += spmc_shmem_obj_size(obj->desc_size);

		return obj;
	}
	return NULL;
}

/*******************************************************************************
 * FF-A memory descriptor helper functions.
 ******************************************************************************/
/**
 * spmc_shmem_obj_get_emad - Get the emad from a given index depending on the
 *                           clients FF-A version.
 * @desc:         The memory transaction descriptor.
 * @index:        The index of the emad element to be accessed.
 * @ffa_version:  FF-A version of the provided structure.
 * @emad_size:    Will be populated with the size of the returned emad
 *                descriptor.
 * Return: A pointer to the requested emad structure.
 */
static void *
spmc_shmem_obj_get_emad(const struct ffa_mtd *desc, uint32_t index,
			uint32_t ffa_version, size_t *emad_size)
{
	uint8_t *emad;
	/*
	 * If the caller is using FF-A v1.0 interpret the descriptor as a v1.0
	 * format, otherwise assume it is a v1.1 format.
	 */
	if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
		/* Cast our descriptor to the v1.0 format. */
		struct ffa_mtd_v1_0 *mtd_v1_0 =
					(struct ffa_mtd_v1_0 *) desc;
		emad = (uint8_t *)  &(mtd_v1_0->emad);
		*emad_size = sizeof(struct ffa_emad_v1_0);
	} else {
		if (!is_aligned(desc->emad_offset, 16)) {
			WARN("Emad offset is not aligned.\n");
			return NULL;
		}
		emad = ((uint8_t *) desc + desc->emad_offset);
		*emad_size = desc->emad_size;
	}
	return (emad + (*emad_size * index));
}

/**
 * spmc_shmem_obj_get_comp_mrd - Get comp_mrd from a mtd struct based on the
 *				 FF-A version of the descriptor.
 * @obj:    Object containing ffa_memory_region_descriptor.
 *
 * Return: struct ffa_comp_mrd object corresponding to the composite memory
 *	   region descriptor.
 */
static struct ffa_comp_mrd *
spmc_shmem_obj_get_comp_mrd(struct spmc_shmem_obj *obj, uint32_t ffa_version)
{
	size_t emad_size;
	/*
	 * The comp_mrd_offset field of the emad descriptor remains consistent
	 * between FF-A versions therefore we can use the v1.0 descriptor here
	 * in all cases.
	 */
	struct ffa_emad_v1_0 *emad = spmc_shmem_obj_get_emad(&obj->desc, 0,
							     ffa_version,
							     &emad_size);
	/* Ensure the emad array was found. */
	if (emad == NULL) {
		return NULL;
	}

	/* Ensure the composite descriptor offset is aligned. */
	if (!is_aligned(emad->comp_mrd_offset, 8)) {
		WARN("Unaligned composite memory region descriptor offset.\n");
		return NULL;
	}

	return (struct ffa_comp_mrd *)
	       ((uint8_t *)(&obj->desc) + emad->comp_mrd_offset);
}

/**
 * spmc_shmem_obj_ffa_constituent_size - Calculate variable size part of obj.
 * @obj:    Object containing ffa_memory_region_descriptor.
 *
 * Return: Size of ffa_constituent_memory_region_descriptors in @obj.
 */
static size_t
spmc_shmem_obj_ffa_constituent_size(struct spmc_shmem_obj *obj,
				    uint32_t ffa_version)
{
	struct ffa_comp_mrd *comp_mrd;

	comp_mrd = spmc_shmem_obj_get_comp_mrd(obj, ffa_version);
	if (comp_mrd == NULL) {
		return 0;
	}
	return comp_mrd->address_range_count * sizeof(struct ffa_cons_mrd);
}

/*
 * Compare two memory regions to determine if any range overlaps with another
 * ongoing memory transaction.
 */
static bool
overlapping_memory_regions(struct ffa_comp_mrd *region1,
			   struct ffa_comp_mrd *region2)
{
	uint64_t region1_start;
	uint64_t region1_size;
	uint64_t region1_end;
	uint64_t region2_start;
	uint64_t region2_size;
	uint64_t region2_end;

	assert(region1 != NULL);
	assert(region2 != NULL);

	if (region1 == region2) {
		return true;
	}

	/*
	 * Check each memory region in the request against existing
	 * transactions.
	 */
	for (size_t i = 0; i < region1->address_range_count; i++) {

		region1_start = region1->address_range_array[i].address;
		region1_size =
			region1->address_range_array[i].page_count *
			PAGE_SIZE_4KB;
		region1_end = region1_start + region1_size;

		for (size_t j = 0; j < region2->address_range_count; j++) {

			region2_start = region2->address_range_array[j].address;
			region2_size =
				region2->address_range_array[j].page_count *
				PAGE_SIZE_4KB;
			region2_end = region2_start + region2_size;

			if ((region1_start >= region2_start &&
			     region1_start < region2_end) ||
			    (region1_end > region2_start
			     && region1_end < region2_end)) {
				WARN("Overlapping mem regions 0x%lx-0x%lx & 0x%lx-0x%lx\n",
				     region1_start, region1_end,
				     region2_start, region2_end);
				return true;
			}
		}
	}
	return false;
}

/*******************************************************************************
 * FF-A v1.0 Memory Descriptor Conversion Helpers.
 ******************************************************************************/
/**
 * spmc_shm_get_v1_1_descriptor_size - Calculate the required size for a v1.1
 *                                     converted descriptor.
 * @orig:       The original v1.0 memory transaction descriptor.
 * @desc_size:  The size of the original v1.0 memory transaction descriptor.
 *
 * Return: the size required to store the descriptor store in the v1.1 format.
 */
static size_t
spmc_shm_get_v1_1_descriptor_size(struct ffa_mtd_v1_0 *orig, size_t desc_size)
{
	size_t size = 0;
	struct ffa_comp_mrd *mrd;
	struct ffa_emad_v1_0 *emad_array = orig->emad;

	/* Get the size of the v1.1 descriptor. */
	size += sizeof(struct ffa_mtd);

	/* Add the size of the emad descriptors. */
	size += orig->emad_count * sizeof(struct ffa_emad_v1_0);

	/* Add the size of the composite mrds. */
	size += sizeof(struct ffa_comp_mrd);

	/* Add the size of the constituent mrds. */
	mrd = (struct ffa_comp_mrd *) ((uint8_t *) orig +
	      emad_array[0].comp_mrd_offset);

	/* Check the calculated address is within the memory descriptor. */
	if ((uintptr_t) mrd >= (uintptr_t)((uint8_t *) orig + desc_size)) {
		return 0;
	}
	size += mrd->address_range_count * sizeof(struct ffa_cons_mrd);

	return size;
}

/**
 * spmc_shm_get_v1_0_descriptor_size - Calculate the required size for a v1.0
 *                                     converted descriptor.
 * @orig:       The original v1.1 memory transaction descriptor.
 * @desc_size:  The size of the original v1.1 memory transaction descriptor.
 *
 * Return: the size required to store the descriptor store in the v1.0 format.
 */
static size_t
spmc_shm_get_v1_0_descriptor_size(struct ffa_mtd *orig, size_t desc_size)
{
	size_t size = 0;
	struct ffa_comp_mrd *mrd;
	struct ffa_emad_v1_0 *emad_array = (struct ffa_emad_v1_0 *)
					   ((uint8_t *) orig +
					    orig->emad_offset);

	/* Get the size of the v1.0 descriptor. */
	size += sizeof(struct ffa_mtd_v1_0);

	/* Add the size of the v1.0 emad descriptors. */
	size += orig->emad_count * sizeof(struct ffa_emad_v1_0);

	/* Add the size of the composite mrds. */
	size += sizeof(struct ffa_comp_mrd);

	/* Add the size of the constituent mrds. */
	mrd = (struct ffa_comp_mrd *) ((uint8_t *) orig +
	      emad_array[0].comp_mrd_offset);

	/* Check the calculated address is within the memory descriptor. */
	if ((uintptr_t) mrd >= (uintptr_t)((uint8_t *) orig + desc_size)) {
		return 0;
	}
	size += mrd->address_range_count * sizeof(struct ffa_cons_mrd);

	return size;
}

/**
 * spmc_shm_convert_shmem_obj_from_v1_0 - Converts a given v1.0 memory object.
 * @out_obj:	The shared memory object to populate the converted descriptor.
 * @orig:	The shared memory object containing the v1.0 descriptor.
 *
 * Return: true if the conversion is successful else false.
 */
static bool
spmc_shm_convert_shmem_obj_from_v1_0(struct spmc_shmem_obj *out_obj,
				     struct spmc_shmem_obj *orig)
{
	struct ffa_mtd_v1_0 *mtd_orig = (struct ffa_mtd_v1_0 *) &orig->desc;
	struct ffa_mtd *out = &out_obj->desc;
	struct ffa_emad_v1_0 *emad_array_in;
	struct ffa_emad_v1_0 *emad_array_out;
	struct ffa_comp_mrd *mrd_in;
	struct ffa_comp_mrd *mrd_out;

	size_t mrd_in_offset;
	size_t mrd_out_offset;
	size_t mrd_size = 0;

	/* Populate the new descriptor format from the v1.0 struct. */
	out->sender_id = mtd_orig->sender_id;
	out->memory_region_attributes = mtd_orig->memory_region_attributes;
	out->flags = mtd_orig->flags;
	out->handle = mtd_orig->handle;
	out->tag = mtd_orig->tag;
	out->emad_count = mtd_orig->emad_count;
	out->emad_size = sizeof(struct ffa_emad_v1_0);

	/*
	 * We will locate the emad descriptors directly after the ffa_mtd
	 * struct. This will be 8-byte aligned.
	 */
	out->emad_offset = sizeof(struct ffa_mtd);

	emad_array_in = mtd_orig->emad;
	emad_array_out = (struct ffa_emad_v1_0 *)
			 ((uint8_t *) out + out->emad_offset);

	/* Copy across the emad structs. */
	for (unsigned int i = 0U; i < out->emad_count; i++) {
		memcpy(&emad_array_out[i], &emad_array_in[i],
		       sizeof(struct ffa_emad_v1_0));
	}

	/* Place the mrd descriptors after the end of the emad descriptors.*/
	mrd_in_offset = emad_array_in->comp_mrd_offset;
	mrd_out_offset = out->emad_offset + (out->emad_size * out->emad_count);
	mrd_out = (struct ffa_comp_mrd *) ((uint8_t *) out + mrd_out_offset);

	/* Add the size of the composite memory region descriptor. */
	mrd_size += sizeof(struct ffa_comp_mrd);

	/* Find the mrd descriptor. */
	mrd_in = (struct ffa_comp_mrd *) ((uint8_t *) mtd_orig + mrd_in_offset);

	/* Add the size of the constituent memory region descriptors. */
	mrd_size += mrd_in->address_range_count * sizeof(struct ffa_cons_mrd);

	/*
	 * Update the offset in the emads by the delta between the input and
	 * output addresses.
	 */
	for (unsigned int i = 0U; i < out->emad_count; i++) {
		emad_array_out[i].comp_mrd_offset =
			emad_array_in[i].comp_mrd_offset +
			(mrd_out_offset - mrd_in_offset);
	}

	/* Verify that we stay within bound of the memory descriptors. */
	if ((uintptr_t)((uint8_t *) mrd_in + mrd_size) >
	     (uintptr_t)((uint8_t *) mtd_orig + orig->desc_size) ||
	    ((uintptr_t)((uint8_t *) mrd_out + mrd_size) >
	     (uintptr_t)((uint8_t *) out + out_obj->desc_size))) {
		ERROR("%s: Invalid mrd structure.\n", __func__);
		return false;
	}

	/* Copy the mrd descriptors directly. */
	memcpy(mrd_out, mrd_in, mrd_size);

	return true;
}

/**
 * spmc_shm_convert_mtd_to_v1_0 - Converts a given v1.1 memory object to
 *                                v1.0 memory object.
 * @out_obj:    The shared memory object to populate the v1.0 descriptor.
 * @orig:       The shared memory object containing the v1.1 descriptor.
 *
 * Return: true if the conversion is successful else false.
 */
static bool
spmc_shm_convert_mtd_to_v1_0(struct spmc_shmem_obj *out_obj,
			     struct spmc_shmem_obj *orig)
{
	struct ffa_mtd *mtd_orig = &orig->desc;
	struct ffa_mtd_v1_0 *out = (struct ffa_mtd_v1_0 *) &out_obj->desc;
	struct ffa_emad_v1_0 *emad_in;
	struct ffa_emad_v1_0 *emad_array_in;
	struct ffa_emad_v1_0 *emad_array_out;
	struct ffa_comp_mrd *mrd_in;
	struct ffa_comp_mrd *mrd_out;

	size_t mrd_in_offset;
	size_t mrd_out_offset;
	size_t emad_out_array_size;
	size_t mrd_size = 0;

	/* Populate the v1.0 descriptor format from the v1.1 struct. */
	out->sender_id = mtd_orig->sender_id;
	out->memory_region_attributes = mtd_orig->memory_region_attributes;
	out->flags = mtd_orig->flags;
	out->handle = mtd_orig->handle;
	out->tag = mtd_orig->tag;
	out->emad_count = mtd_orig->emad_count;

	/* Determine the location of the emad array in both descriptors. */
	emad_array_in = (struct ffa_emad_v1_0 *)
			((uint8_t *) mtd_orig + mtd_orig->emad_offset);
	emad_array_out = out->emad;

	/* Copy across the emad structs. */
	emad_in = emad_array_in;
	for (unsigned int i = 0U; i < out->emad_count; i++) {
		memcpy(&emad_array_out[i], emad_in,
		       sizeof(struct ffa_emad_v1_0));

		emad_in +=  mtd_orig->emad_size;
	}

	/* Place the mrd descriptors after the end of the emad descriptors. */
	emad_out_array_size = sizeof(struct ffa_emad_v1_0) * out->emad_count;

	mrd_out_offset =  (uint8_t *) out->emad - (uint8_t *) out +
			  emad_out_array_size;

	mrd_out = (struct ffa_comp_mrd *) ((uint8_t *) out + mrd_out_offset);

	mrd_in_offset = mtd_orig->emad_offset +
			(mtd_orig->emad_size * mtd_orig->emad_count);

	/* Add the size of the composite memory region descriptor. */
	mrd_size += sizeof(struct ffa_comp_mrd);

	/* Find the mrd descriptor. */
	mrd_in = (struct ffa_comp_mrd *) ((uint8_t *) mtd_orig + mrd_in_offset);

	/* Add the size of the constituent memory region descriptors. */
	mrd_size += mrd_in->address_range_count * sizeof(struct ffa_cons_mrd);

	/*
	 * Update the offset in the emads by the delta between the input and
	 * output addresses.
	 */
	emad_in = emad_array_in;

	for (unsigned int i = 0U; i < out->emad_count; i++) {
		emad_array_out[i].comp_mrd_offset = emad_in->comp_mrd_offset +
						    (mrd_out_offset -
						     mrd_in_offset);
		emad_in +=  mtd_orig->emad_size;
	}

	/* Verify that we stay within bound of the memory descriptors. */
	if ((uintptr_t)((uint8_t *) mrd_in + mrd_size) >
	     (uintptr_t)((uint8_t *) mtd_orig + orig->desc_size) ||
	    ((uintptr_t)((uint8_t *) mrd_out + mrd_size) >
	     (uintptr_t)((uint8_t *) out + out_obj->desc_size))) {
		ERROR("%s: Invalid mrd structure.\n", __func__);
		return false;
	}

	/* Copy the mrd descriptors directly. */
	memcpy(mrd_out, mrd_in, mrd_size);

	return true;
}

/**
 * spmc_populate_ffa_v1_0_descriptor - Converts a given v1.1 memory object to
 *                                     the v1.0 format and populates the
 *                                     provided buffer.
 * @dst:	    Buffer to populate v1.0 ffa_memory_region_descriptor.
 * @orig_obj:	    Object containing v1.1 ffa_memory_region_descriptor.
 * @buf_size:	    Size of the buffer to populate.
 * @offset:	    The offset of the converted descriptor to copy.
 * @copy_size:	    Will be populated with the number of bytes copied.
 * @out_desc_size:  Will be populated with the total size of the v1.0
 *                  descriptor.
 *
 * Return: 0 if conversion and population succeeded.
 * Note: This function invalidates the reference to @orig therefore
 * `spmc_shmem_obj_lookup` must be called if further usage is required.
 */
static uint32_t
spmc_populate_ffa_v1_0_descriptor(void *dst, struct spmc_shmem_obj *orig_obj,
				 size_t buf_size, size_t offset,
				 size_t *copy_size, size_t *v1_0_desc_size)
{
		struct spmc_shmem_obj *v1_0_obj;

		/* Calculate the size that the v1.0 descriptor will require. */
		*v1_0_desc_size = spmc_shm_get_v1_0_descriptor_size(
					&orig_obj->desc, orig_obj->desc_size);

		if (*v1_0_desc_size == 0) {
			ERROR("%s: cannot determine size of descriptor.\n",
			      __func__);
			return FFA_ERROR_INVALID_PARAMETER;
		}

		/* Get a new obj to store the v1.0 descriptor. */
		v1_0_obj = spmc_shmem_obj_alloc(&spmc_shmem_obj_state,
						*v1_0_desc_size);

		if (!v1_0_obj) {
			return FFA_ERROR_NO_MEMORY;
		}

		/* Perform the conversion from v1.1 to v1.0. */
		if (!spmc_shm_convert_mtd_to_v1_0(v1_0_obj, orig_obj)) {
			spmc_shmem_obj_free(&spmc_shmem_obj_state, v1_0_obj);
			return FFA_ERROR_INVALID_PARAMETER;
		}

		*copy_size = MIN(v1_0_obj->desc_size - offset, buf_size);
		memcpy(dst, (uint8_t *) &v1_0_obj->desc + offset, *copy_size);

		/*
		 * We're finished with the v1.0 descriptor for now so free it.
		 * Note that this will invalidate any references to the v1.1
		 * descriptor.
		 */
		spmc_shmem_obj_free(&spmc_shmem_obj_state, v1_0_obj);

		return 0;
}

/**
 * spmc_shmem_check_obj - Check that counts in descriptor match overall size.
 * @obj:	  Object containing ffa_memory_region_descriptor.
 * @ffa_version:  FF-A version of the provided descriptor.
 *
 * Return: 0 if object is valid, -EINVAL if constituent_memory_region_descriptor
 * offset or count is invalid.
 */
static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
				uint32_t ffa_version)
{
	uint32_t comp_mrd_offset = 0;

	if (obj->desc.emad_count == 0U) {
		WARN("%s: unsupported attribute desc count %u.\n",
		     __func__, obj->desc.emad_count);
		return -EINVAL;
	}

	for (size_t emad_num = 0; emad_num < obj->desc.emad_count; emad_num++) {
		size_t size;
		size_t count;
		size_t expected_size;
		size_t total_page_count;
		size_t emad_size;
		size_t desc_size;
		size_t header_emad_size;
		uint32_t offset;
		struct ffa_comp_mrd *comp;
		struct ffa_emad_v1_0 *emad;

		emad = spmc_shmem_obj_get_emad(&obj->desc, emad_num,
					       ffa_version, &emad_size);
		if (emad == NULL) {
			WARN("%s: invalid emad structure.\n", __func__);
			return -EINVAL;
		}

		/*
		 * Validate the calculated emad address resides within the
		 * descriptor.
		 */
		if ((uintptr_t) emad >=
		    (uintptr_t)((uint8_t *) &obj->desc + obj->desc_size)) {
			WARN("Invalid emad access.\n");
			return -EINVAL;
		}

		offset = emad->comp_mrd_offset;

		if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
			desc_size =  sizeof(struct ffa_mtd_v1_0);
		} else {
			desc_size =  sizeof(struct ffa_mtd);
		}

		header_emad_size = desc_size +
			(obj->desc.emad_count * emad_size);

		if (offset < header_emad_size) {
			WARN("%s: invalid object, offset %u < header + emad %zu\n",
			     __func__, offset, header_emad_size);
			return -EINVAL;
		}

		size = obj->desc_size;

		if (offset > size) {
			WARN("%s: invalid object, offset %u > total size %zu\n",
			     __func__, offset, obj->desc_size);
			return -EINVAL;
		}
		size -= offset;

		if (size < sizeof(struct ffa_comp_mrd)) {
			WARN("%s: invalid object, offset %u, total size %zu, no header space.\n",
			     __func__, offset, obj->desc_size);
			return -EINVAL;
		}
		size -= sizeof(struct ffa_comp_mrd);

		count = size / sizeof(struct ffa_cons_mrd);

		comp = spmc_shmem_obj_get_comp_mrd(obj, ffa_version);

		if (comp == NULL) {
			WARN("%s: invalid comp_mrd offset\n", __func__);
			return -EINVAL;
		}

		if (comp->address_range_count != count) {
			WARN("%s: invalid object, desc count %u != %zu\n",
			     __func__, comp->address_range_count, count);
			return -EINVAL;
		}

		expected_size = offset + sizeof(*comp) +
				spmc_shmem_obj_ffa_constituent_size(obj,
								    ffa_version);

		if (expected_size != obj->desc_size) {
			WARN("%s: invalid object, computed size %zu != size %zu\n",
			       __func__, expected_size, obj->desc_size);
			return -EINVAL;
		}

		if (obj->desc_filled < obj->desc_size) {
			/*
			 * The whole descriptor has not yet been received.
			 * Skip final checks.
			 */
			return 0;
		}

		/*
		 * The offset provided to the composite memory region descriptor
		 * should be consistent across endpoint descriptors. Store the
		 * first entry and compare against subsequent entries.
		 */
		if (comp_mrd_offset == 0) {
			comp_mrd_offset = offset;
		} else {
			if (comp_mrd_offset != offset) {
				ERROR("%s: mismatching offsets provided, %u != %u\n",
				       __func__, offset, comp_mrd_offset);
				return -EINVAL;
			}
		}

		total_page_count = 0;

		for (size_t i = 0; i < count; i++) {
			total_page_count +=
				comp->address_range_array[i].page_count;
		}
		if (comp->total_page_count != total_page_count) {
			WARN("%s: invalid object, desc total_page_count %u != %zu\n",
			     __func__, comp->total_page_count,
			total_page_count);
			return -EINVAL;
		}
	}
	return 0;
}

/**
 * spmc_shmem_check_state_obj - Check if the descriptor describes memory
 *				regions that are currently involved with an
 *				existing memory transactions. This implies that
 *				the memory is not in a valid state for lending.
 * @obj:    Object containing ffa_memory_region_descriptor.
 *
 * Return: 0 if object is valid, -EINVAL if invalid memory state.
 */
static int spmc_shmem_check_state_obj(struct spmc_shmem_obj *obj,
				      uint32_t ffa_version)
{
	size_t obj_offset = 0;
	struct spmc_shmem_obj *inflight_obj;

	struct ffa_comp_mrd *other_mrd;
	struct ffa_comp_mrd *requested_mrd = spmc_shmem_obj_get_comp_mrd(obj,
								  ffa_version);

	if (requested_mrd == NULL) {
		return -EINVAL;
	}

	inflight_obj = spmc_shmem_obj_get_next(&spmc_shmem_obj_state,
					       &obj_offset);

	while (inflight_obj != NULL) {
		/*
		 * Don't compare the transaction to itself or to partially
		 * transmitted descriptors.
		 */
		if ((obj->desc.handle != inflight_obj->desc.handle) &&
		    (obj->desc_size == obj->desc_filled)) {
			other_mrd = spmc_shmem_obj_get_comp_mrd(inflight_obj,
							  FFA_VERSION_COMPILED);
			if (other_mrd == NULL) {
				return -EINVAL;
			}
			if (overlapping_memory_regions(requested_mrd,
						       other_mrd)) {
				return -EINVAL;
			}
		}

		inflight_obj = spmc_shmem_obj_get_next(&spmc_shmem_obj_state,
						       &obj_offset);
	}
	return 0;
}

static long spmc_ffa_fill_desc(struct mailbox *mbox,
			       struct spmc_shmem_obj *obj,
			       uint32_t fragment_length,
			       ffa_mtd_flag32_t mtd_flag,
			       uint32_t ffa_version,
			       void *smc_handle)
{
	int ret;
	size_t emad_size;
	uint32_t handle_low;
	uint32_t handle_high;
	struct ffa_emad_v1_0 *emad;
	struct ffa_emad_v1_0 *other_emad;

	if (mbox->rxtx_page_count == 0U) {
		WARN("%s: buffer pair not registered.\n", __func__);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_arg;
	}

	if (fragment_length > mbox->rxtx_page_count * PAGE_SIZE_4KB) {
		WARN("%s: bad fragment size %u > %u buffer size\n", __func__,
		     fragment_length, mbox->rxtx_page_count * PAGE_SIZE_4KB);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_arg;
	}

	memcpy((uint8_t *)&obj->desc + obj->desc_filled,
	       (uint8_t *) mbox->tx_buffer, fragment_length);

	if (fragment_length > obj->desc_size - obj->desc_filled) {
		WARN("%s: bad fragment size %u > %zu remaining\n", __func__,
		     fragment_length, obj->desc_size - obj->desc_filled);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_arg;
	}

	/* Ensure that the sender ID resides in the normal world. */
	if (ffa_is_secure_world_id(obj->desc.sender_id)) {
		WARN("%s: Invalid sender ID 0x%x.\n",
		     __func__, obj->desc.sender_id);
		ret = FFA_ERROR_DENIED;
		goto err_arg;
	}

	/* Ensure the NS bit is set to 0. */
	if ((obj->desc.memory_region_attributes & FFA_MEM_ATTR_NS_BIT) != 0U) {
		WARN("%s: NS mem attributes flags MBZ.\n", __func__);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_arg;
	}

	/*
	 * We don't currently support any optional flags so ensure none are
	 * requested.
	 */
	if (obj->desc.flags != 0U && mtd_flag != 0U &&
	    (obj->desc.flags != mtd_flag)) {
		WARN("%s: invalid memory transaction flags %u != %u\n",
		     __func__, obj->desc.flags, mtd_flag);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_arg;
	}

	if (obj->desc_filled == 0U) {
		/* First fragment, descriptor header has been copied */
		obj->desc.handle = spmc_shmem_obj_state.next_handle++;
		obj->desc.flags |= mtd_flag;
	}

	obj->desc_filled += fragment_length;
	ret = spmc_shmem_check_obj(obj, ffa_version);
	if (ret != 0) {
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_bad_desc;
	}

	handle_low = (uint32_t)obj->desc.handle;
	handle_high = obj->desc.handle >> 32;

	if (obj->desc_filled != obj->desc_size) {
		SMC_RET8(smc_handle, FFA_MEM_FRAG_RX, handle_low,
			 handle_high, obj->desc_filled,
			 (uint32_t)obj->desc.sender_id << 16, 0, 0, 0);
	}

	/* The full descriptor has been received, perform any final checks. */

	/*
	 * If a partition ID resides in the secure world validate that the
	 * partition ID is for a known partition. Ignore any partition ID
	 * belonging to the normal world as it is assumed the Hypervisor will
	 * have validated these.
	 */
	for (size_t i = 0; i < obj->desc.emad_count; i++) {
		emad = spmc_shmem_obj_get_emad(&obj->desc, i, ffa_version,
					       &emad_size);
		if (emad == NULL) {
			ret = FFA_ERROR_INVALID_PARAMETER;
			goto err_bad_desc;
		}

		ffa_endpoint_id16_t ep_id = emad->mapd.endpoint_id;

		if (ffa_is_secure_world_id(ep_id)) {
			if (spmc_get_sp_ctx(ep_id) == NULL) {
				WARN("%s: Invalid receiver id 0x%x\n",
				     __func__, ep_id);
				ret = FFA_ERROR_INVALID_PARAMETER;
				goto err_bad_desc;
			}
		}
	}

	/* Ensure partition IDs are not duplicated. */
	for (size_t i = 0; i < obj->desc.emad_count; i++) {
		emad = spmc_shmem_obj_get_emad(&obj->desc, i, ffa_version,
					       &emad_size);
		if (emad == NULL) {
			ret = FFA_ERROR_INVALID_PARAMETER;
			goto err_bad_desc;
		}
		for (size_t j = i + 1; j < obj->desc.emad_count; j++) {
			other_emad = spmc_shmem_obj_get_emad(&obj->desc, j,
							     ffa_version,
							     &emad_size);
			if (other_emad == NULL) {
				ret = FFA_ERROR_INVALID_PARAMETER;
				goto err_bad_desc;
			}

			if (emad->mapd.endpoint_id ==
				other_emad->mapd.endpoint_id) {
				WARN("%s: Duplicated endpoint id 0x%x\n",
				     __func__, emad->mapd.endpoint_id);
				ret = FFA_ERROR_INVALID_PARAMETER;
				goto err_bad_desc;
			}
		}
	}

	ret = spmc_shmem_check_state_obj(obj, ffa_version);
	if (ret) {
		ERROR("%s: invalid memory region descriptor.\n", __func__);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_bad_desc;
	}

	/*
	 * Everything checks out, if the sender was using FF-A v1.0, convert
	 * the descriptor format to use the v1.1 structures.
	 */
	if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
		struct spmc_shmem_obj *v1_1_obj;
		uint64_t mem_handle;

		/* Calculate the size that the v1.1 descriptor will required. */
		size_t v1_1_desc_size =
		    spmc_shm_get_v1_1_descriptor_size((void *) &obj->desc,
						      fragment_length);

		if (v1_1_desc_size == 0U) {
			ERROR("%s: cannot determine size of descriptor.\n",
			      __func__);
			goto err_arg;
		}

		/* Get a new obj to store the v1.1 descriptor. */
		v1_1_obj =
		    spmc_shmem_obj_alloc(&spmc_shmem_obj_state, v1_1_desc_size);

		if (!obj) {
			ret = FFA_ERROR_NO_MEMORY;
			goto err_arg;
		}

		/* Perform the conversion from v1.0 to v1.1. */
		v1_1_obj->desc_size = v1_1_desc_size;
		v1_1_obj->desc_filled = v1_1_desc_size;
		if (!spmc_shm_convert_shmem_obj_from_v1_0(v1_1_obj, obj)) {
			ERROR("%s: Could not convert mtd!\n", __func__);
			spmc_shmem_obj_free(&spmc_shmem_obj_state, v1_1_obj);
			goto err_arg;
		}

		/*
		 * We're finished with the v1.0 descriptor so free it
		 * and continue our checks with the new v1.1 descriptor.
		 */
		mem_handle = obj->desc.handle;
		spmc_shmem_obj_free(&spmc_shmem_obj_state, obj);
		obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, mem_handle);
		if (obj == NULL) {
			ERROR("%s: Failed to find converted descriptor.\n",
			     __func__);
			ret = FFA_ERROR_INVALID_PARAMETER;
			return spmc_ffa_error_return(smc_handle, ret);
		}
	}

	/* Allow for platform specific operations to be performed. */
	ret = plat_spmc_shmem_begin(&obj->desc);
	if (ret != 0) {
		goto err_arg;
	}

	SMC_RET8(smc_handle, FFA_SUCCESS_SMC32, 0, handle_low, handle_high, 0,
		 0, 0, 0);

err_bad_desc:
err_arg:
	spmc_shmem_obj_free(&spmc_shmem_obj_state, obj);
	return spmc_ffa_error_return(smc_handle, ret);
}

/**
 * spmc_ffa_mem_send - FFA_MEM_SHARE/LEND implementation.
 * @client:             Client state.
 * @total_length:       Total length of shared memory descriptor.
 * @fragment_length:    Length of fragment of shared memory descriptor passed in
 *                      this call.
 * @address:            Not supported, must be 0.
 * @page_count:         Not supported, must be 0.
 * @smc_handle:         Handle passed to smc call. Used to return
 *                      FFA_MEM_FRAG_RX or SMC_FC_FFA_SUCCESS.
 *
 * Implements a subset of the FF-A FFA_MEM_SHARE and FFA_MEM_LEND calls needed
 * to share or lend memory from non-secure os to secure os (with no stream
 * endpoints).
 *
 * Return: 0 on success, error code on failure.
 */
long spmc_ffa_mem_send(uint32_t smc_fid,
			bool secure_origin,
			uint64_t total_length,
			uint32_t fragment_length,
			uint64_t address,
			uint32_t page_count,
			void *cookie,
			void *handle,
			uint64_t flags)

{
	long ret;
	struct spmc_shmem_obj *obj;
	struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);
	ffa_mtd_flag32_t mtd_flag;
	uint32_t ffa_version = get_partition_ffa_version(secure_origin);

	if (address != 0U || page_count != 0U) {
		WARN("%s: custom memory region for message not supported.\n",
		     __func__);
		return spmc_ffa_error_return(handle,
					     FFA_ERROR_INVALID_PARAMETER);
	}

	if (secure_origin) {
		WARN("%s: unsupported share direction.\n", __func__);
		return spmc_ffa_error_return(handle,
					     FFA_ERROR_INVALID_PARAMETER);
	}

	/*
	 * Check if the descriptor is smaller than the v1.0 descriptor. The
	 * descriptor cannot be smaller than this structure.
	 */
	if (fragment_length < sizeof(struct ffa_mtd_v1_0)) {
		WARN("%s: bad first fragment size %u < %zu\n",
		     __func__, fragment_length, sizeof(struct ffa_mtd_v1_0));
		return spmc_ffa_error_return(handle,
					     FFA_ERROR_INVALID_PARAMETER);
	}

	if ((smc_fid & FUNCID_NUM_MASK) == FFA_FNUM_MEM_SHARE) {
		mtd_flag = FFA_MTD_FLAG_TYPE_SHARE_MEMORY;
	} else if ((smc_fid & FUNCID_NUM_MASK) == FFA_FNUM_MEM_LEND) {
		mtd_flag = FFA_MTD_FLAG_TYPE_LEND_MEMORY;
	} else {
		WARN("%s: invalid memory management operation.\n", __func__);
		return spmc_ffa_error_return(handle,
					     FFA_ERROR_INVALID_PARAMETER);
	}

	spin_lock(&spmc_shmem_obj_state.lock);
	obj = spmc_shmem_obj_alloc(&spmc_shmem_obj_state, total_length);
	if (obj == NULL) {
		ret = FFA_ERROR_NO_MEMORY;
		goto err_unlock;
	}

	spin_lock(&mbox->lock);
	ret = spmc_ffa_fill_desc(mbox, obj, fragment_length, mtd_flag,
				 ffa_version, handle);
	spin_unlock(&mbox->lock);

	spin_unlock(&spmc_shmem_obj_state.lock);
	return ret;

err_unlock:
	spin_unlock(&spmc_shmem_obj_state.lock);
	return spmc_ffa_error_return(handle, ret);
}

/**
 * spmc_ffa_mem_frag_tx - FFA_MEM_FRAG_TX implementation.
 * @client:             Client state.
 * @handle_low:         Handle_low value returned from FFA_MEM_FRAG_RX.
 * @handle_high:        Handle_high value returned from FFA_MEM_FRAG_RX.
 * @fragment_length:    Length of fragments transmitted.
 * @sender_id:          Vmid of sender in bits [31:16]
 * @smc_handle:         Handle passed to smc call. Used to return
 *                      FFA_MEM_FRAG_RX or SMC_FC_FFA_SUCCESS.
 *
 * Return: @smc_handle on success, error code on failure.
 */
long spmc_ffa_mem_frag_tx(uint32_t smc_fid,
			  bool secure_origin,
			  uint64_t handle_low,
			  uint64_t handle_high,
			  uint32_t fragment_length,
			  uint32_t sender_id,
			  void *cookie,
			  void *handle,
			  uint64_t flags)
{
	long ret;
	uint32_t desc_sender_id;
	uint32_t ffa_version = get_partition_ffa_version(secure_origin);
	struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);

	struct spmc_shmem_obj *obj;
	uint64_t mem_handle = handle_low | (((uint64_t)handle_high) << 32);

	spin_lock(&spmc_shmem_obj_state.lock);

	obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, mem_handle);
	if (obj == NULL) {
		WARN("%s: invalid handle, 0x%lx, not a valid handle.\n",
		     __func__, mem_handle);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock;
	}

	desc_sender_id = (uint32_t)obj->desc.sender_id << 16;
	if (sender_id != desc_sender_id) {
		WARN("%s: invalid sender_id 0x%x != 0x%x\n", __func__,
		     sender_id, desc_sender_id);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock;
	}

	if (obj->desc_filled == obj->desc_size) {
		WARN("%s: object desc already filled, %zu\n", __func__,
		     obj->desc_filled);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock;
	}

	spin_lock(&mbox->lock);
	ret = spmc_ffa_fill_desc(mbox, obj, fragment_length, 0, ffa_version,
				 handle);
	spin_unlock(&mbox->lock);

	spin_unlock(&spmc_shmem_obj_state.lock);
	return ret;

err_unlock:
	spin_unlock(&spmc_shmem_obj_state.lock);
	return spmc_ffa_error_return(handle, ret);
}

/**
 * spmc_ffa_mem_retrieve_set_ns_bit - Set the NS bit in the response descriptor
 *				      if the caller implements a version greater
 *				      than FF-A 1.0 or if they have requested
 *				      the functionality.
 *				      TODO: We are assuming that the caller is
 *				      an SP. To support retrieval from the
 *				      normal world this function will need to be
 *				      expanded accordingly.
 * @resp:       Descriptor populated in callers RX buffer.
 * @sp_ctx:     Context of the calling SP.
 */
void spmc_ffa_mem_retrieve_set_ns_bit(struct ffa_mtd *resp,
			 struct secure_partition_desc *sp_ctx)
{
	if (sp_ctx->ffa_version > MAKE_FFA_VERSION(1, 0) ||
	    sp_ctx->ns_bit_requested) {
		/*
		 * Currently memory senders must reside in the normal
		 * world, and we do not have the functionlaity to change
		 * the state of memory dynamically. Therefore we can always set
		 * the NS bit to 1.
		 */
		resp->memory_region_attributes |= FFA_MEM_ATTR_NS_BIT;
	}
}

/**
 * spmc_ffa_mem_retrieve_req - FFA_MEM_RETRIEVE_REQ implementation.
 * @smc_fid:            FID of SMC
 * @total_length:       Total length of retrieve request descriptor if this is
 *                      the first call. Otherwise (unsupported) must be 0.
 * @fragment_length:    Length of fragment of retrieve request descriptor passed
 *                      in this call. Only @fragment_length == @length is
 *                      supported by this implementation.
 * @address:            Not supported, must be 0.
 * @page_count:         Not supported, must be 0.
 * @smc_handle:         Handle passed to smc call. Used to return
 *                      FFA_MEM_RETRIEVE_RESP.
 *
 * Implements a subset of the FF-A FFA_MEM_RETRIEVE_REQ call.
 * Used by secure os to retrieve memory already shared by non-secure os.
 * If the data does not fit in a single FFA_MEM_RETRIEVE_RESP message,
 * the client must call FFA_MEM_FRAG_RX until the full response has been
 * received.
 *
 * Return: @handle on success, error code on failure.
 */
long
spmc_ffa_mem_retrieve_req(uint32_t smc_fid,
			  bool secure_origin,
			  uint32_t total_length,
			  uint32_t fragment_length,
			  uint64_t address,
			  uint32_t page_count,
			  void *cookie,
			  void *handle,
			  uint64_t flags)
{
	int ret;
	size_t buf_size;
	size_t copy_size = 0;
	size_t min_desc_size;
	size_t out_desc_size = 0;

	/*
	 * Currently we are only accessing fields that are the same in both the
	 * v1.0 and v1.1 mtd struct therefore we can use a v1.1 struct directly
	 * here. We only need validate against the appropriate struct size.
	 */
	struct ffa_mtd *resp;
	const struct ffa_mtd *req;
	struct spmc_shmem_obj *obj = NULL;
	struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);
	uint32_t ffa_version = get_partition_ffa_version(secure_origin);
	struct secure_partition_desc *sp_ctx = spmc_get_current_sp_ctx();

	if (!secure_origin) {
		WARN("%s: unsupported retrieve req direction.\n", __func__);
		return spmc_ffa_error_return(handle,
					     FFA_ERROR_INVALID_PARAMETER);
	}

	if (address != 0U || page_count != 0U) {
		WARN("%s: custom memory region not supported.\n", __func__);
		return spmc_ffa_error_return(handle,
					     FFA_ERROR_INVALID_PARAMETER);
	}

	spin_lock(&mbox->lock);

	req = mbox->tx_buffer;
	resp = mbox->rx_buffer;
	buf_size = mbox->rxtx_page_count * FFA_PAGE_SIZE;

	if (mbox->rxtx_page_count == 0U) {
		WARN("%s: buffer pair not registered.\n", __func__);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_mailbox;
	}

	if (mbox->state != MAILBOX_STATE_EMPTY) {
		WARN("%s: RX Buffer is full! %d\n", __func__, mbox->state);
		ret = FFA_ERROR_DENIED;
		goto err_unlock_mailbox;
	}

	if (fragment_length != total_length) {
		WARN("%s: fragmented retrieve request not supported.\n",
		     __func__);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_mailbox;
	}

	if (req->emad_count == 0U) {
		WARN("%s: unsupported attribute desc count %u.\n",
		     __func__, obj->desc.emad_count);
		return -EINVAL;
	}

	/* Determine the appropriate minimum descriptor size. */
	if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
		min_desc_size = sizeof(struct ffa_mtd_v1_0);
	} else {
		min_desc_size = sizeof(struct ffa_mtd);
	}
	if (total_length < min_desc_size) {
		WARN("%s: invalid length %u < %zu\n", __func__, total_length,
		     min_desc_size);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_mailbox;
	}

	spin_lock(&spmc_shmem_obj_state.lock);

	obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, req->handle);
	if (obj == NULL) {
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_all;
	}

	if (obj->desc_filled != obj->desc_size) {
		WARN("%s: incomplete object desc filled %zu < size %zu\n",
		     __func__, obj->desc_filled, obj->desc_size);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_all;
	}

	if (req->emad_count != 0U && req->sender_id != obj->desc.sender_id) {
		WARN("%s: wrong sender id 0x%x != 0x%x\n",
		     __func__, req->sender_id, obj->desc.sender_id);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_all;
	}

	if (req->emad_count != 0U && req->tag != obj->desc.tag) {
		WARN("%s: wrong tag 0x%lx != 0x%lx\n",
		     __func__, req->tag, obj->desc.tag);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_all;
	}

	if (req->emad_count != 0U && req->emad_count != obj->desc.emad_count) {
		WARN("%s: mistmatch of endpoint counts %u != %u\n",
		     __func__, req->emad_count, obj->desc.emad_count);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_all;
	}

	/* Ensure the NS bit is set to 0 in the request. */
	if ((req->memory_region_attributes & FFA_MEM_ATTR_NS_BIT) != 0U) {
		WARN("%s: NS mem attributes flags MBZ.\n", __func__);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_all;
	}

	if (req->flags != 0U) {
		if ((req->flags & FFA_MTD_FLAG_TYPE_MASK) !=
		    (obj->desc.flags & FFA_MTD_FLAG_TYPE_MASK)) {
			/*
			 * If the retrieve request specifies the memory
			 * transaction ensure it matches what we expect.
			 */
			WARN("%s: wrong mem transaction flags %x != %x\n",
			__func__, req->flags, obj->desc.flags);
			ret = FFA_ERROR_INVALID_PARAMETER;
			goto err_unlock_all;
		}

		if (req->flags != FFA_MTD_FLAG_TYPE_SHARE_MEMORY &&
		    req->flags != FFA_MTD_FLAG_TYPE_LEND_MEMORY) {
			/*
			 * Current implementation does not support donate and
			 * it supports no other flags.
			 */
			WARN("%s: invalid flags 0x%x\n", __func__, req->flags);
			ret = FFA_ERROR_INVALID_PARAMETER;
			goto err_unlock_all;
		}
	}

	/* Validate that the provided emad offset and structure is valid.*/
	for (size_t i = 0; i < req->emad_count; i++) {
		size_t emad_size;
		struct ffa_emad_v1_0 *emad;

		emad = spmc_shmem_obj_get_emad(req, i, ffa_version,
					       &emad_size);
		if (emad == NULL) {
			WARN("%s: invalid emad structure.\n", __func__);
			ret = FFA_ERROR_INVALID_PARAMETER;
			goto err_unlock_all;
		}

		if ((uintptr_t) emad >= (uintptr_t)
					((uint8_t *) req + total_length)) {
			WARN("Invalid emad access.\n");
			ret = FFA_ERROR_INVALID_PARAMETER;
			goto err_unlock_all;
		}
	}

	/*
	 * Validate all the endpoints match in the case of multiple
	 * borrowers. We don't mandate that the order of the borrowers
	 * must match in the descriptors therefore check to see if the
	 * endpoints match in any order.
	 */
	for (size_t i = 0; i < req->emad_count; i++) {
		bool found = false;
		size_t emad_size;
		struct ffa_emad_v1_0 *emad;
		struct ffa_emad_v1_0 *other_emad;

		emad = spmc_shmem_obj_get_emad(req, i, ffa_version,
					       &emad_size);
		if (emad == NULL) {
			ret = FFA_ERROR_INVALID_PARAMETER;
			goto err_unlock_all;
		}

		for (size_t j = 0; j < obj->desc.emad_count; j++) {
			other_emad = spmc_shmem_obj_get_emad(
					&obj->desc, j, MAKE_FFA_VERSION(1, 1),
					&emad_size);

			if (other_emad == NULL) {
				ret = FFA_ERROR_INVALID_PARAMETER;
				goto err_unlock_all;
			}

			if (req->emad_count &&
			    emad->mapd.endpoint_id ==
			    other_emad->mapd.endpoint_id) {
				found = true;
				break;
			}
		}

		if (!found) {
			WARN("%s: invalid receiver id (0x%x).\n",
			     __func__, emad->mapd.endpoint_id);
			ret = FFA_ERROR_INVALID_PARAMETER;
			goto err_unlock_all;
		}
	}

	mbox->state = MAILBOX_STATE_FULL;

	if (req->emad_count != 0U) {
		obj->in_use++;
	}

	/*
	 * If the caller is v1.0 convert the descriptor, otherwise copy
	 * directly.
	 */
	if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
		ret = spmc_populate_ffa_v1_0_descriptor(resp, obj, buf_size, 0,
							&copy_size,
							&out_desc_size);
		if (ret != 0U) {
			ERROR("%s: Failed to process descriptor.\n", __func__);
			goto err_unlock_all;
		}
	} else {
		copy_size = MIN(obj->desc_size, buf_size);
		out_desc_size = obj->desc_size;

		memcpy(resp, &obj->desc, copy_size);
	}

	/* Set the NS bit in the response if applicable. */
	spmc_ffa_mem_retrieve_set_ns_bit(resp, sp_ctx);

	spin_unlock(&spmc_shmem_obj_state.lock);
	spin_unlock(&mbox->lock);

	SMC_RET8(handle, FFA_MEM_RETRIEVE_RESP, out_desc_size,
		 copy_size, 0, 0, 0, 0, 0);

err_unlock_all:
	spin_unlock(&spmc_shmem_obj_state.lock);
err_unlock_mailbox:
	spin_unlock(&mbox->lock);
	return spmc_ffa_error_return(handle, ret);
}

/**
 * spmc_ffa_mem_frag_rx - FFA_MEM_FRAG_RX implementation.
 * @client:             Client state.
 * @handle_low:         Handle passed to &FFA_MEM_RETRIEVE_REQ. Bit[31:0].
 * @handle_high:        Handle passed to &FFA_MEM_RETRIEVE_REQ. Bit[63:32].
 * @fragment_offset:    Byte offset in descriptor to resume at.
 * @sender_id:          Bit[31:16]: Endpoint id of sender if client is a
 *                      hypervisor. 0 otherwise.
 * @smc_handle:         Handle passed to smc call. Used to return
 *                      FFA_MEM_FRAG_TX.
 *
 * Return: @smc_handle on success, error code on failure.
 */
long spmc_ffa_mem_frag_rx(uint32_t smc_fid,
			  bool secure_origin,
			  uint32_t handle_low,
			  uint32_t handle_high,
			  uint32_t fragment_offset,
			  uint32_t sender_id,
			  void *cookie,
			  void *handle,
			  uint64_t flags)
{
	int ret;
	void *src;
	size_t buf_size;
	size_t copy_size;
	size_t full_copy_size;
	uint32_t desc_sender_id;
	struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);
	uint64_t mem_handle = handle_low | (((uint64_t)handle_high) << 32);
	struct spmc_shmem_obj *obj;
	uint32_t ffa_version = get_partition_ffa_version(secure_origin);

	if (!secure_origin) {
		WARN("%s: can only be called from swld.\n",
		     __func__);
		return spmc_ffa_error_return(handle,
					     FFA_ERROR_INVALID_PARAMETER);
	}

	spin_lock(&spmc_shmem_obj_state.lock);

	obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, mem_handle);
	if (obj == NULL) {
		WARN("%s: invalid handle, 0x%lx, not a valid handle.\n",
		     __func__, mem_handle);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_shmem;
	}

	desc_sender_id = (uint32_t)obj->desc.sender_id << 16;
	if (sender_id != 0U && sender_id != desc_sender_id) {
		WARN("%s: invalid sender_id 0x%x != 0x%x\n", __func__,
		     sender_id, desc_sender_id);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_shmem;
	}

	if (fragment_offset >= obj->desc_size) {
		WARN("%s: invalid fragment_offset 0x%x >= 0x%zx\n",
		     __func__, fragment_offset, obj->desc_size);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_shmem;
	}

	spin_lock(&mbox->lock);

	if (mbox->rxtx_page_count == 0U) {
		WARN("%s: buffer pair not registered.\n", __func__);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_all;
	}

	if (mbox->state != MAILBOX_STATE_EMPTY) {
		WARN("%s: RX Buffer is full!\n", __func__);
		ret = FFA_ERROR_DENIED;
		goto err_unlock_all;
	}

	buf_size = mbox->rxtx_page_count * FFA_PAGE_SIZE;

	mbox->state = MAILBOX_STATE_FULL;

	/*
	 * If the caller is v1.0 convert the descriptor, otherwise copy
	 * directly.
	 */
	if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
		size_t out_desc_size;

		ret = spmc_populate_ffa_v1_0_descriptor(mbox->rx_buffer, obj,
							buf_size,
							fragment_offset,
							&copy_size,
							&out_desc_size);
		if (ret != 0U) {
			ERROR("%s: Failed to process descriptor.\n", __func__);
			goto err_unlock_all;
		}
	} else {
		full_copy_size = obj->desc_size - fragment_offset;
		copy_size = MIN(full_copy_size, buf_size);

		src = &obj->desc;

		memcpy(mbox->rx_buffer, src + fragment_offset, copy_size);
	}

	spin_unlock(&mbox->lock);
	spin_unlock(&spmc_shmem_obj_state.lock);

	SMC_RET8(handle, FFA_MEM_FRAG_TX, handle_low, handle_high,
		 copy_size, sender_id, 0, 0, 0);

err_unlock_all:
	spin_unlock(&mbox->lock);
err_unlock_shmem:
	spin_unlock(&spmc_shmem_obj_state.lock);
	return spmc_ffa_error_return(handle, ret);
}

/**
 * spmc_ffa_mem_relinquish - FFA_MEM_RELINQUISH implementation.
 * @client:             Client state.
 *
 * Implements a subset of the FF-A FFA_MEM_RELINQUISH call.
 * Used by secure os release previously shared memory to non-secure os.
 *
 * The handle to release must be in the client's (secure os's) transmit buffer.
 *
 * Return: 0 on success, error code on failure.
 */
int spmc_ffa_mem_relinquish(uint32_t smc_fid,
			    bool secure_origin,
			    uint32_t handle_low,
			    uint32_t handle_high,
			    uint32_t fragment_offset,
			    uint32_t sender_id,
			    void *cookie,
			    void *handle,
			    uint64_t flags)
{
	int ret;
	struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);
	struct spmc_shmem_obj *obj;
	const struct ffa_mem_relinquish_descriptor *req;

	if (!secure_origin) {
		WARN("%s: unsupported relinquish direction.\n", __func__);
		return spmc_ffa_error_return(handle,
					     FFA_ERROR_INVALID_PARAMETER);
	}

	spin_lock(&mbox->lock);

	if (mbox->rxtx_page_count == 0U) {
		WARN("%s: buffer pair not registered.\n", __func__);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_mailbox;
	}

	req = mbox->tx_buffer;

	if (req->flags != 0U) {
		WARN("%s: unsupported flags 0x%x\n", __func__, req->flags);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_mailbox;
	}

	if (req->endpoint_count == 0) {
		WARN("%s: endpoint count cannot be 0.\n", __func__);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_mailbox;
	}

	spin_lock(&spmc_shmem_obj_state.lock);

	obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, req->handle);
	if (obj == NULL) {
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_all;
	}

	if (obj->desc.emad_count != req->endpoint_count) {
		WARN("%s: mismatch of endpoint count %u != %u\n", __func__,
		     obj->desc.emad_count, req->endpoint_count);
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_all;
	}

	/* Validate requested endpoint IDs match descriptor. */
	for (size_t i = 0; i < req->endpoint_count; i++) {
		bool found = false;
		size_t emad_size;
		struct ffa_emad_v1_0 *emad;

		for (unsigned int j = 0; j < obj->desc.emad_count; j++) {
			emad = spmc_shmem_obj_get_emad(&obj->desc, j,
							MAKE_FFA_VERSION(1, 1),
							&emad_size);
			if (req->endpoint_array[i] ==
			    emad->mapd.endpoint_id) {
				found = true;
				break;
			}
		}

		if (!found) {
			WARN("%s: Invalid endpoint ID (0x%x).\n",
			     __func__, req->endpoint_array[i]);
			ret = FFA_ERROR_INVALID_PARAMETER;
			goto err_unlock_all;
		}
	}

	if (obj->in_use == 0U) {
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock_all;
	}
	obj->in_use--;

	spin_unlock(&spmc_shmem_obj_state.lock);
	spin_unlock(&mbox->lock);

	SMC_RET1(handle, FFA_SUCCESS_SMC32);

err_unlock_all:
	spin_unlock(&spmc_shmem_obj_state.lock);
err_unlock_mailbox:
	spin_unlock(&mbox->lock);
	return spmc_ffa_error_return(handle, ret);
}

/**
 * spmc_ffa_mem_reclaim - FFA_MEM_RECLAIM implementation.
 * @client:         Client state.
 * @handle_low:     Unique handle of shared memory object to reclaim. Bit[31:0].
 * @handle_high:    Unique handle of shared memory object to reclaim.
 *                  Bit[63:32].
 * @flags:          Unsupported, ignored.
 *
 * Implements a subset of the FF-A FFA_MEM_RECLAIM call.
 * Used by non-secure os reclaim memory previously shared with secure os.
 *
 * Return: 0 on success, error code on failure.
 */
int spmc_ffa_mem_reclaim(uint32_t smc_fid,
			 bool secure_origin,
			 uint32_t handle_low,
			 uint32_t handle_high,
			 uint32_t mem_flags,
			 uint64_t x4,
			 void *cookie,
			 void *handle,
			 uint64_t flags)
{
	int ret;
	struct spmc_shmem_obj *obj;
	uint64_t mem_handle = handle_low | (((uint64_t)handle_high) << 32);

	if (secure_origin) {
		WARN("%s: unsupported reclaim direction.\n", __func__);
		return spmc_ffa_error_return(handle,
					     FFA_ERROR_INVALID_PARAMETER);
	}

	if (mem_flags != 0U) {
		WARN("%s: unsupported flags 0x%x\n", __func__, mem_flags);
		return spmc_ffa_error_return(handle,
					     FFA_ERROR_INVALID_PARAMETER);
	}

	spin_lock(&spmc_shmem_obj_state.lock);

	obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, mem_handle);
	if (obj == NULL) {
		ret = FFA_ERROR_INVALID_PARAMETER;
		goto err_unlock;
	}
	if (obj->in_use != 0U) {
		ret = FFA_ERROR_DENIED;
		goto err_unlock;
	}

	/* Allow for platform specific operations to be performed. */
	ret = plat_spmc_shmem_reclaim(&obj->desc);
	if (ret != 0) {
		goto err_unlock;
	}

	spmc_shmem_obj_free(&spmc_shmem_obj_state, obj);
	spin_unlock(&spmc_shmem_obj_state.lock);

	SMC_RET1(handle, FFA_SUCCESS_SMC32);

err_unlock:
	spin_unlock(&spmc_shmem_obj_state.lock);
	return spmc_ffa_error_return(handle, ret);
}
