board.c 4.9 KB
Newer Older
W
wdenk 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/*
 * (C) Copyright 2003, Psyent Corporation <www.psyent.com>
 * Scott McNutt <smcnutt@psyent.com>
 *
 * (C) Copyright 2000-2002
 * 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 <devices.h>
#include <watchdog.h>
W
wdenk 已提交
30
#include <net.h>
W
wdenk 已提交
31 32 33
#ifdef CONFIG_STATUS_LED
#include <status_led.h>
#endif
W
wdenk 已提交
34

35
DECLARE_GLOBAL_DATA_PTR;
W
wdenk 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

/*
 * All attempts to come up with a "common" initialization sequence
 * that works for all boards and architectures failed: some of the
 * requirements are just _too_ different. To get rid of the resulting
 * mess of board dependend #ifdef'ed code we now make the whole
 * initialization sequence configurable to the user.
 *
 * The requirements for any new initalization function is simple: it
 * receives a pointer to the "global data" structure as it's only
 * argument, and returns an integer return code, where 0 means
 * "continue" and != 0 means "fatal error, hang the system".
 */


extern void malloc_bin_reloc (void);
typedef int (init_fnc_t) (void);

/*
 * Begin and End of memory area for malloc(), and current "brk"
 */
static	ulong	mem_malloc_start = 0;
static	ulong	mem_malloc_end	 = 0;
static	ulong	mem_malloc_brk	 = 0;

/*
 * The Malloc area is immediately below the monitor copy in RAM
 */
static void mem_malloc_init (void)
{
66 67
	mem_malloc_start = CONFIG_SYS_MALLOC_BASE;
	mem_malloc_end = mem_malloc_start + CONFIG_SYS_MALLOC_LEN;
W
wdenk 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
	mem_malloc_brk = mem_malloc_start;
	memset ((void *) mem_malloc_start,
		0,
		mem_malloc_end - mem_malloc_start);
}

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

	if ((new < mem_malloc_start) || (new > mem_malloc_end)) {
		return (NULL);
	}
	mem_malloc_brk = new;
	return ((void *) old);
}


/************************************************************************
 * Initialization sequence						*
 ***********************************************************************/

init_fnc_t *init_sequence[] = {

93 94
#if defined(CONFIG_BOARD_EARLY_INIT_F)
	board_early_init_f,	/* Call board-specific init code early.*/
W
wdenk 已提交
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
#endif

	env_init,
	serial_init,
	console_init_f,
	display_options,
	checkcpu,
	checkboard,
	NULL,			/* Terminate this list */
};


/***********************************************************************/
void board_init (void)
{
	bd_t *bd;
	init_fnc_t **init_fnc_ptr;
W
wdenk 已提交
112 113
	char *s, *e;
	int i;
W
wdenk 已提交
114 115

	/* Pointer is writable since we allocated a register for it.
116
	 * Nios treats CONFIG_SYS_GBL_DATA_OFFSET as an address.
W
wdenk 已提交
117
	 */
118
	gd = (gd_t *)CONFIG_SYS_GBL_DATA_OFFSET;
119 120 121
	/* compiler optimization barrier needed for GCC >= 3.4 */
	__asm__ __volatile__("": : :"memory");

122
	memset( gd, 0, CONFIG_SYS_GBL_DATA_SIZE );
W
wdenk 已提交
123 124 125 126 127 128

	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;
129 130 131 132 133 134
	bd->bi_memstart	= CONFIG_SYS_SDRAM_BASE;
	bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE;
	bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
#if	defined(CONFIG_SYS_SRAM_BASE) && defined(CONFIG_SYS_SRAM_SIZE)
	bd->bi_sramstart= CONFIG_SYS_SRAM_BASE;
	bd->bi_sramsize	= CONFIG_SYS_SRAM_SIZE;
W
wdenk 已提交
135
#endif
W
wdenk 已提交
136 137 138
	bd->bi_baudrate	= CONFIG_BAUDRATE;

	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
W
wdenk 已提交
139
		WATCHDOG_RESET ();
W
wdenk 已提交
140 141 142 143 144
		if ((*init_fnc_ptr) () != 0) {
			hang ();
		}
	}

W
wdenk 已提交
145
	WATCHDOG_RESET ();
W
wdenk 已提交
146 147
	bd->bi_flashsize = flash_init();

W
wdenk 已提交
148
	WATCHDOG_RESET ();
W
wdenk 已提交
149 150 151 152
	mem_malloc_init();
	malloc_bin_reloc();
	env_relocate();

W
wdenk 已提交
153 154
	bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

W
wdenk 已提交
155
	WATCHDOG_RESET ();
W
wdenk 已提交
156 157 158 159 160 161
	devices_init();
	jumptable_init();
	console_init_r();
	/*
	 */

W
wdenk 已提交
162
	WATCHDOG_RESET ();
W
wdenk 已提交
163
	interrupt_init ();
W
wdenk 已提交
164 165 166 167 168

#ifdef CONFIG_STATUS_LED
	status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING);
#endif

W
wdenk 已提交
169 170 171 172 173 174 175 176 177 178 179 180
	/* main_loop */
	for (;;) {
		WATCHDOG_RESET ();
		main_loop ();
	}
}


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

void hang (void)
{
W
wdenk 已提交
181 182 183 184
#ifdef CONFIG_STATUS_LED
	status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
	status_led_set(STATUS_LED_RED, STATUS_LED_BLINKING);
#endif
W
wdenk 已提交
185 186 187
	puts("### ERROR ### Please reset board ###\n");
	for (;;);
}
188 189 190 191 192 193 194 195 196 197

unsigned long do_go_exec (ulong (*entry)(int, char *[]), int argc, char *argv[])
{
	/*
	 * x86 does not use a dedicated register to pass the pointer
	 * to the global_data
	 */
	argv[-1] = (char *)gd;
	return entry (argc, argv);
}