board.c 16.7 KB
Newer Older
W
wdenk 已提交
1
/*
W
wdenk 已提交
2 3 4 5
 * (C) Copyright 2003
 * Josef Baumgartner <josef.baumgartner@telex.de>
 *
 * (C) Copyright 2000-2002
W
wdenk 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 * 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 <watchdog.h>
#include <command.h>
#include <malloc.h>
#include <devices.h>
W
wdenk 已提交
32 33 34 35 36

#ifdef	CONFIG_M5272
#include <asm/immap_5272.h>
#endif

W
wdenk 已提交
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
#if (CONFIG_COMMANDS & CFG_CMD_IDE)
#include <ide.h>
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
#include <scsi.h>
#endif
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#include <kgdb.h>
#endif
#ifdef CONFIG_STATUS_LED
#include <status_led.h>
#endif
#include <net.h>
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
#include <cmd_bedbug.h>
#endif
#ifdef CFG_ALLOC_DPRAM
#include <commproc.h>
#endif
#include <version.h>

static char *failed = "*** failed ***\n";

#ifdef	CONFIG_PCU_E
extern flash_info_t flash_info[];
#endif

W
wdenk 已提交
64 65
#include <environment.h>

W
wdenk 已提交
66 67 68 69 70 71 72 73
#if ( ((CFG_ENV_ADDR+CFG_ENV_SIZE) < CFG_MONITOR_BASE) || \
      (CFG_ENV_ADDR >= (CFG_MONITOR_BASE + CFG_MONITOR_LEN)) ) || \
    defined(CFG_ENV_IS_IN_NVRAM)
#define	TOTAL_MALLOC_LEN	(CFG_MALLOC_LEN + CFG_ENV_SIZE)
#else
#define	TOTAL_MALLOC_LEN	CFG_MALLOC_LEN
#endif

W
wdenk 已提交
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
extern ulong __init_end;
extern ulong _end;

extern	void timer_init(void);

#if defined(CONFIG_WATCHDOG)
# define INIT_FUNC_WATCHDOG_INIT	watchdog_init,
# define WATCHDOG_DISABLE		watchdog_disable

extern int watchdog_init(void);
extern int watchdog_disable(void);
#else
# define INIT_FUNC_WATCHDOG_INIT	/* undef */
# define WATCHDOG_DISABLE		/* undef */
#endif /* CONFIG_WATCHDOG */

ulong monitor_flash_len;

W
wdenk 已提交
92 93 94
/*
 * Begin and End of memory area for malloc(), and current "brk"
 */
W
wdenk 已提交
95 96 97
static	ulong	mem_malloc_start = 0;
static	ulong	mem_malloc_end	 = 0;
static	ulong	mem_malloc_brk	 = 0;
W
wdenk 已提交
98 99 100 101 102 103 104 105 106

/************************************************************************
 * Utilities								*
 ************************************************************************
 */

/*
 * The Malloc area is immediately below the monitor copy in DRAM
 */
W
wdenk 已提交
107
static void mem_malloc_init (void)
W
wdenk 已提交
108
{
W
wdenk 已提交
109 110 111 112
	DECLARE_GLOBAL_DATA_PTR;

	ulong dest_addr = CFG_MONITOR_BASE + gd->reloc_off;

W
wdenk 已提交
113 114 115 116
	mem_malloc_end = dest_addr;
	mem_malloc_start = dest_addr - TOTAL_MALLOC_LEN;
	mem_malloc_brk = mem_malloc_start;

W
wdenk 已提交
117 118
	memset ((void *) mem_malloc_start,
		0,
W
wdenk 已提交
119 120 121 122 123 124 125 126
		mem_malloc_end - mem_malloc_start);
}

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

W
wdenk 已提交
127 128
	if ((new < mem_malloc_start) ||
	    (new > mem_malloc_end) ) {
W
wdenk 已提交
129 130 131
		return (NULL);
	}
	mem_malloc_brk = new;
W
wdenk 已提交
132
	return ((void *)old);
W
wdenk 已提交
133 134
}

