/*
 * (C) Copyright 2003
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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 <common.h>
#include <command.h>
#include <cmd_boot.h>
#include <image.h>
#include <zlib.h>
#include <asm/byteorder.h>
#include <asm/addrspace.h>

#define	LINUX_MAX_ENVS		256
#define	LINUX_MAX_ARGS		256

#ifdef CONFIG_SHOW_BOOT_PROGRESS
# include <status_led.h>
# define SHOW_BOOT_PROGRESS(arg)	show_boot_progress(arg)
#else
# define SHOW_BOOT_PROGRESS(arg)
#endif

extern image_header_t header;           /* from cmd_bootm.c */

static int	linux_argc;
static char **	linux_argv;

static char **	linux_env;
static char *	linux_env_p;
static int	linux_env_idx;

static void linux_params_init (ulong start, char * commandline);
static void linux_env_set (char * env_name, char * env_val);


void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
		ulong addr, ulong *len_ptr, int   verify)
{
    DECLARE_GLOBAL_DATA_PTR;

    ulong len = 0, checksum;
    ulong initrd_start, initrd_end;
    ulong data;
    void (*theKernel)(int, char **, char **, int *);
    image_header_t *hdr = &header;
    char *commandline = getenv("bootargs");
    char env_buf[12];

    theKernel = (void (*)(int, char **, char **, int *))ntohl(hdr->ih_ep);

    /*
     * Check if there is an initrd image
     */
    if (argc >= 3) {
	SHOW_BOOT_PROGRESS (9);

	addr = simple_strtoul(argv[2], NULL, 16);

	printf ("## Loading Ramdisk Image at %08lx ...\n", addr);

	/* Copy header so we can blank CRC field for re-calculation */
	memcpy (&header, (char *)addr, sizeof(image_header_t));

	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
	    printf ("Bad Magic Number\n");
	    SHOW_BOOT_PROGRESS (-10);
	    do_reset (cmdtp, flag, argc, argv);
	}

	data = (ulong)&header;
	len  = sizeof(image_header_t);

	checksum = ntohl(hdr->ih_hcrc);
	hdr->ih_hcrc = 0;

	if (crc32 (0, (char *)data, len) != checksum) {
	    printf ("Bad Header Checksum\n");
	    SHOW_BOOT_PROGRESS (-11);
	    do_reset (cmdtp, flag, argc, argv);
	}

	SHOW_BOOT_PROGRESS (10);

	print_image_hdr (hdr);

	data = addr + sizeof(image_header_t);
	len  = ntohl(hdr->ih_size);

	if (verify) {
	    ulong csum = 0;

	    printf ("   Verifying Checksum ... ");
	    csum = crc32 (0, (char *)data, len);
	    if (csum != ntohl(hdr->ih_dcrc)) {
		printf ("Bad Data CRC\n");
	        SHOW_BOOT_PROGRESS (-12);
		do_reset (cmdtp, flag, argc, argv);
	    }
	    printf ("OK\n");
	}

	SHOW_BOOT_PROGRESS (11);

	if ((hdr->ih_os   != IH_OS_LINUX)	||
	    (hdr->ih_arch != IH_CPU_MIPS)	||
	    (hdr->ih_type != IH_TYPE_RAMDISK)	) {
	    printf ("No Linux MIPS Ramdisk Image\n");
	    SHOW_BOOT_PROGRESS (-13);
	    do_reset (cmdtp, flag, argc, argv);
	}

	/*
	 * Now check if we have a multifile image
	 */
    } else if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) {
	ulong tail    = ntohl(len_ptr[0]) % 4;
	int i;

	SHOW_BOOT_PROGRESS (13);

	/* skip kernel length and terminator */
	data = (ulong)(&len_ptr[2]);
	/* skip any additional image length fields */
	for (i=1; len_ptr[i]; ++i)
	  data += 4;
	/* add kernel length, and align */
	data += ntohl(len_ptr[0]);
	if (tail) {
	    data += 4 - tail;
	}

	len   = ntohl(len_ptr[1]);

    } else {
	/*
	 * no initrd image
	 */
        SHOW_BOOT_PROGRESS (14);

	data = 0;
    }

#ifdef	DEBUG
    if (!data) {
	printf ("No initrd\n");
    }
#endif

    if (data) {
	initrd_start = data;
	initrd_end   = initrd_start + len;
    } else {
	initrd_start = 0;
	initrd_end = 0;
    }

    SHOW_BOOT_PROGRESS (15);

#ifdef DEBUG
    printf ("## Transferring control to Linux (at address %08lx) ...\n",
	    (ulong)theKernel);
#endif

    linux_params_init (PHYSADDR(gd->bd->bi_boot_params), commandline);

    sprintf (env_buf, "%lu", gd->ram_size >> 20);
    linux_env_set ("memsize", env_buf);

    sprintf (env_buf, "0x%08X", (uint)PHYSADDR(initrd_start));
    linux_env_set ("initrd_start", env_buf);

    sprintf (env_buf, "0x%X", (uint)(initrd_end - initrd_start));
    linux_env_set ("initrd_size", env_buf);

    sprintf (env_buf, "0x%08X", (uint)(gd->bd->bi_flashstart));
    linux_env_set ("flash_start", env_buf);

    sprintf (env_buf, "0x%X", (uint)(gd->bd->bi_flashsize));
    linux_env_set ("flash_size", env_buf);

    /* we assume that the kernel is in place */
    printf("\nStarting kernel ...\n\n");

    theKernel(linux_argc, linux_argv, linux_env, 0);
}

static void linux_params_init (ulong start, char * line)
{
    char * next, * quote, * argp;

    linux_argc = 1;
    linux_argv = (char **) start;
    linux_argv[0] = 0;
    argp = (char *)(linux_argv + LINUX_MAX_ARGS);

    next = line;

    while (line && *line && linux_argc < LINUX_MAX_ARGS)
    {
	quote = strchr (line, '"');
	next = strchr (line, ' ');

        while (next != NULL && quote != NULL && quote < next)
	{
	    /* we found a left quote before the next blank
             * now we have to find the matching right quote
             */
            next = strchr (quote + 1, '"');
            if (next != NULL)
	    {
                quote = strchr (next + 1, '"');
                next = strchr (next + 1, ' ');
            }
        }
	
	if (next == NULL)
	{
	    next = line + strlen (line);
	}

	linux_argv [linux_argc] = argp;
	memcpy (argp, line, next - line);
	argp [next - line] = 0;

	argp += next - line + 1;
	linux_argc ++;
        
	if (*next) next ++;
	
	line = next;
    }

    linux_env = (char **)(((ulong)argp + 15) & ~15);
    linux_env [0] = 0;
    linux_env_p = (char *)(linux_env + LINUX_MAX_ENVS);
    linux_env_idx = 0;
}

static void linux_env_set (char * env_name, char * env_val)
{
    if (linux_env_idx < LINUX_MAX_ENVS - 1)
    {
	linux_env [linux_env_idx] = linux_env_p;

	strcpy (linux_env_p, env_name);
	linux_env_p += strlen (env_name);

	strcpy (linux_env_p, "=");
	linux_env_p += 1;

	strcpy (linux_env_p, env_val);
	linux_env_p += strlen (env_val);
	
	linux_env_p ++;
	linux_env [++ linux_env_idx] = 0;
    }
}
