/*
 * Copyright (c) 2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * ICBMsg backend.
 *
 * This is an IPC service backend that dynamically allocates buffers for data storage
 * and uses ICMsg to send references to them.
 *
 * Shared memory organization
 * --------------------------
 *
 * Single channel (RX or TX) of the shared memory is divided into two areas: ICMsg area
 * followed by Blocks area. ICMsg is used to send and receive short 3-byte messages.
 * Blocks area is evenly divided into aligned blocks. Blocks are used to allocate
 * buffers containing actual data. Data buffers can span multiple blocks. The first block
 * starts with the size of the following data.
 *
 *  +------------+-------------+
 *  | ICMsg area | Blocks area |
 *  +------------+-------------+
 *       _______/               \_________________________________________
 *      /                                                                 \
 *      +-----------+-----------+-----------+-----------+-   -+-----------+
 *      |  Block 0  |  Block 1  |  Block 2  |  Block 3  | ... | Block N-1 |
 *      +-----------+-----------+-----------+-----------+-   -+-----------+
 *            _____/                                     \_____
 *           /                                                 \
 *           +------+--------------------------------+---------+
 *           | size | data_buffer[size] ...          | padding |
 *           +------+--------------------------------+---------+
 *
 * The sender holds information about reserved blocks using bitarray and it is responsible
 * for allocating and releasing the blocks. The receiver just tells the sender that it
 * does not need a specific buffer anymore.
 *
 * Control messages
 * ----------------
 *
 * ICMsg is used to send and receive small 3-byte control messages.
 *
 *  - Send data
 *    | MSG_DATA | endpoint address | block index |
 *    This message is used to send data buffer to specific endpoint.
 *
 *  - Release data
 *    | MSG_RELEASE_DATA | 0 | block index |
 *    This message is a response to the "Send data" message and it is used to inform that
 *    specific buffer is not used anymore and can be released. Endpoint addresses does
 *    not matter here, so it is zero.
 *
 *  - Bound endpoint
 *    | MSG_BOUND | endpoint address | block index |
 *    This message starts the bounding of the endpoint. The buffer contains a
 *    null-terminated endpoint name.
 *
 *  - Release bound endpoint
 *    | MSG_RELEASE_BOUND | endpoint address | block index |
 *    This message is a response to the "Bound endpoint" message and it is used to inform
 *    that a specific buffer (starting at "block index") is not used anymore and
 *    a the endpoint is bounded and can now receive a data.
 *
 * Bounding endpoints
 * ------------------
 *
 * When ICMsg is bounded and user registers an endpoint on initiator side, the backend
 * sends "Bound endpoint". Endpoint address is assigned by the initiator. When follower
 * gets the message and user on follower side also registered the same endpoint,
 * the backend calls "bound" callback and sends back "Release bound endpoint".
 * The follower saves the endpoint address. The follower's endpoint is ready to send
 * and receive data. When the initiator gets "Release bound endpoint" message or any
 * data messages, it calls bound endpoint and it is ready to send data.
 */

#include <string.h>

#include <zephyr/logging/log.h>
#include <zephyr/device.h>
#include <zephyr/sys/bitarray.h>
#include <zephyr/ipc/icmsg.h>
#include <zephyr/ipc/ipc_service_backend.h>
#include <zephyr/cache.h>

LOG_MODULE_REGISTER(ipc_icbmsg,
		    CONFIG_IPC_SERVICE_BACKEND_ICBMSG_LOG_LEVEL);

#define DT_DRV_COMPAT zephyr_ipc_icbmsg

/** Allowed number of endpoints. */
#define NUM_EPT CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP

/** Special endpoint address indicating invalid (or empty) entry. */
#define EPT_ADDR_INVALID 0xFF

/** Special value for empty entry in bound message waiting table. */
#define WAITING_BOUND_MSG_EMPTY 0xFFFF

/** Size of the header (size field) of the block. */
#define BLOCK_HEADER_SIZE (sizeof(struct block_header))

/** Flag indicating that ICMsg was bounded for this instance. */
#define CONTROL_BOUNDED BIT(31)

/** Registered endpoints count mask in flags. */
#define FLAG_EPT_COUNT_MASK 0xFFFF

enum msg_type {
	MSG_DATA = 0,		/* Data message. */
	MSG_RELEASE_DATA,	/* Release data buffer message. */
	MSG_BOUND,		/* Endpoint bounding message. */
	MSG_RELEASE_BOUND,	/* Release endpoint bound message.
				 * This message is also indicator for the receiving side
				 * that the endpoint bounding was fully processed on
				 * the sender side.
				 */
};

enum ept_bounding_state {
	EPT_UNCONFIGURED = 0,	/* Endpoint in not configured (initial state). */
	EPT_CONFIGURED,		/* Endpoint is configured, waiting for work queue to
				 * start bounding process.
				 */
	EPT_BOUNDING,		/* Only on initiator. Bound message was send,
				 * but bound callback was not called yet, because
				 * we are waiting for any incoming messages.
				 */
	EPT_READY,		/* Bounding is done. Bound callback was called. */
};

struct channel_config {
	uint8_t *blocks_ptr;	/* Address where the blocks start. */
	size_t block_size;	/* Size of one block. */
	size_t block_count;	/* Number of blocks. */
};

struct icbmsg_config {
	struct icmsg_config_t control_config;	/* Configuration of the ICMsg. */
	struct channel_config rx;		/* RX channel config. */
	struct channel_config tx;		/* TX channel config. */
	sys_bitarray_t *tx_usage_bitmap;	/* Bit is set when TX block is in use */
	sys_bitarray_t *rx_hold_bitmap;		/* Bit is set, if the buffer starting at
						 * this block should be kept after exit
						 * from receive handler.
						 */
};

struct ept_data {
	const struct ipc_ept_cfg *cfg;	/* Endpoint configuration. */
	atomic_t state;			/* Bounding state. */
	uint8_t addr;			/* Endpoint address. */
};

