/*
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * Copyright (C) 2001  Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
 *
 * 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 <image.h>
#include <u-boot/zlib.h>
#include <asm/byteorder.h>
#include <asm/setup.h>
#include <asm/uboot-arc.h>


DECLARE_GLOBAL_DATA_PTR;



#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
    defined (CONFIG_CMDLINE_TAG) || \
    defined (CONFIG_INITRD_TAG) || \
    defined (CONFIG_SERIAL_TAG) || \
    defined (CONFIG_REVISION_TAG) || \
    defined (CONFIG_VFD) || \
    defined (CONFIG_LCD)
static void setup_start_tag (bd_t *bd);

# ifdef CONFIG_SETUP_MEMORY_TAGS
static void setup_memory_tags (bd_t *bd);
# endif
static void setup_commandline_tag (bd_t *bd, char *commandline);
static void setup_hwid_tag(void);
static void setup_spiflashprotect_tag(u32 qtn_flags);
#ifdef CONFIG_CMDLINE_TAG
char *commandline_tag = NULL;
#endif

#if 0
static void setup_ramdisk_tag (bd_t *bd);
#endif
# ifdef CONFIG_INITRD_TAG
static void setup_initrd_tag (bd_t *bd, ulong initrd_start,
			      ulong initrd_end);
# endif
static void setup_end_tag (bd_t *bd);

# if defined (CONFIG_VFD) || defined (CONFIG_LCD)
static void setup_videolfb_tag (gd_t *gd);
# endif

static struct tag *params;
#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */

extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);

typedef void (*KernelEntry)(int zero, int arch, uint params);

static uint8_t __atag_mem[CONFIG_ATAGS_MAX_SIZE] __attribute__((__section__(".bss.atags")));

void do_bootm_linux (int flag, int argc, char *argv[], bootm_headers_t *images)
{
	bd_t *bd = gd->bd;

	// pass atag parameters through space in the u-boot heap
	bd->bi_boot_params = __atag_mem;

	setup_start_tag(bd);
#ifdef CONFIG_CMDLINE_TAG
	char *commandline = getenv ("bootargs");
	setup_commandline_tag (bd, commandline);
#endif
	setup_hwid_tag();

	/* Both conditions has to be met:
	 * 1) env: spi_protect == enable
	 * 2) new kernel that support Protection Mode
         */

	if ((protect_env_get() == 0) && (images->qtn_flags & 0x1)){
		printf("##  Set TAG qtn_flags %x\n", images->qtn_flags);
		setup_spiflashprotect_tag((u32)images->qtn_flags);
	} else {
		printf("##  Unset TAG qtn_flags %x\n", images->qtn_flags);
		spi_unprotect_global();
	}

	setup_end_tag(bd);

	KernelEntry theKernel = (KernelEntry)images->ep;

	printf("## Transferring control to Linux (at address %08lx) ATAG parameters %08lx - %08lx...\n",
		(ulong)theKernel, bd->bi_boot_params, params);

	cleanup_before_linux ();

	int arch = read_new_aux_reg(0x04 /*IDENTITY*/);
#if defined(GFRG240) && defined(CONFIG_CMDLINE_TAG)
	if (commandline_tag != NULL) {
	  theKernel (1, arch, commandline_tag);
	  /* no return */
	}
	/* otherwise FALL THROUGH to no-command line args jump */
#endif
	theKernel (0, arch, bd->bi_boot_params);
	/* no return */
}

#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
    defined (CONFIG_CMDLINE_TAG) || \
    defined (CONFIG_INITRD_TAG) || \
    defined (CONFIG_SERIAL_TAG) || \
    defined (CONFIG_REVISION_TAG) || \
    defined (CONFIG_LCD) || \
    defined (CONFIG_VFD)
static void setup_start_tag (bd_t *bd)
{
	params = (struct tag *) bd->bi_boot_params;

	params->hdr.tag = ATAG_CORE;
	params->hdr.size = tag_size (tag_core);

//	params->u.core.flags = 0;
//	params->u.core.pagesize = 0;
//	params->u.core.rootdev = 0;

	params = tag_next (params);
}


#ifdef CONFIG_SETUP_MEMORY_TAGS
static void setup_memory_tags (bd_t *bd)
{
	int i;

	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
		params->hdr.tag = ATAG_MEM;
		params->hdr.size = tag_size (tag_mem32);

//		params->u.mem.start = bd->bi_dram[i].start;
//		params->u.mem.size = bd->bi_dram[i].size;

		params = tag_next (params);
	}
}
#endif /* CONFIG_SETUP_MEMORY_TAGS */


