/* SPDX-License-Identifier: Apache-2.0 */
/* Copyright (C) 2018 IBM Corp. */
/* Copyright (C) 2018 Evan Lojewski. */

#ifndef BACKEND_H
#define BACKEND_H

#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <mtd/mtd-abi.h>

#define FLASH_DIRTY	0x00
#define FLASH_ERASED	0x01

/* Estimate as to how long (milliseconds) it takes to access a MB from flash */
#define FLASH_ACCESS_MS_PER_MB		8000

struct backend backend_get_mtd(void);
struct backend backend_get_file(void);
struct backend backend_get_vpnor(void);

enum backend_reset_mode { reset_lpc_flash, reset_lpc_memory };

struct backend_ops;

struct backend {
	const struct backend_ops *ops;

	/* Backend private data */
	void *priv;

	/* Flash size from command line (bytes) */
	uint32_t flash_size;

	/* Erase size (as a shift) */
	uint32_t erase_size_shift;
	/* Block size (as a shift) */
	uint32_t block_size_shift;
};

struct backend_ops {
	/*
	 * init() - Main initialization function for backing device
	 * @context:	The backend context pointer
	 * @data:	Additional backend-implementation-specifc data
	 * Return:	Zero on success, otherwise negative error
	 */
	int 	(*init)(struct backend *backend, void *data);

	/*
	 * free() - Main teardown function for backing device
	 * @context:	The backend context pointer
	 */
	void 	(*free)(struct backend *backend);

	/*
	 * copy() - Copy data from the flash device into a provided buffer
	 * @context:	The mbox context pointer
	 * @offset:	The flash offset to copy from (bytes)
	 * @mem:	The buffer to copy into (must be of atleast 'size' bytes)
	 * @size:	The number of bytes to copy
	 * Return:	Number of bytes copied on success, otherwise negative error
	 *		code. flash_copy will copy at most 'size' bytes, but it may
	 *		copy less.
	 */
	int64_t (*copy)(struct backend *backend, uint32_t offset, void *mem,
			uint32_t size);

	/*
	 * set_bytemap() - Set the flash erased bytemap
	 * @context:	The mbox context pointer
	 * @offset:	The flash offset to set (bytes)
	 * @count:	Number of bytes to set
	 * @val:	Value to set the bytemap to
	 *
	 * The flash bytemap only tracks the erased status at the erase block level so
	 * this will update the erased state for an (or many) erase blocks
	 *
	 * Return:	0 if success otherwise negative error code
	 */
	 int 	(*set_bytemap)(struct backend *backend, uint32_t offset,
			       uint32_t count, uint8_t val);

	/*
	 * erase() - Erase the flash
	 * @context:	The backend context pointer
	 * @offset:	The flash offset to erase (bytes)
	 * @size:	The number of bytes to erase
	 *
	 * Return:	0 on success otherwise negative error code
	 */
	int 	(*erase)(struct backend *backend, uint32_t offset,
			 uint32_t count);
	/*
	 * write() - Write the flash from a provided buffer
	 * @context:	The backend context pointer
	 * @offset:	The flash offset to write to (bytes)
	 * @buf:	The buffer to write from (must be of atleast size)
	 * @size:	The number of bytes to write
	 *
	 * Return:	0 on success otherwise negative error code
	 */
	int 	(*write)(struct backend *backend, uint32_t offset, void *buf,
			 uint32_t count);

	/*
	 * validate() - Validates a requested window
	 * @context:	The backend context pointer
	 * @offset:	The requested flash offset
	 * @size:	The requested region size
	 * @ro:		The requested access type: True for read-only, false
	 *		for read-write
	 *
	 * Return:	0 on valid otherwise negative error code
	 */
	int 	(*validate)(struct backend *backend,
			    uint32_t offset, uint32_t size, bool ro);

	/*
	 * reset() - Ready the reserved memory for host startup
	 * @context:    The backend context pointer
	 * @buf:	The LPC reserved memory pointer
	 * @count	The size of the LPC reserved memory region
	 *
	 * Return:      0 on success otherwise negative error code
	 */
	int	(*reset)(struct backend *backend, void *buf, uint32_t count);
};

/* Make this better */
static inline int backend_init(struct backend *master, struct backend *with,
			       void *data)
{
	int rc;

	assert(master);

	/* FIXME: A bit hacky? */
	with->flash_size = master->flash_size;
	*master = *with;

#ifndef NDEBUG
	/* Set some poison values to ensure backends init properly */
	master->erase_size_shift = 33;
	master->block_size_shift = 34;
#endif

	assert(master->ops->init);

	rc = master->ops->init(master, data);
	if (rc < 0)
		return rc;

	assert(master->erase_size_shift < 32);
	assert(master->block_size_shift < 32);

	return 0;
}

static inline void backend_free(struct backend *backend)
{
	assert(backend);

	if (backend->ops->free)
		backend->ops->free(backend);
}

static inline int64_t backend_copy(struct backend *backend,
				   uint32_t offset, void *mem, uint32_t size)
{
	assert(backend);
	assert(backend->ops->copy);
	return backend->ops->copy(backend, offset, mem, size);

}

static inline int backend_set_bytemap(struct backend *backend,
				      uint32_t offset, uint32_t count,
				      uint8_t val)
{
	assert(backend);

	if (backend->ops->set_bytemap)
		return backend->ops->set_bytemap(backend, offset, count, val);

	return 0;
}

static inline int backend_erase(struct backend *backend, uint32_t offset,
				uint32_t count)
{
	assert(backend);
	if (backend->ops->erase)
		return backend->ops->erase(backend, offset, count);

	return 0;
}

static inline int backend_write(struct backend *backend, uint32_t offset,
				void *buf, uint32_t count)
{
	assert(backend);
	assert(backend->ops->write);
	return backend->ops->write(backend, offset, buf, count);
}

static inline int backend_validate(struct backend *backend,
				   uint32_t offset, uint32_t size, bool ro)
{
	assert(backend);

	if (backend->ops->validate)
		return backend->ops->validate(backend, offset, size, ro);

	return 0;
}

static inline int backend_reset(struct backend *backend, void *buf,
				uint32_t count)
{
	assert(backend);
	assert(backend->ops->reset);
	return backend->ops->reset(backend, buf, count);
}

int backend_probe_mtd(struct backend *master, const char *path);
int backend_probe_file(struct backend *master, const char *path);
/* Avoid dependency on vpnor/mboxd_pnor_partition_table.h */
struct vpnor_partition_paths;
int backend_probe_vpnor(struct backend *master,
                        const struct vpnor_partition_paths *paths);

#endif /* BACKEND_H */
