#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <libgen.h>
#include <getopt.h>

#define NETX_IDENTIFICATION   0x5854454E /* Valid signature 'N' 'E' 'T' 'X' */

#define MAGICCOOKIE_8BIT      0xF8BEAF08  /* Cookie used for  8Bit Flashes */
#define MAGICCOOKIE_16BIT     0xF8BEAF16  /* Cookie used for 16Bit Flashes */
#define MAGICCOOKIE_32BIT     0xF8BEAF32  /* Cookie used for 32Bit Flashes */

struct netx_block_normal {
	uint32_t sdram_general_ctrl;	/* SDRam General control value */
	uint32_t sdram_timing_ctrl;	/* SDRam Timing control register value */
	uint32_t reserved[3];
};

struct netx_block_expbus {
		uint32_t exp_bus_reg;	/* Expension bus register value (EXPBus Bootmode) */
		uint32_t io_reg_mode0;	/* IORegmode0 register value (EXPBus Bootmode) */
		uint32_t io_reg_mode1;	/* IORegmode1 register value (EXPBus Bootmode) */
		uint32_t if_conf1;	/* IfConfig1 register value (EXPBus Bootmode) */
		uint32_t if_conf2;	/* IfConfig2 register value (EXPBus Bootmode) */
};

struct netx_bootblock {
	uint32_t cookie;     /* Cookie identifying bus width and valid bootblock */

	union {
		uint32_t mem_ctrl;        /* Parallel/Serial Flash Mode for setting up timing parameters */
		uint32_t speed;          /* I2C/SPI Mode for identifying speed of device */
		uint32_t reserved;       /* PCI/DPM mode */
	} ctrl;

	uint32_t appl_entrypoint;   /* Entrypoint to application after relocation */
	uint32_t appl_checksum;     /* Checksum of application (DWORD sum over application) */
	uint32_t appl_size;         /* size of application in DWORDs */
	uint32_t appl_start_addr;    /* Relocation address of application */
	uint32_t signature;        /* Bootblock signature ('NETX') */

	union {
		struct netx_block_normal normal;
		struct netx_block_expbus expbus;
	} config;

	uint32_t misc_asic_ctrl;            /* ASIC CTRL register value */
	uint32_t reserved[2];
	uint32_t boot_checksum;            /* Bootblock checksum (complement of DWORD sum over bootblock) */
};

void print_usage(char *prg)
{
        fprintf(stderr, "Usage: %s [Options]\n"
                        "Options:\n"
			" -i, --infile=FILE      input file\n"
			" -o  --outfile=FILE     outputfile\n"
			" -m  --memctrl=REG      Memory Control register value\n"
	                " -s, --sdramctrl=REG    SDRAM Control regster value\n"
                        " -t, --sdramtimctrl=REG SDRAM Timing Control regster value\n"
                        " -e, --entrypoint=ADR   Application entrypoint\n"
                        " -c, --cookie=BITS      Cookie to use (8|16|32)\n"
			" -h, --help            this help\n",
				prg);
}