W
wdenk 已提交
135
char *strmhz(char *buf, long hz)
W
wdenk 已提交
136
{
W
wdenk 已提交
137 138
    long l, n;
    long m;
W
wdenk 已提交
139

W
wdenk 已提交
140
    n = hz / 1000000L;
W
wdenk 已提交
141

W
wdenk 已提交
142
    l = sprintf (buf, "%ld", n);
W
wdenk 已提交
143

W
wdenk 已提交
144
    m = (hz % 1000000L) / 1000L;
W
wdenk 已提交
145

W
wdenk 已提交
146 147
    if (m != 0)
	sprintf (buf+l, ".%03ld", m);
W
wdenk 已提交
148

W
wdenk 已提交
149
    return (buf);
W
wdenk 已提交
150 151
}

W
wdenk 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
/*
 * 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".
 */
typedef int (init_fnc_t) (void);

/************************************************************************
 * Init Utilities							*
 ************************************************************************
 * Some of this code should be moved into the core functions,
 * but let's get it working (again) first...
 */

static int init_baudrate (void)
W
wdenk 已提交
174
{
W
wdenk 已提交
175 176 177 178 179 180 181 182 183 184
	DECLARE_GLOBAL_DATA_PTR;

	uchar tmp[64];	/* long enough for environment variables */
	int i = getenv_r ("baudrate", tmp, sizeof (tmp));

	gd->baudrate = (i > 0)
			? (int) simple_strtoul (tmp, NULL, 10)
			: CONFIG_BAUDRATE;
	return (0);
}
W
wdenk 已提交
185

W
wdenk 已提交
186
/***********************************************************************/
W
wdenk 已提交
187

W
wdenk 已提交
188 189 190
static int init_func_ram (void)
{
	DECLARE_GLOBAL_DATA_PTR;
W
wdenk 已提交
191

W
wdenk 已提交
192 193
	int board_type = 0;	/* use dummy arg */
	puts ("DRAM:  ");
W
wdenk 已提交
194

W
wdenk 已提交
195 196 197 198 199 200
	if ((gd->ram_size = initdram (board_type)) > 0) {
		print_size (gd->ram_size, "\n");
		return (0);
	}
	puts (failed);
	return (1);
W
wdenk 已提交
201 202
}

W
wdenk 已提交
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
/***********************************************************************/

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

init_fnc_t *init_sequence[] = {
	env_init,
	init_baudrate,
	serial_init,
	console_init_f,
	display_options,
	checkcpu,
	checkboard,
	init_func_ram,
#if defined(CFG_DRAM_TEST)
	testdram,
#endif /* CFG_DRAM_TEST */
	INIT_FUNC_WATCHDOG_INIT
	NULL,			/* Terminate this list */
};


W
wdenk 已提交
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
/************************************************************************
 *
 * This is the first part of the initialization sequence that is
 * implemented in C, but still running from ROM.
 *
 * The main purpose is to provide a (serial) console interface as
 * soon as possible (so we can see any error messages), and to
 * initialize the RAM so that we can relocate the monitor code to
 * RAM.
 *
 * Be aware of the restrictions: global data is read-only, BSS is not
 * initialized, and stack space is limited to a few kB.
 *
 ************************************************************************
 */

W
wdenk 已提交
243 244
void
board_init_f (ulong bootflag)
W
wdenk 已提交
245
{
W
wdenk 已提交
246
    DECLARE_GLOBAL_DATA_PTR;
W
wdenk 已提交
247 248

	bd_t *bd;
W
wdenk 已提交
249 250 251 252 253 254
	ulong len, addr, addr_sp;
	gd_t *id;
	init_fnc_t **init_fnc_ptr;
#ifdef CONFIG_PRAM
	int i;
	ulong reg;
W
wdenk 已提交
255
	uchar tmp[64];		/* long enough for environment variables */
W
wdenk 已提交
256
#endif
W
wdenk 已提交
257

W
wdenk 已提交
258 259
	/* Pointer is writable since we allocated a register for it */
	gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
260 261
	/* compiler optimization barrier needed for GCC >= 3.4 */
	__asm__ __volatile__("": : :"memory");
W
wdenk 已提交
262

W
wdenk 已提交
263 264
	/* Clear initial global data */
	memset ((void *) gd, 0, sizeof (gd_t));
W
wdenk 已提交
265

W
wdenk 已提交
266 267 268 269
	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
		if ((*init_fnc_ptr)() != 0) {
			hang ();
		}
W
wdenk 已提交
270 271 272 273 274 275 276
	}

	/*
	 * Now that we have DRAM mapped and working, we can
	 * relocate the code and continue running from DRAM.
	 *
	 * Reserve memory at end of RAM for (top down in that order):
W
wdenk 已提交
277 278 279 280
	 *	- protected RAM
	 *	- LCD framebuffer
	 *	- monitor code
	 *	- board info struct
W
wdenk 已提交
281
	 */
