/*
 * Copyright (C) 2007
 * Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
 *
 * 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 <malloc.h>
#include <devices.h>
#include <version.h>
#include <net.h>
#include <environment.h>

extern void malloc_bin_reloc (void);
extern int cpu_init(void);
extern int board_init(void);
extern int dram_init(void);
extern int watchdog_init(void);
extern int timer_init(void);

const char version_string[] = U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")";

unsigned long monitor_flash_len = CFG_MONITOR_LEN;

static unsigned long mem_malloc_start;
static unsigned long mem_malloc_end;
static unsigned long mem_malloc_brk;

static void mem_malloc_init (void)
{

	mem_malloc_start = (TEXT_BASE - CFG_GBL_DATA_SIZE - CFG_MALLOC_LEN);
	mem_malloc_end = (mem_malloc_start + CFG_MALLOC_LEN - 16);
	mem_malloc_brk = mem_malloc_start;
	memset ((void *) mem_malloc_start, 0, 
		(mem_malloc_end - mem_malloc_start));
}

void *sbrk (ptrdiff_t increment)
{
	unsigned long old = mem_malloc_brk;
	unsigned long new = old + increment;

	if ((new < mem_malloc_start) ||
	    (new > mem_malloc_end)) {
		return NULL;
	}

	mem_malloc_brk = new;
	return (void *) old;
}

static int sh_flash_init(void)
{
	DECLARE_GLOBAL_DATA_PTR;

	gd->bd->bi_flashsize = flash_init();
	printf("FLASH: %dMB\n", gd->bd->bi_flashsize / (1024*1024));

	return 0;
}

#if defined(CONFIG_CMD_NAND)
void nand_init (void);
static int sh_nand_init(void)
{
	printf("NAND: ");
	nand_init();	/* go init the NAND */
	return 0;
}
#endif /* CONFIG_CMD_NAND */

#if defined(CONFIG_CMD_IDE)
#include <ide.h>
static int sh_marubun_init(void)
{
	puts ("IDE:   ");
	ide_init();
	return 0;
}
#endif /* (CONFIG_CMD_IDE) */

static int sh_mem_env_init(void)
{
	mem_malloc_init();
	malloc_bin_reloc();
	env_relocate();
	jumptable_init();
	return 0;
}

static int sh_net_init(void)
{
	DECLARE_GLOBAL_DATA_PTR;
	char *s, *e;
	int i;

	gd->bd->bi_ip_addr = getenv_IPaddr("ipaddr");
	s = getenv("ethaddr");
	for (i = 0; i < 6; ++i) {
		gd->bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0;
		if (s) s = (*e) ? e + 1 : e;
	}

	return 0;
}

typedef int (init_fnc_t) (void);

init_fnc_t *init_sequence[] =
{
	cpu_init,		/* basic cpu dependent setup */
	board_init,		/* basic board dependent setup */
	interrupt_init,		/* set up exceptions */
	env_init,		/* event init */
	serial_init,		/* SCIF init */
	watchdog_init,		/* watchdog init */
	console_init_f,
	display_options,
	checkcpu,
	checkboard,		/* Check support board */
	dram_init,		/* SDRAM init */
	timer_init,		/* SuperH Timer (TCNT0 only) init */
	sh_flash_init,		/* Flash memory(NOR) init*/
	sh_mem_env_init,
#if defined(CONFIG_CMD_NAND)
	sh_nand_init,		/* Flash memory (NAND) init */
#endif
	devices_init,
	console_init_r,
	interrupt_init,
#ifdef BOARD_LATE_INIT
	board_late_init,
#endif
#if defined(CONFIG_CMD_NET)
	sh_net_init,		/* SH specific eth init */
#endif
	NULL			/* Terminate this list */
};

void sh_generic_init (void)
{
	DECLARE_GLOBAL_DATA_PTR;

	bd_t *bd;
	init_fnc_t **init_fnc_ptr;
	char *s;
	int i;

	memset (gd, 0, CFG_GBL_DATA_SIZE);

	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */

	gd->bd = (bd_t *) (gd + 1);	/* At end of global data */
	gd->baudrate = CONFIG_BAUDRATE;

	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;

	bd = gd->bd;
	bd->bi_memstart	= CFG_SDRAM_BASE;
	bd->bi_memsize = CFG_SDRAM_SIZE;
	bd->bi_flashstart = CFG_FLASH_BASE;
#if defined(CFG_SRAM_BASE) && defined(CFG_SRAM_SIZE)
	bd->bi_sramstart= CFG_SRAM_BASE;
	bd->bi_sramsize	= CFG_SRAM_SIZE;
#endif
	bd->bi_baudrate	= CONFIG_BAUDRATE;

	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr , i++) {
		if ((*init_fnc_ptr) () != 0) {
			hang();
		}
	}

#if defined(CONFIG_CMD_NET)
	puts ("Net:   ");
	eth_initialize(gd->bd);

        if ((s = getenv ("bootfile")) != NULL) {
		copy_filename (BootFile, s, sizeof (BootFile));
	}
#endif /* CONFIG_CMD_NET */

	while (1) {
		main_loop();
	}
}

/***********************************************************************/

void hang (void)
{
	puts ("Board ERROR\n");
	for (;;);
}
