// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2011-2012 The Chromium OS Authors.
 */

#include <common.h>
#include <autoboot.h>
#include <bloblist.h>
#include <errno.h>
#include <fdtdec.h>
#include <log.h>
#include <os.h>
#include <trace.h>
#include <asm/malloc.h>
#include <asm/state.h>
#include <asm/test.h>

/* Main state record for the sandbox */
static struct sandbox_state main_state;
static struct sandbox_state *state;	/* Pointer to current state record */

static int state_ensure_space(int extra_size)
{
	void *blob = state->state_fdt;
	int used, size, free_bytes;
	void *buf;
	int ret;

	used = fdt_off_dt_strings(blob) + fdt_size_dt_strings(blob);
	size = fdt_totalsize(blob);
	free_bytes = size - used;
	if (free_bytes > extra_size)
		return 0;

	size = used + extra_size;
	buf = os_malloc(size);
	if (!buf)
		return -ENOMEM;

	ret = fdt_open_into(blob, buf, size);
	if (ret) {
		os_free(buf);
		return -EIO;
	}

	os_free(blob);
	state->state_fdt = buf;
	return 0;
}

static int state_read_file(struct sandbox_state *state, const char *fname)
{
	loff_t size;
	int ret;
	int fd;

	ret = os_get_filesize(fname, &size);
	if (ret < 0) {
		printf("Cannot find sandbox state file '%s'\n", fname);
		return -ENOENT;
	}
	state->state_fdt = os_malloc(size);
	if (!state->state_fdt) {
		puts("No memory to read sandbox state\n");
		return -ENOMEM;
	}
	fd = os_open(fname, OS_O_RDONLY);
	if (fd < 0) {
		printf("Cannot open sandbox state file '%s'\n", fname);
		ret = -EPERM;
		goto err_open;
	}
	if (os_read(fd, state->state_fdt, size) != size) {
		printf("Cannot read sandbox state file '%s'\n", fname);
		ret = -EIO;
		goto err_read;
	}
	os_close(fd);

	return 0;
err_read:
	os_close(fd);
err_open:
	/*
	 * tainted scalar, since size is obtained from the file. But we can rely
	 * on os_malloc() to handle invalid values.
	 */
	os_free(state->state_fdt);
	state->state_fdt = NULL;

	return ret;
}

/***
 * sandbox_read_state_nodes() - Read state associated with a driver
 *
 * This looks through all compatible nodes and calls the read function on
 * each one, to read in the state.
 *
 * If nothing is found, it still calls the read function once, to set up a
 * single global state for that driver.
 *
 * @state: Sandbox state
 * @io: Method to use for reading state
 * @blob: FDT containing state
 * Return: 0 if OK, -EINVAL if the read function returned failure
 */
int sandbox_read_state_nodes(struct sandbox_state *state,
			     struct sandbox_state_io *io, const void *blob)
{
	int count;
	int node;
	int ret;

	debug("   - read %s\n", io->name);
	if (!io->read)
		return 0;

	node = -1;
	count = 0;
	while (blob) {
		node = fdt_node_offset_by_compatible(blob, node, io->compat);
		if (node < 0)
			return 0;	/* No more */
		debug("   - read node '%s'\n", fdt_get_name(blob, node, NULL));
		ret = io->read(blob, node);
		if (ret) {
			printf("Unable to read state for '%s'\n", io->compat);
			return -EINVAL;
		}
		count++;
	}

	/*
	 * If we got no saved state, call the read function once without a
	 * node, to set up the global state.
	 */
	if (count == 0) {
		debug("   - read global\n");
		ret = io->read(NULL, -1);
		if (ret) {
			printf("Unable to read global state for '%s'\n",
			       io->name);
			return -EINVAL;
		}
	}

	return 0;
}

int sandbox_read_state(struct sandbox_state *state, const char *fname)
{
	struct sandbox_state_io *io;
	const void *blob;
	bool got_err;
	int ret;

	if (state->read_state && fname) {
		ret = state_read_file(state, fname);
		if (ret == -ENOENT && state->ignore_missing_state_on_read)
			ret = 0;
		if (ret)
			return ret;
	}

	/* Call all the state read functions */
	got_err = false;
	blob = state->state_fdt;
	io = ll_entry_start(struct sandbox_state_io, state_io);
	for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) {
		ret = sandbox_read_state_nodes(state, io, blob);
		if (ret < 0)
			got_err = true;
	}

	if (state->read_state && fname) {
		debug("Read sandbox state from '%s'%s\n", fname,
		      got_err ? " (with errors)" : "");
	}

	return got_err ? -1 : 0;
}

