/*
 * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <debug.h>
#include <errno.h>
#include <io_block.h>
#include <io_driver.h>
#include <io_storage.h>
#include <platform_def.h>
#include <string.h>
#include <utils.h>

typedef struct {
	io_block_dev_spec_t	*dev_spec;
	uintptr_t		base;
	size_t			file_pos;
	size_t			size;
} block_dev_state_t;

#define is_power_of_2(x)	((x != 0) && ((x & (x - 1)) == 0))

io_type_t device_type_block(void);

static int block_open(io_dev_info_t *dev_info, const uintptr_t spec,
		      io_entity_t *entity);
static int block_seek(io_entity_t *entity, int mode, ssize_t offset);
static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
		      size_t *length_read);
static int block_write(io_entity_t *entity, const uintptr_t buffer,
		       size_t length, size_t *length_written);
static int block_close(io_entity_t *entity);
static int block_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
static int block_dev_close(io_dev_info_t *dev_info);

static const io_dev_connector_t block_dev_connector = {
	.dev_open	= block_dev_open
};

static const io_dev_funcs_t block_dev_funcs = {
	.type		= device_type_block,
	.open		= block_open,
	.seek		= block_seek,
	.size		= NULL,
	.read		= block_read,
	.write		= block_write,
	.close		= block_close,
	.dev_init	= NULL,
	.dev_close	= block_dev_close,
};

static block_dev_state_t state_pool[MAX_IO_BLOCK_DEVICES];
static io_dev_info_t dev_info_pool[MAX_IO_BLOCK_DEVICES];

/* Track number of allocated block state */
static unsigned int block_dev_count;

io_type_t device_type_block(void)
{
	return IO_TYPE_BLOCK;
}

/* Locate a block state in the pool, specified by address */
static int find_first_block_state(const io_block_dev_spec_t *dev_spec,
				  unsigned int *index_out)
{
	int result = -ENOENT;
	for (int index = 0; index < MAX_IO_BLOCK_DEVICES; ++index) {
		/* dev_spec is used as identifier since it's unique */
		if (state_pool[index].dev_spec == dev_spec) {
			result = 0;
			*index_out = index;
			break;
		}
	}
	return result;
}

/* Allocate a device info from the pool and return a pointer to it */
static int allocate_dev_info(io_dev_info_t **dev_info)
{
	int result = -ENOMEM;
	assert(dev_info != NULL);

	if (block_dev_count < MAX_IO_BLOCK_DEVICES) {
		unsigned int index = 0;
		result = find_first_block_state(NULL, &index);
		assert(result == 0);
		/* initialize dev_info */
		dev_info_pool[index].funcs = &block_dev_funcs;
		dev_info_pool[index].info = (uintptr_t)&state_pool[index];
		*dev_info = &dev_info_pool[index];
		++block_dev_count;
	}

	return result;
}


/* Release a device info to the pool */
static int free_dev_info(io_dev_info_t *dev_info)
{
	int result;
	unsigned int index = 0;
	block_dev_state_t *state;
	assert(dev_info != NULL);

	state = (block_dev_state_t *)dev_info->info;
	result = find_first_block_state(state->dev_spec, &index);
	if (result ==  0) {
		/* free if device info is valid */
		zeromem(state, sizeof(block_dev_state_t));
		zeromem(dev_info, sizeof(io_dev_info_t));
		--block_dev_count;
	}

	return result;
}

static int block_open(io_dev_info_t *dev_info, const uintptr_t spec,
		      io_entity_t *entity)
{
	block_dev_state_t *cur;
	io_block_spec_t *region;

	assert((dev_info->info != (uintptr_t)NULL) &&
	       (spec != (uintptr_t)NULL) &&
	       (entity->info == (uintptr_t)NULL));

	region = (io_block_spec_t *)spec;
	cur = (block_dev_state_t *)dev_info->info;
	assert(((region->offset % cur->dev_spec->block_size) == 0) &&
	       ((region->length % cur->dev_spec->block_size) == 0));

	cur->base = region->offset;
	cur->size = region->length;
	cur->file_pos = 0;

	entity->info = (uintptr_t)cur;
	return 0;
}

