2002-11-03 00:24:07 +00:00
|
|
|
/*
|
2006-01-29 18:12:41 +00:00
|
|
|
* (C) Copyright 2002-2006
|
2002-11-03 00:24:07 +00:00
|
|
|
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
|
|
|
*
|
|
|
|
* (C) Copyright 2002
|
|
|
|
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
|
|
|
* Marius Groeger <mgroeger@sysgo.de>
|
|
|
|
*
|
2013-07-08 07:37:19 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0+
|
2002-11-03 00:24:07 +00:00
|
|
|
*/
|
|
|
|
|
2006-01-29 18:12:41 +00:00
|
|
|
/*
|
|
|
|
* To match the U-Boot user interface on ARM platforms to the U-Boot
|
|
|
|
* standard (as on PPC platforms), some messages with debug character
|
|
|
|
* are removed from the default U-Boot build.
|
|
|
|
*
|
|
|
|
* Define DEBUG here if you want additional info as shown below
|
|
|
|
* printed upon startup:
|
|
|
|
*
|
|
|
|
* U-Boot code: 00F00000 -> 00F3C774 BSS: -> 00FC3274
|
|
|
|
* IRQ Stack: 00ebff7c
|
|
|
|
* FIQ Stack: 00ebef7c
|
|
|
|
*/
|
|
|
|
|
2002-11-03 00:24:07 +00:00
|
|
|
#include <common.h>
|
|
|
|
#include <command.h>
|
2012-11-30 13:01:17 +00:00
|
|
|
#include <environment.h>
|
2003-06-22 17:18:28 +00:00
|
|
|
#include <malloc.h>
|
2009-05-16 10:14:54 +00:00
|
|
|
#include <stdio_dev.h>
|
2002-11-03 00:24:07 +00:00
|
|
|
#include <version.h>
|
|
|
|
#include <net.h>
|
2008-05-01 07:05:26 +00:00
|
|
|
#include <serial.h>
|
2008-05-22 15:49:46 +00:00
|
|
|
#include <nand.h>
|
|
|
|
#include <onenand_uboot.h>
|
2009-06-08 00:12:50 +00:00
|
|
|
#include <mmc.h>
|
2014-03-07 01:20:56 +00:00
|
|
|
#include <scsi.h>
|
2014-10-08 20:57:53 +00:00
|
|
|
#include <status_led.h>
|
2011-10-24 19:15:33 +00:00
|
|
|
#include <libfdt.h>
|
|
|
|
#include <fdtdec.h>
|
2011-09-02 04:59:03 +00:00
|
|
|
#include <post.h>
|
|
|
|
#include <logbuff.h>
|
2013-03-05 14:39:38 +00:00
|
|
|
#include <asm/sections.h>
|
2002-11-03 00:24:07 +00:00
|
|
|
|
2009-10-10 10:42:21 +00:00
|
|
|
#ifdef CONFIG_BITBANGMII
|
|
|
|
#include <miiphy.h>
|
|
|
|
#endif
|
|
|
|
|
2006-02-10 10:25:41 +00:00
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
|
2003-05-30 12:48:29 +00:00
|
|
|
ulong monitor_flash_len;
|
|
|
|
|
2003-06-16 23:50:08 +00:00
|
|
|
#ifdef CONFIG_HAS_DATAFLASH
|
|
|
|
extern int AT91F_DataflashInit(void);
|
|
|
|
extern void dataflash_print_info(void);
|
|
|
|
#endif
|
|
|
|
|
2007-12-19 00:00:54 +00:00
|
|
|
#if defined(CONFIG_HARD_I2C) || \
|
2012-01-16 21:12:24 +00:00
|
|
|
defined(CONFIG_SYS_I2C)
|
2007-12-19 00:00:54 +00:00
|
|
|
#include <i2c.h>
|
|
|
|
#endif
|
|
|
|
|
2007-09-04 15:18:38 +00:00
|
|
|
/************************************************************************
|
|
|
|
* Coloured LED functionality
|
|
|
|
************************************************************************
|
|
|
|
* May be supplied by boards if desired
|
|
|
|
*/
|
2014-10-08 20:57:21 +00:00
|
|
|
__weak void coloured_LED_init(void) {}
|
|
|
|
__weak void red_led_on(void) {}
|
|
|
|
__weak void red_led_off(void) {}
|
|
|
|
__weak void green_led_on(void) {}
|
|
|
|
__weak void green_led_off(void) {}
|
|
|
|
__weak void yellow_led_on(void) {}
|
|
|
|
__weak void yellow_led_off(void) {}
|
|
|
|
__weak void blue_led_on(void) {}
|
|
|
|
__weak void blue_led_off(void) {}
|
2007-09-04 15:18:38 +00:00
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
/*
|
|
|
|
************************************************************************
|
2002-11-03 00:24:07 +00:00
|
|
|
* Init Utilities *
|
|
|
|
************************************************************************
|
|
|
|
* Some of this code should be moved into the core functions,
|
|
|
|
* or dropped completely,
|
|
|
|
* but let's get it working (again) first...
|
|
|
|
*/
|
|
|
|
|
2009-02-22 14:49:28 +00:00
|
|
|
#if defined(CONFIG_ARM_DCC) && !defined(CONFIG_BAUDRATE)
|
|
|
|
#define CONFIG_BAUDRATE 115200
|
|
|
|
#endif
|
2011-10-13 14:43:06 +00:00
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
static int init_baudrate(void)
|
2002-11-03 00:24:07 +00:00
|
|
|
{
|
2011-10-13 14:43:06 +00:00
|
|
|
gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
|
|
|
|
return 0;
|
2002-11-03 00:24:07 +00:00
|
|
|
}
|
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
static int display_banner(void)
|
2002-11-03 00:24:07 +00:00
|
|
|
{
|
2011-07-15 19:36:36 +00:00
|
|
|
printf("\n\n%s\n\n", version_string);
|
|
|
|
debug("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n",
|
2014-02-22 16:53:43 +00:00
|
|
|
(ulong)&_start,
|
|
|
|
(ulong)&__bss_start, (ulong)&__bss_end);
|
2002-11-03 00:24:07 +00:00
|
|
|
#ifdef CONFIG_MODEM_SUPPORT
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("Modem Support enabled\n");
|
2002-11-03 00:24:07 +00:00
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_USE_IRQ
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("IRQ Stack: %08lx\n", IRQ_STACK_START);
|
|
|
|
debug("FIQ Stack: %08lx\n", FIQ_STACK_START);
|
2002-11-03 00:24:07 +00:00
|
|
|
#endif
|
2003-10-10 10:05:42 +00:00
|
|
|
|
2002-11-03 00:24:07 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* WARNING: this code looks "cleaner" than the PowerPC version, but
|
|
|
|
* has the disadvantage that you either get nothing, or everything.
|
|
|
|
* On PowerPC, you might see "DRAM: " before the system hangs - which
|
|
|
|
* gives a simple yet clear indication which part of the
|
|
|
|
* initialization if failing.
|
|
|
|
*/
|
2011-07-15 19:36:36 +00:00
|
|
|
static int display_dram_config(void)
|
2002-11-03 00:24:07 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2006-01-29 18:12:41 +00:00
|
|
|
#ifdef DEBUG
|
2011-07-15 19:36:36 +00:00
|
|
|
puts("RAM Configuration:\n");
|
2002-11-03 00:24:07 +00:00
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
|
|
|
|
printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
|
|
|
|
print_size(gd->bd->bi_dram[i].size, "\n");
|
2002-11-03 00:24:07 +00:00
|
|
|
}
|
2006-01-29 18:12:41 +00:00
|
|
|
#else
|
|
|
|
ulong size = 0;
|
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
|
2006-01-29 18:12:41 +00:00
|
|
|
size += gd->bd->bi_dram[i].size;
|
2011-07-15 19:36:36 +00:00
|
|
|
|
2006-01-29 18:12:41 +00:00
|
|
|
puts("DRAM: ");
|
|
|
|
print_size(size, "\n");
|
|
|
|
#endif
|
2002-11-03 00:24:07 +00:00
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2013-01-29 07:53:15 +00:00
|
|
|
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
|
2011-07-15 19:36:36 +00:00
|
|
|
static int init_func_i2c(void)
|
2007-12-19 00:00:54 +00:00
|
|
|
{
|
2011-07-15 19:36:36 +00:00
|
|
|
puts("I2C: ");
|
2012-01-16 21:12:24 +00:00
|
|
|
#ifdef CONFIG_SYS_I2C
|
|
|
|
i2c_init_all();
|
|
|
|
#else
|
2011-07-15 19:36:36 +00:00
|
|
|
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
|
2012-01-16 21:12:24 +00:00
|
|
|
#endif
|
2011-07-15 19:36:36 +00:00
|
|
|
puts("ready\n");
|
2007-12-19 00:00:54 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-01-31 08:04:58 +00:00
|
|
|
#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
|
|
|
|
#include <pci.h>
|
|
|
|
static int arm_pci_init(void)
|
|
|
|
{
|
|
|
|
pci_init();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_CMD_PCI || CONFIG_PCI */
|
|
|
|
|
2002-11-03 00:24:07 +00:00
|
|
|
/*
|
2003-12-06 19:49:23 +00:00
|
|
|
* Breathe some life into the board...
|
2002-11-03 00:24:07 +00:00
|
|
|
*
|
2003-09-17 22:48:07 +00:00
|
|
|
* Initialize a serial port as console, and carry out some hardware
|
2002-11-03 00:24:07 +00:00
|
|
|
* tests.
|
|
|
|
*
|
|
|
|
* The first part of initialization is running from Flash memory;
|
|
|
|
* its main purpose is to initialize the RAM so that we
|
|
|
|
* can relocate the monitor code to RAM.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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
|
2004-02-08 19:38:38 +00:00
|
|
|
* mess of board dependent #ifdef'ed code we now make the whole
|
2002-11-03 00:24:07 +00:00
|
|
|
* 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);
|
|
|
|
|
2014-10-08 20:57:21 +00:00
|
|
|
__weak void dram_init_banksize(void)
|
2010-09-17 11:10:39 +00:00
|
|
|
{
|
|
|
|
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
|
|
|
|
gd->bd->bi_dram[0].size = gd->ram_size;
|
|
|
|
}
|
|
|
|
|
2014-10-08 20:57:21 +00:00
|
|
|
__weak int arch_cpu_init(void)
|
2012-03-01 04:02:38 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-10-08 20:57:21 +00:00
|
|
|
__weak int power_init_board(void)
|
2012-11-13 03:21:56 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
arm: Move bootstage record for board_init_f() to after arch_cpu_init()
The timer may be inited in arch_cpu_init() so it is not safe to make a
bootstage mark before this is called. Arrange the code to fix this.
Note: The question was raised as to why we don't keep all archs in sync.
PowerPC doesn't have specific bootstage markers at present (although it
does use boot progress). I hope that the generic board series will solve
this problem in general, but in the meantime this is a real problem, and
only in ARM.
We now get a correct time for board_init_f:
Timer summary in microseconds:
Mark Elapsed Stage
0 0 reset
100,000 100,000 spl_start
848,530 748,530 board_init_f
907,301 58,771 board_init_r
910,478 3,177 board_init
Signed-off-by: Simon Glass <sjg@chromium.org>
2012-11-30 13:01:22 +00:00
|
|
|
/* Record the board_init_f() bootstage (after arch_cpu_init()) */
|
|
|
|
static int mark_bootstage(void)
|
|
|
|
{
|
|
|
|
bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-09-17 11:10:39 +00:00
|
|
|
init_fnc_t *init_sequence[] = {
|
|
|
|
arch_cpu_init, /* basic arch cpu dependent setup */
|
arm: Move bootstage record for board_init_f() to after arch_cpu_init()
The timer may be inited in arch_cpu_init() so it is not safe to make a
bootstage mark before this is called. Arrange the code to fix this.
Note: The question was raised as to why we don't keep all archs in sync.
PowerPC doesn't have specific bootstage markers at present (although it
does use boot progress). I hope that the generic board series will solve
this problem in general, but in the meantime this is a real problem, and
only in ARM.
We now get a correct time for board_init_f:
Timer summary in microseconds:
Mark Elapsed Stage
0 0 reset
100,000 100,000 spl_start
848,530 748,530 board_init_f
907,301 58,771 board_init_r
910,478 3,177 board_init
Signed-off-by: Simon Glass <sjg@chromium.org>
2012-11-30 13:01:22 +00:00
|
|
|
mark_bootstage,
|
2011-10-24 19:15:33 +00:00
|
|
|
#ifdef CONFIG_OF_CONTROL
|
|
|
|
fdtdec_check_fdt,
|
2012-11-30 13:01:16 +00:00
|
|
|
#endif
|
|
|
|
#if defined(CONFIG_BOARD_EARLY_INIT_F)
|
|
|
|
board_early_init_f,
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
timer_init, /* initialize timer */
|
2012-08-16 08:22:08 +00:00
|
|
|
#ifdef CONFIG_BOARD_POSTCLK_INIT
|
|
|
|
board_postclk_init,
|
|
|
|
#endif
|
2010-09-17 11:10:39 +00:00
|
|
|
#ifdef CONFIG_FSL_ESDHC
|
|
|
|
get_clocks,
|
|
|
|
#endif
|
|
|
|
env_init, /* initialize environment */
|
|
|
|
init_baudrate, /* initialze baudrate settings */
|
|
|
|
serial_init, /* serial communications setup */
|
|
|
|
console_init_f, /* stage 1 init of console */
|
|
|
|
display_banner, /* say that we are here */
|
|
|
|
print_cpuinfo, /* display cpu info (and speed) */
|
|
|
|
#if defined(CONFIG_DISPLAY_BOARDINFO)
|
|
|
|
checkboard, /* display board info */
|
|
|
|
#endif
|
2013-01-29 07:53:15 +00:00
|
|
|
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
|
2010-09-17 11:10:39 +00:00
|
|
|
init_func_i2c,
|
|
|
|
#endif
|
|
|
|
dram_init, /* configure available RAM banks */
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
void board_init_f(ulong bootflag)
|
2010-09-17 11:10:39 +00:00
|
|
|
{
|
|
|
|
bd_t *bd;
|
|
|
|
init_fnc_t **init_fnc_ptr;
|
|
|
|
gd_t *id;
|
|
|
|
ulong addr, addr_sp;
|
2011-10-13 14:43:06 +00:00
|
|
|
#ifdef CONFIG_PRAM
|
|
|
|
ulong reg;
|
|
|
|
#endif
|
2012-09-27 15:41:55 +00:00
|
|
|
void *new_fdt = NULL;
|
|
|
|
size_t fdt_size = 0;
|
2010-09-17 11:10:39 +00:00
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
memset((void *)gd, 0, sizeof(gd_t));
|
2010-09-17 11:10:39 +00:00
|
|
|
|
2014-02-22 16:53:43 +00:00
|
|
|
gd->mon_len = (ulong)&__bss_end - (ulong)_start;
|
2011-10-24 19:15:33 +00:00
|
|
|
#ifdef CONFIG_OF_EMBED
|
|
|
|
/* Get a pointer to the FDT */
|
2014-04-25 12:51:09 +00:00
|
|
|
gd->fdt_blob = __dtb_dt_begin;
|
2011-10-24 19:15:33 +00:00
|
|
|
#elif defined CONFIG_OF_SEPARATE
|
|
|
|
/* FDT is at end of image */
|
2014-02-22 16:53:43 +00:00
|
|
|
gd->fdt_blob = &_end;
|
2011-10-24 19:15:33 +00:00
|
|
|
#endif
|
2011-10-24 19:15:34 +00:00
|
|
|
/* Allow the early environment to override the fdt address */
|
|
|
|
gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
|
|
|
|
(uintptr_t)gd->fdt_blob);
|
2010-09-17 11:10:39 +00:00
|
|
|
|
|
|
|
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
|
|
|
|
if ((*init_fnc_ptr)() != 0) {
|
|
|
|
hang ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-28 10:08:25 +00:00
|
|
|
#ifdef CONFIG_OF_CONTROL
|
|
|
|
/* For now, put this check after the console is ready */
|
|
|
|
if (fdtdec_prepare_fdt()) {
|
|
|
|
panic("** CONFIG_OF_CONTROL defined but no FDT - please see "
|
|
|
|
"doc/README.fdt-control");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("monitor len: %08lX\n", gd->mon_len);
|
2010-09-17 11:10:39 +00:00
|
|
|
/*
|
|
|
|
* Ram is setup, size stored in gd !!
|
|
|
|
*/
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("ramsize: %08lX\n", gd->ram_size);
|
2010-09-17 11:10:39 +00:00
|
|
|
#if defined(CONFIG_SYS_MEM_TOP_HIDE)
|
|
|
|
/*
|
|
|
|
* Subtract specified amount of memory to hide so that it won't
|
|
|
|
* get "touched" at all by U-Boot. By fixing up gd->ram_size
|
|
|
|
* the Linux kernel should now get passed the now "corrected"
|
|
|
|
* memory size and won't touch it either. This should work
|
|
|
|
* for arch/ppc and arch/powerpc. Only Linux board ports in
|
|
|
|
* arch/powerpc with bootwrapper support, that recalculate the
|
|
|
|
* memory size from the SDRAM controller setup will have to
|
|
|
|
* get fixed.
|
|
|
|
*/
|
|
|
|
gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
|
|
|
|
#endif
|
|
|
|
|
2014-02-11 19:57:26 +00:00
|
|
|
addr = CONFIG_SYS_SDRAM_BASE + get_effective_memsize();
|
2010-09-17 11:10:39 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_LOGBUFFER
|
|
|
|
#ifndef CONFIG_ALT_LB_ADDR
|
|
|
|
/* reserve kernel log buffer */
|
|
|
|
addr -= (LOGBUFF_RESERVE);
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN,
|
|
|
|
addr);
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_PRAM
|
|
|
|
/*
|
|
|
|
* reserve protected RAM
|
|
|
|
*/
|
2011-10-13 14:43:06 +00:00
|
|
|
reg = getenv_ulong("pram", 10, CONFIG_PRAM);
|
2010-09-17 11:10:39 +00:00
|
|
|
addr -= (reg << 10); /* size is in kB */
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("Reserving %ldk for protected RAM at %08lx\n", reg, addr);
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif /* CONFIG_PRAM */
|
|
|
|
|
2011-06-16 23:30:48 +00:00
|
|
|
#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
|
2010-09-17 11:10:39 +00:00
|
|
|
/* reserve TLB table */
|
2013-12-14 03:47:35 +00:00
|
|
|
gd->arch.tlb_size = PGTABLE_SIZE;
|
2012-12-13 20:48:39 +00:00
|
|
|
addr -= gd->arch.tlb_size;
|
2010-09-17 11:10:39 +00:00
|
|
|
|
|
|
|
/* round down to next 64 kB limit */
|
|
|
|
addr &= ~(0x10000 - 1);
|
|
|
|
|
2012-12-13 20:48:39 +00:00
|
|
|
gd->arch.tlb_addr = addr;
|
|
|
|
debug("TLB table from %08lx to %08lx\n", addr, addr + gd->arch.tlb_size);
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* round down to next 4 kB limit */
|
|
|
|
addr &= ~(4096 - 1);
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("Top of RAM usable for U-Boot at: %08lx\n", addr);
|
2010-09-17 11:10:39 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_LCD
|
2011-04-24 22:22:34 +00:00
|
|
|
#ifdef CONFIG_FB_ADDR
|
|
|
|
gd->fb_base = CONFIG_FB_ADDR;
|
|
|
|
#else
|
2010-09-17 11:10:39 +00:00
|
|
|
/* reserve memory for LCD display (always full pages) */
|
2011-07-15 19:36:36 +00:00
|
|
|
addr = lcd_setmem(addr);
|
2010-09-17 11:10:39 +00:00
|
|
|
gd->fb_base = addr;
|
2011-04-24 22:22:34 +00:00
|
|
|
#endif /* CONFIG_FB_ADDR */
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif /* CONFIG_LCD */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* reserve memory for U-Boot code, data & bss
|
|
|
|
* round down to next 4 kB limit
|
|
|
|
*/
|
|
|
|
addr -= gd->mon_len;
|
|
|
|
addr &= ~(4096 - 1);
|
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr);
|
2010-09-17 11:10:39 +00:00
|
|
|
|
2011-07-13 05:11:07 +00:00
|
|
|
#ifndef CONFIG_SPL_BUILD
|
2010-09-17 11:10:39 +00:00
|
|
|
/*
|
|
|
|
* reserve memory for malloc() arena
|
|
|
|
*/
|
|
|
|
addr_sp = addr - TOTAL_MALLOC_LEN;
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("Reserving %dk for malloc() at: %08lx\n",
|
2010-09-17 11:10:39 +00:00
|
|
|
TOTAL_MALLOC_LEN >> 10, addr_sp);
|
|
|
|
/*
|
|
|
|
* (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;
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("Reserving %zu Bytes for Board Info at: %08lx\n",
|
2010-09-17 11:10:39 +00:00
|
|
|
sizeof (bd_t), addr_sp);
|
2011-08-16 23:48:23 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_MACH_TYPE
|
|
|
|
gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
|
|
|
|
#endif
|
|
|
|
|
2010-09-17 11:10:39 +00:00
|
|
|
addr_sp -= sizeof (gd_t);
|
|
|
|
id = (gd_t *) addr_sp;
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("Reserving %zu Bytes for Global Data at: %08lx\n",
|
2010-09-17 11:10:39 +00:00
|
|
|
sizeof (gd_t), addr_sp);
|
|
|
|
|
2012-09-27 15:41:55 +00:00
|
|
|
#if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL)
|
|
|
|
/*
|
|
|
|
* If the device tree is sitting immediate above our image then we
|
|
|
|
* must relocate it. If it is embedded in the data section, then it
|
|
|
|
* will be relocated with other data.
|
|
|
|
*/
|
|
|
|
if (gd->fdt_blob) {
|
|
|
|
fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
|
|
|
|
|
|
|
|
addr_sp -= fdt_size;
|
|
|
|
new_fdt = (void *)addr_sp;
|
|
|
|
debug("Reserving %zu Bytes for FDT at: %08lx\n",
|
|
|
|
fdt_size, addr_sp);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-12-14 03:47:35 +00:00
|
|
|
#ifndef CONFIG_ARM64
|
2010-09-17 11:10:39 +00:00
|
|
|
/* setup stackpointer for exeptions */
|
|
|
|
gd->irq_sp = addr_sp;
|
|
|
|
#ifdef CONFIG_USE_IRQ
|
|
|
|
addr_sp -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("Reserving %zu Bytes for IRQ stack at: %08lx\n",
|
2010-09-17 11:10:39 +00:00
|
|
|
CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp);
|
|
|
|
#endif
|
|
|
|
/* leave 3 words for abort-stack */
|
2011-04-14 12:32:37 +00:00
|
|
|
addr_sp -= 12;
|
2010-09-17 11:10:39 +00:00
|
|
|
|
|
|
|
/* 8-byte alignment for ABI compliance */
|
|
|
|
addr_sp &= ~0x07;
|
2013-12-14 03:47:35 +00:00
|
|
|
#else /* CONFIG_ARM64 */
|
|
|
|
/* 16-byte alignment for ABI compliance */
|
|
|
|
addr_sp &= ~0x0f;
|
|
|
|
#endif /* CONFIG_ARM64 */
|
2010-09-17 11:10:39 +00:00
|
|
|
#else
|
|
|
|
addr_sp += 128; /* leave 32 words for abort-stack */
|
|
|
|
gd->irq_sp = addr_sp;
|
|
|
|
#endif
|
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("New Stack Pointer is: %08lx\n", addr_sp);
|
2010-09-17 11:10:39 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_POST
|
|
|
|
post_bootmode_init();
|
2011-07-15 19:36:36 +00:00
|
|
|
post_run(NULL, POST_ROM | post_bootmode_get(0));
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Ram ist board specific, so move it to board code ... */
|
|
|
|
dram_init_banksize();
|
|
|
|
display_dram_config(); /* and display it */
|
|
|
|
|
|
|
|
gd->relocaddr = addr;
|
|
|
|
gd->start_addr_sp = addr_sp;
|
2014-02-22 16:53:43 +00:00
|
|
|
gd->reloc_off = addr - (ulong)&_start;
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("relocation Offset is: %08lx\n", gd->reloc_off);
|
2012-09-27 15:41:55 +00:00
|
|
|
if (new_fdt) {
|
|
|
|
memcpy(new_fdt, gd->fdt_blob, fdt_size);
|
|
|
|
gd->fdt_blob = new_fdt;
|
|
|
|
}
|
2011-07-15 19:36:36 +00:00
|
|
|
memcpy(id, (void *)gd, sizeof(gd_t));
|
2010-09-17 11:10:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if !defined(CONFIG_SYS_NO_FLASH)
|
|
|
|
static char *failed = "*** failed ***\n";
|
|
|
|
#endif
|
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
/*
|
2012-11-30 13:01:17 +00:00
|
|
|
* Tell if it's OK to load the environment early in boot.
|
|
|
|
*
|
|
|
|
* If CONFIG_OF_CONFIG is defined, we'll check with the FDT to see
|
|
|
|
* if this is OK (defaulting to saying it's not OK).
|
|
|
|
*
|
|
|
|
* NOTE: Loading the environment early can be a bad idea if security is
|
|
|
|
* important, since no verification is done on the environment.
|
|
|
|
*
|
|
|
|
* @return 0 if environment should not be loaded, !=0 if it is ok to load
|
|
|
|
*/
|
|
|
|
static int should_load_env(void)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_OF_CONTROL
|
2013-01-22 00:15:49 +00:00
|
|
|
return fdtdec_get_config_int(gd->fdt_blob, "load-environment", 1);
|
2012-11-30 13:01:17 +00:00
|
|
|
#elif defined CONFIG_DELAY_ENVIRONMENT
|
|
|
|
return 0;
|
|
|
|
#else
|
|
|
|
return 1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
arm: Add CONFIG_DISPLAY_BOARDINFO_LATE to display board info on LCD
This option displays board info after stdio is running, so that it will
appear on the LCD. If it is displayed earlier, the board info will appear
on the serial console but not on the LCD.
Here follows a blow-by-blow description.
1a. Without CONFIG_DISPLAY_BOARDINFO_LATE, on serial:
U-Boot 2011.12-02550-g037e1c5-dirty (Nov 15 2012 - 14:29:42) for SMDK5250
CPU: S5PC520 @ 1700MHz
Board: Google Snow, rev 0
I2C: ready
DRAM: 2 GiB Elpida DDR3 @ 800MHz
MMC: S5P MSHC0: 0, S5P MSHC1: 1
SF: Detected W25Q32 with page size 4 KiB, total 4 MiB
*** Warning - bad CRC, using default environment
In: mkbp-keyb
Out: lcd
Err: lcd
Net: No ethernet found.
Hit any key to stop autoboot: 0
SMDK5250 #
1b. Without CONFIG_DISPLAY_BOARDINFO_LATE, on LCD (note machine info
is missing):
In: mkbp-keyb
Out: lcd
Err: lcd
Net: No ethernet found.
Hit any key to stop autoboot: 0
SMDK5250 #
2a. With CONFIG_DISPLAY_BOARDINFO_LATE, on serial:
U-Boot 2011.12-02550-g037e1c5 (Nov 15 2012 - 14:27:40) for SMDK5250
CPU: S5PC520 @ 1700MHz
I2C: ready
DRAM: 2 GiB Elpida DDR3 @ 800MHz
MMC: S5P MSHC0: 0, S5P MSHC1: 1
SF: Detected W25Q32 with page size 4 KiB, total 4 MiB
*** Warning - bad CRC, using default environment
Model: Google Snow
In: mkbp-keyb
Out: lcd
Err: lcd
Net: No ethernet found.
Hit any key to stop autoboot: 0
SMDK5250 #
2b. With CONFIG_DISPLAY_BOARDINFO_LATE, on LCD (note machine info is present):
Model: Google Snow
In: mkbp-keyb
Out: lcd
Err: lcd
Net: No ethernet found.
Hit any key to stop autoboot: 0
SMDK5250 #
Since the LCD is all that a typical user sees, it is useful to display
the model there.
We may be able to rearrange things some other way one day, but at
present this seems like a convenient way of getting the required
behaviour.
Signed-off-by: Simon Glass <sjg@chromium.org>
2012-11-30 13:01:19 +00:00
|
|
|
#if defined(CONFIG_DISPLAY_BOARDINFO_LATE) && defined(CONFIG_OF_CONTROL)
|
|
|
|
static void display_fdt_model(const void *blob)
|
|
|
|
{
|
|
|
|
const char *model;
|
|
|
|
|
|
|
|
model = (char *)fdt_getprop(blob, 0, "model", NULL);
|
|
|
|
printf("Model: %s\n", model ? model : "<unknown>");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-11-30 13:01:17 +00:00
|
|
|
/************************************************************************
|
2010-09-17 11:10:39 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
************************************************************************
|
|
|
|
*/
|
2010-10-11 11:13:28 +00:00
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
void board_init_r(gd_t *id, ulong dest_addr)
|
2010-09-17 11:10:39 +00:00
|
|
|
{
|
|
|
|
ulong malloc_start;
|
|
|
|
#if !defined(CONFIG_SYS_NO_FLASH)
|
|
|
|
ulong flash_size;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
|
2012-02-13 13:51:21 +00:00
|
|
|
bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
|
2010-09-17 11:10:39 +00:00
|
|
|
|
2014-02-22 16:53:43 +00:00
|
|
|
monitor_flash_len = (ulong)&__rel_dyn_end - (ulong)_start;
|
2011-08-16 04:33:05 +00:00
|
|
|
|
|
|
|
/* Enable caches */
|
|
|
|
enable_caches();
|
2011-06-16 23:30:49 +00:00
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("monitor flash len: %08lX\n", monitor_flash_len);
|
2010-09-17 11:10:39 +00:00
|
|
|
board_init(); /* Setup chipselects */
|
2012-02-06 00:30:44 +00:00
|
|
|
/*
|
|
|
|
* TODO: printing of the clock inforamtion of the board is now
|
|
|
|
* implemented as part of bdinfo command. Currently only support for
|
|
|
|
* davinci SOC's is added. Remove this check once all the board
|
|
|
|
* implement this.
|
|
|
|
*/
|
|
|
|
#ifdef CONFIG_CLOCKS
|
|
|
|
set_cpu_clk_info(); /* Setup clock information */
|
|
|
|
#endif
|
2010-09-17 11:10:39 +00:00
|
|
|
serial_initialize();
|
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
|
2010-09-17 11:10:39 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_LOGBUFFER
|
2011-07-15 19:36:36 +00:00
|
|
|
logbuff_init_ptrs();
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_POST
|
2011-07-15 19:36:36 +00:00
|
|
|
post_output_backlog();
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* The Malloc area is immediately below the monitor copy in DRAM */
|
|
|
|
malloc_start = dest_addr - TOTAL_MALLOC_LEN;
|
|
|
|
mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN);
|
|
|
|
|
2012-04-02 11:19:45 +00:00
|
|
|
#ifdef CONFIG_ARCH_EARLY_INIT_R
|
|
|
|
arch_early_init_r();
|
|
|
|
#endif
|
2012-11-13 03:21:56 +00:00
|
|
|
power_init_board();
|
2012-04-02 11:19:45 +00:00
|
|
|
|
2010-09-17 11:10:39 +00:00
|
|
|
#if !defined(CONFIG_SYS_NO_FLASH)
|
2011-07-15 19:36:36 +00:00
|
|
|
puts("Flash: ");
|
2010-09-17 11:10:39 +00:00
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
flash_size = flash_init();
|
|
|
|
if (flash_size > 0) {
|
2010-09-17 11:10:39 +00:00
|
|
|
# ifdef CONFIG_SYS_FLASH_CHECKSUM
|
2011-07-15 19:36:36 +00:00
|
|
|
print_size(flash_size, "");
|
2010-09-17 11:10:39 +00:00
|
|
|
/*
|
|
|
|
* Compute and print flash CRC if flashchecksum is set to 'y'
|
|
|
|
*
|
|
|
|
* NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
|
|
|
|
*/
|
2012-12-12 04:16:22 +00:00
|
|
|
if (getenv_yesno("flashchecksum") == 1) {
|
2011-07-15 19:36:36 +00:00
|
|
|
printf(" CRC: %08X", crc32(0,
|
|
|
|
(const unsigned char *) CONFIG_SYS_FLASH_BASE,
|
|
|
|
flash_size));
|
2010-09-17 11:10:39 +00:00
|
|
|
}
|
2011-07-15 19:36:36 +00:00
|
|
|
putc('\n');
|
2010-09-17 11:10:39 +00:00
|
|
|
# else /* !CONFIG_SYS_FLASH_CHECKSUM */
|
2011-07-15 19:36:36 +00:00
|
|
|
print_size(flash_size, "\n");
|
2010-09-17 11:10:39 +00:00
|
|
|
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
|
|
|
|
} else {
|
2011-07-15 19:36:36 +00:00
|
|
|
puts(failed);
|
|
|
|
hang();
|
2010-09-17 11:10:39 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(CONFIG_CMD_NAND)
|
2011-07-15 19:36:36 +00:00
|
|
|
puts("NAND: ");
|
2010-09-17 11:10:39 +00:00
|
|
|
nand_init(); /* go init the NAND */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(CONFIG_CMD_ONENAND)
|
|
|
|
onenand_init();
|
|
|
|
#endif
|
|
|
|
|
2010-10-11 12:51:39 +00:00
|
|
|
#ifdef CONFIG_GENERIC_MMC
|
2012-11-30 13:01:23 +00:00
|
|
|
puts("MMC: ");
|
|
|
|
mmc_initialize(gd->bd);
|
2010-10-11 12:51:39 +00:00
|
|
|
#endif
|
|
|
|
|
2014-03-07 01:20:56 +00:00
|
|
|
#ifdef CONFIG_CMD_SCSI
|
|
|
|
puts("SCSI: ");
|
|
|
|
scsi_init();
|
|
|
|
#endif
|
|
|
|
|
2010-09-17 11:10:39 +00:00
|
|
|
#ifdef CONFIG_HAS_DATAFLASH
|
|
|
|
AT91F_DataflashInit();
|
|
|
|
dataflash_print_info();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* initialize environment */
|
2012-11-30 13:01:17 +00:00
|
|
|
if (should_load_env())
|
|
|
|
env_relocate();
|
|
|
|
else
|
|
|
|
set_default_env(NULL);
|
2010-09-17 11:10:39 +00:00
|
|
|
|
2011-05-22 22:00:13 +00:00
|
|
|
#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)
|
|
|
|
arm_pci_init();
|
|
|
|
#endif
|
2010-09-17 11:10:39 +00:00
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
stdio_init(); /* get the devices list going. */
|
2010-09-17 11:10:39 +00:00
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
jumptable_init();
|
2010-09-17 11:10:39 +00:00
|
|
|
|
|
|
|
#if defined(CONFIG_API)
|
|
|
|
/* Initialize API */
|
2011-07-15 19:36:36 +00:00
|
|
|
api_init();
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
|
2011-07-15 19:36:36 +00:00
|
|
|
console_init_r(); /* fully init console as a device */
|
2010-09-17 11:10:39 +00:00
|
|
|
|
arm: Add CONFIG_DISPLAY_BOARDINFO_LATE to display board info on LCD
This option displays board info after stdio is running, so that it will
appear on the LCD. If it is displayed earlier, the board info will appear
on the serial console but not on the LCD.
Here follows a blow-by-blow description.
1a. Without CONFIG_DISPLAY_BOARDINFO_LATE, on serial:
U-Boot 2011.12-02550-g037e1c5-dirty (Nov 15 2012 - 14:29:42) for SMDK5250
CPU: S5PC520 @ 1700MHz
Board: Google Snow, rev 0
I2C: ready
DRAM: 2 GiB Elpida DDR3 @ 800MHz
MMC: S5P MSHC0: 0, S5P MSHC1: 1
SF: Detected W25Q32 with page size 4 KiB, total 4 MiB
*** Warning - bad CRC, using default environment
In: mkbp-keyb
Out: lcd
Err: lcd
Net: No ethernet found.
Hit any key to stop autoboot: 0
SMDK5250 #
1b. Without CONFIG_DISPLAY_BOARDINFO_LATE, on LCD (note machine info
is missing):
In: mkbp-keyb
Out: lcd
Err: lcd
Net: No ethernet found.
Hit any key to stop autoboot: 0
SMDK5250 #
2a. With CONFIG_DISPLAY_BOARDINFO_LATE, on serial:
U-Boot 2011.12-02550-g037e1c5 (Nov 15 2012 - 14:27:40) for SMDK5250
CPU: S5PC520 @ 1700MHz
I2C: ready
DRAM: 2 GiB Elpida DDR3 @ 800MHz
MMC: S5P MSHC0: 0, S5P MSHC1: 1
SF: Detected W25Q32 with page size 4 KiB, total 4 MiB
*** Warning - bad CRC, using default environment
Model: Google Snow
In: mkbp-keyb
Out: lcd
Err: lcd
Net: No ethernet found.
Hit any key to stop autoboot: 0
SMDK5250 #
2b. With CONFIG_DISPLAY_BOARDINFO_LATE, on LCD (note machine info is present):
Model: Google Snow
In: mkbp-keyb
Out: lcd
Err: lcd
Net: No ethernet found.
Hit any key to stop autoboot: 0
SMDK5250 #
Since the LCD is all that a typical user sees, it is useful to display
the model there.
We may be able to rearrange things some other way one day, but at
present this seems like a convenient way of getting the required
behaviour.
Signed-off-by: Simon Glass <sjg@chromium.org>
2012-11-30 13:01:19 +00:00
|
|
|
#ifdef CONFIG_DISPLAY_BOARDINFO_LATE
|
|
|
|
# ifdef CONFIG_OF_CONTROL
|
|
|
|
/* Put this here so it appears on the LCD, now it is ready */
|
|
|
|
display_fdt_model(gd->fdt_blob);
|
|
|
|
# else
|
|
|
|
checkboard();
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2010-09-17 11:10:39 +00:00
|
|
|
#if defined(CONFIG_ARCH_MISC_INIT)
|
|
|
|
/* miscellaneous arch dependent initialisations */
|
2011-07-15 19:36:36 +00:00
|
|
|
arch_misc_init();
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
#if defined(CONFIG_MISC_INIT_R)
|
|
|
|
/* miscellaneous platform dependent initialisations */
|
2011-07-15 19:36:36 +00:00
|
|
|
misc_init_r();
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
|
2013-11-08 21:37:33 +00:00
|
|
|
/* set up exceptions */
|
|
|
|
interrupt_init();
|
2010-09-17 11:10:39 +00:00
|
|
|
/* enable exceptions */
|
2011-07-15 19:36:36 +00:00
|
|
|
enable_interrupts();
|
2010-09-17 11:10:39 +00:00
|
|
|
|
|
|
|
/* Initialize from environment */
|
2011-10-13 14:43:06 +00:00
|
|
|
load_addr = getenv_ulong("loadaddr", 16, load_addr);
|
2010-09-17 11:10:39 +00:00
|
|
|
|
2011-10-20 04:19:47 +00:00
|
|
|
#ifdef CONFIG_BOARD_LATE_INIT
|
2011-07-15 19:36:36 +00:00
|
|
|
board_late_init();
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_BITBANGMII
|
|
|
|
bb_miiphy_init();
|
|
|
|
#endif
|
|
|
|
#if defined(CONFIG_CMD_NET)
|
2011-07-15 19:36:36 +00:00
|
|
|
puts("Net: ");
|
2010-09-17 11:10:39 +00:00
|
|
|
eth_initialize(gd->bd);
|
|
|
|
#if defined(CONFIG_RESET_PHY_R)
|
2011-07-15 19:36:36 +00:00
|
|
|
debug("Reset Ethernet PHY\n");
|
2010-09-17 11:10:39 +00:00
|
|
|
reset_phy();
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_POST
|
2011-07-15 19:36:36 +00:00
|
|
|
post_run(NULL, POST_RAM | post_bootmode_get(0));
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
|
|
|
|
/*
|
|
|
|
* Export available size of memory for Linux,
|
|
|
|
* taking into account the protected RAM at top of memory
|
|
|
|
*/
|
|
|
|
{
|
2011-10-13 14:43:06 +00:00
|
|
|
ulong pram = 0;
|
2010-09-17 11:10:39 +00:00
|
|
|
uchar memsz[32];
|
|
|
|
|
2011-10-13 14:43:06 +00:00
|
|
|
#ifdef CONFIG_PRAM
|
|
|
|
pram = getenv_ulong("pram", 10, CONFIG_PRAM);
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_LOGBUFFER
|
|
|
|
#ifndef CONFIG_ALT_LB_ADDR
|
|
|
|
/* Also take the logbuffer into account (pram is in kB) */
|
2011-07-15 19:36:36 +00:00
|
|
|
pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024;
|
2010-09-17 11:10:39 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
2011-06-02 22:11:37 +00:00
|
|
|
sprintf((char *)memsz, "%ldk", (gd->ram_size / 1024) - pram);
|
2011-07-15 19:36:36 +00:00
|
|
|
setenv("mem", (char *)memsz);
|
2010-09-17 11:10:39 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* main_loop() can return to retry autoboot, if so just run it again. */
|
|
|
|
for (;;) {
|
2011-07-15 19:36:36 +00:00
|
|
|
main_loop();
|
2010-09-17 11:10:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* NOTREACHED - no way out of command loop except booting */
|
|
|
|
}
|