W
wdenk 已提交
282
	len = (ulong)&_end - CFG_MONITOR_BASE;
W
wdenk 已提交
283

W
wdenk 已提交
284
	addr = CFG_SDRAM_BASE + gd->ram_size;
W
wdenk 已提交
285

W
wdenk 已提交
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
#ifdef CONFIG_LOGBUFFER
	/* reserve kernel log buffer */
	addr -= (LOGBUFF_RESERVE);
	debug ("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, addr);
#endif

#ifdef CONFIG_PRAM
	/*
	 * reserve protected RAM
	 */
	i = getenv_r ("pram", tmp, sizeof (tmp));
	reg = (i > 0) ? simple_strtoul (tmp, NULL, 10) : CONFIG_PRAM;
	addr -= (reg << 10);		/* size is in kB */
	debug ("Reserving %ldk for protected RAM at %08lx\n", reg, addr);
#endif /* CONFIG_PRAM */
W
wdenk 已提交
301

W
wdenk 已提交
302 303 304 305
	/*
	 * reserve memory for U-Boot code, data & bss
	 * round down to next 4 kB limit
	 */
W
wdenk 已提交
306
	addr -= len;
W
wdenk 已提交
307 308 309
	addr &= ~(4096 - 1);

	debug ("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr);
W
wdenk 已提交
310 311

	/*
W
wdenk 已提交
312
	 * reserve memory for malloc() arena
W
wdenk 已提交
313
	 */
W
wdenk 已提交
314 315 316
	addr_sp = addr - TOTAL_MALLOC_LEN;
	debug ("Reserving %dk for malloc() at: %08lx\n",
			TOTAL_MALLOC_LEN >> 10, addr_sp);
W
wdenk 已提交
317

W
wdenk 已提交
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
	/*
	 * (permanently) allocate a Board Info struct
	 * and a permanent copy of the "global" data
	 */
	addr_sp -= sizeof (bd_t);
	bd = (bd_t *) addr_sp;
	gd->bd = bd;
	debug ("Reserving %d Bytes for Board Info at: %08lx\n",
			sizeof (bd_t), addr_sp);
	addr_sp -= sizeof (gd_t);
	id = (gd_t *) addr_sp;
	debug ("Reserving %d Bytes for Global Data at: %08lx\n",
			sizeof (gd_t), addr_sp);

 	/* Reserve memory for boot params. */
	addr_sp -= CFG_BOOTPARAMS_LEN;
	bd->bi_boot_params = addr_sp;
	debug ("Reserving %dk for boot parameters at: %08lx\n",
			CFG_BOOTPARAMS_LEN >> 10, addr_sp);
W
wdenk 已提交
337

W
wdenk 已提交
338 339 340 341 342 343 344 345 346 347 348
	/*
	 * Finally, we set up a new (bigger) stack.
	 *
	 * Leave some safety gap for SP, force alignment on 16 byte boundary
	 * Clear initial stack frame
	 */
	addr_sp -= 16;
	addr_sp &= ~0xF;
	*((ulong *) addr_sp)-- = 0;
	*((ulong *) addr_sp)-- = 0;
	debug ("Stack Pointer at: %08lx\n", addr_sp);
W
wdenk 已提交
349

W
wdenk 已提交
350 351 352 353 354 355 356 357 358 359 360 361 362
	/*
	 * Save local variables to board info struct
	 */
	bd->bi_memstart  = CFG_SDRAM_BASE;	/* start of  DRAM memory      */
	bd->bi_memsize   = gd->ram_size;	/* size  of  DRAM memory in bytes */
	bd->bi_mbar_base = CFG_MBAR;		/* base of internal registers */

	bd->bi_bootflags = bootflag;		/* boot / reboot flag (for LynxOS)    */

	WATCHDOG_RESET ();
	bd->bi_intfreq = gd->cpu_clk;	/* Internal Freq, in Hz */
	bd->bi_busfreq = gd->bus_clk;	/* Bus Freq,      in Hz */
	bd->bi_baudrate = gd->baudrate;	/* Console Baudrate     */
W
wdenk 已提交
363 364 365

#ifdef CFG_EXTBDINFO
	strncpy (bd->bi_s_version, "1.2", sizeof (bd->bi_s_version));
W
wdenk 已提交
366 367 368 369
	strncpy (bd->bi_r_version, U_BOOT_VERSION, sizeof (bd->bi_r_version));
#endif

	WATCHDOG_RESET ();
W
wdenk 已提交
370

W
wdenk 已提交
371 372 373
#ifdef CONFIG_POST
	post_bootmode_init();
	post_run (NULL, POST_ROM | post_bootmode_get(0));
W
wdenk 已提交
374 375
#endif

W
wdenk 已提交
376
	WATCHDOG_RESET();
W
wdenk 已提交
377

W
wdenk 已提交
378 379 380 381
	memcpy (id, (void *)gd, sizeof (gd_t));

	debug ("Start relocate of code from %08x to %08lx\n", CFG_MONITOR_BASE, addr);
	relocate_code (addr_sp, id, addr);
W
wdenk 已提交
382

W
wdenk 已提交
383 384
	/* NOTREACHED - jump_to_ram() does not return */
}
W
wdenk 已提交
385 386 387 388 389 390 391 392 393 394

/************************************************************************
 *
 * This is the next part if the initialization sequence: we are now
 * running from RAM and have a "normal" C environment, i. e. global
 * data can be written, BSS has been cleared, the stack size in not
 * that critical any more, etc.
 *
 ************************************************************************
 */
W
wdenk 已提交
395
void board_init_r (gd_t *id, ulong dest_addr)
W
wdenk 已提交
396 397 398
{
	DECLARE_GLOBAL_DATA_PTR;
	cmd_tbl_t *cmdtp;
W
wdenk 已提交
399
	char *s, *e;
W
wdenk 已提交
400
	bd_t *bd;
W
wdenk 已提交
401 402
	int i;
	extern void malloc_bin_reloc (void);
W
wdenk 已提交
403

W
wdenk 已提交
404 405 406 407 408 409 410
#ifndef CFG_ENV_IS_NOWHERE
	extern char * env_name_spec;
#endif
#ifndef CFG_NO_FLASH
	ulong flash_size;
#endif
	gd = id;		/* initialize RAM version of global data */
W
wdenk 已提交
411
	bd = gd->bd;
W
wdenk 已提交
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469

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

	debug ("Now running in RAM - U-Boot at: %08lx\n", dest_addr);

	WATCHDOG_RESET ();

	gd->reloc_off =  dest_addr - CFG_MONITOR_BASE;

	monitor_flash_len = (ulong)&__init_end - dest_addr;

	/*
	 * We have to relocate the command table manually
	 */
	for (cmdtp = &__u_boot_cmd_start; cmdtp !=  &__u_boot_cmd_end; cmdtp++) {
		ulong addr;
		addr = (ulong) (cmdtp->cmd) + gd->reloc_off;
#if 0
		printf ("Command \"%s\": 0x%08lx => 0x%08lx\n",
				cmdtp->name, (ulong) (cmdtp->cmd), addr);
#endif
		cmdtp->cmd =
			(int (*)(struct cmd_tbl_s *, int, int, char *[]))addr;

		addr = (ulong)(cmdtp->name) + gd->reloc_off;
		cmdtp->name = (char *)addr;

		if (cmdtp->usage) {
			addr = (ulong)(cmdtp->usage) + gd->reloc_off;
			cmdtp->usage = (char *)addr;
		}
#ifdef	CFG_LONGHELP
		if (cmdtp->help) {
			addr = (ulong)(cmdtp->help) + gd->reloc_off;
			cmdtp->help = (char *)addr;
		}
#endif
	}
	/* there are some other pointer constants we must deal with */
#ifndef CFG_ENV_IS_NOWHERE
	env_name_spec += gd->reloc_off;
#endif

	WATCHDOG_RESET ();

#ifdef CONFIG_LOGBUFFER
	logbuff_init_ptrs ();
#endif
#ifdef CONFIG_POST
	post_output_backlog ();
	post_reloc ();
#endif
	WATCHDOG_RESET();

#if 0
	/* instruction cache enabled in cpu_init_f() for faster relocation */
	icache_enable ();	/* it's time to enable the instruction cache */
#endif
W
wdenk 已提交
470 471 472 473

	/*
	 * Setup trap handlers
	 */
W
wdenk 已提交
474
	trap_init (0);
W
wdenk 已提交
475

W
wdenk 已提交
476
#if !defined(CFG_NO_FLASH)
W
wdenk 已提交
477 478 479
	puts ("FLASH: ");

	if ((flash_size = flash_init ()) > 0) {
W
wdenk 已提交
480 481
# ifdef CFG_FLASH_CHECKSUM
		print_size (flash_size, "");
W
wdenk 已提交
482 483 484
		/*
		 * Compute and print flash CRC if flashchecksum is set to 'y'
		 *
W
wdenk 已提交
485
		 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
W
wdenk 已提交
486 487 488 489
		 */
		s = getenv ("flashchecksum");
		if (s && (*s == 'y')) {
			printf ("  CRC: %08lX",
W
wdenk 已提交
490 491 492 493
					crc32 (0,
						   (const unsigned char *) CFG_FLASH_BASE,
						   flash_size)
					);
W
wdenk 已提交
494 495
		}
		putc ('\n');
W
wdenk 已提交
496 497 498
# else	/* !CFG_FLASH_CHECKSUM */
		print_size (flash_size, "\n");
# endif /* CFG_FLASH_CHECKSUM */
W
wdenk 已提交
499 500 501 502 503
	} else {
		puts (failed);
		hang ();
	}

W
wdenk 已提交
504 505 506 507 508 509 510 511
	bd->bi_flashstart = CFG_FLASH_BASE;	/* update start of FLASH memory    */
	bd->bi_flashsize = flash_size;	/* size of FLASH memory (final value) */
	bd->bi_flashoffset = 0;
#else	/* CFG_NO_FLASH */
	bd->bi_flashsize = 0;
	bd->bi_flashstart = 0;
	bd->bi_flashoffset = 0;
#endif /* !CFG_NO_FLASH */
W
wdenk 已提交
512 513 514 515 516 517 518 519 520

	WATCHDOG_RESET ();

	/* initialize higher level parts of CPU like time base and timers */
	cpu_init_r ();

	WATCHDOG_RESET ();

	/* initialize malloc() area */
W
wdenk 已提交
521 522
	mem_malloc_init ();
	malloc_bin_reloc ();
W
wdenk 已提交
523 524 525 526 527 528 529 530 531 532 533

#ifdef CONFIG_SPI
# if !defined(CFG_ENV_IS_IN_EEPROM)
	spi_init_f ();
# endif
	spi_init_r ();
#endif

	/* relocate environment function pointers etc. */
	env_relocate ();

W
wdenk 已提交
534 535 536 537 538 539 540 541 542 543 544 545 546 547
	/*
	 * Fill in missing fields of bd_info.
	 * We do this here, where we have "normal" access to the
	 * environment; we used to do this still running from ROM,
	 * where had to use getenv_r(), which can be pretty slow when
	 * the environment is in EEPROM.
	 */
	s = getenv ("ethaddr");
	for (i = 0; i < 6; ++i) {
		bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0;
		if (s)
			s = (*e) ? e + 1 : e;
	}

W
wdenk 已提交
548 549 550 551 552 553
	/* IP Address */
	bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

	WATCHDOG_RESET ();


W
wdenk 已提交
554 555 556
	/** leave this here (after malloc(), environment and PCI are working) **/
	/* Initialize devices */
	devices_init ();
W
wdenk 已提交
557

W
wdenk 已提交
558 559
	/* Initialize the jump table for applications */
	jumptable_init ();
W
wdenk 已提交
560

W
wdenk 已提交
561 562
	/* Initialize the console (after the relocation and devices init) */
	console_init_r ();
W
wdenk 已提交
563 564 565 566 567 568 569

#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
	WATCHDOG_RESET ();
	puts ("KGDB:  ");
	kgdb_init ();
#endif

W
wdenk 已提交
570 571
	debug ("U-Boot relocated to %08lx\n", dest_addr);

W
wdenk 已提交
572 573 574 575
	/*
	 * Enable Interrupts
	 */
	interrupt_init ();
W
wdenk 已提交
576 577 578 579 580 581

	/* Must happen after interrupts are initialized since
	 * an irq handler gets installed
	 */
	timer_init();

582
#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
W
wdenk 已提交
583 584 585 586 587 588 589
	serial_buffered_init();
#endif

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

W
wdenk 已提交
590
	udelay (20);
W
wdenk 已提交
591

W
wdenk 已提交
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607
	set_timer (0);

	/* Insert function pointers now that we have relocated the code */

	/* Initialize from environment */
	if ((s = getenv ("loadaddr")) != NULL) {
		load_addr = simple_strtoul (s, NULL, 16);
	}
#if (CONFIG_COMMANDS & CFG_CMD_NET)
	if ((s = getenv ("bootfile")) != NULL) {
		copy_filename (BootFile, s, sizeof (BootFile));
	}
#endif /* CFG_CMD_NET */

	WATCHDOG_RESET ();

W
wdenk 已提交
608 609 610 611 612 613 614
#if (CONFIG_COMMANDS & CFG_CMD_DOC)
	WATCHDOG_RESET ();
	puts ("DOC:   ");
	doc_init ();
#endif

#if (CONFIG_COMMANDS & CFG_CMD_NAND)
W
wdenk 已提交
615
	WATCHDOG_RESET ();
W
wdenk 已提交
616 617 618 619 620 621 622 623 624 625 626
	puts ("NAND:");
	nand_init();		/* go init the NAND */
#endif

#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(FEC_ENET)
	WATCHDOG_RESET();
	eth_init(bd);
#endif

#ifdef CONFIG_POST
	post_run (NULL, POST_RAM | post_bootmode_get(0));
W
wdenk 已提交
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643
#endif

#ifdef CONFIG_LAST_STAGE_INIT
	WATCHDOG_RESET ();
	/*
	 * Some parts can be only initialized if all others (like
	 * Interrupts) are up and running (i.e. the PC-style ISA
	 * keyboard).
	 */
	last_stage_init ();
#endif

#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
	WATCHDOG_RESET ();
	bedbug_init ();
#endif

W
wdenk 已提交
644
#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
W
wdenk 已提交
645 646 647 648 649 650 651
	/*
	 * Export available size of memory for Linux,
	 * taking into account the protected RAM at top of memory
	 */
	{
		ulong pram;
		uchar memsz[32];
W
wdenk 已提交
652 653
#ifdef CONFIG_PRAM
		char *s;
W
wdenk 已提交
654 655 656 657 658 659

		if ((s = getenv ("pram")) != NULL) {
			pram = simple_strtoul (s, NULL, 10);
		} else {
			pram = CONFIG_PRAM;
		}
W
wdenk 已提交
660 661 662 663 664 665 666
#else
		pram=0;
#endif
#ifdef CONFIG_LOGBUFFER
		/* Also take the logbuffer into account (pram is in kB) */
		pram += (LOGBUFF_LEN+LOGBUFF_OVERHEAD)/1024;
#endif
W
wdenk 已提交
667 668 669 670 671
		sprintf (memsz, "%ldk", (bd->bi_memsize / 1024) - pram);
		setenv ("mem", memsz);
	}
#endif

W
wdenk 已提交
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
#ifdef CONFIG_MODEM_SUPPORT
 {
	 extern int do_mdm_init;
	 do_mdm_init = gd->do_mdm_init;
 }
#endif

#ifdef CONFIG_WATCHDOG
	/* disable watchdog if environment is set */
	if ((s = getenv ("watchdog")) != NULL) {
		if (strncmp (s, "off", 3) == 0) {
			WATCHDOG_DISABLE ();
		}
	}
#endif /* CONFIG_WATCHDOG*/


W
wdenk 已提交
689 690 691 692 693 694 695 696 697 698 699
	/* Initialization complete - start the monitor */

	/* main_loop() can return to retry autoboot, if so just run it again. */
	for (;;) {
		WATCHDOG_RESET ();
		main_loop ();
	}

	/* NOTREACHED - no way out of command loop except booting */
}

W
wdenk 已提交
700 701

void hang(void)
W
wdenk 已提交
702 703 704 705
{
	puts ("### ERROR ### Please RESET the board ###\n");
	for (;;);
}