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

#define _GNU_SOURCE
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <poll.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/timerfd.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <inttypes.h>
#include <mtd/mtd-abi.h>

#include "mbox.h"
#include "common.h"
#include "transport_mbox.h"
#include "windows.h"
#include "flash.h"

/* Initialisation Functions */

/*
 * init_window_state() - Initialise a new window to a known state
 * @window:	The window to initialise
 * @size:	The size of the window
 */
static void init_window_state(struct window_context *window, uint32_t size)
{
	window->mem = NULL;
	window->flash_offset = FLASH_OFFSET_UNINIT;
	window->size = size;
	window->dirty_bmap = NULL;
	window->age = 0;
}

/*
 * init_window_mem() - Divide the reserved memory region among the windows
 * @context:	The mbox context pointer
 *
 * Return:	0 on success otherwise negative error code
 */
static int init_window_mem(struct mbox_context *context)
{
	void *mem_location = context->mem;
	int i;

	/*
	 * Carve up the reserved memory region and allocate it to each of the
	 * windows. The windows are placed one after the other in ascending
	 * order, so the first window will be first in memory and so on. We
	 * shouldn't have allocated more windows than we have memory, but if we
	 * did we will error out here
	 */
	for (i = 0; i < context->windows.num; i++) {
		uint32_t size = context->windows.window[i].size;
		MSG_DBG("Window %d @ %p for size 0x%.8x\n", i,
			mem_location, size);
		context->windows.window[i].mem = mem_location;
		mem_location += size;
		if (mem_location > (context->mem + context->mem_size)) {
			/* Tried to allocate window past the end of memory */
			MSG_ERR("Total size of windows exceeds reserved mem\n");
			MSG_ERR("Try smaller or fewer windows\n");
			MSG_ERR("Mem size: 0x%.8x\n", context->mem_size);
			return -1;
		}
	}

	return 0;
}
/*
 * windows_init() - Initalise the window cache
 * @context:    The mbox context pointer
 *
 * Return:      0 on success otherwise negative
 */
int windows_init(struct mbox_context *context)
{
	int i;

	/* Check if window size and number set - otherwise set to default */
	if (!context->windows.default_size) {
		/* Default to 1MB windows */
		context->windows.default_size = 1 << 20;
	}
	MSG_INFO("Window size: 0x%.8x\n", context->windows.default_size);
	if (!context->windows.num) {
		/* Use the entire reserved memory region by default */
		context->windows.num = context->mem_size /
				       context->windows.default_size;
	}
	MSG_INFO("Number of windows: %d\n", context->windows.num);

	context->windows.window = calloc(context->windows.num,
					 sizeof(*context->windows.window));
	if (!context->windows.window) {
		MSG_ERR("Memory allocation failed\n");
		return -1;
	}

	for (i = 0; i < context->windows.num; i++) {
		init_window_state(&context->windows.window[i],
				  context->windows.default_size);
	}

	return init_window_mem(context);
}

/*
 * windows_free() - Free the window cache
 * @context:	The mbox context pointer
 */
void windows_free(struct mbox_context *context)
{
	int i;

	/* Check window cache has actually been allocated */
	if (context->windows.window) {
		for (i = 0; i < context->windows.num; i++) {
			free(context->windows.window[i].dirty_bmap);
		}
		free(context->windows.window);
	}
}

/* Write from Window Functions */

/*
 * window_flush_v1() - Handle writing when erase and block size differ
 * @context:		The mbox context pointer
 * @offset_bytes:	The offset in the current window to write from (bytes)
 * @count_bytes:	Number of bytes to write
 *
 * Handle a window_flush for dirty memory when block_size is less than the
 * flash erase size
 * This requires us to be a bit careful because we might have to erase more
 * than we want to write which could result in data loss if we don't have the
 * entire portion of flash to be erased already saved in memory (for us to
 * write back after the erase)
 *
 * Return:	0 on success otherwise negative error code
 */