/***
 * sandbox_write_state_node() - Write state associated with a driver
 *
 * This calls the write function to write out global state for that driver.
 *
 * TODO(sjg@chromium.org): Support writing out state from multiple drivers
 * of the same time. We don't need this yet,and it will be much easier to
 * do when driver model is available.
 *
 * @state: Sandbox state
 * @io: Method to use for writing state
 * Return: 0 if OK, -EIO if there is a fatal error (such as out of space
 * for adding the data), -EINVAL if the write function failed.
 */
int sandbox_write_state_node(struct sandbox_state *state,
			     struct sandbox_state_io *io)
{
	void *blob;
	int node;
	int ret;

	if (!io->write)
		return 0;

	ret = state_ensure_space(SANDBOX_STATE_MIN_SPACE);
	if (ret) {
		printf("Failed to add more space for state\n");
		return -EIO;
	}

	/* The blob location can change when the size increases */
	blob = state->state_fdt;
	node = fdt_node_offset_by_compatible(blob, -1, io->compat);
	if (node == -FDT_ERR_NOTFOUND) {
		node = fdt_add_subnode(blob, 0, io->name);
		if (node < 0) {
			printf("Cannot create node '%s': %s\n", io->name,
			       fdt_strerror(node));
			return -EIO;
		}

		if (fdt_setprop_string(blob, node, "compatible", io->compat)) {
			puts("Cannot set compatible\n");
			return -EIO;
		}
	} else if (node < 0) {
		printf("Cannot access node '%s': %s\n", io->name,
		       fdt_strerror(node));
		return -EIO;
	}
	debug("Write state for '%s' to node %d\n", io->compat, node);
	ret = io->write(blob, node);
	if (ret) {
		printf("Unable to write state for '%s'\n", io->compat);
		return -EINVAL;
	}

	return 0;
}

int sandbox_write_state(struct sandbox_state *state, const char *fname)
{
	struct sandbox_state_io *io;
	bool got_err;
	int size;
	int ret;
	int fd;

	/* Create a state FDT if we don't have one */
	if (!state->state_fdt) {
		size = 0x4000;
		state->state_fdt = os_malloc(size);
		if (!state->state_fdt) {
			puts("No memory to create FDT\n");
			return -ENOMEM;
		}
		ret = fdt_create_empty_tree(state->state_fdt, size);
		if (ret < 0) {
			printf("Cannot create empty state FDT: %s\n",
			       fdt_strerror(ret));
			ret = -EIO;
			goto err_create;
		}
	}

	/* Call all the state write funtcions */
	got_err = false;
	io = ll_entry_start(struct sandbox_state_io, state_io);
	ret = 0;
	for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) {
		ret = sandbox_write_state_node(state, io);
		if (ret == -EIO)
			break;
		else if (ret)
			got_err = true;
	}

	if (ret == -EIO) {
		printf("Could not write sandbox state\n");
		goto err_create;
	}

	ret = fdt_pack(state->state_fdt);
	if (ret < 0) {
		printf("Cannot pack state FDT: %s\n", fdt_strerror(ret));
		ret = -EINVAL;
		goto err_create;
	}
	size = fdt_totalsize(state->state_fdt);
	fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT);
	if (fd < 0) {
		printf("Cannot open sandbox state file '%s'\n", fname);
		ret = -EIO;
		goto err_create;
	}
	if (os_write(fd, state->state_fdt, size) != size) {
		printf("Cannot write sandbox state file '%s'\n", fname);
		ret = -EIO;
		goto err_write;
	}
	os_close(fd);

	debug("Wrote sandbox state to '%s'%s\n", fname,
	      got_err ? " (with errors)" : "");

	return 0;
err_write:
	os_close(fd);
err_create:
	os_free(state->state_fdt);

	return ret;
}

int state_setprop(int node, const char *prop_name, const void *data, int size)
{
	void *blob;
	int len;
	int ret;

	fdt_getprop(state->state_fdt, node, prop_name, &len);

	/* Add space for the new property, its name and some overhead */
	ret = state_ensure_space(size - len + strlen(prop_name) + 32);
	if (ret)
		return ret;

	/* This should succeed, barring a mutiny */
	blob = state->state_fdt;
	ret = fdt_setprop(blob, node, prop_name, data, size);
	if (ret) {
		printf("%s: Unable to set property '%s' in node '%s': %s\n",
		       __func__, prop_name, fdt_get_name(blob, node, NULL),
			fdt_strerror(ret));
		return -ENOSPC;
	}

	return 0;
}

struct sandbox_state *state_get_current(void)
{
	assert(state);
	return state;
}

void state_set_skip_delays(bool skip_delays)
{
	struct sandbox_state *state = state_get_current();

	state->skip_delays = skip_delays;
}

bool state_get_skip_delays(void)
{
	struct sandbox_state *state = state_get_current();

	return state->skip_delays;
}