static void setup_commandline_tag (bd_t *bd, char *commandline)
{
	char *p;

	if (!commandline)
		return;

	/* eat leading white space */
	for (p = commandline; *p == ' '; p++);

	/* skip non-existent command lines so the kernel will still
	 * use its default command line.
	 */
	if (*p == '\0')
		return;
printf("Command line TAG setup\n");
	params->hdr.tag = ATAG_CMDLINE;
	params->hdr.size =
		(sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2;

	strcpy (params->u.cmdline.cmdline, p);
    printf("Params->u.cmdline.cmdline %s\n", params->u.cmdline.cmdline);
    printf("p %s\n", p);
#ifdef CONFIG_CMDLINE_TAG
	commandline_tag = params->u.cmdline.cmdline;
#endif

	params = tag_next (params);
}

static void setup_hwid_tag(void)
{
	char *hwid_str = getenv("hw_config_id");
	if (hwid_str) {
		params->hdr.tag = ATAG_HW_CONFIG_ID;
		params->hdr.size = tag_size(tag_hwid);
		params->u.hwid.hwid = simple_strtoul(hwid_str, NULL, 10);
		params = tag_next (params);
	}
}

static void setup_spiflashprotect_tag(u32 qtn_flags)
{
	params->hdr.tag = ATAG_SPI_FLASH_PROTECT_MODE;
	params->hdr.size = tag_size(tag_spiflash);
	params->u.spi_flash_protect_mode.spi_flash_protect_mode = (qtn_flags & 0x1);
	params = tag_next (params);
}

#ifdef CONFIG_INITRD_TAG
static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
{
	/* an ATAG_INITRD node tells the kernel where the compressed
	 * ramdisk can be found. ATAG_RDIMG is a better name, actually.
	 */
	params->hdr.tag = ATAG_INITRD2;
	params->hdr.size = tag_size (tag_initrd);

	params->u.initrd.start = initrd_start;
	params->u.initrd.size = initrd_end - initrd_start;

	params = tag_next (params);
}
#endif /* CONFIG_INITRD_TAG */


#if defined (CONFIG_VFD) || defined (CONFIG_LCD)
extern ulong calc_fbsize (void);
static void setup_videolfb_tag (gd_t *gd)
{
	/* An ATAG_VIDEOLFB node tells the kernel where and how large
	 * the framebuffer for video was allocated (among other things).
	 * Note that a _physical_ address is passed !
	 *
	 * We only use it to pass the address and size, the other entries
	 * in the tag_videolfb are not of interest.
	 */
	params->hdr.tag = ATAG_VIDEOLFB;
	params->hdr.size = tag_size (tag_videolfb);

	params->u.videolfb.lfb_base = (u32) gd->fb_base;
	/* Fb size is calculated according to parameters for our panel
	 */
	params->u.videolfb.lfb_size = calc_fbsize();

	params = tag_next (params);
}
#endif /* CONFIG_VFD || CONFIG_LCD */

#ifdef CONFIG_SERIAL_TAG
void setup_serial_tag (struct tag **tmp)
{
	struct tag *params = *tmp;
	struct tag_serialnr serialnr;
	void get_board_serial(struct tag_serialnr *serialnr);

	get_board_serial(&serialnr);
	params->hdr.tag = ATAG_SERIAL;
	params->hdr.size = tag_size (tag_serialnr);
	params->u.serialnr.low = serialnr.low;
	params->u.serialnr.high= serialnr.high;
	params = tag_next (params);
	*tmp = params;
printf("config_serial_tag\n");

}
#endif

#ifdef CONFIG_REVISION_TAG
void setup_revision_tag(struct tag **in_params)
{
	u32 rev = 0;
	u32 get_board_rev(void);

	rev = get_board_rev();
	params->hdr.tag = ATAG_REVISION;
	params->hdr.size = tag_size (tag_revision);
	params->u.revision.rev = rev;
	params = tag_next (params);
}
#endif  /* CONFIG_REVISION_TAG */


static void setup_end_tag (bd_t *bd)
{
	params->hdr.tag = ATAG_NONE;
	params->hdr.size = 0;
}

#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */

