/*
 * (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);
	}

	if ((unsigned)sbuf.st_size < image_get_header_size ()) {
		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);
	}
}