struct backend_data {
	const struct icbmsg_config *conf;/* Backend instance config. */
	struct icmsg_data_t control_data;/* ICMsg data. */
	struct k_mutex mutex;		/* Mutex to protect: ICMsg send call and
					 * waiting_bound field.
					 */
	struct k_work ep_bound_work;	/* Work item for bounding processing. */
	struct k_sem block_wait_sem;	/* Semaphore for waiting for free blocks. */
	struct ept_data ept[NUM_EPT];	/* Array of registered endpoints. */
	uint8_t ept_map[NUM_EPT];	/* Array that maps endpoint address to index. */
	uint16_t waiting_bound[NUM_EPT];/* The bound messages waiting to be registered. */
	atomic_t flags;			/* Flags on higher bits, number of registered
					 * endpoints on lower.
					 */
	bool is_initiator;		/* This side has an initiator role. */
};

struct block_header {
	volatile size_t size;	/* Size of the data field. It must be volatile, because
				 * when this value is read and validated for security
				 * reasons, compiler cannot generate code that reads
				 * it again after validation.
				 */
};

struct block_content {
	struct block_header header;
	uint8_t data[];		/* Buffer data. */
};

struct control_message {
	uint8_t msg_type;	/* Message type. */
	uint8_t ept_addr;	/* Endpoint address or zero for MSG_RELEASE_DATA. */
	uint8_t block_index;	/* Block index to send or release. */
};

BUILD_ASSERT(NUM_EPT <= EPT_ADDR_INVALID, "Too many endpoints");

/**
 * Calculate pointer to block from its index and channel configuration (RX or TX).
 * No validation is performed.
 */
static struct block_content *block_from_index(const struct channel_config *ch_conf,
					      size_t block_index)
{
	return (struct block_content *)(ch_conf->blocks_ptr +
					block_index * ch_conf->block_size);
}

/**
 * Calculate pointer to data buffer from block index and channel configuration (RX or TX).
 * Also validate the index and optionally the buffer size allocated on the this block.
 *
 * @param[in]  ch_conf		The channel
 * @param[in]  block_index	Block index
 * @param[out] size		Size of the buffer allocated on the block if not NULL.
 *				The size is also checked if it fits in the blocks area.
 *				If it is NULL, no size validation is performed.
 * @param[in]  invalidate_cache	If size is not NULL, invalidates cache for entire buffer
 *				(all blocks). Otherwise, it is ignored.
 * @return	Pointer to data buffer or NULL if validation failed.
 */
static uint8_t *buffer_from_index_validate(const struct channel_config *ch_conf,
					   size_t block_index, size_t *size,
					   bool invalidate_cache)
{
	size_t allocable_size;
	size_t buffer_size;
	uint8_t *end_ptr;
	struct block_content *block;

	if (block_index >= ch_conf->block_count) {
		LOG_ERR("Block index invalid");
		return NULL;
	}

	block = block_from_index(ch_conf, block_index);

	if (size != NULL) {
		if (invalidate_cache) {
			sys_cache_data_invd_range(block, BLOCK_HEADER_SIZE);
			__sync_synchronize();
		}
		allocable_size = ch_conf->block_count * ch_conf->block_size;
		end_ptr = ch_conf->blocks_ptr + allocable_size;
		buffer_size = block->header.size;

		if ((buffer_size > allocable_size - BLOCK_HEADER_SIZE) ||
		    (&block->data[buffer_size] > end_ptr)) {
			LOG_ERR("Block corrupted");
			return NULL;
		}

		*size = buffer_size;
		if (invalidate_cache) {
			sys_cache_data_invd_range(block->data, buffer_size);
			__sync_synchronize();
		}
	}

	return block->data;
}

/**
 * Calculate block index based on data buffer pointer and validate it.
 *
 * @param[in]  ch_conf		The channel
 * @param[in]  buffer		Pointer to data buffer
 * @param[out] size		Size of the allocated buffer if not NULL.
 *				The size is also checked if it fits in the blocks area.
 *				If it is NULL, no size validation is performed.
 * @return		Block index or negative error code
 * @retval -EINVAL	The buffer is not correct
 */
static int buffer_to_index_validate(const struct channel_config *ch_conf,
				    const uint8_t *buffer, size_t *size)
{
	size_t block_index;
	uint8_t *expected;

	block_index = (buffer - ch_conf->blocks_ptr) / ch_conf->block_size;

	expected = buffer_from_index_validate(ch_conf, block_index, size, false);

	if (expected == NULL || expected != buffer) {
		LOG_ERR("Pointer invalid");
		return -EINVAL;
	}

	return block_index;
}

/**
 * Allocate buffer for transmission
 *
 * @param[in,out] size	Required size of the buffer. If zero, first available block is
 *			allocated and all subsequent available blocks. Size actually
 *			allocated which is not less than requested.
 * @param[out] buffer	Allocated buffer data.
 * @param[in] timeout	Timeout.
 *
 * @return		Positive index of the first allocated block or negative error.
 * @retval -EINVAL	If requested size is bigger than entire allocable space.
 * @retval -ENOSPC	If timeout was K_NO_WAIT and there was not enough space.
 * @retval -EAGAIN	If timeout occurred.
 */