int main(int argc, char *argv[])
{
	struct netx_bootblock *nb;
	int fd;
	struct stat s;
	int opt;
	unsigned char *buf;
	int bytes, err, barebox_size, ofs, i;
	uint32_t *ptr;
	uint32_t checksum = 0;
	uint32_t memctrl = 0, sdramctrl = 0, sdramtimctrl = 0, entrypoint = 0, cookie = 0;
	char *infile = NULL, *outfile = NULL;

	struct option long_options[] = {
		{ "help", no_argument, 0, 'h' },
		{ "infile", required_argument, 0, 'i'},
		{ "outfile", required_argument, 0, 'o'},
		{ "memctrl", required_argument, 0, 'm'},
		{ "sdramctrl", required_argument, 0, 's' },
		{ "sdramtimctrl", required_argument, 0, 't' },
		{ "entrypoint", required_argument, 0, 'e' },
		{ "cookie", required_argument, 0 , 'c' },
		{ 0, 0, 0, 0},
	};

	while ((opt = getopt_long(argc, argv, "hi:o:m:s:t:e:c:", long_options, NULL)) != -1) {
		switch (opt) {
			case 'h':
				print_usage(basename(argv[0]));
				exit(0);
			case 'i':
				infile = optarg;
				break;
			case 'o':
				outfile = optarg;
				break;
			case 'm':
				memctrl = strtoul(optarg, NULL, 0);
				break;
			case 's':
				sdramctrl = strtoul(optarg, NULL, 0);
				break;
			case 't':
				sdramtimctrl = strtoul(optarg, NULL, 0);
				break;
			case 'e':
				entrypoint = strtoul(optarg, NULL, 0);
				break;
			case 'c':
				cookie = strtoul(optarg, NULL, 0);
				break;
		}
	}

	if(!infile) {
		printf("no input filename supplied\n");
		exit(1);
	}

	if(!outfile) {
		printf("no outpu filename supplied\n");
		exit(1);
	}

	switch (cookie) {
		case 8:
			cookie = MAGICCOOKIE_8BIT;
			break;
		case 16:
			cookie = MAGICCOOKIE_16BIT;
			break;
		case 32:
			cookie = MAGICCOOKIE_32BIT;
			break;
		default:
			fprintf(stderr, "invalid coookie size %d\n",cookie);
	}

	fd = open(infile,O_RDONLY);
	if(fd < 0) {
		perror("open");
		exit(1);
	}

	if( fstat(fd, &s) < 0) {
		perror("fstat");
		exit(1);
	}

	barebox_size = s.st_size;
	printf("found barebox image. size: %d bytes. Using entrypoint 0x%08x\n",barebox_size,entrypoint);

	buf = malloc(barebox_size + sizeof(struct netx_bootblock) + 4);
	if(!buf) {
		perror("malloc");
		exit(1);
	}
	memset(buf, 0, barebox_size + sizeof(struct netx_bootblock) + 4);

	nb = (struct netx_bootblock *)buf;

	nb->cookie = cookie;
	nb->ctrl.mem_ctrl = memctrl;
	nb->appl_entrypoint = entrypoint;
	nb->appl_size = (barebox_size >> 2);

	nb->appl_start_addr = entrypoint;
	nb->signature = NETX_IDENTIFICATION;
	nb->config.normal.sdram_general_ctrl = sdramctrl;
	nb->config.normal.sdram_timing_ctrl = sdramtimctrl;

	ofs = sizeof(struct netx_bootblock);
	bytes = barebox_size;

	while(bytes) {
		err = read(fd, buf + ofs, bytes);
		if( err < 0 ) {
			perror("read");
			exit(1);
		}
		bytes -= err;
		ofs += err;
	}

	close(fd);

	/* calculate application checksum */
	ptr = (uint32_t *)(buf + sizeof(struct netx_bootblock));

	checksum = 0;

	for( i = 0; i < nb->appl_size; i++) {
		checksum += *ptr++;
	}

	nb->appl_checksum = checksum;
	printf("application checksum: 0x%08x\n",nb->appl_checksum);

	/* calculate bootblock checksum */
	ptr = (uint32_t *)buf;
	checksum = 0;
	for( i = 0; i < (sizeof(struct netx_bootblock) >> 2); i++)
		checksum += *ptr++;
	nb->boot_checksum = -1 * checksum;

	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
	if(fd < 0) {
		perror("open");
		exit(1);
	}

	bytes = barebox_size + sizeof(struct netx_bootblock);
	ofs = 0;
	while(bytes) {
		err = write(fd, buf + ofs, bytes);
		if( err < 0) {
			perror("write");
			exit(1);
		}
		bytes -= err;
		ofs += err;
	}

	close(fd);
	free(buf);
	return 0;
}
