// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2016 Google, Inc
 */

#define LOG_CATEGORY	LOGC_BOOT

#include <dm.h>
#include <hang.h>
#include <handoff.h>
#include <image.h>
#include <init.h>
#include <log.h>
#include <mapmem.h>
#include <os.h>
#include <spl.h>
#include <upl.h>
#include <asm/global_data.h>
#include <asm/spl.h>
#include <asm/state.h>
#include <test/ut.h>

DECLARE_GLOBAL_DATA_PTR;

int sandbox_find_next_phase(char *fname, int maxlen, bool use_img)
{
	const char *cur_prefix, *next_prefix;
	int ret;

	cur_prefix = xpl_prefix(xpl_phase());
	next_prefix = xpl_prefix(xpl_next_phase());
	ret = os_find_u_boot(fname, maxlen, use_img, cur_prefix, next_prefix);
	if (ret)
		return log_msg_ret("find", ret);

	return 0;
}

/* SPL / TPL / VPL init function */
void board_init_f(ulong flag)
{
	struct sandbox_state *state = state_get_current();
	int ret;

	gd->arch.ram_buf = state->ram_buf;
	gd->ram_size = state->ram_size;

	ret = spl_early_init();
	if (ret) {
		debug("spl_early_init() failed: %d\n", ret);
		hang();
	}
	preloader_console_init();
}

void board_boot_order(u32 *spl_boot_list)
{
	spl_boot_list[0] = BOOT_DEVICE_VBE;
	spl_boot_list[1] = BOOT_DEVICE_UPL;
	spl_boot_list[2] = BOOT_DEVICE_BOARD;
}

static int spl_board_load_file(struct spl_image_info *spl_image,
			       struct spl_boot_device *bootdev)
{
	char fname[256];
	int ret;

	ret = sandbox_find_next_phase(fname, sizeof(fname), false);
	if (ret) {
		printf("(%s not found, error %d)\n", fname, ret);
		return ret;
	}

	/*
	 * Set up spl_image to boot from jump_to_image_no_args(). Allocate this
	 * outsdide the RAM buffer (i.e. don't use strdup()).
	 */
	spl_image->arg = os_malloc(strlen(fname) + 1);
	if (!spl_image->arg)
		return log_msg_ret("exec", -ENOMEM);
	strcpy(spl_image->arg, fname);
	spl_image->flags = SPL_SANDBOXF_ARG_IS_FNAME;

	return 0;
}
SPL_LOAD_IMAGE_METHOD("sandbox_file", 9, BOOT_DEVICE_BOARD,
		      spl_board_load_file);

static int load_from_image(struct spl_image_info *spl_image,
			   struct spl_boot_device *bootdev)
{
	struct sandbox_state *state = state_get_current();
	enum xpl_phase_t next_phase;
	const char *fname;
	ulong pos, size;
	int full_size;
	void *buf;
	int ret;

	if (!IS_ENABLED(CONFIG_SANDBOX_VPL))
		return -ENOENT;

	next_phase = xpl_next_phase();
	pos = spl_get_image_pos();
	size = spl_get_image_size();
	if (pos == BINMAN_SYM_MISSING || size == BINMAN_SYM_MISSING) {
		log_debug("No image found\n");
		return -ENOENT;
	}
	log_info("Reading from pos %lx size %lx\n", pos, size);

	/*
	 * Set up spl_image to boot from jump_to_image_no_args(). Allocate this
	 * outside the RAM buffer (i.e. don't use strdup()).
	 */
	fname = state->prog_fname ? state->prog_fname : state->argv[0];
	ret = os_read_file(fname, &buf, &full_size);
	if (ret)
		return log_msg_ret("rd", -ENOMEM);
	spl_image->flags = SPL_SANDBOXF_ARG_IS_BUF;
	spl_image->arg = buf;
	spl_image->offset = pos;
	spl_image->size = size;

	return 0;
}
SPL_LOAD_IMAGE_METHOD("sandbox_image", 7, BOOT_DEVICE_BOARD, load_from_image);

int dram_init_banksize(void)
{
	/* These are necessary so TFTP can use LMBs to check its load address */
	gd->bd->bi_dram[0].start = gd->ram_base;
	gd->bd->bi_dram[0].size = get_effective_memsize();

	return 0;
}

void spl_board_init(void)
{
	struct sandbox_state *state = state_get_current();

	if (!CONFIG_IS_ENABLED(UNIT_TEST))
		return;

	if (state->run_unittests) {
		struct unit_test *tests = UNIT_TEST_ALL_START();
		const int count = UNIT_TEST_ALL_COUNT();
		int ret;

		ret = ut_run_list("spl", NULL, tests, count,
				  state->select_unittests, 1, false, NULL);
		/* continue execution into U-Boot */
	}
}