static int alloc_tx_buffer(struct backend_data *dev_data, uint32_t *size,
			   uint8_t **buffer, k_timeout_t timeout)
{
	const struct icbmsg_config *conf = dev_data->conf;
	size_t total_size = *size + BLOCK_HEADER_SIZE;
	size_t num_blocks = DIV_ROUND_UP(total_size, conf->tx.block_size);
	struct block_content *block;
	bool sem_taken = false;
	size_t tx_block_index;
	size_t next_bit;
	int prev_bit_val;
	int r;

	do {
		/* Try to allocate specified number of blocks. */
		r = sys_bitarray_alloc(conf->tx_usage_bitmap, num_blocks,
				       &tx_block_index);
		if (r == -ENOSPC && !K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
			/* Wait for releasing if there is no enough space and exit loop
			 * on timeout.
			 */
			r = k_sem_take(&dev_data->block_wait_sem, timeout);
			if (r < 0) {
				break;
			}
			sem_taken = true;
		} else {
			/* Exit loop if space was allocated or other error occurred. */
			break;
		}
	} while (true);

	/* If semaphore was taken, give it back because this thread does not
	 * necessary took all available space, so other thread may need it.
	 */
	if (sem_taken) {
		k_sem_give(&dev_data->block_wait_sem);
	}

	if (r < 0) {
		if (r != -ENOSPC && r != -EAGAIN) {
			LOG_ERR("Failed to allocate buffer, err: %d", r);
			/* Only -EINVAL is allowed in this place. Any other code
			 * indicates something wrong with the logic.
			 */
			__ASSERT_NO_MSG(r == -EINVAL);
		}

		if (r == -ENOSPC || r == -EINVAL) {
			/* IPC service require -ENOMEM error in case of no memory. */
			r = -ENOMEM;
		}
		return r;
	}

	/* If size is 0 try to allocate more blocks after already allocated. */
	if (*size == 0) {
		prev_bit_val = 0;
		for (next_bit = tx_block_index + 1; next_bit < conf->tx.block_count;
		     next_bit++) {
			r = sys_bitarray_test_and_set_bit(conf->tx_usage_bitmap, next_bit,
							  &prev_bit_val);
			/** Setting bit should always success. */
			__ASSERT_NO_MSG(r == 0);
			if (prev_bit_val) {
				break;
			}
		}
		num_blocks = next_bit - tx_block_index;
	}

	/* Get block pointer and adjust size to actually allocated space. */
	*size = conf->tx.block_size * num_blocks - BLOCK_HEADER_SIZE;
	block = block_from_index(&conf->tx, tx_block_index);
	block->header.size = *size;
	*buffer = block->data;
	return tx_block_index;
}

/**
 * Release all or part of the blocks occupied by the buffer.
 *
 * @param[in] tx_block_index	First block index to release, no validation is performed,
 *				so caller is responsible for passing valid index.
 * @param[in] size		Size of data buffer, no validation is performed,
 *				so caller is responsible for passing valid size.
 * @param[in] new_size		If less than zero, release all blocks, otherwise reduce
 *				size to this value and update size in block header.
 *
 * @returns		Positive block index where the buffer starts or negative error.
 * @retval -EINVAL	If invalid buffer was provided or size is greater than already
 *			allocated size.
 */
static int release_tx_blocks(struct backend_data *dev_data, size_t tx_block_index,
			     size_t size, int new_size)
{
	const struct icbmsg_config *conf = dev_data->conf;
	struct block_content *block;
	size_t num_blocks;
	size_t total_size;
	size_t new_total_size;
	size_t new_num_blocks;
	size_t release_index;
	int r;

	/* Calculate number of blocks. */
	total_size = size + BLOCK_HEADER_SIZE;
	num_blocks = DIV_ROUND_UP(total_size, conf->tx.block_size);

	if (new_size >= 0) {
		/* Calculate and validate new values. */
		new_total_size = new_size + BLOCK_HEADER_SIZE;
		new_num_blocks = DIV_ROUND_UP(new_total_size, conf->tx.block_size);
		if (new_num_blocks > num_blocks) {
			LOG_ERR("Requested %d blocks, allocated %d", new_num_blocks,
				num_blocks);
			return -EINVAL;
		}
		/* Update actual buffer size and number of blocks to release. */
		block = block_from_index(&conf->tx, tx_block_index);
		block->header.size = new_size;
		release_index = tx_block_index + new_num_blocks;
		num_blocks = num_blocks - new_num_blocks;
	} else {
		/* If size is negative, release all blocks. */
		release_index = tx_block_index;
	}

	if (num_blocks > 0) {
		/* Free bits in the bitmap. */
		r = sys_bitarray_free(conf->tx_usage_bitmap, num_blocks,
				      release_index);
		if (r < 0) {
			LOG_ERR("Cannot free bits, err %d", r);
			return r;
		}

		/* Wake up all waiting threads. */
		k_sem_give(&dev_data->block_wait_sem);
	}

	return tx_block_index;
}

/**
 * Release all or part of the blocks occupied by the buffer.
 *
 * @param[in] buffer	Buffer to release.
 * @param[in] new_size	If less than zero, release all blocks, otherwise reduce size to
 *			this value and update size in block header.
 *
 * @returns		Positive block index where the buffer starts or negative error.
 * @retval -EINVAL	If invalid buffer was provided or size is greater than already
 *			allocated size.
 */
static int release_tx_buffer(struct backend_data *dev_data, const uint8_t *buffer,
			     int new_size)
{
	const struct icbmsg_config *conf = dev_data->conf;
	size_t size;
	int tx_block_index;

	tx_block_index = buffer_to_index_validate(&conf->tx, buffer, &size);
	if (tx_block_index < 0) {
		return tx_block_index;
	}

	return release_tx_blocks(dev_data, tx_block_index, size, new_size);
}

/**
 * Send control message over ICMsg with mutex locked. Mutex must be locked because
 * ICMsg may return error on concurrent invocations even when there is enough space
 * in queue.
 */
static int send_control_message(struct backend_data *dev_data, enum msg_type msg_type,
				uint8_t ept_addr, uint8_t block_index)
{
	const struct icbmsg_config *conf = dev_data->conf;
	const struct control_message message = {
		.msg_type = (uint8_t)msg_type,
		.ept_addr = ept_addr,
		.block_index = block_index,
	};
	int r;

	k_mutex_lock(&dev_data->mutex, K_FOREVER);
	r = icmsg_send(&conf->control_config, &dev_data->control_data, &message,
		       sizeof(message));
	k_mutex_unlock(&dev_data->mutex);
	if (r < 0) {
		LOG_ERR("Cannot send over ICMsg, err %d", r);
	}
	return r;
}