int window_flush_v1(struct mbox_context *context,
			 uint32_t offset_bytes, uint32_t count_bytes)
{
	int rc;
	uint32_t flash_offset;
	struct window_context low_mem = { 0 }, high_mem = { 0 };

	/* Find where in phys flash this is based on the window.flash_offset */
	flash_offset = context->current->flash_offset + offset_bytes;

	/*
	 * low_mem.flash_offset = erase boundary below where we're writing
	 * low_mem.size = size from low_mem.flash_offset to where we're writing
	 *
	 * high_mem.flash_offset = end of where we're writing
	 * high_mem.size = size from end of where we're writing to next erase
	 * 		   boundary
	 */
	low_mem.flash_offset = align_down(flash_offset,
					  context->mtd_info.erasesize);
	low_mem.size = flash_offset - low_mem.flash_offset;
	high_mem.flash_offset = flash_offset + count_bytes;
	high_mem.size = align_up(high_mem.flash_offset,
				 context->mtd_info.erasesize) -
			high_mem.flash_offset;

	/*
	 * Check if we already have a copy of the required flash areas in
	 * memory as part of the existing window
	 */
	if (low_mem.flash_offset < context->current->flash_offset) {
		/* Before the start of our current window */
		low_mem.mem = malloc(low_mem.size);
		if (!low_mem.mem) {
			MSG_ERR("Unable to allocate memory\n");
			return -ENOMEM;
		}
		rc = flash_copy(context, low_mem.flash_offset,
				low_mem.mem, low_mem.size);
		if (rc < 0) {
			goto out;
		}
	}
	if ((high_mem.flash_offset + high_mem.size) >
	    (context->current->flash_offset + context->current->size)) {
		/* After the end of our current window */
		high_mem.mem = malloc(high_mem.size);
		if (!high_mem.mem) {
			MSG_ERR("Unable to allocate memory\n");
			rc = -ENOMEM;
			goto out;
		}
		rc = flash_copy(context, high_mem.flash_offset,
				high_mem.mem, high_mem.size);
		if (rc < 0) {
			goto out;
		}
	}

	/*
	 * We need to erase the flash from low_mem.flash_offset->
	 * high_mem.flash_offset + high_mem.size
	 */
	rc = flash_erase(context, low_mem.flash_offset,
			 (high_mem.flash_offset - low_mem.flash_offset) +
			 high_mem.size);
	if (rc < 0) {
		MSG_ERR("Couldn't erase flash\n");
		goto out;
	}

	/* Write back over the erased area */
	if (low_mem.mem) {
		/* Exceed window at the start */
		rc = flash_write(context, low_mem.flash_offset, low_mem.mem,
				 low_mem.size);
		if (rc < 0) {
			goto out;
		}
	}
	rc = flash_write(context, flash_offset,
			 context->current->mem + offset_bytes, count_bytes);
	if (rc < 0) {
		goto out;
	}
	/*
	 * We still need to write the last little bit that we erased - it's
	 * either in the current window or the high_mem window.
	 */
	if (high_mem.mem) {
		/* Exceed window at the end */
		rc = flash_write(context, high_mem.flash_offset, high_mem.mem,
				 high_mem.size);
		if (rc < 0) {
			goto out;
		}
	} else {
		/* Write from the current window - it's atleast that big */
		rc = flash_write(context, high_mem.flash_offset,
				 context->current->mem + offset_bytes +
				 count_bytes, high_mem.size);
		if (rc < 0) {
			goto out;
		}
	}

out:
	free(low_mem.mem);
	free(high_mem.mem);
	return rc;
}

/*
 * window_flush() - Write back to the flash from the current window
 * @context:		The mbox context pointer
 * @offset_bytes:	The offset in the current window to write from (blocks)
 * @count_bytes:	Number of blocks to write
 * @type:		Whether this is an erase & write or just an erase
 *
 * Return:	0 on success otherwise negative error code
 */
