// SPDX-License-Identifier: GPL-2.0+
/*
 * (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>
 */


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

static int
do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	ulong		addr = image_load_addr;
	ulong		dest = 0;
	ulong		data, len;
	int		verify;
	int		part = 0;
#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
	ulong		count;
	struct legacy_img_hdr	*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 = env_get_yesno("verify");

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

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

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

		hdr = (struct legacy_img_hdr *)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, IMAGE_SIZE_INVAL)) {
			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/external data address and length */
		if (fit_image_get_data_and_size(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))
			comp = IH_COMP_NONE;

		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;
					schedule();
					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_LEGACY_IMAGE_FORMAT)
		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, ALIGN(len, ARCH_DMA_MINALIGN));

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

	return 0;
}

U_BOOT_LONGHELP(imgextract,
	"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
	);

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