/**
 * Release received buffer. This function will just send release control message.
 *
 * @param[in] buffer	Buffer to release.
 * @param[in] msg_type	Message type: MSG_RELEASE_BOUND or MSG_RELEASE_DATA.
 * @param[in] ept_addr	Endpoint address or zero for MSG_RELEASE_DATA.
 *
 * @return	zero or ICMsg send error.
 */
static int send_release(struct backend_data *dev_data, const uint8_t *buffer,
			enum msg_type msg_type, uint8_t ept_addr)
{
	const struct icbmsg_config *conf = dev_data->conf;
	int rx_block_index;

	rx_block_index = buffer_to_index_validate(&conf->rx, buffer, NULL);
	if (rx_block_index < 0) {
		return rx_block_index;
	}

	return send_control_message(dev_data, msg_type, ept_addr, rx_block_index);
}

/**
 * Send data contained in specified block. It will adjust data size and flush cache
 * if necessary. If sending failed, allocated blocks will be released.
 *
 * @param[in] msg_type		Message type: MSG_BOUND or MSG_DATA.
 * @param[in] ept_addr		Endpoints address.
 * @param[in] tx_block_index	Index of first block containing data, it is not validated,
 *				so caller is responsible for passing only valid index.
 * @param[in] size		Actual size of the data, can be smaller than allocated,
 *				but it cannot change number of required blocks.
 *
 * @return			O or negative error code.
 */
static int send_block(struct backend_data *dev_data, enum msg_type msg_type,
		      uint8_t ept_addr, size_t tx_block_index, size_t size)
{
	struct block_content *block;
	int r;

	block = block_from_index(&dev_data->conf->tx, tx_block_index);

	block->header.size = size;
	__sync_synchronize();
	sys_cache_data_flush_range(block, size + BLOCK_HEADER_SIZE);

	r = send_control_message(dev_data, msg_type, ept_addr, tx_block_index);
	if (r < 0) {
		release_tx_blocks(dev_data, tx_block_index, size, -1);
	}

	return r;
}

/**
 * Find endpoint that was registered with name that matches name
 * contained in the endpoint bound message received from remote.
 *
 * @param[in] name	Endpoint name, it must be in a received block.
 *
 * @return	Found endpoint index or -ENOENT if not found.
 */
static int find_ept_by_name(struct backend_data *dev_data, const char *name)
{
	const struct channel_config *rx_conf = &dev_data->conf->rx;
	const char *buffer_end = (const char *)rx_conf->blocks_ptr +
				 rx_conf->block_count * rx_conf->block_size;
	struct ept_data *ept;
	size_t name_size;
	size_t i;

	/* Requested name is in shared memory, so we have to assume that it
	 * can be corrupted. Extra care must be taken to avoid out of
	 * bounds reads.
	 */
	name_size = strnlen(name, buffer_end - name - 1) + 1;

	for (i = 0; i < NUM_EPT; i++) {
		ept = &dev_data->ept[i];
		if (atomic_get(&ept->state) == EPT_CONFIGURED &&
		    strncmp(ept->cfg->name, name, name_size) == 0) {
			return i;
		}
	}

	return -ENOENT;
}

/**
 * Find registered endpoint that matches given "bound endpoint" message. When found,
 * the "release bound endpoint" message is send.
 *
 * @param[in] rx_block_index	Block containing the "bound endpoint" message.
 * @param[in] ept_addr		Endpoint address.
 *
 * @return	negative error code or non-negative search result.
 * @retval 0	match not found.
 * @retval 1	match found and processing was successful.
 */
static int match_bound_msg(struct backend_data *dev_data, size_t rx_block_index,
			   uint8_t ept_addr)
{
	const struct icbmsg_config *conf = dev_data->conf;
	struct block_content *block;
	uint8_t *buffer;
	int ept_index;
	struct ept_data *ept;
	int r;
	bool valid_state;

	/* Find endpoint that matches requested name. */
	block = block_from_index(&conf->rx, rx_block_index);
	buffer = block->data;
	ept_index = find_ept_by_name(dev_data, buffer);
	if (ept_index < 0) {
		return 0;
	}

	/* Set endpoint address and mapping. Move it to "ready" state. */
	ept = &dev_data->ept[ept_index];
	ept->addr = ept_addr;
	dev_data->ept_map[ept->addr] = ept_index;
	valid_state = atomic_cas(&ept->state, EPT_CONFIGURED, EPT_READY);
	if (!valid_state) {
		LOG_ERR("Unexpected bounding from remote on endpoint %d", ept_addr);
		return -EINVAL;
	}

	/* Endpoint is ready to send messages, so call bound callback. */
	if (ept->cfg->cb.bound != NULL) {
		ept->cfg->cb.bound(ept->cfg->priv);
	}

	/* Release the bound message and inform remote that we are ready to receive. */
	r = send_release(dev_data, buffer, MSG_RELEASE_BOUND, ept_addr);
	if (r < 0) {
		return r;
	}

	return 1;
}

/**
 * Send bound message on specified endpoint.
 *
 * @param[in] ept	Endpoint to use.
 *
 * @return		O or negative error code.
 */
static int send_bound_message(struct backend_data *dev_data, struct ept_data *ept)
{
	size_t msg_len;
	uint32_t alloc_size;
	uint8_t *buffer;
	int r;

	msg_len = strlen(ept->cfg->name) + 1;
	alloc_size = msg_len;
	r = alloc_tx_buffer(dev_data, &alloc_size, &buffer, K_FOREVER);
	if (r >= 0) {
		strcpy(buffer, ept->cfg->name);
		r = send_block(dev_data, MSG_BOUND, ept->addr, r, msg_len);
	}

	return r;
}