int window_flush(struct mbox_context *context, uint32_t offset,
		      uint32_t count, uint8_t type)
{
	int rc;
	uint32_t flash_offset, count_bytes = count << context->block_size_shift;
	uint32_t offset_bytes = offset << context->block_size_shift;

	switch (type) {
	case WINDOW_ERASED: /* >= V2 ONLY -> block_size == erasesize */
		flash_offset = context->current->flash_offset + offset_bytes;
		rc = flash_erase(context, flash_offset, count_bytes);
		if (rc < 0) {
			MSG_ERR("Couldn't erase flash\n");
			return rc;
		}
		break;
	case WINDOW_DIRTY:
		/*
		 * For protocol V1, block_size may be smaller than erase size
		 * so we have a special function to make sure that we do this
		 * correctly without losing data.
		 */
		if (log_2(context->mtd_info.erasesize) !=
						context->block_size_shift) {
			return window_flush_v1(context, offset_bytes,
						    count_bytes);
		}
		flash_offset = context->current->flash_offset + offset_bytes;

		/* Erase the flash */
		rc = flash_erase(context, flash_offset, count_bytes);
		if (rc < 0) {
			return rc;
		}

		/* Write to the erased flash */
		rc = flash_write(context, flash_offset,
				 context->current->mem + offset_bytes,
				 count_bytes);
		if (rc < 0) {
			return rc;
		}

		break;
	default:
		/* We shouldn't be able to get here */
		MSG_ERR("Write from window with invalid type: %d\n", type);
		return -EPERM;
	}

	return 0;
}

/* Window Management Functions */

/*
 * windows_alloc_dirty_bytemap() - (re)allocate all the window dirty bytemaps
 * @context:		The mbox context pointer
 */
void windows_alloc_dirty_bytemap(struct mbox_context *context)
{
	struct window_context *cur;
	int i;

	for (i = 0; i < context->windows.num; i++) {
		cur = &context->windows.window[i];
		/* There may already be one allocated */
		free(cur->dirty_bmap);
		/* Allocate the new one */
		cur->dirty_bmap = calloc((cur->size >>
					  context->block_size_shift),
					 sizeof(*cur->dirty_bmap));
	}
}

/*
 * window_set_bytemap() - Set the window bytemap
 * @context:	The mbox context pointer
 * @cur:	The window to set the bytemap of
 * @offset:	Where in the window to set the bytemap (blocks)
 * @size:	The number of blocks to set
 * @val:	The value to set the bytemap to
 *
 * Return:	0 on success otherwise negative error code
 */
int window_set_bytemap(struct mbox_context *context, struct window_context *cur,
		       uint32_t offset, uint32_t size, uint8_t val)
{
	if (offset + size > (cur->size >> context->block_size_shift)) {
		MSG_ERR("Tried to set window bytemap past end of window\n");
		MSG_ERR("Requested offset: 0x%x size: 0x%x window size: 0x%x\n",
			offset << context->block_size_shift,
			size << context->block_size_shift,
			cur->size << context->block_size_shift);
		return -EACCES;
	}

	memset(cur->dirty_bmap + offset, val, size);
	return 0;
}

/*
 * windows_close_current() - Close the current (active) window
 * @context:   		The mbox context pointer
 * @set_bmc_event:	Whether to set the bmc event bit
 * @flags:		Flags as defined for a close command in the protocol
 *
 * This closes the current window. If the host has requested the current window
 * be closed then we don't need to set the bmc event bit
 * (set_bmc_event == false), otherwise if the current window has been closed
 * without the host requesting it the bmc event bit must be set to indicate this
 * to the host (set_bmc_event == true).
 */
void windows_close_current(struct mbox_context *context, bool set_bmc_event,
			  uint8_t flags)
{
	MSG_DBG("Close current window, flags: 0x%.2x\n", flags);

	if (set_bmc_event) {
		set_bmc_events(context, BMC_EVENT_WINDOW_RESET, SET_BMC_EVENT);
	}

	if (flags & FLAGS_SHORT_LIFETIME) {
		context->current->age = 0;
	}

	context->current = NULL;
	context->current_is_write = false;
}

/*
 * window_reset() - Reset a window context to a well defined default state
 * @context:   	The mbox context pointer
 * @window:	The window to reset
 */
