/*
 * (C) Copyright 2010 Quantenna Communications
 *
 * (C) Copyright 2008 Semihalf
 *
 * (C) Copyright 2000-2004
 * DENX Software Engineering
 * Wolfgang Denk, wd@denx.de
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include "mkimage.h"
#include <image.h>

#define IMAGE_DATA_OFFSET	0x2000

extern int errno;

#ifndef MAP_FAILED
#define MAP_FAILED (void *)(-1)
#endif

extern	unsigned long	crc32 (unsigned long crc, const char *buf, unsigned int len);
static	void		usage (void);
static	void		image_verify_header (char *, int);

char	*imagefile;
char	*cmdname;

int dflag    = 0;
int eflag    = 0;
int fflag    = 0;
int vflag    = 0;
int check_os = -1;
int check_arch = -1;
int check_type = -1;
int check_comp = -1;
int check_addr = -1;
int check_ep = -1;
int check_name = -1;

image_header_t header;
image_header_t *hdr = &header;

int main (int argc, char **argv)
{
	int ifd = -1;
	uint32_t addr;
	uint32_t ep;
	struct stat sbuf;
	unsigned char *ptr;
	char *name = "";

	cmdname = *argv;

	addr = ep = 0;

	while (--argc > 0 && **++argv == '-') {
		while (*++*argv) {
			switch (**argv) {
				case 'A':
					if ((--argc <= 0) ||
							(check_arch = genimg_get_arch_id (*++argv)) < 0)
						usage ();
					goto NXTARG;
				case 'C':
					if ((--argc <= 0) ||
							(check_comp = genimg_get_comp_id (*++argv)) < 0)
						usage ();
					goto NXTARG;
				case 'O':
					if ((--argc <= 0) ||
							(check_os = genimg_get_os_id (*++argv)) < 0)
						usage ();
					goto NXTARG;
				case 'T':
					if ((--argc <= 0) ||
							(check_type = genimg_get_type_id (*++argv)) < 0)
						usage ();
					goto NXTARG;

				case 'a':
					if (--argc <= 0)
						usage ();
					addr = strtoul (*++argv, (char **)&ptr, 16);
					check_addr = 1;
					if (*ptr) {
						fprintf (stderr,
								"%s: invalid load address %s\n",
								cmdname, *argv);
						exit (EXIT_FAILURE);
					}
					goto NXTARG;
				case 'e':
					if (--argc <= 0)
						usage ();
					ep = strtoul (*++argv, (char **)&ptr, 16);
					check_ep = 1;
					if (*ptr) {
						fprintf (stderr,
								"%s: invalid entry point %s\n",
								cmdname, *argv);
						exit (EXIT_FAILURE);
					}
					eflag = 1;
					goto NXTARG;
				case 'n':
					if (--argc <= 0)
						usage ();
					name = *++argv;
					check_name = 1;
					goto NXTARG;
				case 'v':
					vflag = 1;
					goto NXTARG;
				default:
					usage ();
			}
		}
NXTARG:		;
	}

	if (argc != 1)
		usage();

	if (!eflag) {
		ep = addr;
	}

	imagefile = *argv;

	ifd = open (imagefile, O_RDONLY|O_BINARY);

	if (ifd < 0) {
		fprintf (stderr, "%s: Can't open %s: %s\n",
				cmdname, imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	/*
	 * list header information of existing image
	 */
	if (fstat(ifd, &sbuf) < 0) {
		fprintf (stderr, "%s: Can't stat %s: %s\n",
				cmdname, imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	/* This chkimage is not used: NULL passed just so it compiles */
	if ((unsigned)sbuf.st_size < image_get_header_size (NULL)) {
		fprintf (stderr,
				"%s: Bad size: \"%s\" is no valid image\n",
				cmdname, imagefile);
		exit (EXIT_FAILURE);
	}

	ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
	if (ptr == MAP_FAILED) {
		fprintf (stderr, "%s: Can't read %s: %s\n",
				cmdname, imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	if (fdt_check_header (ptr)) {
		/* old-style image */
		image_header_t *hdr = (image_header_t *)ptr;
		image_verify_header ((char *)ptr, sbuf.st_size);
		if (vflag) {
			image_print_contents (hdr);
		}

		int correct = 1;
		/* go through various options checking that the image parameters are correct */
		if (check_os >= 0 && image_get_os(hdr) != check_os) {
			fprintf (stderr, "%s: incorrect image OS\n", cmdname);
			correct = 0;
		}
		if (check_arch >= 0 && image_get_arch(hdr) != check_arch) {
			fprintf (stderr, "%s: incorrect arch\n", cmdname);
			correct = 0;
		}	
		if (check_type >= 0 && image_get_type(hdr) != check_type) {
			fprintf (stderr, "%s: incorrect image type\n", cmdname);
			correct = 0;
		}
		if (check_comp >= 0 && image_get_comp(hdr) != check_comp) {
			fprintf (stderr, "%s: incorrect compression type\n", cmdname);
			correct = 0;
		}
		if (check_addr >= 0 && image_get_load(hdr) != addr) {
			fprintf (stderr, "%s: incorrect load address\n", cmdname);
			correct = 0;
		}
		if (check_ep >= 0 && image_get_ep(hdr) != ep) {
			fprintf (stderr, "%s: incorrect entry point address\n", cmdname);
			correct = 0;
		}
		if (check_name >= 0 && strcmp(image_get_name(hdr), name)) {
			fprintf (stderr, "%s: incorrect name\n", cmdname);
			correct = 0;
		}
		if (!correct) {
			exit (EXIT_FAILURE);
		}
	} else {
		/* FIT image */
		fit_print_contents (ptr);

		/* FIT option checking not supported */
	}

	(void) munmap((void *)ptr, sbuf.st_size);
	(void) close (ifd);

	exit (EXIT_SUCCESS);
} 

void usage ()
{
	fprintf (stderr, "       %s [-x] [-A arch] [-O os] [-T type] [-C comp] "
			"[-a addr] [-e ep] [-n name] image\n"
			"          -A ==> check architecture is 'arch'\n"
			"          -O ==> check operating system is 'os'\n"
			"          -T ==> check image type is 'type'\n"
			"          -C ==> check compression type is 'comp'\n"
			"          -a ==> check load address is 'addr' (hex)\n"
			"          -e ==> check entry point is 'ep' (hex)\n"
			"          -n ==> check image name is 'name'\n",
			cmdname);

	exit (EXIT_FAILURE);
}

static void image_verify_header (char *ptr, int image_size)
{
	int len;
	char *data;
	uint32_t checksum;
	image_header_t header;
	image_header_t *hdr = &header;

	/*
	 * create copy of header so that we can blank out the
	 * checksum field for checking - this can't be done
	 * on the PROT_READ mapped data.
	 */
	memcpy (hdr, ptr, sizeof(image_header_t));

	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
		fprintf (stderr,
				"%s: Bad Magic Number: \"%s\" is no valid image\n",
				cmdname, imagefile);
		exit (EXIT_FAILURE);
	}

	data = (char *)hdr;
	len  = sizeof(image_header_t);

	checksum = ntohl(hdr->ih_hcrc);
	hdr->ih_hcrc = htonl(0);	/* clear for re-calculation */

	if (crc32 (0, data, len) != checksum) {
		fprintf (stderr,
				"%s: ERROR: \"%s\" has bad header checksum!\n",
				cmdname, imagefile);
		exit (EXIT_FAILURE);
	}

	unsigned long data_offset = IMAGE_DATA_OFFSET;
	data = ptr + data_offset;
	len  = image_size - data_offset;

	if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) {
		fprintf (stderr,
				"%s: ERROR: \"%s\" has corrupted data!\n",
				cmdname, imagefile);
		exit (EXIT_FAILURE);
	}
}