/**
 * Put endpoint bound processing into system workqueue.
 */
static void schedule_ept_bound_process(struct backend_data *dev_data)
{
	k_work_submit(&dev_data->ep_bound_work);
}

/**
 * Work handler that is responsible to start bounding when ICMsg is bound.
 */
static void ept_bound_process(struct k_work *item)
{
	struct backend_data *dev_data = CONTAINER_OF(item, struct backend_data,
						     ep_bound_work);
	struct ept_data *ept = NULL;
	size_t i;
	int r = 0;
	bool matching_state;

	/* Skip processing if ICMsg was not bounded yet. */
	if (!(atomic_get(&dev_data->flags) & CONTROL_BOUNDED)) {
		return;
	}

	if (dev_data->is_initiator) {
		/* Initiator just sends bound message after endpoint was registered. */
		for (i = 0; i < NUM_EPT; i++) {
			ept = &dev_data->ept[i];
			matching_state = atomic_cas(&ept->state, EPT_CONFIGURED,
						    EPT_BOUNDING);
			if (matching_state) {
				r = send_bound_message(dev_data, ept);
				if (r < 0) {
					atomic_set(&ept->state, EPT_UNCONFIGURED);
					LOG_ERR("Failed to send bound, err %d", r);
				}
			}
		}
	} else {
		/* Walk over all waiting bound messages and match to local endpoints. */
		k_mutex_lock(&dev_data->mutex, K_FOREVER);
		for (i = 0; i < NUM_EPT; i++) {
			if (dev_data->waiting_bound[i] != WAITING_BOUND_MSG_EMPTY) {
				k_mutex_unlock(&dev_data->mutex);
				r = match_bound_msg(dev_data,
						    dev_data->waiting_bound[i], i);
				k_mutex_lock(&dev_data->mutex, K_FOREVER);
				if (r != 0) {
					dev_data->waiting_bound[i] =
						WAITING_BOUND_MSG_EMPTY;
					if (r < 0) {
						LOG_ERR("Failed bound, err %d", r);
					}
				}
			}
		}
		k_mutex_unlock(&dev_data->mutex);
	}
}

/**
 * Get endpoint from endpoint address. Also validates if the address is correct and
 * endpoint is in correct state for receiving. If bounding callback was not called yet,
 * then call it.
 */
static struct ept_data *get_ept_and_rx_validate(struct backend_data *dev_data,
						uint8_t ept_addr)
{
	struct ept_data *ept;
	enum ept_bounding_state state;

	if (ept_addr >= NUM_EPT || dev_data->ept_map[ept_addr] >= NUM_EPT) {
		LOG_ERR("Received invalid endpoint addr %d", ept_addr);
		return NULL;
	}

	ept = &dev_data->ept[dev_data->ept_map[ept_addr]];

	state = atomic_get(&ept->state);

	if (state == EPT_READY) {
		/* Valid state - nothing to do. */
	} else if (state == EPT_BOUNDING) {
		/* Endpoint bound callback was not called yet - call it. */
		atomic_set(&ept->state, EPT_READY);
		if (ept->cfg->cb.bound != NULL) {
			ept->cfg->cb.bound(ept->cfg->priv);
		}
	} else {
		LOG_ERR("Invalid state %d of receiving endpoint %d", state, ept->addr);
		return NULL;
	}

	return ept;
}

/**
 * Data message received.
 */
static int received_data(struct backend_data *dev_data, size_t rx_block_index,
			 uint8_t ept_addr)
{
	const struct icbmsg_config *conf = dev_data->conf;
	uint8_t *buffer;
	struct ept_data *ept;
	size_t size;
	int bit_val;

	/* Validate. */
	buffer = buffer_from_index_validate(&conf->rx, rx_block_index, &size, true);
	ept = get_ept_and_rx_validate(dev_data, ept_addr);
	if (buffer == NULL || ept == NULL) {
		LOG_ERR("Received invalid block index %d or addr %d", rx_block_index,
			ept_addr);
		return -EINVAL;
	}

	/* Clear bit. If cleared, specific block will not be hold after the callback. */
	sys_bitarray_clear_bit(conf->rx_hold_bitmap, rx_block_index);

	/* Call the endpoint callback. It can set the hold bit. */
	ept->cfg->cb.received(buffer, size, ept->cfg->priv);

	/* If the bit is still cleared, request release of the buffer. */
	sys_bitarray_test_bit(conf->rx_hold_bitmap, rx_block_index, &bit_val);
	if (!bit_val) {
		send_release(dev_data, buffer, MSG_RELEASE_DATA, 0);
	}

	return 0;
}

/**
 * Release data message received.
 */
static int received_release_data(struct backend_data *dev_data, size_t tx_block_index)
{
	const struct icbmsg_config *conf = dev_data->conf;
	uint8_t *buffer;
	size_t size;
	int r;

	/* Validate. */
	buffer = buffer_from_index_validate(&conf->tx, tx_block_index, &size, false);
	if (buffer == NULL) {
		LOG_ERR("Received invalid block index %d", tx_block_index);
		return -EINVAL;
	}

	/* Release. */
	r = release_tx_blocks(dev_data, tx_block_index, size, -1);
	if (r < 0) {
		return r;
	}

	return r;
}

/**
 * Bound endpoint message received.
 */
static int received_bound(struct backend_data *dev_data, size_t rx_block_index,
			  uint8_t ept_addr)
{
	const struct icbmsg_config *conf = dev_data->conf;
	size_t size;
	uint8_t *buffer;

	/* Validate */
	buffer = buffer_from_index_validate(&conf->rx, rx_block_index, &size, true);
	if (buffer == NULL) {
		LOG_ERR("Received invalid block index %d", rx_block_index);
		return -EINVAL;
	}

	/* Put message to waiting array. */
	k_mutex_lock(&dev_data->mutex, K_FOREVER);
	dev_data->waiting_bound[ept_addr] = rx_block_index;
	k_mutex_unlock(&dev_data->mutex);

	/* Schedule processing the message. */
	schedule_ept_bound_process(dev_data);

	return 0;
}