void window_reset(struct mbox_context *context, struct window_context *window)
{
	window->flash_offset = FLASH_OFFSET_UNINIT;
	window->size = context->windows.default_size;
	if (window->dirty_bmap) { /* Might not have been allocated */
		window_set_bytemap(context, window, 0,
				   window->size >> context->block_size_shift,
				   WINDOW_CLEAN);
	}
	window->age = 0;
}

/*
 * windows_reset_all() - Reset all windows to a well defined default state
 * @context:		The mbox context pointer
 * @set_bmc_event:	If any state change should be indicated to the host
 */
void windows_reset_all(struct mbox_context *context, bool set_bmc_event)
{
	int i;

	MSG_DBG("Resetting all windows\n");
	/* We might have an open window which needs closing */
	if (context->current) {
		windows_close_current(context, set_bmc_event, FLAGS_NONE);
	}
	for (i = 0; i < context->windows.num; i++) {
		window_reset(context, &context->windows.window[i]);
	}

	context->windows.max_age = 0;
}

/*
 * windows_find_oldest() - Find the oldest (Least Recently Used) window
 * @context:		The mbox context pointer
 *
 * Return:	Pointer to the least recently used window
 */
struct window_context *windows_find_oldest(struct mbox_context *context)
{
	struct window_context *oldest = NULL, *cur;
	uint32_t min_age = context->windows.max_age + 1;
	int i;

	for (i = 0; i < context->windows.num; i++) {
		cur = &context->windows.window[i];

		if (cur->age < min_age) {
			min_age = cur->age;
			oldest = cur;
		}
	}

	return oldest;
}

/*
 * windows_find_largest() - Find the largest window in the window cache
 * @context:	The mbox context pointer
 *
 * Return:	The largest window
 */
struct window_context *windows_find_largest(struct mbox_context *context)
{
	struct window_context *largest = NULL, *cur;
	uint32_t max_size = 0;
	int i;

	for (i = 0; i < context->windows.num; i++) {
		cur = &context->windows.window[i];

		if (cur->size > max_size) {
			max_size = cur->size;
			largest = cur;
		}
	}

	return largest;
}

/*
 * windows_search() - Search the window cache for a window containing offset
 * @context:	The mbox context pointer
 * @offset:	Absolute flash offset to search for (bytes)
 * @exact:	If the window must exactly map the requested offset
 *
 * This will search the cache of windows for one containing the requested
 * offset. For V1 of the protocol windows must exactly map the offset since we
 * can't tell the host how much of its request we actually mapped and it will
 * thus assume it can access window->size from the offset we give it.
 *
 * Return:	Pointer to a window containing the requested offset otherwise
 *		NULL
 */
struct window_context *windows_search(struct mbox_context *context,
				      uint32_t offset, bool exact)
{
	struct window_context *cur;
	int i;

	MSG_DBG("Searching for window which contains 0x%.8x %s\n",
		offset, exact ? "exactly" : "");
	for (i = 0; i < context->windows.num; i++) {
		cur = &context->windows.window[i];
		if (cur->flash_offset == FLASH_OFFSET_UNINIT) {
			/* Uninitialised Window */
			if (offset == FLASH_OFFSET_UNINIT) {
				return cur;
			}
			continue;
		}
		if ((offset >= cur->flash_offset) &&
		    (offset < (cur->flash_offset + cur->size))) {
			if (exact && (cur->flash_offset != offset)) {
				continue;
			}
			/* This window contains the requested offset */
			cur->age = ++(context->windows.max_age);
			return cur;
		}
	}

	return NULL;
}

/*
 * windows_create_map() - Create a window mapping which maps the requested offset
 * @context:		The mbox context pointer
 * @this_window:	A pointer to update to the "new" window
 * @offset:		Absolute flash offset to create a mapping for (bytes)
 * @exact:		If the window must exactly map the requested offset
 *
 * This is used to create a window mapping for the requested offset when there
 * is no existing window in the cache which satisfies the offset. This involves
 * choosing an existing window from the window cache to evict so we can use it
 * to store the flash contents from the requested offset, we then point the
 * caller to that window since it now maps their request.
 *
 * Return:	0 on success otherwise negative error code
 */