void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
{
	switch (spl_image->flags) {
	case SPL_SANDBOXF_ARG_IS_FNAME: {
		const char *fname = spl_image->arg;

		if (fname) {
			os_fd_restore();
			os_spl_to_uboot(fname);
		} else {
			log_err("No filename provided for U-Boot\n");
		}
		break;
	}
	case SPL_SANDBOXF_ARG_IS_BUF: {
		int ret;

		ret = os_jump_to_image(spl_image->arg + spl_image->offset,
				       spl_image->size);
		if (ret)
			log_err("Failed to load image\n");
		break;
	}
	default:
		log_err("Invalid flags\n");
		break;
	}
	hang();
}

int handoff_arch_save(struct spl_handoff *ho)
{
	ho->arch.magic = TEST_HANDOFF_MAGIC;

	return 0;
}

/* Context used to hold file descriptor */
struct load_ctx {
	int fd;
};

static ulong read_fit_image(struct spl_load_info *load, ulong offset,
			    ulong size, void *buf)
{
	struct load_ctx *load_ctx = load->priv;
	off_t ret;
	ssize_t res;

	ret = os_lseek(load_ctx->fd, offset, OS_SEEK_SET);
	if (ret < 0) {
		printf("Failed to seek to %zx, got %zx\n", offset, ret);
		return log_msg_ret("lse", ret);
	}

	res = os_read(load_ctx->fd, buf, size);
	if (res < 0) {
		printf("Failed to read %lx bytes, got %ld\n", size, res);
		return log_msg_ret("osr", res);
	}

	return size;
}

int sandbox_spl_load_fit(char *fname, int maxlen, struct spl_image_info *image)
{
	struct legacy_img_hdr *header;
	struct load_ctx load_ctx;
	struct spl_load_info load;
	int ret;
	int fd;

	spl_load_init(&load, read_fit_image, &load_ctx,
		      IS_ENABLED(CONFIG_SPL_LOAD_BLOCK) ? 512 : 1);

	ret = sandbox_find_next_phase(fname, maxlen, true);
	if (ret) {
		printf("%s not found, error %d\n", fname, ret);
		return log_msg_ret("nph", ret);
	}

	header = spl_get_load_buffer(-sizeof(*header), sizeof(*header));

	log_debug("reading from %s\n", fname);
	fd = os_open(fname, OS_O_RDONLY);
	if (fd < 0) {
		printf("Failed to open '%s'\n", fname);
		return log_msg_ret("ope", -errno);
	}
	ret = os_read(fd, header, sizeof(*header));
	if (ret != sizeof(*header)) {
		printf("Failed to read %lx bytes, got %d\n", sizeof(*header),
		       ret);
		return log_msg_ret("rea", ret);
	}
	load_ctx.fd = fd;

	load.priv = &load_ctx;

	ret = spl_load_simple_fit(image, &load, 0, header);
	if (ret)
		return log_msg_ret("slf", ret);

	return 0;
}

static int upl_load_from_image(struct spl_image_info *spl_image,
			       struct spl_boot_device *bootdev)
{
	long long size;
	char *fname;
	int ret, fd;
	ulong addr;

	if (!CONFIG_IS_ENABLED(UPL_OUT))
		return -ENOTSUPP;

	spl_upl_init();
	fname = os_malloc(256);

	ret = sandbox_spl_load_fit(fname, 256, spl_image);
	if (ret)
		return log_msg_ret("fit", ret);
	spl_image->flags = SPL_SANDBOXF_ARG_IS_BUF;
	spl_image->arg = map_sysmem(spl_image->load_addr, 0);
	/* size is set by load_simple_fit(), offset is left as 0 */

	/* now read the whole FIT into memory */
	fd = os_open(fname, OS_O_RDONLY);
	if (fd < 0)
		return log_msg_ret("op2", -ENOENT);
	if (os_get_filesize(fname,  &size))
		return log_msg_ret("fis", -ENOENT);

	/* place it after the loaded image, allowing plenty of space */
	addr = ALIGN(spl_image->load_addr + size, 0x1000);
	log_debug("Loading whole FIT to %lx\n", addr);
	if (os_read(fd, map_sysmem(addr, 0), size) != size)
		return log_msg_ret("rea", -EIO);
	os_close(fd);

	/* tell UPL where it is */
	upl_set_fit_addr(addr);

	return 0;
}
SPL_LOAD_IMAGE_METHOD("upl", 4, BOOT_DEVICE_UPL, upl_load_from_image);