/**
 * Callback called by ICMsg that handles message (data or endpoint bound) received
 * from the remote.
 *
 * @param[in] data	Message received from the ICMsg.
 * @param[in] len	Number of bytes of data.
 * @param[in] priv	Opaque pointer to device instance.
 */
static void control_received(const void *data, size_t len, void *priv)
{
	const struct device *instance = priv;
	struct backend_data *dev_data = instance->data;
	const struct control_message *message = (const struct control_message *)data;
	struct ept_data *ept;
	uint8_t ept_addr;
	int r = 0;

	/* Allow messages longer than 3 bytes, e.g. for future protocol versions. */
	if (len < sizeof(struct control_message)) {
		r = -EINVAL;
		goto exit;
	}

	ept_addr = message->ept_addr;
	if (ept_addr >= NUM_EPT) {
		r = -EINVAL;
		goto exit;
	}

	switch (message->msg_type) {
	case MSG_RELEASE_DATA:
		r = received_release_data(dev_data, message->block_index);
		break;
	case MSG_RELEASE_BOUND:
		r = received_release_data(dev_data, message->block_index);
		if (r >= 0) {
			ept = get_ept_and_rx_validate(dev_data, ept_addr);
			if (ept == NULL) {
				r = -EINVAL;
			}
		}
		break;
	case MSG_BOUND:
		r = received_bound(dev_data, message->block_index, ept_addr);
		break;
	case MSG_DATA:
		r = received_data(dev_data, message->block_index, ept_addr);
		break;
	default:
		/* Silently ignore other messages types. They can be used in future
		 * protocol version.
		 */
		break;
	}

exit:
	if (r < 0) {
		LOG_ERR("Failed to receive, err %d", r);
	}
}

/**
 * Callback called when ICMsg is bound.
 */
static void control_bound(void *priv)
{
	const struct device *instance = priv;
	struct backend_data *dev_data = instance->data;

	/* Set flag that ICMsg is bounded and now, endpoint bounding may start. */
	atomic_or(&dev_data->flags, CONTROL_BOUNDED);
	schedule_ept_bound_process(dev_data);
}

/**
 * Open the backend instance callback.
 */
static int open(const struct device *instance)
{
	const struct icbmsg_config *conf = instance->config;
	struct backend_data *dev_data = instance->data;

	static const struct ipc_service_cb cb = {
		.bound = control_bound,
		.received = control_received,
		.error = NULL,
	};

	LOG_DBG("Open instance 0x%08X, initiator=%d", (uint32_t)instance,
		dev_data->is_initiator ? 1 : 0);
	LOG_DBG("  TX %d blocks of %d bytes at 0x%08X, max allocable %d bytes",
		(uint32_t)conf->tx.block_count,
		(uint32_t)conf->tx.block_size,
		(uint32_t)conf->tx.blocks_ptr,
		(uint32_t)(conf->tx.block_size * conf->tx.block_count -
			   BLOCK_HEADER_SIZE));
	LOG_DBG("  RX %d blocks of %d bytes at 0x%08X, max allocable %d bytes",
		(uint32_t)conf->rx.block_count,
		(uint32_t)conf->rx.block_size,
		(uint32_t)conf->rx.blocks_ptr,
		(uint32_t)(conf->rx.block_size * conf->rx.block_count -
			   BLOCK_HEADER_SIZE));

	return icmsg_open(&conf->control_config, &dev_data->control_data, &cb,
			  (void *)instance);
}

/**
 * Endpoint send callback function (with copy).
 */
static int send(const struct device *instance, void *token, const void *msg, size_t len)
{
	struct backend_data *dev_data = instance->data;
	struct ept_data *ept = token;
	uint32_t alloc_size;
	uint8_t *buffer;
	int r;

	/* Allocate the buffer. */
	alloc_size = len;
	r = alloc_tx_buffer(dev_data, &alloc_size, &buffer, K_NO_WAIT);
	if (r < 0) {
		return r;
	}

	/* Copy data to allocated buffer. */
	memcpy(buffer, msg, len);

	/* Send data message. */
	return send_block(dev_data, MSG_DATA, ept->addr, r, len);
}

/**
 * Backend endpoint registration callback.
 */
static int register_ept(const struct device *instance, void **token,
			const struct ipc_ept_cfg *cfg)
{
	struct backend_data *dev_data = instance->data;
	struct ept_data *ept = NULL;
	int ept_index;
	int r = 0;

	/* Reserve new endpoint index. */
	ept_index = atomic_inc(&dev_data->flags) & FLAG_EPT_COUNT_MASK;
	if (ept_index >= NUM_EPT) {
		LOG_ERR("Too many endpoints");
		__ASSERT_NO_MSG(false);
		return -ENOMEM;
	}

	/* Add new endpoint. */
	ept = &dev_data->ept[ept_index];
	ept->cfg = cfg;
	if (dev_data->is_initiator) {
		ept->addr = ept_index;
		dev_data->ept_map[ept->addr] = ept->addr;
	}
	atomic_set(&ept->state, EPT_CONFIGURED);

	/* Keep endpoint address in token. */
	*token = ept;

	/* Rest of the bounding will be done in the system workqueue. */
	schedule_ept_bound_process(dev_data);

	return r;
}

/**
 * Returns maximum TX buffer size.
 */
static int get_tx_buffer_size(const struct device *instance, void *token)
{
	const struct icbmsg_config *conf = instance->config;

	return conf->tx.block_size * conf->tx.block_count - BLOCK_HEADER_SIZE;
}

/**
 * Endpoint TX buffer allocation callback for nocopy sending.
 */