/* parameter offset is relative address at here */
static int block_seek(io_entity_t *entity, int mode, ssize_t offset)
{
	block_dev_state_t *cur;

	assert(entity->info != (uintptr_t)NULL);

	cur = (block_dev_state_t *)entity->info;
	assert((offset >= 0) && (offset < cur->size));

	switch (mode) {
	case IO_SEEK_SET:
		cur->file_pos = offset;
		break;
	case IO_SEEK_CUR:
		cur->file_pos += offset;
		break;
	default:
		return -EINVAL;
	}
	assert(cur->file_pos < cur->size);
	return 0;
}

static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
		      size_t *length_read)
{
	block_dev_state_t *cur;
	io_block_spec_t *buf;
	io_block_ops_t *ops;
	size_t aligned_length, skip, count, left, padding, block_size;
	int lba;
	int buffer_not_aligned;

	assert(entity->info != (uintptr_t)NULL);
	cur = (block_dev_state_t *)entity->info;
	ops = &(cur->dev_spec->ops);
	buf = &(cur->dev_spec->buffer);
	block_size = cur->dev_spec->block_size;
	assert((length <= cur->size) &&
	       (length > 0) &&
	       (ops->read != 0));

	if ((buffer & (block_size - 1)) != 0) {
		/*
		 * buffer isn't aligned with block size.
		 * Block device always relies on DMA operation.
		 * It's better to make the buffer as block size aligned.
		 */
		buffer_not_aligned = 1;
	} else {
		buffer_not_aligned = 0;
	}

	skip = cur->file_pos % block_size;
	aligned_length = ((skip + length) + (block_size - 1)) &
			 ~(block_size - 1);
	padding = aligned_length - (skip + length);
	left = aligned_length;
	do {
		lba = (cur->file_pos + cur->base) / block_size;
		if (left >= buf->length) {
			/*
			 * Since left is larger, it's impossible to padding.
			 *
			 * If buffer isn't aligned, we need to use aligned
			 * buffer instead.
			 */
			if (skip || buffer_not_aligned) {
				/*
				 * The beginning address (file_pos) isn't
				 * aligned with block size, we need to use
				 * block buffer to read block. Since block
				 * device is always relied on DMA operation.
				 */
				count = ops->read(lba, buf->offset,
						  buf->length);
			} else {
				count = ops->read(lba, buffer, buf->length);
			}
			assert(count == buf->length);
			cur->file_pos += count - skip;
			if (skip || buffer_not_aligned) {
				/*
				 * Since there's not aligned block size caused
				 * by skip or not aligned buffer, block buffer
				 * is used to store data.
				 */
				memcpy((void *)buffer,
				       (void *)(buf->offset + skip),
				       count - skip);
			}
			left = left - (count - skip);
		} else {
			if (skip || padding || buffer_not_aligned) {
				/*
				 * The beginning address (file_pos) isn't
				 * aligned with block size, we have to read
				 * full block by block buffer instead.
				 * The size isn't aligned with block size.
				 * Use block buffer to avoid overflow.
				 *
				 * If buffer isn't aligned, use block buffer
				 * to avoid DMA error.
				 */
				count = ops->read(lba, buf->offset, left);
			} else
				count = ops->read(lba, buffer, left);
			assert(count == left);
			left = left - (skip + padding);
			cur->file_pos += left;
			if (skip || padding || buffer_not_aligned) {
				/*
				 * Since there's not aligned block size or
				 * buffer, block buffer is used to store data.
				 */
				memcpy((void *)buffer,
				       (void *)(buf->offset + skip),
				       left);
			}
			/* It's already the last block operation */
			left = 0;
		}
		skip = cur->file_pos % block_size;
	} while (left > 0);
	*length_read = length;

	return 0;
}

