/*
 * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <string.h>

#include <common/debug.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_storage.h>

#include "io_common.h"
#include "io_private.h"
#include "io_memdrv.h"
#include "rcar_def.h"

extern void rcar_dma_exec(uintptr_t dst, uint32_t src, uint32_t len);

static int32_t memdrv_dev_open(const uintptr_t dev __attribute__ ((unused)),
			       io_dev_info_t **dev_info);
static int32_t memdrv_dev_close(io_dev_info_t *dev_info);

/* As we need to be able to keep state for seek, only one file can be open
 * at a time. Make this a structure and point to the entity->info. When we
 * can malloc memory we can change this to support more open files.
 */
typedef struct {
	uint32_t in_use;
	uintptr_t base;
	ssize_t file_pos;
} file_state_t;

static file_state_t current_file = { 0 };

static io_type_t device_type_memdrv(void)
{
	return IO_TYPE_MEMMAP;
}

static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
				 io_entity_t *entity)
{
	const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec;

	/* Since we need to track open state for seek() we only allow one open
	 * spec at a time. When we have dynamic memory we can malloc and set
	 * entity->info.
	 */
	if (current_file.in_use)
		return IO_RESOURCES_EXHAUSTED;

	/* File cursor offset for seek and incremental reads etc. */
	current_file.base = block_spec->offset;
	current_file.file_pos = 0;
	current_file.in_use = 1;

	entity->info = (uintptr_t) &current_file;

	return IO_SUCCESS;
}

static int32_t memdrv_block_seek(io_entity_t *entity, int32_t mode,
				 ssize_t offset)
{
	if (mode != IO_SEEK_SET)
		return IO_FAIL;

	((file_state_t *) entity->info)->file_pos = offset;

	return IO_SUCCESS;
}

static int32_t memdrv_block_read(io_entity_t *entity, uintptr_t buffer,
				 size_t length, size_t *cnt)
{
	file_state_t *fp;

	fp = (file_state_t *) entity->info;

	NOTICE("BL2: dst=0x%lx src=0x%lx len=%ld(0x%lx)\n",
	       buffer, fp->base + fp->file_pos, length, length);

	if (FLASH_MEMORY_SIZE < fp->file_pos + length) {
		ERROR("BL2: check load image (source address)\n");
		return IO_FAIL;
	}

	rcar_dma_exec(buffer, fp->base + fp->file_pos, length);
	fp->file_pos += length;
	*cnt = length;

	return IO_SUCCESS;
}

static int32_t memdrv_block_close(io_entity_t *entity)
{
	entity->info = 0U;

	memset((void *)&current_file, 0, sizeof(current_file));

	return IO_SUCCESS;
}

static const io_dev_funcs_t memdrv_dev_funcs = {
	.type = &device_type_memdrv,
	.open = &memdrv_block_open,
	.seek = &memdrv_block_seek,
	.size = NULL,
	.read = &memdrv_block_read,
	.write = NULL,
	.close = &memdrv_block_close,
	.dev_init = NULL,
	.dev_close = &memdrv_dev_close,
};

static const io_dev_info_t memdrv_dev_info = {
	.funcs = &memdrv_dev_funcs,
	.info = 0,
};

static const io_dev_connector_t memdrv_dev_connector = {
	.dev_open = &memdrv_dev_open
};

static int32_t memdrv_dev_open(const uintptr_t dev __attribute__ ((unused)),
			       io_dev_info_t **dev_info)
{
	*dev_info = (io_dev_info_t *) &memdrv_dev_info;

	return IO_SUCCESS;
}

static int32_t memdrv_dev_close(io_dev_info_t *dev_info)
{
	return IO_SUCCESS;
}

int32_t rcar_register_io_dev_memdrv(const io_dev_connector_t **dev_con)
{
	int32_t result;

	result = io_register_device(&memdrv_dev_info);
	if (result == IO_SUCCESS)
		*dev_con = &memdrv_dev_connector;

	return result;
}