int windows_create_map(struct mbox_context *context,
		      struct window_context **this_window, uint32_t offset,
		      bool exact)
{
	struct window_context *cur = NULL;
	int rc;

	MSG_DBG("Creating window which maps 0x%.8x %s\n", offset,
		exact ? "exactly" : "");

	/* Search for an uninitialised window, use this before evicting */
	cur = windows_search(context, FLASH_OFFSET_UNINIT, true);

	/* No uninitialised window found, we need to choose one to "evict" */
	if (!cur) {
		MSG_DBG("No uninitialised window, evicting one\n");
		cur = windows_find_oldest(context);
		window_reset(context, cur);
	}

/*
 * In case of the virtual pnor, as of now it's possible that a window may
 * have content less than it's max size. We basically copy one flash partition
 * per window, and some partitions are smaller than the max size. An offset
 * right after such a small partition ends should lead to new mapping. The code
 * below prevents that.
 */
#ifndef VIRTUAL_PNOR_ENABLED
	if (!exact) {
		/*
		 * It would be nice to align the offsets which we map to window
		 * size, this will help prevent overlap which would be an
		 * inefficient use of our reserved memory area (we would like
		 * to "cache" as much of the acutal flash as possible in
		 * memory). If we're protocol V1 however we must ensure the
		 * offset requested is exactly mapped.
		 */
		offset &= ~(cur->size - 1);
	}
#endif

	if (offset > context->flash_size) {
		MSG_ERR("Tried to open read window past flash limit\n");
		return -EINVAL;
	} else if ((offset + cur->size) > context->flash_size) {
		/*
		 * There is V1 skiboot implementations out there which don't
		 * mask offset with window size, meaning when we have
		 * window size == flash size we will never allow the host to
		 * open a window except at 0x0, which isn't always where the
		 * host requests it. Thus we have to ignore this check and just
		 * hope the host doesn't access past the end of the window
		 * (which it shouldn't) for V1 implementations to get around
		 * this.
		 */
		if (context->version == API_VERSION_1) {
			cur->size = align_down(context->flash_size - offset,
					       1 << context->block_size_shift);
		} else {
			/*
			 * Allow requests to exceed the flash size, but limit
			 * the response to the size of the flash.
			 */
			cur->size = context->flash_size - offset;
		}
	}

	/* Copy from flash into the window buffer */
	rc = flash_copy(context, offset, cur->mem, cur->size);
	if (rc < 0) {
		/* We don't know how much we've copied -> better reset window */
		window_reset(context, cur);
		return rc;
	}
	/*
	 * rc isn't guaranteed to be aligned, so align up
	 *
	 * FIXME: This should only be the case for the vpnor ToC now, so handle
	 * it there
	 */
	cur->size = align_up(rc, (1ULL << context->block_size_shift));
	/* Would like a known value, pick 0xFF to it looks like erased flash */
	memset(cur->mem + rc, 0xFF, cur->size - rc);

	/*
	 * Since for V1 windows aren't constrained to start at multiples of
	 * window size it's possible that something already maps this offset.
	 * Reset any windows which map this offset to avoid coherency problems.
	 * We just have to check for anything which maps the start or the end
	 * of the window since all windows are the same size so another window
	 * cannot map just the middle of this window.
	 */
	if (context->version == API_VERSION_1) {
		uint32_t i;

		MSG_DBG("Checking for window overlap\n");

		for (i = offset; i < (offset + cur->size); i += (cur->size - 1)) {
			struct window_context *tmp = NULL;
			do {
				tmp = windows_search(context, i, false);
				if (tmp) {
					window_reset(context, tmp);
				}
			} while (tmp);
		}
	}

	/* Clear the bytemap of the window just loaded -> we know it's clean */
	window_set_bytemap(context, cur, 0,
			   cur->size >> context->block_size_shift,
			   WINDOW_CLEAN);

	/* Update so we know what's in the window */
	cur->flash_offset = offset;
	cur->age = ++(context->windows.max_age);
	*this_window = cur;

	return 0;
}