static int get_tx_buffer(const struct device *instance, void *token, void **data,
			 uint32_t *user_len, k_timeout_t wait)
{
	struct backend_data *dev_data = instance->data;
	int r;

	r = alloc_tx_buffer(dev_data, user_len, (uint8_t **)data, wait);
	if (r < 0) {
		return r;
	}
	return 0;
}

/**
 * Endpoint TX buffer release callback for nocopy sending.
 */
static int drop_tx_buffer(const struct device *instance, void *token, const void *data)
{
	struct backend_data *dev_data = instance->data;
	int r;

	r =  release_tx_buffer(dev_data, data, -1);
	if (r < 0) {
		return r;
	}

	return 0;
}

/**
 * Endpoint nocopy sending.
 */
static int send_nocopy(const struct device *instance, void *token, const void *data,
		       size_t len)
{
	struct backend_data *dev_data = instance->data;
	struct ept_data *ept = token;
	int r;

	/* Actual size may be smaller than requested, so shrink if possible. */
	r = release_tx_buffer(dev_data, data, len);
	if (r < 0) {
		release_tx_buffer(dev_data, data, -1);
		return r;
	}

	return send_block(dev_data, MSG_DATA, ept->addr, r, len);
}

/**
 * Holding RX buffer for nocopy receiving.
 */
static int hold_rx_buffer(const struct device *instance, void *token, void *data)
{
	const struct icbmsg_config *conf = instance->config;
	int rx_block_index;
	uint8_t *buffer = data;

	/* Calculate block index and set associated bit. */
	rx_block_index = buffer_to_index_validate(&conf->rx, buffer, NULL);
	__ASSERT_NO_MSG(rx_block_index >= 0);
	return sys_bitarray_set_bit(conf->rx_hold_bitmap, rx_block_index);
}

/**
 * Release RX buffer that was previously held.
 */
static int release_rx_buffer(const struct device *instance, void *token, void *data)
{
	struct backend_data *dev_data = instance->data;

	return send_release(dev_data, (uint8_t *)data, MSG_RELEASE_DATA, 0);
}

/**
 * Backend device initialization.
 */
static int backend_init(const struct device *instance)
{
	const struct icbmsg_config *conf = instance->config;
	struct backend_data *dev_data = instance->data;

	dev_data->conf = conf;
	dev_data->is_initiator = (conf->rx.blocks_ptr < conf->tx.blocks_ptr);
	k_mutex_init(&dev_data->mutex);
	k_work_init(&dev_data->ep_bound_work, ept_bound_process);
	k_sem_init(&dev_data->block_wait_sem, 0, 1);
	memset(&dev_data->waiting_bound, 0xFF, sizeof(dev_data->waiting_bound));
	memset(&dev_data->ept_map, EPT_ADDR_INVALID, sizeof(dev_data->ept_map));
	return 0;
}

/**
 * IPC service backend callbacks.
 */
const static struct ipc_service_backend backend_ops = {
	.open_instance = open,
	.close_instance = NULL, /* not implemented */
	.send = send,
	.register_endpoint = register_ept,
	.deregister_endpoint = NULL, /* not implemented */
	.get_tx_buffer_size = get_tx_buffer_size,
	.get_tx_buffer = get_tx_buffer,
	.drop_tx_buffer = drop_tx_buffer,
	.send_nocopy = send_nocopy,
	.hold_rx_buffer = hold_rx_buffer,
	.release_rx_buffer = release_rx_buffer,
};

/**
 * Number of bytes per each ICMsg message. It is used to calculate size of ICMsg area.
 */
#define BYTES_PER_ICMSG_MESSAGE (ROUND_UP(sizeof(struct control_message),		\
					  sizeof(void *)) + PBUF_PACKET_LEN_SZ)

/**
 * Maximum ICMsg overhead. It is used to calculate size of ICMsg area.
 */
#define ICMSG_BUFFER_OVERHEAD(i)							\
	(PBUF_HEADER_OVERHEAD(GET_CACHE_ALIGNMENT(i)) + 2 * BYTES_PER_ICMSG_MESSAGE)

/**
 * Returns required block alignment for instance "i".
 */
#define GET_CACHE_ALIGNMENT(i) \
	MAX(sizeof(uint32_t), DT_INST_PROP_OR(i, dcache_alignment, 0))

/**
 * Calculates minimum size required for ICMsg region for specific number of local
 * and remote blocks. The minimum size ensures that ICMsg queue is will never overflow
 * because it can hold data message for each local block and release message
 * for each remote block.
 */
#define GET_ICMSG_MIN_SIZE(i, local_blocks, remote_blocks)				\
	(ICMSG_BUFFER_OVERHEAD(i) + BYTES_PER_ICMSG_MESSAGE *				\
	 (local_blocks + remote_blocks))

/**
 * Calculate aligned block size by evenly dividing remaining space after removing
 * the space for ICMsg.
 */
#define GET_BLOCK_SIZE(i, total_size, local_blocks, remote_blocks) ROUND_DOWN(		\
	((total_size) - GET_ICMSG_MIN_SIZE(i, (local_blocks), (remote_blocks))) /	\
	(local_blocks), GET_CACHE_ALIGNMENT(i))

/**
 * Calculate offset where area for blocks starts which is just after the ICMsg.
 */
#define GET_BLOCKS_OFFSET(i, total_size, local_blocks, remote_blocks)			\
	((total_size) - GET_BLOCK_SIZE(i, (total_size), (local_blocks),			\
				       (remote_blocks)) * (local_blocks))

/**
 * Return shared memory start address aligned to block alignment and cache line.
 */
