/*
 * (C) Copyright 2000-2004
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * (C) Copyright 2003
 * Kai-Uwe Bloem, Auerswald GmbH & Co KG, <linux-development@auerswald.de>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */


/*
 * Multi Image extract
 */
#include <common.h>
#include <command.h>
#include <image.h>
#include <mapmem.h>
#include <watchdog.h>
#if defined(CONFIG_BZIP2)
#include <bzlib.h>
#endif
#include <asm/byteorder.h>
#include <asm/io.h>

#ifndef CONFIG_SYS_XIMG_LEN
/* use 8MByte as default max gunzip size */
#define CONFIG_SYS_XIMG_LEN	0x800000
#endif

static int
do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	ulong		addr = load_addr;
	ulong		dest = 0;
	ulong		data, len;
	int		verify;
	int		part = 0;
#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
	ulong		count;
	image_header_t	*hdr = NULL;
#endif
#if defined(CONFIG_FIT)
	const char	*uname = NULL;
	const void*	fit_hdr;
	int		noffset;
	const void	*fit_data;
	size_t		fit_len;
#endif
#ifdef CONFIG_GZIP
	uint		unc_len = CONFIG_SYS_XIMG_LEN;
#endif
	uint8_t		comp;

	verify = getenv_yesno("verify");

	if (argc > 1) {
		addr = simple_strtoul(argv[1], NULL, 16);
	}
	if (argc > 2) {
		part = simple_strtoul(argv[2], NULL, 16);
#if defined(CONFIG_FIT)
		uname = argv[2];
#endif
	}
	if (argc > 3) {
		dest = simple_strtoul(argv[3], NULL, 16);
	}

	switch (genimg_get_format((void *)addr)) {
#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
	case IMAGE_FORMAT_LEGACY:

		printf("## Copying part %d from legacy image "
			"at %08lx ...\n", part, addr);

		hdr = (image_header_t *)addr;
		if (!image_check_magic(hdr)) {
			printf("Bad Magic Number\n");
			return 1;
		}

		if (!image_check_hcrc(hdr)) {
			printf("Bad Header Checksum\n");
			return 1;
		}
#ifdef DEBUG
		image_print_contents(hdr);
#endif

		if (!image_check_type(hdr, IH_TYPE_MULTI) &&
		    !image_check_type(hdr, IH_TYPE_SCRIPT)) {
			printf("Wrong Image Type for %s command\n",
					cmdtp->name);
			return 1;
		}

		comp = image_get_comp(hdr);
		if ((comp != IH_COMP_NONE) && (argc < 4)) {
			printf("Must specify load address for %s command "
					"with compressed image\n",
					cmdtp->name);
			return 1;
		}

		if (verify) {
			printf("   Verifying Checksum ... ");
			if (!image_check_dcrc(hdr)) {
				printf("Bad Data CRC\n");
				return 1;
			}
			printf("OK\n");
		}

		count = image_multi_count(hdr);
		if (part >= count) {
			printf("Bad Image Part\n");
			return 1;
		}

		image_multi_getimg(hdr, part, &data, &len);
		break;
#endif
#if defined(CONFIG_FIT)
	case IMAGE_FORMAT_FIT:
		if (uname == NULL) {
			puts("No FIT subimage unit name\n");
			return 1;
		}

		printf("## Copying '%s' subimage from FIT image "
			"at %08lx ...\n", uname, addr);

		fit_hdr = (const void *)addr;
		if (!fit_check_format(fit_hdr)) {
			puts("Bad FIT image format\n");
			return 1;
		}

		/* get subimage node offset */
		noffset = fit_image_get_node(fit_hdr, uname);
		if (noffset < 0) {
			printf("Can't find '%s' FIT subimage\n", uname);
			return 1;
		}

		if (!fit_image_check_comp(fit_hdr, noffset, IH_COMP_NONE)
		    && (argc < 4)) {
			printf("Must specify load address for %s command "
				"with compressed image\n",
				cmdtp->name);
			return 1;
		}

		/* verify integrity */
		if (verify) {
			if (!fit_image_verify(fit_hdr, noffset)) {
				puts("Bad Data Hash\n");
				return 1;
			}
		}

		/* get subimage data address and length */
		if (fit_image_get_data(fit_hdr, noffset,
					&fit_data, &fit_len)) {
			puts("Could not find script subimage data\n");
			return 1;
		}

		if (fit_image_get_comp(fit_hdr, noffset, &comp)) {
			puts("Could not find script subimage "
				"compression type\n");
			return 1;
		}

		data = (ulong)fit_data;
		len = (ulong)fit_len;
		break;
#endif
	default:
		puts("Invalid image type for imxtract\n");
		return 1;
	}

	if (argc > 3) {
		switch (comp) {
		case IH_COMP_NONE:
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
			{
				size_t l = len;
				size_t tail;
				void *to = (void *) dest;
				void *from = (void *)data;

				printf("   Loading part %d ... ", part);

				while (l > 0) {
					tail = (l > CHUNKSZ) ? CHUNKSZ : l;
					WATCHDOG_RESET();
					memmove(to, from, tail);
					to += tail;
					from += tail;
					l -= tail;
				}
			}
#else	/* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
			printf("   Loading part %d ... ", part);
			memmove((char *) dest, (char *)data, len);
#endif	/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
			break;
#ifdef CONFIG_GZIP
		case IH_COMP_GZIP:
			printf("   Uncompressing part %d ... ", part);
			if (gunzip((void *) dest, unc_len,
				   (uchar *) data, &len) != 0) {
				puts("GUNZIP ERROR - image not loaded\n");
				return 1;
			}
			break;
#endif
#if defined(CONFIG_BZIP2) && defined(CONFIG_IMAGE_FORMAT_LEGACY)
		case IH_COMP_BZIP2:
			{
				int i;

				printf("   Uncompressing part %d ... ", part);
				/*
				 * If we've got less than 4 MB of malloc()
				 * space, use slower decompression algorithm
				 * which requires at most 2300 KB of memory.
				 */
				i = BZ2_bzBuffToBuffDecompress(
					map_sysmem(ntohl(hdr->ih_load), 0),
					&unc_len, (char *)data, len,
					CONFIG_SYS_MALLOC_LEN < (4096 * 1024),
					0);
				if (i != BZ_OK) {
					printf("BUNZIP2 ERROR %d - "
						"image not loaded\n", i);
					return 1;
				}
			}
			break;
#endif /* CONFIG_BZIP2 */
		default:
			printf("Unimplemented compression type %d\n", comp);
			return 1;
		}
		puts("OK\n");
		flush_cache(dest, len);
	}

	setenv_hex("fileaddr", data);
	setenv_hex("filesize", len);

	return 0;
}

#ifdef CONFIG_SYS_LONGHELP
static char imgextract_help_text[] =
	"addr part [dest]\n"
	"    - extract <part> from legacy image at <addr> and copy to <dest>"
#if defined(CONFIG_FIT)
	"\n"
	"addr uname [dest]\n"
	"    - extract <uname> subimage from FIT image at <addr> and copy to <dest>"
#endif
	"";
#endif

U_BOOT_CMD(
	imxtract, 4, 1, do_imgextract,
	"extract a part of a multi-image", imgextract_help_text
);
