/*
 * Copyright (c) 2019 The Fuchsia Authors
 */

#include <common.h>
#include <command.h>
#include <environment.h>
#include <linux/compat.h>

#include <bootm.h>
#include <config.h>
#include <aml_image.h>
#include <image.h>
#include <asm/arch/bl31_apis.h>
#include <asm/arch/secure_apb.h>

#include <libavb/libavb.h>
#include <zircon/boot/image.h>
#include <zircon-estelle/partition.h>
#include <zircon-estelle/vboot.h>
#include <zircon-estelle/zircon.h>

#ifdef DEBUG
#define debugP(fmt...) printf("[Dbg %s]L%d:", __func__, __LINE__), printf(fmt)
#else
#define debugP(fmt...)
#endif

#define errorP(fmt...) printf("Err %s(L%d):", __func__, __LINE__), printf(fmt)

static size_t img_offset;

static int do_zbi_load(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	long unsigned int loadaddr = 0;
	size_t loadsize = 0;
	aml_boot_header_t *aml_hdr;
	const char *type = NULL;
	bool force_recovery = false;
	int ret;

	if (argc < 4) {
		return 1;
	}

	type = argv[1];
	loadaddr = simple_strtoul(argv[2], NULL, 16);
	loadsize = simple_strtoul(argv[3], NULL, 16);

	/* check recovery mode */
	if (!strcmp(type, "recovery") ||
	    getenv_ulong("force_recovery", 10, 0)) {
		force_recovery = true;
	} else if (strcmp(type, "kernel")) {
		errorP("Err zircon_load_and_boot(L%d): unknown image type '%s'",
		       __LINE__, type);
		return __LINE__;
	}

	ret = zircon_vboot_img_load((unsigned char *)loadaddr, loadsize,
				    force_recovery);
	if (ret) {
		errorP("Err zircon_load_and_boot(L%d): failed to load the image\n",
		       __LINE__);
		return __LINE__;
	}

	aml_hdr = (aml_boot_header_t *)loadaddr;
	if (aml_hdr->magic == AML_BOOT_HEADER_MAGIC) {
		debugP("AML image header is detected.\n");
		img_offset = sizeof(aml_boot_header_t);
	}
	debugP("Kernel offset is %zu bytes\n", img_offset);

	zbi_header_t *zbi = (zbi_header_t *)(loadaddr + img_offset);
	size_t capacity = loadsize - img_offset;
	ret = zircon_fixup_zbi(zbi, capacity);
	if (ret) {
		fprintf(stderr,
			"Err zbi_load: failed to fixup the ZBI image\n");
		return __LINE__;
	}

	return 0;
}


static int do_zbi_boot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	long unsigned int loadaddr = 0;
	int ret;

	if (argc < 2) {
		return 1;
	}

	loadaddr = simple_strtoul(argv[1], NULL, 16);

	char argv0_new[12] = { 0 };
	char *argv_new = (char *)&argv0_new;
	snprintf(argv0_new, sizeof(argv0_new), "%lx", loadaddr + img_offset);
	argc = 1;
	argv = (char **)&argv_new;

	extern void ee_gate_off(void);
	extern void ee_gate_on(void);

	ee_gate_off();
	ret = do_bootm_states(
		cmdtp, flag, argc, argv,
		BOOTM_STATE_START | BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER |
			BOOTM_STATE_LOADOS | BOOTM_STATE_OS_PREP |
			BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO,
		&images, 1);
	ee_gate_on();

	/* should be here */
	return ret;
}

static int do_abr_check(cmd_tbl_t *cmdtp, int flag, int argc,
			char *const argv[])
{
	int i;
	unsigned char buff[PAGE_SIZE];
	AvbVBMetaImageHeader *avb_hdr = (AvbVBMetaImageHeader *)buff;
	static const char *idx_to_pname[] = { "vbmeta_a", "vbmeta_b" };

	assert(PAGE_SIZE > sizeof(AvbVBMetaImageHeader));

	/* check that A/B/R slots has valid ZBI image */
	for (i = 0; i < ARRAY_SIZE(idx_to_pname); ++i) {
		const char *name = idx_to_pname[i];

		debugP("reading an image from partition '%s'\n", name);
		int rc = zircon_partition_read(name, 0, buff, sizeof(buff));
		if (rc) {
			/* IO error. higher level has to handle this. */
			errorP("Fail to read 0x%x from part[%s]\n", PAGE_SIZE,
			       name);
			return __LINE__;
		}

		debugP("checking the image format...\n");
		if (memcmp(avb_hdr->magic, AVB_MAGIC, AVB_MAGIC_LEN)) {
			debugP("partition '%s' does not have a valid vbmeta image.\n",
			       name);
			return __LINE__;
		}
	}

	return 0;
}

U_BOOT_CMD(zvb_check_abr_support, 1, 0, do_abr_check,
	   "check if ZBI A/B images are present on the device.", "");

U_BOOT_CMD(zbi_load, 4, 0, do_zbi_load,
	   "Read the image from internal flash with actual size",
	   "argv: <imageType> <loadaddr> <loadsize>\n"
	   "\t<imageType>: current support is kernel or recovery\n"
	   "\t<loadaddr>: memory address in hex to store the image\n"
	   "\t<loadsize>: size in hex of the loadaddr buffer\n");

U_BOOT_CMD(zbi_boot, 2, 0, do_zbi_boot, "Boot the ZBI at the specified address",
	   "argv: <addr>\n"
	   "\t<addr>: memory address in hex of the image to boot\n");