#define GET_MEM_ADDR_INST(i, direction) \
	ROUND_UP(DT_REG_ADDR(DT_INST_PHANDLE(i, direction##_region)),			\
		 GET_CACHE_ALIGNMENT(i))

/**
 * Return shared memory end address aligned to block alignment and cache line.
 */
#define GET_MEM_END_INST(i, direction)							\
	ROUND_DOWN(DT_REG_ADDR(DT_INST_PHANDLE(i, direction##_region)) +		\
		   DT_REG_SIZE(DT_INST_PHANDLE(i, direction##_region)),			\
		   GET_CACHE_ALIGNMENT(i))

/**
 * Return shared memory size aligned to block alignment and cache line.
 */
#define GET_MEM_SIZE_INST(i, direction) \
	(GET_MEM_END_INST(i, direction) - GET_MEM_ADDR_INST(i, direction))

/**
 * Returns GET_ICMSG_SIZE, but for specific instance and direction.
 * 'loc' and 'rem' parameters tells the direction. They can be either "tx, rx"
 *  or "rx, tx".
 */
#define GET_ICMSG_SIZE_INST(i, loc, rem)					\
	GET_BLOCKS_OFFSET(							\
		i,								\
		GET_MEM_SIZE_INST(i, loc),					\
		DT_INST_PROP(i, loc##_blocks),					\
		DT_INST_PROP(i, rem##_blocks))

/**
 * Returns address where area for blocks starts for specific instance and direction.
 * 'loc' and 'rem' parameters tells the direction. They can be either "tx, rx"
 *  or "rx, tx".
 */
#define GET_BLOCKS_ADDR_INST(i, loc, rem)					\
	GET_MEM_ADDR_INST(i, loc) +						\
	GET_BLOCKS_OFFSET(							\
		i,								\
		GET_MEM_SIZE_INST(i, loc),					\
		DT_INST_PROP(i, loc##_blocks),					\
		DT_INST_PROP(i, rem##_blocks))

/**
 * Returns block size for specific instance and direction.
 * 'loc' and 'rem' parameters tells the direction. They can be either "tx, rx"
 *  or "rx, tx".
 */
#define GET_BLOCK_SIZE_INST(i, loc, rem)					\
	GET_BLOCK_SIZE(								\
		i,								\
		GET_MEM_SIZE_INST(i, loc),					\
		DT_INST_PROP(i, loc##_blocks),					\
		DT_INST_PROP(i, rem##_blocks))

#define DEFINE_BACKEND_DEVICE(i)							\
	SYS_BITARRAY_DEFINE_STATIC(tx_usage_bitmap_##i, DT_INST_PROP(i, tx_blocks));	\
	SYS_BITARRAY_DEFINE_STATIC(rx_hold_bitmap_##i, DT_INST_PROP(i, rx_blocks));	\
	PBUF_DEFINE(tx_icbmsg_pb_##i,							\
			GET_MEM_ADDR_INST(i, tx),					\
			GET_ICMSG_SIZE_INST(i, tx, rx),					\
			GET_CACHE_ALIGNMENT(i));					\
	PBUF_DEFINE(rx_icbmsg_pb_##i,							\
			GET_MEM_ADDR_INST(i, rx),					\
			GET_ICMSG_SIZE_INST(i, rx, tx),					\
			GET_CACHE_ALIGNMENT(i));					\
	static struct backend_data backend_data_##i = {					\
		.control_data = {							\
			.tx_pb = &tx_icbmsg_pb_##i,					\
			.rx_pb = &rx_icbmsg_pb_##i,					\
		}									\
	};										\
	static const struct icbmsg_config backend_config_##i =				\
	{										\
		.control_config = {							\
			.mbox_tx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), tx),		\
			.mbox_rx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), rx),		\
		},									\
		.tx = {									\
			.blocks_ptr = (uint8_t *)GET_BLOCKS_ADDR_INST(i, tx, rx),	\
			.block_count = DT_INST_PROP(i, tx_blocks),			\
			.block_size = GET_BLOCK_SIZE_INST(i, tx, rx),			\
		},									\
		.rx = {									\
			.blocks_ptr = (uint8_t *)GET_BLOCKS_ADDR_INST(i, rx, tx),	\
			.block_count = DT_INST_PROP(i, rx_blocks),			\
			.block_size = GET_BLOCK_SIZE_INST(i, rx, tx),			\
		},									\
		.tx_usage_bitmap = &tx_usage_bitmap_##i,				\
		.rx_hold_bitmap = &rx_hold_bitmap_##i,					\
	};										\
	BUILD_ASSERT(IS_POWER_OF_TWO(GET_CACHE_ALIGNMENT(i)),				\
		     "This module supports only power of two cache alignment");		\
	BUILD_ASSERT((GET_BLOCK_SIZE_INST(i, tx, rx) > GET_CACHE_ALIGNMENT(i)) &&	\
		     (GET_BLOCK_SIZE_INST(i, tx, rx) <					\
		      GET_MEM_SIZE_INST(i, tx)),					\
		     "TX region is too small for provided number of blocks");		\
	BUILD_ASSERT((GET_BLOCK_SIZE_INST(i, rx, tx) > GET_CACHE_ALIGNMENT(i)) &&	\
		     (GET_BLOCK_SIZE_INST(i, rx, tx) <					\
		      GET_MEM_SIZE_INST(i, rx)),					\
		     "RX region is too small for provided number of blocks");		\
	BUILD_ASSERT(DT_INST_PROP(i, rx_blocks) <= 256, "Too many RX blocks");		\
	BUILD_ASSERT(DT_INST_PROP(i, tx_blocks) <= 256, "Too many TX blocks");		\
	DEVICE_DT_INST_DEFINE(i,							\
			      &backend_init,						\
			      NULL,							\
			      &backend_data_##i,					\
			      &backend_config_##i,					\
			      POST_KERNEL,						\
			      CONFIG_IPC_SERVICE_REG_BACKEND_PRIORITY,			\
			      &backend_ops);

DT_INST_FOREACH_STATUS_OKAY(DEFINE_BACKEND_DEVICE)