void state_reset_for_test(struct sandbox_state *state)
{
	/* No reset yet, so mark it as such. Always allow power reset */
	state->last_sysreset = SYSRESET_COUNT;
	state->sysreset_allowed[SYSRESET_POWER_OFF] = true;
	state->sysreset_allowed[SYSRESET_COLD] = true;
	state->allow_memio = false;
	sandbox_set_eth_enable(true);

	memset(&state->wdt, '\0', sizeof(state->wdt));
	memset(state->spi, '\0', sizeof(state->spi));

	/*
	 * Set up the memory tag list. Use the top of emulated SDRAM for the
	 * first tag number, since that address offset is outside the legal
	 * range, and can be assumed to be a tag.
	 */
	INIT_LIST_HEAD(&state->mapmem_head);
	state->next_tag = state->ram_size;
}

bool autoboot_keyed(void)
{
	struct sandbox_state *state = state_get_current();

	return IS_ENABLED(CONFIG_AUTOBOOT_KEYED) && state->autoboot_keyed;
}

bool autoboot_set_keyed(bool autoboot_keyed)
{
	struct sandbox_state *state = state_get_current();
	bool old_val = state->autoboot_keyed;

	state->autoboot_keyed = autoboot_keyed;

	return old_val;
}

int state_get_rel_filename(const char *rel_path, char *buf, int size)
{
	struct sandbox_state *state = state_get_current();
	int rel_len, prog_len;
	char *p;
	int len;

	rel_len = strlen(rel_path);
	p = strrchr(state->argv[0], '/');
	prog_len = p ? p - state->argv[0] : 0;

	/* allow space for a / and a terminator */
	len = prog_len + 1 + rel_len + 1;
	if (len > size)
		return -ENOSPC;
	strncpy(buf, state->argv[0], prog_len);
	buf[prog_len] = '/';
	strcpy(buf + prog_len + 1, rel_path);

	return len;
}

int state_load_other_fdt(const char **bufp, int *sizep)
{
	struct sandbox_state *state = state_get_current();
	char fname[256];
	int len, ret;

	/* load the file if needed */
	if (!state->other_fdt_buf) {
		len = state_get_rel_filename("arch/sandbox/dts/other.dtb",
					     fname, sizeof(fname));
		if (len < 0)
			return len;

		ret = os_read_file(fname, &state->other_fdt_buf,
				   &state->other_size);
		if (ret) {
			log_err("Cannot read file '%s'\n", fname);
			return ret;
		}
	}
	*bufp = state->other_fdt_buf;
	*sizep = state->other_size;

	return 0;
}

void sandbox_set_eth_enable(bool enable)
{
	struct sandbox_state *state = state_get_current();

	state->disable_eth = !enable;
}

bool sandbox_eth_enabled(void)
{
	struct sandbox_state *state = state_get_current();

	return !state->disable_eth;
}

void sandbox_sf_set_enable_bootdevs(bool enable)
{
	struct sandbox_state *state = state_get_current();

	state->disable_sf_bootdevs = !enable;
}

bool sandbox_sf_bootdev_enabled(void)
{
	struct sandbox_state *state = state_get_current();

	return !state->disable_sf_bootdevs;
}

int state_init(void)
{
	state = &main_state;

	state->ram_size = CFG_SYS_SDRAM_SIZE;
	state->ram_buf = os_malloc(state->ram_size);
	if (!state->ram_buf) {
		printf("Out of memory\n");
		os_exit(1);
	}

	state_reset_for_test(state);
	/*
	 * Example of how to use GPIOs:
	 *
	 * sandbox_gpio_set_direction(170, 0);
	 * sandbox_gpio_set_value(170, 0);
	 */
	return 0;
}

int state_uninit(void)
{
	int err;

	if (state->write_ram_buf || state->write_state)
		log_debug("Writing sandbox state\n");
	state = &main_state;

	/* Finish the bloblist, so that it is correct before writing memory */
	bloblist_finish();

	if (state->write_ram_buf) {
		err = os_write_ram_buf(state->ram_buf_fname);
		if (err) {
			printf("Failed to write RAM buffer\n");
			return err;
		}
		log_debug("Wrote RAM to file '%s'\n", state->ram_buf_fname);
	}

	if (state->write_state) {
		if (sandbox_write_state(state, state->state_fname)) {
			printf("Failed to write sandbox state\n");
			return -1;
		}
		log_debug("Wrote state to file '%s'\n", state->ram_buf_fname);
	}

	/* Delete this at the last moment so as not to upset gdb too much */
	if (state->jumped_fname)
		os_unlink(state->jumped_fname);

	/* Disable tracing before unmapping RAM */
	if (IS_ENABLED(CONFIG_TRACE))
		trace_set_enabled(0);

	os_free(state->state_fdt);
	os_free(state->ram_buf);
	memset(state, '\0', sizeof(*state));

	return 0;
}
