/*
 * 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 int do_image_load_and_boot(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;
	size_t offset = 0;
	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");
		offset = sizeof(aml_boot_header_t);
	}
	debugP("Kernel offset is %zu bytes\n", offset);

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

	char argv0_new[12] = { 0 };
	char *argv_new = (char *)&argv0_new;
	snprintf(argv0_new, sizeof(argv0_new), "%lx", loadaddr + 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(zvb_load_and_boot, 4, 0, do_image_load_and_boot,
	   "Read the image from internal flash with actual size and boot it",
	   "argv: <imageType> <loadaddr> <loadsize>\n"
	   "\t<imageType>: current support is kernel or recovery\n"
	   "\t<loadaddr>: address to store the image\n"
	   "\t<loadsize>: size in hex of the loadaddr buffer\n");