static int block_write(io_entity_t *entity, const uintptr_t buffer,
		       size_t length, size_t *length_written)
{
	block_dev_state_t *cur;
	io_block_spec_t *buf;
	io_block_ops_t *ops;
	size_t aligned_length, skip, count, left, padding, block_size;
	int lba;
	int buffer_not_aligned;

	assert(entity->info != (uintptr_t)NULL);
	cur = (block_dev_state_t *)entity->info;
	ops = &(cur->dev_spec->ops);
	buf = &(cur->dev_spec->buffer);
	block_size = cur->dev_spec->block_size;
	assert((length <= cur->size) &&
	       (length > 0) &&
	       (ops->read != 0) &&
	       (ops->write != 0));

	if ((buffer & (block_size - 1)) != 0) {
		/*
		 * buffer isn't aligned with block size.
		 * Block device always relies on DMA operation.
		 * It's better to make the buffer as block size aligned.
		 */
		buffer_not_aligned = 1;
	} else {
		buffer_not_aligned = 0;
	}

	skip = cur->file_pos % block_size;
	aligned_length = ((skip + length) + (block_size - 1)) &
			 ~(block_size - 1);
	padding = aligned_length - (skip + length);
	left = aligned_length;
	do {
		lba = (cur->file_pos + cur->base) / block_size;
		if (left >= buf->length) {
			/* Since left is larger, it's impossible to padding. */
			if (skip || buffer_not_aligned) {
				/*
				 * The beginning address (file_pos) isn't
				 * aligned with block size or buffer isn't
				 * aligned, we need to use block buffer to
				 * write block.
				 */
				count = ops->read(lba, buf->offset,
						  buf->length);
				assert(count == buf->length);
				memcpy((void *)(buf->offset + skip),
				       (void *)buffer,
				       count - skip);
				count = ops->write(lba, buf->offset,
						   buf->length);
			} else
				count = ops->write(lba, buffer, buf->length);
			assert(count == buf->length);
			cur->file_pos += count - skip;
			left = left - (count - skip);
		} else {
			if (skip || padding || buffer_not_aligned) {
				/*
				 * The beginning address (file_pos) isn't
				 * aligned with block size, we need to avoid
				 * poluate data in the beginning. Reading and
				 * skipping the beginning is the only way.
				 * The size isn't aligned with block size.
				 * Use block buffer to avoid overflow.
				 *
				 * If buffer isn't aligned, use block buffer
				 * to avoid DMA error.
				 */
				count = ops->read(lba, buf->offset, left);
				assert(count == left);
				memcpy((void *)(buf->offset + skip),
				       (void *)buffer,
				       left - skip - padding);
				count = ops->write(lba, buf->offset, left);
			} else
				count = ops->write(lba, buffer, left);
			assert(count == left);
			cur->file_pos += left - (skip + padding);
			/* It's already the last block operation */
			left = 0;
		}
		skip = cur->file_pos % block_size;
	} while (left > 0);
	*length_written = length;
	return 0;
}

static int block_close(io_entity_t *entity)
{
	entity->info = (uintptr_t)NULL;
	return 0;
}

static int block_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info)
{
	block_dev_state_t *cur;
	io_block_spec_t *buffer;
	io_dev_info_t *info;
	size_t block_size;
	int result;

	assert(dev_info != NULL);
	result = allocate_dev_info(&info);
	if (result)
		return -ENOENT;

	cur = (block_dev_state_t *)info->info;
	/* dev_spec is type of io_block_dev_spec_t. */
	cur->dev_spec = (io_block_dev_spec_t *)dev_spec;
	buffer = &(cur->dev_spec->buffer);
	block_size = cur->dev_spec->block_size;
	assert((block_size > 0) &&
	       (is_power_of_2(block_size) != 0) &&
	       ((buffer->offset % block_size) == 0) &&
	       ((buffer->length % block_size) == 0));

	*dev_info = info;	/* cast away const */
	(void)block_size;
	(void)buffer;
	return 0;
}

static int block_dev_close(io_dev_info_t *dev_info)
{
	return free_dev_info(dev_info);
}

/* Exported functions */

/* Register the Block driver with the IO abstraction */
int register_io_dev_block(const io_dev_connector_t **dev_con)
{
	int result;

	assert(dev_con != NULL);

	/*
	 * Since dev_info isn't really used in io_register_device, always
	 * use the same device info at here instead.
	 */
	result = io_register_device(&dev_info_pool[0]);
	if (result == 0)
		*dev_con = &block_dev_connector;
	return result;
}
