summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Makefile7
-rw-r--r--common/bedbug.c75
-rw-r--r--common/board_f.c1012
-rw-r--r--common/board_r.c917
-rw-r--r--common/cmd_bedbug.c4
-rw-r--r--common/cmd_bootm.c47
-rw-r--r--common/cmd_bootmenu.c517
-rw-r--r--common/cmd_df.c36
-rw-r--r--common/cmd_dfu.c5
-rw-r--r--common/cmd_dtt.c32
-rw-r--r--common/cmd_ext4.c6
-rw-r--r--common/cmd_fat.c3
-rw-r--r--common/cmd_fdc.c117
-rw-r--r--common/cmd_mem.c5
-rw-r--r--common/cmd_mmc.c14
-rw-r--r--common/cmd_mtdparts.c29
-rw-r--r--common/cmd_nand.c55
-rw-r--r--common/cmd_nvedit.c61
-rw-r--r--common/cmd_part.c2
-rw-r--r--common/cmd_pxe.c3
-rw-r--r--common/cmd_scsi.c18
-rw-r--r--common/cmd_sf.c10
-rw-r--r--common/cmd_test.c9
-rw-r--r--common/cmd_ubi.c153
-rw-r--r--common/cmd_usb_mass_storage.c86
-rw-r--r--common/dlmalloc.c2
-rw-r--r--common/dlmalloc.src2
-rw-r--r--common/env_callback.c2
-rw-r--r--common/env_nand.c3
-rw-r--r--common/env_ubi.c220
-rw-r--r--common/hash.c18
-rw-r--r--common/image.c1
-rw-r--r--common/lcd.c147
-rw-r--r--common/main.c22
-rw-r--r--common/menu.c44
35 files changed, 3311 insertions, 373 deletions
diff --git a/common/Makefile b/common/Makefile
index 719fc231b8..0e0fff1ffa 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -36,6 +36,10 @@ COBJS-y += s_record.o
COBJS-y += xyzModem.o
COBJS-y += cmd_disk.o
+# boards
+COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o
+COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o
+
# core command
COBJS-y += cmd_boot.o
COBJS-$(CONFIG_CMD_BOOTM) += cmd_bootm.o
@@ -62,6 +66,7 @@ COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o
COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o
COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
COBJS-$(CONFIG_ENV_IS_IN_REMOTE) += env_remote.o
+COBJS-$(CONFIG_ENV_IS_IN_UBI) += env_ubi.o
COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
# command
@@ -71,6 +76,7 @@ COBJS-$(CONFIG_CMD_SOURCE) += cmd_source.o
COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
COBJS-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o
COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
+COBJS-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o
COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
COBJS-$(CONFIG_CMD_BOOTSTAGE) += cmd_bootstage.o
COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o
@@ -175,6 +181,7 @@ COBJS-y += cmd_usb.o
COBJS-y += usb.o usb_hub.o
COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o
endif
+COBJS-$(CONFIG_CMD_USB_MASS_STORAGE) += cmd_usb_mass_storage.o
COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o
COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
diff --git a/common/bedbug.c b/common/bedbug.c
index 60109cf827..42ecf61eff 100644
--- a/common/bedbug.c
+++ b/common/bedbug.c
@@ -72,7 +72,7 @@ int downstring __P ((char *));
* F_INSTR - output raw instruction.
* F_LINENO - show line # info if available.
*
- * Returns TRUE if the area was successfully disassembled or FALSE if
+ * Returns true if the area was successfully disassembled or false if
* a problem was encountered with accessing the memory.
*/
@@ -137,8 +137,8 @@ int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr,
for (i = 0; i < num_instr; ++i, memaddr += 4, ctx.virtual += 4) {
#ifdef USE_SOURCE_CODE
if (ctx.flags & F_LINENO) {
- if ((line_info_from_addr ((Elf32_Word) ctx.virtual, filename,
- funcname, &line_no) == TRUE) &&
+ if ((line_info_from_addr ((Elf32_Word) ctx.virtual,
+ filename, funcname, &line_no) == true) &&
((line_no != last_line_no) ||
(strcmp (last_funcname, funcname) != 0))) {
print_source_line (filename, funcname, line_no, pfunc);
@@ -154,15 +154,15 @@ int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr,
#ifdef USE_SOURCE_CODE
if (ctx.flags & F_SYMBOL) {
if ((symname =
- symbol_name_from_addr ((Elf32_Word) ctx.virtual,
- TRUE, 0)) != 0) {
+ symbol_name_from_addr((Elf32_Word) ctx.virtual,
+ true, 0)) != 0) {
cursym = symname;
symoffset = 0;
} else {
if ((cursym == 0) &&
((symname =
- symbol_name_from_addr ((Elf32_Word) ctx.virtual,
- FALSE, &symoffset)) != 0)) {
+ symbol_name_from_addr((Elf32_Word) ctx.virtual,
+ false, &symoffset)) != 0)) {
cursym = symname;
} else {
symoffset += 4;
@@ -205,7 +205,8 @@ int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr,
}
if (((ctx.flags & F_SIMPLE) == 0) ||
- (ctx.op->hfunc == 0) || ((*ctx.op->hfunc) (&ctx) == FALSE)) {
+ (ctx.op->hfunc == 0) ||
+ ((*ctx.op->hfunc) (&ctx) == false)) {
sprintf (&ctx.data[ctx.datalen], "%-7s ", ctx.op->name);
ctx.datalen += 8;
print_operands (&ctx);
@@ -214,7 +215,7 @@ int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr,
(*pfunc) (ctx.data);
}
- return TRUE;
+ return true;
} /* disppc */
@@ -364,10 +365,10 @@ int print_operands (struct ppc_ctx *ctx)
* value The address of an unsigned long to be filled in
* with the value of the operand if it is found. This
* will only be filled in if the function returns
- * TRUE. This may be passed as 0 if the value is
+ * true. This may be passed as 0 if the value is
* not required.
*
- * Returns TRUE if the operand was found or FALSE if it was not.
+ * Returns true if the operand was found or false if it was not.
*/
int get_operand_value (struct opcode *op, unsigned long instr,
@@ -379,7 +380,7 @@ int get_operand_value (struct opcode *op, unsigned long instr,
/*------------------------------------------------------------*/
if (field > n_operands) {
- return FALSE; /* bad operand ?! */
+ return false; /* bad operand ?! */
}
/* Walk through the operands and list each in order */
@@ -393,10 +394,10 @@ int get_operand_value (struct opcode *op, unsigned long instr,
if (value) {
*value = (instr >> opr->shift) & ((1 << opr->bits) - 1);
}
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
} /* operand_value */
@@ -649,7 +650,7 @@ int tbr_value (char *name)
* Arguments:
* ctx A pointer to the disassembler context record.
*
- * Returns TRUE if the simpler form was printed or FALSE if it was not.
+ * Returns true if the simpler form was printed or false if it was not.
*/
int handle_bc (struct ppc_ctx *ctx)
@@ -669,33 +670,33 @@ int handle_bc (struct ppc_ctx *ctx)
/*------------------------------------------------------------*/
- if (get_operand_value (ctx->op, ctx->instr, O_BO, &bo) == FALSE)
- return FALSE;
+ if (get_operand_value(ctx->op, ctx->instr, O_BO, &bo) == false)
+ return false;
- if (get_operand_value (ctx->op, ctx->instr, O_BI, &bi) == FALSE)
- return FALSE;
+ if (get_operand_value(ctx->op, ctx->instr, O_BI, &bi) == false)
+ return false;
if ((bo == 12) && (bi == 0)) {
ctx->op = &blt;
sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
ctx->datalen += 8;
print_operands (ctx);
- return TRUE;
+ return true;
} else if ((bo == 4) && (bi == 10)) {
ctx->op = &bne;
sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
ctx->datalen += 8;
print_operands (ctx);
- return TRUE;
+ return true;
} else if ((bo == 16) && (bi == 0)) {
ctx->op = &bdnz;
sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
ctx->datalen += 8;
print_operands (ctx);
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
} /* handle_blt */
@@ -719,7 +720,7 @@ int handle_bc (struct ppc_ctx *ctx)
* pfunc The address of a function to call to print the output.
*
*
- * Returns TRUE if it was able to output the line info, or false if it was
+ * Returns true if it was able to output the line info, or false if it was
* not.
*/
@@ -734,7 +735,7 @@ int print_source_line (char *filename, char *funcname,
sprintf (out_buf, "%s %s(): line %d", filename, funcname, line_no);
(*pfunc) (out_buf);
- return TRUE;
+ return true;
} /* print_source_line */
@@ -1039,14 +1040,14 @@ int downstring (char *s)
* Arguments:
* nextaddr The address (to be filled in) of the next
* instruction to execute. This will only be a valid
- * address if TRUE is returned.
+ * address if true is returned.
*
* step_over A flag indicating how to compute addresses for
* branch statements:
- * TRUE = Step over the branch (next)
- * FALSE = step into the branch (step)
+ * true = Step over the branch (next)
+ * false = step into the branch (step)
*
- * Returns TRUE if it was able to compute the address. Returns FALSE if
+ * Returns true if it was able to compute the address. Returns false if
* it has a problem reading the current instruction or one of the registers.
*/
@@ -1075,7 +1076,7 @@ int find_next_address (unsigned char *nextaddr, int step_over,
if (nextaddr == 0 || regs == 0) {
printf ("find_next_address: bad args");
- return FALSE;
+ return false;
}
pc = regs->nip & 0xfffffffc;
@@ -1083,7 +1084,7 @@ int find_next_address (unsigned char *nextaddr, int step_over,
if ((op = find_opcode (instr)) == (struct opcode *) 0) {
printf ("find_next_address: can't parse opcode 0x%lx", instr);
- return FALSE;
+ return false;
}
ctr = regs->ctr;
@@ -1100,7 +1101,7 @@ int find_next_address (unsigned char *nextaddr, int step_over,
!get_operand_value (op, instr, O_BI, &bi) ||
!get_operand_value (op, instr, O_AA, &aa) ||
!get_operand_value (op, instr, O_LK, &lk))
- return FALSE;
+ return false;
if ((addr & (1 << 13)) != 0)
addr = addr - (1 << 14);
@@ -1116,7 +1117,7 @@ int find_next_address (unsigned char *nextaddr, int step_over,
if (!get_operand_value (op, instr, O_LI, &addr) ||
!get_operand_value (op, instr, O_AA, &aa) ||
!get_operand_value (op, instr, O_LK, &lk))
- return FALSE;
+ return false;
if ((addr & (1 << 23)) != 0)
addr = addr - (1 << 24);
@@ -1130,7 +1131,7 @@ int find_next_address (unsigned char *nextaddr, int step_over,
if (!get_operand_value (op, instr, O_BO, &bo) ||
!get_operand_value (op, instr, O_BI, &bi) ||
!get_operand_value (op, instr, O_LK, &lk))
- return FALSE;
+ return false;
addr = ctr;
aa = 1;
@@ -1143,7 +1144,7 @@ int find_next_address (unsigned char *nextaddr, int step_over,
if (!get_operand_value (op, instr, O_BO, &bo) ||
!get_operand_value (op, instr, O_BI, &bi) ||
!get_operand_value (op, instr, O_LK, &lk))
- return FALSE;
+ return false;
addr = lr;
aa = 1;
@@ -1227,12 +1228,12 @@ int find_next_address (unsigned char *nextaddr, int step_over,
step = next = pc + 4;
}
- if (step_over == TRUE)
+ if (step_over == true)
*(unsigned long *) nextaddr = next;
else
*(unsigned long *) nextaddr = step;
- return TRUE;
+ return true;
} /* find_next_address */
diff --git a/common/board_f.c b/common/board_f.c
new file mode 100644
index 0000000000..769889123b
--- /dev/null
+++ b/common/board_f.c
@@ -0,0 +1,1012 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2002-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.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 <linux/compiler.h>
+#include <version.h>
+#include <environment.h>
+#include <fdtdec.h>
+#if defined(CONFIG_CMD_IDE)
+#include <ide.h>
+#endif
+#include <i2c.h>
+#include <initcall.h>
+#include <logbuff.h>
+
+/* TODO: Can we move these into arch/ headers? */
+#ifdef CONFIG_8xx
+#include <mpc8xx.h>
+#endif
+#ifdef CONFIG_5xx
+#include <mpc5xx.h>
+#endif
+#ifdef CONFIG_MPC5xxx
+#include <mpc5xxx.h>
+#endif
+
+#include <post.h>
+#include <spi.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#ifdef CONFIG_MP
+#include <asm/mp.h>
+#endif
+#include <asm/sections.h>
+#ifdef CONFIG_X86
+#include <asm/init_helpers.h>
+#include <asm/relocate.h>
+#endif
+#include <linux/compiler.h>
+
+/*
+ * Pointer to initial global data area
+ *
+ * Here we initialize it if needed.
+ */
+#ifdef XTRN_DECLARE_GLOBAL_DATA_PTR
+#undef XTRN_DECLARE_GLOBAL_DATA_PTR
+#define XTRN_DECLARE_GLOBAL_DATA_PTR /* empty = allocate here */
+DECLARE_GLOBAL_DATA_PTR = (gd_t *) (CONFIG_SYS_INIT_GD_ADDR);
+#else
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
+/*
+ * sjg: IMO this code should be
+ * refactored to a single function, something like:
+ *
+ * void led_set_state(enum led_colour_t colour, int on);
+ */
+/************************************************************************
+ * Coloured LED functionality
+ ************************************************************************
+ * May be supplied by boards if desired
+ */
+inline void __coloured_LED_init(void) {}
+void coloured_LED_init(void)
+ __attribute__((weak, alias("__coloured_LED_init")));
+inline void __red_led_on(void) {}
+void red_led_on(void) __attribute__((weak, alias("__red_led_on")));
+inline void __red_led_off(void) {}
+void red_led_off(void) __attribute__((weak, alias("__red_led_off")));
+inline void __green_led_on(void) {}
+void green_led_on(void) __attribute__((weak, alias("__green_led_on")));
+inline void __green_led_off(void) {}
+void green_led_off(void) __attribute__((weak, alias("__green_led_off")));
+inline void __yellow_led_on(void) {}
+void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on")));
+inline void __yellow_led_off(void) {}
+void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off")));
+inline void __blue_led_on(void) {}
+void blue_led_on(void) __attribute__((weak, alias("__blue_led_on")));
+inline void __blue_led_off(void) {}
+void blue_led_off(void) __attribute__((weak, alias("__blue_led_off")));
+
+/*
+ * Why is gd allocated a register? Prior to reloc it might be better to
+ * just pass it around to each function in this file?
+ *
+ * After reloc one could argue that it is hardly used and doesn't need
+ * to be in a register. Or if it is it should perhaps hold pointers to all
+ * global data for all modules, so that post-reloc we can avoid the massive
+ * literal pool we get on ARM. Or perhaps just encourage each module to use
+ * a structure...
+ */
+
+/*
+ * Could the CONFIG_SPL_BUILD infection become a flag in gd?
+ */
+
+#if defined(CONFIG_WATCHDOG)
+static int init_func_watchdog_init(void)
+{
+ puts(" Watchdog enabled\n");
+ WATCHDOG_RESET();
+
+ return 0;
+}
+
+int init_func_watchdog_reset(void)
+{
+ WATCHDOG_RESET();
+
+ return 0;
+}
+#endif /* CONFIG_WATCHDOG */
+
+void __board_add_ram_info(int use_default)
+{
+ /* please define platform specific board_add_ram_info() */
+}
+
+void board_add_ram_info(int)
+ __attribute__ ((weak, alias("__board_add_ram_info")));
+
+static int init_baud_rate(void)
+{
+ gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
+ return 0;
+}
+
+static int display_text_info(void)
+{
+ ulong bss_start, bss_end;
+
+#ifdef CONFIG_SYS_SYM_OFFSETS
+ bss_start = _bss_start_ofs + _TEXT_BASE;
+ bss_end = _bss_end_ofs + _TEXT_BASE;
+#else
+ bss_start = (ulong)&__bss_start;
+ bss_end = (ulong)&__bss_end;
+#endif
+ debug("U-Boot code: %08X -> %08lX BSS: -> %08lX\n",
+ CONFIG_SYS_TEXT_BASE, bss_start, bss_end);
+
+#ifdef CONFIG_MODEM_SUPPORT
+ debug("Modem Support enabled\n");
+#endif
+#ifdef CONFIG_USE_IRQ
+ debug("IRQ Stack: %08lx\n", IRQ_STACK_START);
+ debug("FIQ Stack: %08lx\n", FIQ_STACK_START);
+#endif
+
+ return 0;
+}
+
+static int announce_dram_init(void)
+{
+ puts("DRAM: ");
+ return 0;
+}
+
+#ifdef CONFIG_PPC
+static int init_func_ram(void)
+{
+#ifdef CONFIG_BOARD_TYPES
+ int board_type = gd->board_type;
+#else
+ int board_type = 0; /* use dummy arg */
+#endif
+
+ gd->ram_size = initdram(board_type);
+
+ if (gd->ram_size > 0)
+ return 0;
+
+ puts("*** failed ***\n");
+ return 1;
+}
+#endif
+
+static int show_dram_config(void)
+{
+ ulong size;
+
+#ifdef CONFIG_NR_DRAM_BANKS
+ int i;
+
+ debug("\nRAM Configuration:\n");
+ for (i = size = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ size += gd->bd->bi_dram[i].size;
+ debug("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
+#ifdef DEBUG
+ print_size(gd->bd->bi_dram[i].size, "\n");
+#endif
+ }
+ debug("\nDRAM: ");
+#else
+ size = gd->ram_size;
+#endif
+
+ print_size(size, "");
+ board_add_ram_info(0);
+ putc('\n');
+
+ return 0;
+}
+
+ulong get_effective_memsize(void)
+{
+#ifndef CONFIG_VERY_BIG_RAM
+ return gd->ram_size;
+#else
+ /* limit stack to what we can reasonable map */
+ return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
+ CONFIG_MAX_MEM_MAPPED : gd->ram_size);
+#endif
+}
+
+void __dram_init_banksize(void)
+{
+#if defined(CONFIG_NR_DRAM_BANKS) && defined(CONFIG_SYS_SDRAM_BASE)
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ gd->bd->bi_dram[0].size = get_effective_memsize();
+#endif
+}
+
+void dram_init_banksize(void)
+ __attribute__((weak, alias("__dram_init_banksize")));
+
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+static int init_func_i2c(void)
+{
+ puts("I2C: ");
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ puts("ready\n");
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_HARD_SPI)
+static int init_func_spi(void)
+{
+ puts("SPI: ");
+ spi_init();
+ puts("ready\n");
+ return 0;
+}
+#endif
+
+__maybe_unused
+static int zero_global_data(void)
+{
+ memset((void *)gd, '\0', sizeof(gd_t));
+
+ return 0;
+}
+
+static int setup_mon_len(void)
+{
+#ifdef CONFIG_SYS_SYM_OFFSETS
+ gd->mon_len = _bss_end_ofs;
+#else
+ /* TODO: use (ulong)&__bss_end - (ulong)&__text_start; ? */
+ gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
+#endif
+ return 0;
+}
+
+__weak int arch_cpu_init(void)
+{
+ return 0;
+}
+
+static int setup_fdt(void)
+{
+#ifdef CONFIG_OF_EMBED
+ /* Get a pointer to the FDT */
+ gd->fdt_blob = _binary_dt_dtb_start;
+#elif defined CONFIG_OF_SEPARATE
+ /* FDT is at end of image */
+# ifdef CONFIG_SYS_SYM_OFFSETS
+ gd->fdt_blob = (void *)(_end_ofs + CONFIG_SYS_TEXT_BASE);
+# else
+ gd->fdt_blob = (ulong *)&_end;
+# endif
+#endif
+ /* Allow the early environment to override the fdt address */
+ gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
+ (uintptr_t)gd->fdt_blob);
+ return 0;
+}
+
+/* Get the top of usable RAM */
+__weak ulong board_get_usable_ram_top(ulong total_size)
+{
+ return gd->ram_top;
+}
+
+static int setup_dest_addr(void)
+{
+ debug("Monitor len: %08lX\n", gd->mon_len);
+ /*
+ * Ram is setup, size stored in gd !!
+ */
+ debug("Ram size: %08lX\n", (ulong)gd->ram_size);
+#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
+#ifdef CONFIG_SYS_SDRAM_BASE
+ gd->ram_top = CONFIG_SYS_SDRAM_BASE;
+#endif
+ gd->ram_top += get_effective_memsize();
+ gd->ram_top = board_get_usable_ram_top(gd->mon_len);
+ gd->dest_addr = gd->ram_top;
+ debug("Ram top: %08lX\n", (ulong)gd->ram_top);
+#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
+ /*
+ * We need to make sure the location we intend to put secondary core
+ * boot code is reserved and not used by any part of u-boot
+ */
+ if (gd->dest_addr > determine_mp_bootpg(NULL)) {
+ gd->dest_addr = determine_mp_bootpg(NULL);
+ debug("Reserving MP boot page to %08lx\n", gd->dest_addr);
+ }
+#endif
+ gd->dest_addr_sp = gd->dest_addr;
+ return 0;
+}
+
+#if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
+static int reserve_logbuffer(void)
+{
+ /* reserve kernel log buffer */
+ gd->dest_addr -= LOGBUFF_RESERVE;
+ debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN,
+ gd->dest_addr);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PRAM
+/* reserve protected RAM */
+static int reserve_pram(void)
+{
+ ulong reg;
+
+ reg = getenv_ulong("pram", 10, CONFIG_PRAM);
+ gd->dest_addr -= (reg << 10); /* size is in kB */
+ debug("Reserving %ldk for protected RAM at %08lx\n", reg,
+ gd->dest_addr);
+ return 0;
+}
+#endif /* CONFIG_PRAM */
+
+/* Round memory pointer down to next 4 kB limit */
+static int reserve_round_4k(void)
+{
+ gd->dest_addr &= ~(4096 - 1);
+ return 0;
+}
+
+#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \
+ defined(CONFIG_ARM)
+static int reserve_mmu(void)
+{
+ /* reserve TLB table */
+ gd->arch.tlb_size = 4096 * 4;
+ gd->dest_addr -= gd->arch.tlb_size;
+
+ /* round down to next 64 kB limit */
+ gd->dest_addr &= ~(0x10000 - 1);
+
+ gd->arch.tlb_addr = gd->dest_addr;
+ debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr,
+ gd->arch.tlb_addr + gd->arch.tlb_size);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_LCD
+static int reserve_lcd(void)
+{
+#ifdef CONFIG_FB_ADDR
+ gd->fb_base = CONFIG_FB_ADDR;
+#else
+ /* reserve memory for LCD display (always full pages) */
+ gd->dest_addr = lcd_setmem(gd->dest_addr);
+ gd->fb_base = gd->dest_addr;
+#endif /* CONFIG_FB_ADDR */
+ return 0;
+}
+#endif /* CONFIG_LCD */
+
+#if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) \
+ && !defined(CONFIG_ARM) && !defined(CONFIG_X86)
+static int reserve_video(void)
+{
+ /* reserve memory for video display (always full pages) */
+ gd->dest_addr = video_setmem(gd->dest_addr);
+ gd->fb_base = gd->dest_addr;
+
+ return 0;
+}
+#endif
+
+static int reserve_uboot(void)
+{
+ /*
+ * reserve memory for U-Boot code, data & bss
+ * round down to next 4 kB limit
+ */
+ gd->dest_addr -= gd->mon_len;
+ gd->dest_addr &= ~(4096 - 1);
+#ifdef CONFIG_E500
+ /* round down to next 64 kB limit so that IVPR stays aligned */
+ gd->dest_addr &= ~(65536 - 1);
+#endif
+
+ debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10,
+ gd->dest_addr);
+ return 0;
+}
+
+#ifndef CONFIG_SPL_BUILD
+/* reserve memory for malloc() area */
+static int reserve_malloc(void)
+{
+ gd->dest_addr_sp = gd->dest_addr - TOTAL_MALLOC_LEN;
+ debug("Reserving %dk for malloc() at: %08lx\n",
+ TOTAL_MALLOC_LEN >> 10, gd->dest_addr_sp);
+ return 0;
+}
+
+/* (permanently) allocate a Board Info struct */
+static int reserve_board(void)
+{
+ gd->dest_addr_sp -= sizeof(bd_t);
+ gd->bd = (bd_t *)gd->dest_addr_sp;
+ memset(gd->bd, '\0', sizeof(bd_t));
+ debug("Reserving %zu Bytes for Board Info at: %08lx\n",
+ sizeof(bd_t), gd->dest_addr_sp);
+ return 0;
+}
+#endif
+
+static int setup_machine(void)
+{
+#ifdef CONFIG_MACH_TYPE
+ gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
+#endif
+ return 0;
+}
+
+static int reserve_global_data(void)
+{
+ gd->dest_addr_sp -= sizeof(gd_t);
+ gd->new_gd = (gd_t *)gd->dest_addr_sp;
+ debug("Reserving %zu Bytes for Global Data at: %08lx\n",
+ sizeof(gd_t), gd->dest_addr_sp);
+ return 0;
+}
+
+static int reserve_fdt(void)
+{
+ /*
+ * 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) {
+ gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
+
+ gd->dest_addr_sp -= gd->fdt_size;
+ gd->new_fdt = (void *)gd->dest_addr_sp;
+ debug("Reserving %lu Bytes for FDT at: %p\n",
+ gd->fdt_size, gd->new_fdt);
+ }
+
+ return 0;
+}
+
+static int reserve_stacks(void)
+{
+#ifdef CONFIG_SPL_BUILD
+# ifdef CONFIG_ARM
+ gd->dest_addr_sp -= 128; /* leave 32 words for abort-stack */
+ gd->irq_sp = gd->dest_addr_sp;
+# endif
+#else
+# ifdef CONFIG_PPC
+ ulong *s;
+# endif
+
+ /* setup stack pointer for exceptions */
+ gd->dest_addr_sp -= 16;
+ gd->dest_addr_sp &= ~0xf;
+ gd->irq_sp = gd->dest_addr_sp;
+
+ /*
+ * Handle architecture-specific things here
+ * TODO(sjg@chromium.org): Perhaps create arch_reserve_stack()
+ * to handle this and put in arch/xxx/lib/stack.c
+ */
+# ifdef CONFIG_ARM
+# ifdef CONFIG_USE_IRQ
+ gd->dest_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ);
+ debug("Reserving %zu Bytes for IRQ stack at: %08lx\n",
+ CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->dest_addr_sp);
+
+ /* 8-byte alignment for ARM ABI compliance */
+ gd->dest_addr_sp &= ~0x07;
+# endif
+ /* leave 3 words for abort-stack, plus 1 for alignment */
+ gd->dest_addr_sp -= 16;
+# elif defined(CONFIG_PPC)
+ /* Clear initial stack frame */
+ s = (ulong *) gd->dest_addr_sp;
+ *s = 0; /* Terminate back chain */
+ *++s = 0; /* NULL return address */
+# endif /* Architecture specific code */
+
+ return 0;
+#endif
+}
+
+static int display_new_sp(void)
+{
+ debug("New Stack Pointer is: %08lx\n", gd->dest_addr_sp);
+
+ return 0;
+}
+
+#ifdef CONFIG_PPC
+static int setup_board_part1(void)
+{
+ bd_t *bd = gd->bd;
+
+ /*
+ * Save local variables to board info struct
+ */
+
+ bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; /* start of memory */
+ bd->bi_memsize = gd->ram_size; /* size in bytes */
+
+#ifdef CONFIG_SYS_SRAM_BASE
+ bd->bi_sramstart = CONFIG_SYS_SRAM_BASE; /* start of SRAM */
+ bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; /* size of SRAM */
+#endif
+
+#if defined(CONFIG_8xx) || defined(CONFIG_8260) || defined(CONFIG_5xx) || \
+ defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
+ bd->bi_immr_base = CONFIG_SYS_IMMR; /* base of IMMR register */
+#endif
+#if defined(CONFIG_MPC5xxx)
+ bd->bi_mbar_base = CONFIG_SYS_MBAR; /* base of internal registers */
+#endif
+#if defined(CONFIG_MPC83xx)
+ bd->bi_immrbar = CONFIG_SYS_IMMR;
+#endif
+#if defined(CONFIG_MPC8220)
+ bd->bi_mbar_base = CONFIG_SYS_MBAR; /* base of internal registers */
+ bd->bi_inpfreq = gd->arch.inp_clk;
+ bd->bi_pcifreq = gd->pci_clk;
+ bd->bi_vcofreq = gd->arch.vco_clk;
+ bd->bi_pevfreq = gd->arch.pev_clk;
+ bd->bi_flbfreq = gd->arch.flb_clk;
+
+ /* store bootparam to sram (backward compatible), here? */
+ {
+ u32 *sram = (u32 *) CONFIG_SYS_SRAM_BASE;
+
+ *sram++ = gd->ram_size;
+ *sram++ = gd->bus_clk;
+ *sram++ = gd->arch.inp_clk;
+ *sram++ = gd->cpu_clk;
+ *sram++ = gd->arch.vco_clk;
+ *sram++ = gd->arch.flb_clk;
+ *sram++ = 0xb8c3ba11; /* boot signature */
+ }
+#endif
+
+ return 0;
+}
+
+static int setup_board_part2(void)
+{
+ bd_t *bd = gd->bd;
+
+ bd->bi_intfreq = gd->cpu_clk; /* Internal Freq, in Hz */
+ bd->bi_busfreq = gd->bus_clk; /* Bus Freq, in Hz */
+#if defined(CONFIG_CPM2)
+ bd->bi_cpmfreq = gd->arch.cpm_clk;
+ bd->bi_brgfreq = gd->arch.brg_clk;
+ bd->bi_sccfreq = gd->arch.scc_clk;
+ bd->bi_vco = gd->arch.vco_out;
+#endif /* CONFIG_CPM2 */
+#if defined(CONFIG_MPC512X)
+ bd->bi_ipsfreq = gd->arch.ips_clk;
+#endif /* CONFIG_MPC512X */
+#if defined(CONFIG_MPC5xxx)
+ bd->bi_ipbfreq = gd->arch.ipb_clk;
+ bd->bi_pcifreq = gd->pci_clk;
+#endif /* CONFIG_MPC5xxx */
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_EXTBDINFO
+static int setup_board_extra(void)
+{
+ bd_t *bd = gd->bd;
+
+ strncpy((char *) bd->bi_s_version, "1.2", sizeof(bd->bi_s_version));
+ strncpy((char *) bd->bi_r_version, U_BOOT_VERSION,
+ sizeof(bd->bi_r_version));
+
+ bd->bi_procfreq = gd->cpu_clk; /* Processor Speed, In Hz */
+ bd->bi_plb_busfreq = gd->bus_clk;
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || \
+ defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ bd->bi_pci_busfreq = get_PCI_freq();
+ bd->bi_opbfreq = get_OPB_freq();
+#elif defined(CONFIG_XILINX_405)
+ bd->bi_pci_busfreq = get_PCI_freq();
+#endif
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_POST
+static int init_post(void)
+{
+ post_bootmode_init();
+ post_run(NULL, POST_ROM | post_bootmode_get(0));
+
+ return 0;
+}
+#endif
+
+static int setup_baud_rate(void)
+{
+ /* Ick, can we get rid of this line? */
+ gd->bd->bi_baudrate = gd->baudrate;
+
+ return 0;
+}
+
+static int setup_dram_config(void)
+{
+ /* Ram is board specific, so move it to board code ... */
+ dram_init_banksize();
+
+ return 0;
+}
+
+static int reloc_fdt(void)
+{
+ if (gd->new_fdt) {
+ memcpy(gd->new_fdt, gd->fdt_blob, gd->fdt_size);
+ gd->fdt_blob = gd->new_fdt;
+ }
+
+ return 0;
+}
+
+static int setup_reloc(void)
+{
+ gd->relocaddr = gd->dest_addr;
+ gd->start_addr_sp = gd->dest_addr_sp;
+ gd->reloc_off = gd->dest_addr - CONFIG_SYS_TEXT_BASE;
+ memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
+
+ debug("Relocation Offset is: %08lx\n", gd->reloc_off);
+ debug("Relocating to %08lx, new gd at %p, sp at %08lx\n",
+ gd->dest_addr, gd->new_gd, gd->dest_addr_sp);
+
+ return 0;
+}
+
+/* ARM calls relocate_code from its crt0.S */
+#if !defined(CONFIG_ARM)
+
+static int jump_to_copy(void)
+{
+ /*
+ * x86 is special, but in a nice way. It uses a trampoline which
+ * enables the dcache if possible.
+ *
+ * For now, other archs use relocate_code(), which is implemented
+ * similarly for all archs. When we do generic relocation, hopefully
+ * we can make all archs enable the dcache prior to relocation.
+ */
+#ifdef CONFIG_X86
+ /*
+ * SDRAM and console are now initialised. The final stack can now
+ * be setup in SDRAM. Code execution will continue in Flash, but
+ * with the stack in SDRAM and Global Data in temporary memory
+ * (CPU cache)
+ */
+ board_init_f_r_trampoline(gd->start_addr_sp);
+#else
+ relocate_code(gd->dest_addr_sp, gd->new_gd, gd->dest_addr);
+#endif
+
+ return 0;
+}
+#endif
+
+/* 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;
+}
+
+static init_fnc_t init_sequence_f[] = {
+#if !defined(CONFIG_CPM2) && !defined(CONFIG_MPC512X) && \
+ !defined(CONFIG_MPC83xx) && !defined(CONFIG_MPC85xx) && \
+ !defined(CONFIG_MPC86xx)
+ zero_global_data,
+#endif
+ setup_fdt,
+ setup_mon_len,
+#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
+ /* TODO: can this go into arch_cpu_init()? */
+ probecpu,
+#endif
+ arch_cpu_init, /* basic arch cpu dependent setup */
+#ifdef CONFIG_X86
+ cpu_init_f, /* TODO(sjg@chromium.org): remove */
+# ifdef CONFIG_OF_CONTROL
+ find_fdt, /* TODO(sjg@chromium.org): remove */
+# endif
+#endif
+ mark_bootstage,
+#ifdef CONFIG_OF_CONTROL
+ fdtdec_check_fdt,
+#endif
+#if defined(CONFIG_BOARD_EARLY_INIT_F)
+ board_early_init_f,
+#endif
+ /* TODO: can any of this go into arch_cpu_init()? */
+#if defined(CONFIG_PPC) && !defined(CONFIG_8xx_CPUCLK_DEFAULT)
+ get_clocks, /* get CPU and bus clocks (etc.) */
+#if defined(CONFIG_TQM8xxL) && !defined(CONFIG_TQM866M) \
+ && !defined(CONFIG_TQM885D)
+ adjust_sdram_tbs_8xx,
+#endif
+ /* TODO: can we rename this to timer_init()? */
+ init_timebase,
+#endif
+#ifdef CONFIG_ARM
+ timer_init, /* initialize timer */
+#endif
+#ifdef CONFIG_BOARD_POSTCLK_INIT
+ board_postclk_init,
+#endif
+#ifdef CONFIG_FSL_ESDHC
+ get_clocks,
+#endif
+#ifdef CONFIG_SYS_ALLOC_DPRAM
+#if !defined(CONFIG_CPM2)
+ dpram_init,
+#endif
+#endif
+#if defined(CONFIG_BOARD_POSTCLK_INIT)
+ board_postclk_init,
+#endif
+ env_init, /* initialize environment */
+#if defined(CONFIG_8xx_CPUCLK_DEFAULT)
+ /* get CPU and bus clocks according to the environment variable */
+ get_clocks_866,
+ /* adjust sdram refresh rate according to the new clock */
+ sdram_adjust_866,
+ init_timebase,
+#endif
+ init_baud_rate, /* initialze baudrate settings */
+ serial_init, /* serial communications setup */
+ console_init_f, /* stage 1 init of console */
+#if defined(CONFIG_X86) && defined(CONFIG_OF_CONTROL)
+ prepare_fdt, /* TODO(sjg@chromium.org): remove */
+#endif
+ display_options, /* say that we are here */
+ display_text_info, /* show debugging info if required */
+#if defined(CONFIG_8260)
+ prt_8260_rsr,
+ prt_8260_clks,
+#endif /* CONFIG_8260 */
+#if defined(CONFIG_MPC83xx)
+ prt_83xx_rsr,
+#endif
+#ifdef CONFIG_PPC
+ checkcpu,
+#endif
+#if defined(CONFIG_DISPLAY_CPUINFO)
+ print_cpuinfo, /* display cpu info (and speed) */
+#endif
+#if defined(CONFIG_MPC5xxx)
+ prt_mpc5xxx_clks,
+#endif /* CONFIG_MPC5xxx */
+#if defined(CONFIG_MPC8220)
+ prt_mpc8220_clks,
+#endif
+#if defined(CONFIG_DISPLAY_BOARDINFO)
+ checkboard, /* display board info */
+#endif
+ INIT_FUNC_WATCHDOG_INIT
+#if defined(CONFIG_MISC_INIT_F)
+ misc_init_f,
+#endif
+ INIT_FUNC_WATCHDOG_RESET
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+ init_func_i2c,
+#endif
+#if defined(CONFIG_HARD_SPI)
+ init_func_spi,
+#endif
+#ifdef CONFIG_X86
+ dram_init_f, /* configure available RAM banks */
+ /* x86 would prefer that this happens after relocation */
+ dram_init,
+#endif
+ announce_dram_init,
+ /* TODO: unify all these dram functions? */
+#ifdef CONFIG_ARM
+ dram_init, /* configure available RAM banks */
+#endif
+#ifdef CONFIG_PPC
+ init_func_ram,
+#endif
+#ifdef CONFIG_POST
+ post_init_f,
+#endif
+ INIT_FUNC_WATCHDOG_RESET
+#if defined(CONFIG_SYS_DRAM_TEST)
+ testdram,
+#endif /* CONFIG_SYS_DRAM_TEST */
+ INIT_FUNC_WATCHDOG_RESET
+
+#ifdef CONFIG_POST
+ init_post,
+#endif
+ INIT_FUNC_WATCHDOG_RESET
+ /*
+ * 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):
+ * - area that won't get touched by U-Boot and Linux (optional)
+ * - kernel log buffer
+ * - protected RAM
+ * - LCD framebuffer
+ * - monitor code
+ * - board info struct
+ */
+ setup_dest_addr,
+#if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
+ reserve_logbuffer,
+#endif
+#ifdef CONFIG_PRAM
+ reserve_pram,
+#endif
+ reserve_round_4k,
+#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \
+ defined(CONFIG_ARM)
+ reserve_mmu,
+#endif
+#ifdef CONFIG_LCD
+ reserve_lcd,
+#endif
+ /* TODO: Why the dependency on CONFIG_8xx? */
+#if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) \
+ && !defined(CONFIG_ARM) && !defined(CONFIG_X86)
+ reserve_video,
+#endif
+ reserve_uboot,
+#ifndef CONFIG_SPL_BUILD
+ reserve_malloc,
+ reserve_board,
+#endif
+ setup_machine,
+ reserve_global_data,
+ reserve_fdt,
+ reserve_stacks,
+ setup_dram_config,
+ show_dram_config,
+#ifdef CONFIG_PPC
+ setup_board_part1,
+ INIT_FUNC_WATCHDOG_RESET
+ setup_board_part2,
+#endif
+ setup_baud_rate,
+ display_new_sp,
+#ifdef CONFIG_SYS_EXTBDINFO
+ setup_board_extra,
+#endif
+ INIT_FUNC_WATCHDOG_RESET
+ reloc_fdt,
+ setup_reloc,
+#ifndef CONFIG_ARM
+ jump_to_copy,
+#endif
+ NULL,
+};
+
+void board_init_f(ulong boot_flags)
+{
+#ifndef CONFIG_X86
+ gd_t data;
+
+ gd = &data;
+#endif
+
+ gd->flags = boot_flags;
+
+ if (initcall_run_list(init_sequence_f))
+ hang();
+
+#ifndef CONFIG_ARM
+ /* NOTREACHED - jump_to_copy() does not return */
+ hang();
+#endif
+}
+
+#ifdef CONFIG_X86
+/*
+ * For now this code is only used on x86.
+ *
+ * init_sequence_f_r is the list of init functions which are run when
+ * U-Boot is executing from Flash with a semi-limited 'C' environment.
+ * The following limitations must be considered when implementing an
+ * '_f_r' function:
+ * - 'static' variables are read-only
+ * - Global Data (gd->xxx) is read/write
+ *
+ * The '_f_r' sequence must, as a minimum, copy U-Boot to RAM (if
+ * supported). It _should_, if possible, copy global data to RAM and
+ * initialise the CPU caches (to speed up the relocation process)
+ *
+ * NOTE: At present only x86 uses this route, but it is intended that
+ * all archs will move to this when generic relocation is implemented.
+ */
+static init_fnc_t init_sequence_f_r[] = {
+ init_cache_f_r,
+ copy_uboot_to_ram,
+ clear_bss,
+ do_elf_reloc_fixups,
+
+ NULL,
+};
+
+void board_init_f_r(void)
+{
+ if (initcall_run_list(init_sequence_f_r))
+ hang();
+
+ /*
+ * U-Boot has been copied into SDRAM, the BSS has been cleared etc.
+ * Transfer execution from Flash to RAM by calculating the address
+ * of the in-RAM copy of board_init_r() and calling it
+ */
+ (board_init_r + gd->reloc_off)(gd, gd->relocaddr);
+
+ /* NOTREACHED - board_init_r() does not return */
+ hang();
+}
+#endif /* CONFIG_X86 */
+
+void hang(void)
+{
+ puts("### ERROR ### Please RESET the board ###\n");
+ for (;;);
+}
diff --git a/common/board_r.c b/common/board_r.c
new file mode 100644
index 0000000000..9605f80a0c
--- /dev/null
+++ b/common/board_r.c
@@ -0,0 +1,917 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2002-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.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>
+/* TODO: can we just include all these headers whether needed or not? */
+#if defined(CONFIG_CMD_BEDBUG)
+#include <bedbug/type.h>
+#endif
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+#endif
+#include <environment.h>
+#include <fdtdec.h>
+#if defined(CONFIG_CMD_IDE)
+#include <ide.h>
+#endif
+#include <initcall.h>
+#ifdef CONFIG_PS2KBD
+#include <keyboard.h>
+#endif
+#if defined(CONFIG_CMD_KGDB)
+#include <kgdb.h>
+#endif
+#include <logbuff.h>
+#include <malloc.h>
+#ifdef CONFIG_BITBANGMII
+#include <miiphy.h>
+#endif
+#include <mmc.h>
+#include <nand.h>
+#include <onenand_uboot.h>
+#include <scsi.h>
+#include <serial.h>
+#include <spi.h>
+#include <stdio_dev.h>
+#include <watchdog.h>
+#ifdef CONFIG_ADDR_MAP
+#include <asm/mmu.h>
+#endif
+#include <asm/sections.h>
+#ifdef CONFIG_X86
+#include <asm/init_helpers.h>
+#endif
+#include <linux/compiler.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+ulong monitor_flash_len;
+
+int __board_flash_wp_on(void)
+{
+ /*
+ * Most flashes can't be detected when write protection is enabled,
+ * so provide a way to let U-Boot gracefully ignore write protected
+ * devices.
+ */
+ return 0;
+}
+
+int board_flash_wp_on(void)
+ __attribute__ ((weak, alias("__board_flash_wp_on")));
+
+void __cpu_secondary_init_r(void)
+{
+}
+
+void cpu_secondary_init_r(void)
+ __attribute__ ((weak, alias("__cpu_secondary_init_r")));
+
+static int initr_secondary_cpu(void)
+{
+ /*
+ * after non-volatile devices & environment is setup and cpu code have
+ * another round to deal with any initialization that might require
+ * full access to the environment or loading of some image (firmware)
+ * from a non-volatile device
+ */
+ /* TODO: maybe define this for all archs? */
+ cpu_secondary_init_r();
+
+ return 0;
+}
+
+static int initr_reloc(void)
+{
+ gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
+ bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
+
+ return 0;
+}
+
+#ifdef CONFIG_ARM
+/*
+ * Some of these functions are needed purely because the functions they
+ * call return void. If we change them to return 0, these stubs can go away.
+ */
+static int initr_caches(void)
+{
+ /* Enable caches */
+ enable_caches();
+ return 0;
+}
+#endif
+
+__weak int fixup_cpu(void)
+{
+ return 0;
+}
+
+static int initr_reloc_global_data(void)
+{
+#ifdef CONFIG_SYS_SYM_OFFSETS
+ monitor_flash_len = _end_ofs;
+#else
+ monitor_flash_len = (ulong)&__init_end - gd->dest_addr;
+#endif
+#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
+ /*
+ * The gd->cpu pointer is set to an address in flash before relocation.
+ * We need to update it to point to the same CPU entry in RAM.
+ * TODO: why not just add gd->reloc_ofs?
+ */
+ gd->arch.cpu += gd->dest_addr - CONFIG_SYS_MONITOR_BASE;
+
+ /*
+ * If we didn't know the cpu mask & # cores, we can save them of
+ * now rather than 'computing' them constantly
+ */
+ fixup_cpu();
+#endif
+#ifdef CONFIG_SYS_EXTRA_ENV_RELOC
+ /*
+ * Some systems need to relocate the env_addr pointer early because the
+ * location it points to will get invalidated before env_relocate is
+ * called. One example is on systems that might use a L2 or L3 cache
+ * in SRAM mode and initialize that cache from SRAM mode back to being
+ * a cache in cpu_init_r.
+ */
+ gd->env_addr += gd->dest_addr - CONFIG_SYS_MONITOR_BASE;
+#endif
+ return 0;
+}
+
+static int initr_serial(void)
+{
+ serial_initialize();
+ return 0;
+}
+
+#ifdef CONFIG_PPC
+static int initr_trap(void)
+{
+ /*
+ * Setup trap handlers
+ */
+ trap_init(gd->dest_addr);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_ADDR_MAP
+static int initr_addr_map(void)
+{
+ init_addr_map();
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_LOGBUFFER
+unsigned long logbuffer_base(void)
+{
+ return gd->ram_top - LOGBUFF_LEN;
+}
+
+static int initr_logbuffer(void)
+{
+ logbuff_init_ptrs();
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_POST
+static int initr_post_backlog(void)
+{
+ post_output_backlog();
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_DELAYED_ICACHE
+static int initr_icache_enable(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
+static int initr_unlock_ram_in_cache(void)
+{
+ unlock_ram_in_cache(); /* it's time to unlock D-cache in e500 */
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PCI
+static int initr_pci(void)
+{
+ pci_init();
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_WINBOND_83C553
+static int initr_w83c553f(void)
+{
+ /*
+ * Initialise the ISA bridge
+ */
+ initialise_w83c553f();
+ return 0;
+}
+#endif
+
+static int initr_barrier(void)
+{
+#ifdef CONFIG_PPC
+ /* TODO: Can we not use dmb() macros for this? */
+ asm("sync ; isync");
+#endif
+ return 0;
+}
+
+static int initr_malloc(void)
+{
+ ulong malloc_start;
+
+ /* The malloc area is immediately below the monitor copy in DRAM */
+ malloc_start = gd->dest_addr - TOTAL_MALLOC_LEN;
+ mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN);
+ return 0;
+}
+
+__weak int power_init_board(void)
+{
+ return 0;
+}
+
+static int initr_announce(void)
+{
+ debug("Now running in RAM - U-Boot at: %08lx\n", gd->dest_addr);
+ return 0;
+}
+
+#if !defined(CONFIG_SYS_NO_FLASH)
+static int initr_flash(void)
+{
+ ulong flash_size = 0;
+ bd_t *bd = gd->bd;
+ int ok;
+
+ puts("Flash: ");
+
+ if (board_flash_wp_on()) {
+ printf("Uninitialized - Write Protect On\n");
+ /* Since WP is on, we can't find real size. Set to 0 */
+ ok = 1;
+ } else {
+ flash_size = flash_init();
+ ok = flash_size > 0;
+ }
+ if (!ok) {
+ puts("*** failed ***\n");
+#ifdef CONFIG_PPC
+ /* Why does PPC do this? */
+ hang();
+#endif
+ return -1;
+ }
+ print_size(flash_size, "");
+#ifdef CONFIG_SYS_FLASH_CHECKSUM
+ /*
+ * Compute and print flash CRC if flashchecksum is set to 'y'
+ *
+ * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
+ */
+ if (getenv_yesno("flashchecksum") == 1) {
+ printf(" CRC: %08X", crc32(0,
+ (const unsigned char *) CONFIG_SYS_FLASH_BASE,
+ flash_size));
+ }
+#endif /* CONFIG_SYS_FLASH_CHECKSUM */
+ putc('\n');
+
+ /* update start of FLASH memory */
+#ifdef CONFIG_SYS_FLASH_BASE
+ bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
+#endif
+ /* size of FLASH memory (final value) */
+ bd->bi_flashsize = flash_size;
+
+#if defined(CONFIG_SYS_UPDATE_FLASH_SIZE)
+ /* Make a update of the Memctrl. */
+ update_flash_size(flash_size);
+#endif
+
+
+#if defined(CONFIG_OXC) || defined(CONFIG_RMU)
+ /* flash mapped at end of memory map */
+ bd->bi_flashoffset = CONFIG_SYS_TEXT_BASE + flash_size;
+#elif CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE
+ bd->bi_flashoffset = monitor_flash_len; /* reserved area for monitor */
+#endif
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PPC
+static int initr_spi(void)
+{
+ /* PPC does this here */
+#ifdef CONFIG_SPI
+#if !defined(CONFIG_ENV_IS_IN_EEPROM)
+ spi_init_f();
+#endif
+ spi_init_r();
+#endif
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_CMD_NAND
+/* go init the NAND */
+int initr_nand(void)
+{
+ puts("NAND: ");
+ nand_init();
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_ONENAND)
+/* go init the NAND */
+int initr_onenand(void)
+{
+ puts("NAND: ");
+ onenand_init();
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_GENERIC_MMC
+int initr_mmc(void)
+{
+ puts("MMC: ");
+ mmc_initialize(gd->bd);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_HAS_DATAFLASH
+int initr_dataflash(void)
+{
+ AT91F_DataflashInit();
+ dataflash_print_info();
+ return 0;
+}
+#endif
+
+/*
+ * 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 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
+ return fdtdec_get_config_int(gd->fdt_blob, "load-environment", 1);
+#elif defined CONFIG_DELAY_ENVIRONMENT
+ return 0;
+#else
+ return 1;
+#endif
+}
+
+static int initr_env(void)
+{
+ /* initialize environment */
+ if (should_load_env())
+ env_relocate();
+ else
+ set_default_env(NULL);
+
+ /* Initialize from environment */
+ load_addr = getenv_ulong("loadaddr", 16, load_addr);
+#if defined(CONFIG_SYS_EXTBDINFO)
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
+#if defined(CONFIG_I2CFAST)
+ /*
+ * set bi_iic_fast for linux taking environment variable
+ * "i2cfast" into account
+ */
+ {
+ char *s = getenv("i2cfast");
+
+ if (s && ((*s == 'y') || (*s == 'Y'))) {
+ gd->bd->bi_iic_fast[0] = 1;
+ gd->bd->bi_iic_fast[1] = 1;
+ }
+ }
+#endif /* CONFIG_I2CFAST */
+#endif /* CONFIG_405GP, CONFIG_405EP */
+#endif /* CONFIG_SYS_EXTBDINFO */
+ return 0;
+}
+
+#ifdef CONFIG_HERMES
+static int initr_hermes(void)
+{
+ if ((gd->board_type >> 16) == 2)
+ gd->bd->bi_ethspeed = gd->board_type & 0xFFFF;
+ else
+ gd->bd->bi_ethspeed = 0xFFFF;
+ return 0;
+}
+
+static int initr_hermes_start(void)
+{
+ if (gd->bd->bi_ethspeed != 0xFFFF)
+ hermes_start_lxt980((int) gd->bd->bi_ethspeed);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_SC3
+/* TODO: with new initcalls, move this into the driver */
+extern void sc3_read_eeprom(void);
+
+static int initr_sc3_read_eeprom(void)
+{
+ sc3_read_eeprom();
+ return 0;
+}
+#endif
+
+static int initr_jumptable(void)
+{
+ jumptable_init();
+ return 0;
+}
+
+#if defined(CONFIG_API)
+static int initr_api(void)
+{
+ /* Initialize API */
+ api_init();
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_DISPLAY_BOARDINFO_LATE
+static int show_model_r(void)
+{
+ /* Put this here so it appears on the LCD, now it is ready */
+# ifdef CONFIG_OF_CONTROL
+ const char *model;
+
+ model = (char *)fdt_getprop(gd->fdt_blob, 0, "model", NULL);
+ printf("Model: %s\n", model ? model : "<unknown>");
+# else
+ checkboard();
+# endif
+}
+#endif
+
+/* enable exceptions */
+#ifdef CONFIG_ARM
+static int initr_enable_interrupts(void)
+{
+ enable_interrupts();
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_CMD_NET
+static int initr_ethaddr(void)
+{
+ bd_t *bd = gd->bd;
+
+ /* kept around for legacy kernels only ... ignore the next section */
+ eth_getenv_enetaddr("ethaddr", bd->bi_enetaddr);
+#ifdef CONFIG_HAS_ETH1
+ eth_getenv_enetaddr("eth1addr", bd->bi_enet1addr);
+#endif
+#ifdef CONFIG_HAS_ETH2
+ eth_getenv_enetaddr("eth2addr", bd->bi_enet2addr);
+#endif
+#ifdef CONFIG_HAS_ETH3
+ eth_getenv_enetaddr("eth3addr", bd->bi_enet3addr);
+#endif
+#ifdef CONFIG_HAS_ETH4
+ eth_getenv_enetaddr("eth4addr", bd->bi_enet4addr);
+#endif
+#ifdef CONFIG_HAS_ETH5
+ eth_getenv_enetaddr("eth5addr", bd->bi_enet5addr);
+#endif
+ return 0;
+}
+#endif /* CONFIG_CMD_NET */
+
+#ifdef CONFIG_CMD_KGDB
+static int initr_kgdb(void)
+{
+ puts("KGDB: ");
+ kgdb_init();
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)
+static int initr_status_led(void)
+{
+ status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING);
+
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_SCSI)
+static int initr_scsi(void)
+{
+ /* Not supported properly on ARM yet */
+#ifndef CONFIG_ARM
+ puts("SCSI: ");
+ scsi_init();
+#endif
+
+ return 0;
+}
+#endif /* CONFIG_CMD_NET */
+
+#if defined(CONFIG_CMD_DOC)
+static int initr_doc(void)
+{
+ puts("DOC: ");
+ doc_init();
+}
+#endif
+
+#ifdef CONFIG_BITBANGMII
+static int initr_bbmii(void)
+{
+ bb_miiphy_init();
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_CMD_NET
+static int initr_net(void)
+{
+ puts("Net: ");
+ eth_initialize(gd->bd);
+#if defined(CONFIG_RESET_PHY_R)
+ debug("Reset Ethernet PHY\n");
+ reset_phy();
+#endif
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_POST
+static int initr_post(void)
+{
+ post_run(NULL, POST_RAM | post_bootmode_get(0));
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE)
+static int initr_pcmcia(void)
+{
+ puts("PCMCIA:");
+ pcmcia_init();
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_IDE)
+static int initr_ide(void)
+{
+#ifdef CONFIG_IDE_8xx_PCCARD
+ puts("PCMCIA:");
+#else
+ puts("IDE: ");
+#endif
+#if defined(CONFIG_START_IDE)
+ if (board_start_ide())
+ ide_init();
+#else
+ ide_init();
+#endif
+ return 0;
+}
+#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
+ */
+int initr_mem(void)
+{
+ ulong pram = 0;
+ char memsz[32];
+
+# ifdef CONFIG_PRAM
+ pram = getenv_ulong("pram", 10, CONFIG_PRAM);
+# endif
+# if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
+ /* Also take the logbuffer into account (pram is in kB) */
+ pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024;
+# endif
+ sprintf(memsz, "%ldk", (gd->ram_size / 1024) - pram);
+ setenv("mem", memsz);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_CMD_BEDBUG
+static int initr_bedbug(void)
+{
+ bedbug_init();
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PS2KBD
+static int initr_kbd(void)
+{
+ puts("PS/2: ");
+ kbd_init();
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int initr_modem(void)
+{
+ /* TODO: with new initcalls, move this into the driver */
+ extern int do_mdm_init;
+
+ do_mdm_init = gd->do_mdm_init;
+ return 0;
+}
+#endif
+
+static int run_main_loop(void)
+{
+ /* main_loop() can return to retry autoboot, if so just run it again */
+ for (;;)
+ main_loop();
+ return 0;
+}
+
+/*
+ * Over time we hope to remove these functions with code fragments and
+ * stub funtcions, and instead call the relevant function directly.
+ *
+ * We also hope to remove most of the driver-related init and do it if/when
+ * the driver is later used.
+ *
+ * TODO: perhaps reset the watchdog in the initcall function after each call?
+ */
+init_fnc_t init_sequence_r[] = {
+ initr_reloc,
+ /* TODO: could x86/PPC have this also perhaps? */
+#ifdef CONFIG_ARM
+ initr_caches,
+ board_init, /* Setup chipselects */
+#endif
+ /*
+ * 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
+#ifdef CONFIG_X86
+ init_bd_struct_r,
+#endif
+ initr_reloc_global_data,
+ initr_serial,
+ initr_announce,
+ INIT_FUNC_WATCHDOG_RESET
+#ifdef CONFIG_PPC
+ initr_trap,
+#endif
+#ifdef CONFIG_ADDR_MAP
+ initr_addr_map,
+#endif
+#if defined(CONFIG_BOARD_EARLY_INIT_R)
+ board_early_init_r,
+#endif
+ INIT_FUNC_WATCHDOG_RESET
+#ifdef CONFIG_LOGBUFFER
+ initr_logbuffer,
+#endif
+#ifdef CONFIG_POST
+ initr_post_backlog,
+#endif
+ INIT_FUNC_WATCHDOG_RESET
+#ifdef CONFIG_SYS_DELAYED_ICACHE
+ initr_icache_enable,
+#endif
+#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
+ initr_unlock_ram_in_cache,
+#endif
+#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)
+ /*
+ * Do early PCI configuration _before_ the flash gets initialised,
+ * because PCU ressources are crucial for flash access on some boards.
+ */
+ initr_pci,
+#endif
+#ifdef CONFIG_WINBOND_83C553
+ initr_w83c553f,
+#endif
+ initr_barrier,
+ initr_malloc,
+#ifdef CONFIG_ARCH_EARLY_INIT_R
+ arch_early_init_r,
+#endif
+ power_init_board,
+#ifndef CONFIG_SYS_NO_FLASH
+ initr_flash,
+#endif
+ INIT_FUNC_WATCHDOG_RESET
+#if defined(CONFIG_PPC) || defined(CONFIG_X86)
+ /* initialize higher level parts of CPU like time base and timers */
+ cpu_init_r,
+#endif
+#ifdef CONFIG_PPC
+ initr_spi,
+#endif
+#if defined(CONFIG_X86) && defined(CONFIG_SPI)
+ init_func_spi,
+#endif
+#ifdef CONFIG_CMD_NAND
+ initr_nand,
+#endif
+#ifdef CONFIG_CMD_ONENAND
+ initr_onenand,
+#endif
+#ifdef CONFIG_GENERIC_MMC
+ initr_mmc,
+#endif
+#ifdef CONFIG_HAS_DATAFLASH
+ initr_dataflash,
+#endif
+ initr_env,
+ INIT_FUNC_WATCHDOG_RESET
+ initr_secondary_cpu,
+#ifdef CONFIG_SC3
+ initr_sc3_read_eeprom,
+#endif
+#ifdef CONFIG_HERMES
+ initr_hermes,
+#endif
+#if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET)
+ mac_read_from_eeprom,
+#endif
+ INIT_FUNC_WATCHDOG_RESET
+#if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT)
+ /*
+ * Do pci configuration
+ */
+ initr_pci,
+#endif
+ stdio_init,
+ initr_jumptable,
+#ifdef CONFIG_API
+ initr_api,
+#endif
+ console_init_r, /* fully init console as a device */
+#ifdef CONFIG_DISPLAY_BOARDINFO_LATE
+ show_model_r,
+#endif
+#ifdef CONFIG_ARCH_MISC_INIT
+ arch_misc_init, /* miscellaneous arch-dependent init */
+#endif
+#ifdef CONFIG_MISC_INIT_R
+ misc_init_r, /* miscellaneous platform-dependent init */
+#endif
+#ifdef CONFIG_HERMES
+ initr_hermes_start,
+#endif
+ INIT_FUNC_WATCHDOG_RESET
+#ifdef CONFIG_CMD_KGDB
+ initr_kgdb,
+#endif
+#ifdef CONFIG_X86
+ board_early_init_r,
+#endif
+ interrupt_init,
+#if defined(CONFIG_ARM) || defined(CONFIG_x86)
+ initr_enable_interrupts,
+#endif
+#ifdef CONFIG_X86
+ timer_init, /* initialize timer */
+#endif
+#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)
+ initr_status_led,
+#endif
+ /* PPC has a udelay(20) here dating from 2002. Why? */
+#ifdef CONFIG_CMD_NET
+ initr_ethaddr,
+#endif
+#ifdef CONFIG_BOARD_LATE_INIT
+ board_late_init,
+#endif
+#ifdef CONFIG_CMD_SCSI
+ INIT_FUNC_WATCHDOG_RESET
+ initr_scsi,
+#endif
+#ifdef CONFIG_CMD_DOC
+ INIT_FUNC_WATCHDOG_RESET
+ initr_doc,
+#endif
+#ifdef CONFIG_BITBANGMII
+ initr_bbmii,
+#endif
+#ifdef CONFIG_CMD_NET
+ INIT_FUNC_WATCHDOG_RESET
+ initr_net,
+#endif
+#ifdef CONFIG_POST
+ initr_post,
+#endif
+#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE)
+ initr_pcmcia,
+#endif
+#if defined(CONFIG_CMD_IDE)
+ initr_ide,
+#endif
+#ifdef CONFIG_LAST_STAGE_INIT
+ INIT_FUNC_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
+#ifdef CONFIG_CMD_BEDBUG
+ INIT_FUNC_WATCHDOG_RESET
+ initr_bedbug,
+#endif
+#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
+ initr_mem,
+#endif
+#ifdef CONFIG_PS2KBD
+ initr_kbd,
+#endif
+#ifdef CONFIG_MODEM_SUPPORT
+ initr_modem,
+#endif
+ run_main_loop,
+};
+
+void board_init_r(gd_t *new_gd, ulong dest_addr)
+{
+#ifndef CONFIG_X86
+ gd = new_gd;
+#endif
+ if (initcall_run_list(init_sequence_r))
+ hang();
+
+ /* NOTREACHED - run_main_loop() does not return */
+ hang();
+}
diff --git a/common/cmd_bedbug.c b/common/cmd_bedbug.c
index 9791423205..77b6e3e88e 100644
--- a/common/cmd_bedbug.c
+++ b/common/cmd_bedbug.c
@@ -292,7 +292,7 @@ int do_bedbug_step (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
return 1;
}
- if (!find_next_address ((unsigned char *) &addr, FALSE, bug_ctx.regs))
+ if (!find_next_address((unsigned char *) &addr, false, bug_ctx.regs))
return 1;
if (bug_ctx.set)
@@ -323,7 +323,7 @@ int do_bedbug_next (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
return 1;
}
- if (!find_next_address ((unsigned char *) &addr, TRUE, bug_ctx.regs))
+ if (!find_next_address((unsigned char *) &addr, true, bug_ctx.regs))
return 1;
if (bug_ctx.set)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 2e9335207c..7438469d09 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -88,7 +88,7 @@ static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
#include <linux/err.h>
#include <nand.h>
-#ifdef CONFIG_SILENT_CONSOLE
+#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
static void fixup_silent_linux(void);
#endif
@@ -128,6 +128,9 @@ static boot_os_fn do_bootm_rtems;
#if defined(CONFIG_BOOTM_OSE)
static boot_os_fn do_bootm_ose;
#endif
+#if defined(CONFIG_BOOTM_PLAN9)
+static boot_os_fn do_bootm_plan9;
+#endif
#if defined(CONFIG_CMD_ELF)
static boot_os_fn do_bootm_vxworks;
static boot_os_fn do_bootm_qnxelf;
@@ -154,6 +157,9 @@ static boot_os_fn *boot_os[] = {
#if defined(CONFIG_BOOTM_OSE)
[IH_OS_OSE] = do_bootm_ose,
#endif
+#if defined(CONFIG_BOOTM_PLAN9)
+ [IH_OS_PLAN9] = do_bootm_plan9,
+#endif
#if defined(CONFIG_CMD_ELF)
[IH_OS_VXWORKS] = do_bootm_vxworks,
[IH_OS_QNX] = do_bootm_qnxelf,
@@ -694,7 +700,7 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
bootstage_mark(BOOTSTAGE_ID_CHECK_BOOT_OS);
-#ifdef CONFIG_SILENT_CONSOLE
+#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
if (images.os.os == IH_OS_LINUX)
fixup_silent_linux();
#endif
@@ -1413,7 +1419,7 @@ U_BOOT_CMD(
/*******************************************************************/
/* helper routines */
/*******************************************************************/
-#ifdef CONFIG_SILENT_CONSOLE
+#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
static void fixup_silent_linux(void)
{
char buf[256], *start, *end;
@@ -1628,6 +1634,39 @@ static int do_bootm_ose(int flag, int argc, char * const argv[],
}
#endif /* CONFIG_BOOTM_OSE */
+#if defined(CONFIG_BOOTM_PLAN9)
+static int do_bootm_plan9(int flag, int argc, char * const argv[],
+ bootm_headers_t *images)
+{
+ void (*entry_point)(void);
+
+ if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
+ return 1;
+
+#if defined(CONFIG_FIT)
+ if (!images->legacy_hdr_valid) {
+ fit_unsupported_reset("Plan 9");
+ return 1;
+ }
+#endif
+
+ entry_point = (void (*)(void))images->ep;
+
+ printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
+ (ulong)entry_point);
+
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+ /*
+ * Plan 9 Parameters:
+ * None
+ */
+ (*entry_point)();
+
+ return 1;
+}
+#endif /* CONFIG_BOOTM_PLAN9 */
+
#if defined(CONFIG_CMD_ELF)
static int do_bootm_vxworks(int flag, int argc, char * const argv[],
bootm_headers_t *images)
@@ -1806,7 +1845,7 @@ static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
usb_stop();
#endif
-#ifdef CONFIG_SILENT_CONSOLE
+#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
fixup_silent_linux();
#endif
arch_preboot_os();
diff --git a/common/cmd_bootmenu.c b/common/cmd_bootmenu.c
new file mode 100644
index 0000000000..a3cbffab24
--- /dev/null
+++ b/common/cmd_bootmenu.c
@@ -0,0 +1,517 @@
+/*
+ * (C) Copyright 2011-2013 Pali Rohár <pali.rohar@gmail.com>
+ *
+ * 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 <command.h>
+#include <ansi.h>
+#include <menu.h>
+#include <hush.h>
+#include <watchdog.h>
+#include <malloc.h>
+#include <linux/string.h>
+
+/* maximum bootmenu entries */
+#define MAX_COUNT 99
+
+/* maximal size of bootmenu env
+ * 9 = strlen("bootmenu_")
+ * 2 = strlen(MAX_COUNT)
+ * 1 = NULL term
+ */
+#define MAX_ENV_SIZE (9 + 2 + 1)
+
+struct bootmenu_entry {
+ unsigned short int num; /* unique number 0 .. MAX_COUNT */
+ char key[3]; /* key identifier of number */
+ char *title; /* title of entry */
+ char *command; /* hush command of entry */
+ struct bootmenu_data *menu; /* this bootmenu */
+ struct bootmenu_entry *next; /* next menu entry (num+1) */
+};
+
+struct bootmenu_data {
+ int delay; /* delay for autoboot */
+ int active; /* active menu entry */
+ int count; /* total count of menu entries */
+ struct bootmenu_entry *first; /* first menu entry */
+};
+
+enum bootmenu_key {
+ KEY_NONE = 0,
+ KEY_UP,
+ KEY_DOWN,
+ KEY_SELECT,
+};
+
+static char *bootmenu_getoption(unsigned short int n)
+{
+ char name[MAX_ENV_SIZE] = "bootmenu_";
+
+ if (n > MAX_COUNT)
+ return NULL;
+
+ sprintf(name + 9, "%d", n);
+ return getenv(name);
+}
+
+static void bootmenu_print_entry(void *data)
+{
+ struct bootmenu_entry *entry = data;
+ int reverse = (entry->menu->active == entry->num);
+
+ /*
+ * Move cursor to line where the entry will be drown (entry->num)
+ * First 3 lines contain bootmenu header + 1 empty line
+ */
+ printf(ANSI_CURSOR_POSITION, entry->num + 4, 1);
+
+ puts(" ");
+
+ if (reverse)
+ puts(ANSI_COLOR_REVERSE);
+
+ puts(entry->title);
+
+ if (reverse)
+ puts(ANSI_COLOR_RESET);
+}
+
+static void bootmenu_autoboot_loop(struct bootmenu_data *menu,
+ enum bootmenu_key *key, int *esc)
+{
+ int i, c;
+
+ if (menu->delay > 0) {
+ printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
+ printf(" Hit any key to stop autoboot: %2d ", menu->delay);
+ }
+
+ while (menu->delay > 0) {
+ for (i = 0; i < 100; ++i) {
+ if (!tstc()) {
+ WATCHDOG_RESET();
+ mdelay(10);
+ continue;
+ }
+
+ menu->delay = -1;
+ c = getc();
+
+ switch (c) {
+ case '\e':
+ *esc = 1;
+ *key = KEY_NONE;
+ break;
+ case '\r':
+ *key = KEY_SELECT;
+ break;
+ default:
+ *key = KEY_NONE;
+ break;
+ }
+
+ break;
+ }
+
+ if (menu->delay < 0)
+ break;
+
+ --menu->delay;
+ printf("\b\b\b%2d ", menu->delay);
+ }
+
+ printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
+ puts(ANSI_CLEAR_LINE);
+
+ if (menu->delay == 0)
+ *key = KEY_SELECT;
+}
+
+static void bootmenu_loop(struct bootmenu_data *menu,
+ enum bootmenu_key *key, int *esc)
+{
+ int c;
+
+ while (!tstc()) {
+ WATCHDOG_RESET();
+ mdelay(10);
+ }
+
+ c = getc();
+
+ switch (*esc) {
+ case 0:
+ /* First char of ANSI escape sequence '\e' */
+ if (c == '\e') {
+ *esc = 1;
+ *key = KEY_NONE;
+ }
+ break;
+ case 1:
+ /* Second char of ANSI '[' */
+ if (c == '[') {
+ *esc = 2;
+ *key = KEY_NONE;
+ } else {
+ *esc = 0;
+ }
+ break;
+ case 2:
+ case 3:
+ /* Third char of ANSI (number '1') - optional */
+ if (*esc == 2 && c == '1') {
+ *esc = 3;
+ *key = KEY_NONE;
+ break;
+ }
+
+ *esc = 0;
+
+ /* ANSI 'A' - key up was pressed */
+ if (c == 'A')
+ *key = KEY_UP;
+ /* ANSI 'B' - key down was pressed */
+ else if (c == 'B')
+ *key = KEY_DOWN;
+ /* other key was pressed */
+ else
+ *key = KEY_NONE;
+
+ break;
+ }
+
+ /* enter key was pressed */
+ if (c == '\r')
+ *key = KEY_SELECT;
+}
+
+static char *bootmenu_choice_entry(void *data)
+{
+ struct bootmenu_data *menu = data;
+ struct bootmenu_entry *iter;
+ enum bootmenu_key key = KEY_NONE;
+ int esc = 0;
+ int i;
+
+ while (1) {
+ if (menu->delay >= 0) {
+ /* Autoboot was not stopped */
+ bootmenu_autoboot_loop(menu, &key, &esc);
+ } else {
+ /* Some key was pressed, so autoboot was stopped */
+ bootmenu_loop(menu, &key, &esc);
+ }
+
+ switch (key) {
+ case KEY_UP:
+ if (menu->active > 0)
+ --menu->active;
+ /* no menu key selected, regenerate menu */
+ return NULL;
+ case KEY_DOWN:
+ if (menu->active < menu->count - 1)
+ ++menu->active;
+ /* no menu key selected, regenerate menu */
+ return NULL;
+ case KEY_SELECT:
+ iter = menu->first;
+ for (i = 0; i < menu->active; ++i)
+ iter = iter->next;
+ return iter->key;
+ default:
+ break;
+ }
+ }
+
+ /* never happens */
+ debug("bootmenu: this should not happen");
+ return NULL;
+}
+
+static void bootmenu_destroy(struct bootmenu_data *menu)
+{
+ struct bootmenu_entry *iter = menu->first;
+ struct bootmenu_entry *next;
+
+ while (iter) {
+ next = iter->next;
+ free(iter->title);
+ free(iter->command);
+ free(iter);
+ iter = next;
+ }
+ free(menu);
+}
+
+static struct bootmenu_data *bootmenu_create(int delay)
+{
+ unsigned short int i = 0;
+ const char *option;
+ struct bootmenu_data *menu;
+ struct bootmenu_entry *iter = NULL;
+
+ int len;
+ char *sep;
+ struct bootmenu_entry *entry;
+
+ menu = malloc(sizeof(struct bootmenu_data));
+ if (!menu)
+ return NULL;
+
+ menu->delay = delay;
+ menu->active = 0;
+ menu->first = NULL;
+
+ while ((option = bootmenu_getoption(i))) {
+ sep = strchr(option, '=');
+ if (!sep) {
+ printf("Invalid bootmenu entry: %s\n", option);
+ break;
+ }
+
+ entry = malloc(sizeof(struct bootmenu_entry));
+ if (!entry)
+ goto cleanup;
+
+ len = sep-option;
+ entry->title = malloc(len + 1);
+ if (!entry->title) {
+ free(entry);
+ goto cleanup;
+ }
+ memcpy(entry->title, option, len);
+ entry->title[len] = 0;
+
+ len = strlen(sep + 1);
+ entry->command = malloc(len + 1);
+ if (!entry->command) {
+ free(entry->title);
+ free(entry);
+ goto cleanup;
+ }
+ memcpy(entry->command, sep + 1, len);
+ entry->command[len] = 0;
+
+ sprintf(entry->key, "%d", i);
+
+ entry->num = i;
+ entry->menu = menu;
+ entry->next = NULL;
+
+ if (!iter)
+ menu->first = entry;
+ else
+ iter->next = entry;
+
+ iter = entry;
+ ++i;
+
+ if (i == MAX_COUNT - 1)
+ break;
+ }
+
+ /* Add U-Boot console entry at the end */
+ if (i <= MAX_COUNT - 1) {
+ entry = malloc(sizeof(struct bootmenu_entry));
+ if (!entry)
+ goto cleanup;
+
+ entry->title = strdup("U-Boot console");
+ if (!entry->title) {
+ free(entry);
+ goto cleanup;
+ }
+
+ entry->command = strdup("");
+ if (!entry->command) {
+ free(entry->title);
+ free(entry);
+ goto cleanup;
+ }
+
+ sprintf(entry->key, "%d", i);
+
+ entry->num = i;
+ entry->menu = menu;
+ entry->next = NULL;
+
+ if (!iter)
+ menu->first = entry;
+ else
+ iter->next = entry;
+
+ iter = entry;
+ ++i;
+ }
+
+ menu->count = i;
+ return menu;
+
+cleanup:
+ bootmenu_destroy(menu);
+ return NULL;
+}
+
+static void bootmenu_show(int delay)
+{
+ int init = 0;
+ void *choice = NULL;
+ char *title = NULL;
+ char *command = NULL;
+ struct menu *menu;
+ struct bootmenu_data *bootmenu;
+ struct bootmenu_entry *iter;
+ char *option, *sep;
+
+ /* If delay is 0 do not create menu, just run first entry */
+ if (delay == 0) {
+ option = bootmenu_getoption(0);
+ if (!option) {
+ puts("bootmenu option 0 was not found\n");
+ return;
+ }
+ sep = strchr(option, '=');
+ if (!sep) {
+ puts("bootmenu option 0 is invalid\n");
+ return;
+ }
+ run_command(sep+1, 0);
+ return;
+ }
+
+ bootmenu = bootmenu_create(delay);
+ if (!bootmenu)
+ return;
+
+ menu = menu_create(NULL, bootmenu->delay, 1, bootmenu_print_entry,
+ bootmenu_choice_entry, bootmenu);
+ if (!menu) {
+ bootmenu_destroy(bootmenu);
+ return;
+ }
+
+ for (iter = bootmenu->first; iter; iter = iter->next) {
+ if (!menu_item_add(menu, iter->key, iter))
+ goto cleanup;
+ }
+
+ /* Default menu entry is always first */
+ menu_default_set(menu, "0");
+
+ puts(ANSI_CURSOR_HIDE);
+ puts(ANSI_CLEAR_CONSOLE);
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+
+ init = 1;
+
+ if (menu_get_choice(menu, &choice)) {
+ iter = choice;
+ title = strdup(iter->title);
+ command = strdup(iter->command);
+ }
+
+cleanup:
+ menu_destroy(menu);
+ bootmenu_destroy(bootmenu);
+
+ if (init) {
+ puts(ANSI_CURSOR_SHOW);
+ puts(ANSI_CLEAR_CONSOLE);
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+ }
+
+ if (title && command) {
+ debug("Starting entry '%s'\n", title);
+ free(title);
+ run_command(command, 0);
+ free(command);
+ }
+
+#ifdef CONFIG_POSTBOOTMENU
+ run_command(CONFIG_POSTBOOTMENU, 0);
+#endif
+}
+
+void menu_display_statusline(struct menu *m)
+{
+ struct bootmenu_entry *entry;
+ struct bootmenu_data *menu;
+
+ if (menu_default_choice(m, (void *)&entry) < 0)
+ return;
+
+ menu = entry->menu;
+
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+ puts(ANSI_CLEAR_LINE);
+ printf(ANSI_CURSOR_POSITION, 2, 1);
+ puts(" *** U-Boot Boot Menu ***");
+ puts(ANSI_CLEAR_LINE_TO_END);
+ printf(ANSI_CURSOR_POSITION, 3, 1);
+ puts(ANSI_CLEAR_LINE);
+
+ /* First 3 lines are bootmenu header + 2 empty lines between entries */
+ printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
+ puts(ANSI_CLEAR_LINE);
+ printf(ANSI_CURSOR_POSITION, menu->count + 6, 1);
+ puts(" Press UP/DOWN to move, ENTER to select");
+ puts(ANSI_CLEAR_LINE_TO_END);
+ printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
+ puts(ANSI_CLEAR_LINE);
+}
+
+#ifdef CONFIG_MENU_SHOW
+int menu_show(int bootdelay)
+{
+ bootmenu_show(bootdelay);
+ return -1; /* -1 - abort boot and run monitor code */
+}
+#endif
+
+int do_bootmenu(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ char *delay_str = NULL;
+ int delay = 10;
+
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+ delay = CONFIG_BOOTDELAY;
+#endif
+
+ if (argc >= 2)
+ delay_str = argv[1];
+
+ if (!delay_str)
+ delay_str = getenv("bootmenu_delay");
+
+ if (delay_str)
+ delay = (int)simple_strtol(delay_str, NULL, 10);
+
+ bootmenu_show(delay);
+ return 0;
+}
+
+U_BOOT_CMD(
+ bootmenu, 2, 1, do_bootmenu,
+ "ANSI terminal bootmenu",
+ "[delay]\n"
+ " - show ANSI terminal bootmenu with autoboot delay"
+);
diff --git a/common/cmd_df.c b/common/cmd_df.c
deleted file mode 100644
index f7e5df3e2d..0000000000
--- a/common/cmd_df.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Command for accessing DataFlash.
- *
- * Copyright (C) 2008 Atmel Corporation
- */
-#include <common.h>
-#include <df.h>
-
-static int do_df(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- const char *cmd;
-
- /* need at least two arguments */
- if (argc < 2)
- goto usage;
-
- cmd = argv[1];
-
- if (strcmp(cmd, "init") == 0) {
- df_init(0, 0, 1000000);
- return 0;
- }
-
- if (strcmp(cmd, "info") == 0) {
- df_show_info();
- return 0;
- }
-
-usage:
- return CMD_RET_USAGE;
-}
-
-U_BOOT_CMD(
- sf, 2, 1, do_serial_flash,
- "Serial flash sub-system",
- "probe [bus:]cs - init flash device on given SPI bus and CS")
diff --git a/common/cmd_dfu.c b/common/cmd_dfu.c
index 01d6b3a2d6..83ef32497a 100644
--- a/common/cmd_dfu.c
+++ b/common/cmd_dfu.c
@@ -50,12 +50,15 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (ret)
return CMD_RET_FAILURE;
- if (strcmp(argv[3], "list") == 0) {
+ if (argc > 3 && strcmp(argv[3], "list") == 0) {
dfu_show_entities();
goto done;
}
+#ifdef CONFIG_TRATS
board_usb_init();
+#endif
+
g_dnl_register(s);
while (1) {
if (ctrlc())
diff --git a/common/cmd_dtt.c b/common/cmd_dtt.c
index cd94423d21..edbd4a83ca 100644
--- a/common/cmd_dtt.c
+++ b/common/cmd_dtt.c
@@ -27,7 +27,9 @@
#include <dtt.h>
#include <i2c.h>
+#include <tmu.h>
+#if defined CONFIG_DTT_SENSORS
static unsigned long sensor_initialized;
static void _initialize_dtt(void)
@@ -59,9 +61,11 @@ void dtt_init(void)
/* switch back to original I2C bus */
I2C_SET_BUS(old_bus);
}
+#endif
-int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+int dtt_i2c(void)
{
+#if defined CONFIG_DTT_SENSORS
int i;
unsigned char sensors[] = CONFIG_DTT_SENSORS;
int old_bus;
@@ -83,8 +87,34 @@ int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
/* switch back to original I2C bus */
I2C_SET_BUS(old_bus);
+#endif
return 0;
+}
+
+int dtt_tmu(void)
+{
+#if defined CONFIG_TMU_CMD_DTT
+ int cur_temp;
+
+ /* Sense and return latest thermal info */
+ if (tmu_monitor(&cur_temp) == TMU_STATUS_INIT) {
+ puts("TMU is in unknown state, temperature is invalid\n");
+ return -1;
+ }
+ printf("Current temperature: %u degrees Celsius\n", cur_temp);
+#endif
+ return 0;
+}
+
+int do_dtt(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ int err = 0;
+
+ err |= dtt_i2c();
+ err |= dtt_tmu();
+
+ return err;
} /* do_dtt() */
/***************************************************/
diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c
index dcf76a50cd..706fd54a55 100644
--- a/common/cmd_ext4.c
+++ b/common/cmd_ext4.c
@@ -88,10 +88,10 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,
dev = dev_desc->dev;
/* get the filename */
- filename = argv[3];
+ filename = argv[4];
/* get the address in hexadecimal format (string to int) */
- ram_address = simple_strtoul(argv[4], NULL, 16);
+ ram_address = simple_strtoul(argv[3], NULL, 16);
/* get the filesize in base 10 format */
file_size = simple_strtoul(argv[5], NULL, 10);
@@ -122,7 +122,7 @@ fail:
U_BOOT_CMD(ext4write, 6, 1, do_ext4_write,
"create a file in the root directory",
- "<interface> <dev[:part]> [Absolute filename path] [Address] [sizebytes]\n"
+ "<interface> <dev[:part]> <addr> <absolute filename path> [sizebytes]\n"
" - create a file in / directory");
#endif
diff --git a/common/cmd_fat.c b/common/cmd_fat.c
index 86be044725..0487438faa 100644
--- a/common/cmd_fat.c
+++ b/common/cmd_fat.c
@@ -49,6 +49,9 @@ U_BOOT_CMD(
" If 'pos' is omitted, 0 is used. 'pos' requires 'bytes'.\n"
" 'bytes' gives the size to load. If 'bytes' is 0 or omitted,\n"
" the load stops on end of file.\n"
+ " If either 'pos' or 'bytes' are not aligned to\n"
+ " ARCH_DMA_MINALIGN then a misaligned buffer warning will\n"
+ " be printed and performance will suffer for the load.\n"
" All numeric parameters are assumed to be hex."
);
diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c
index 66e0ef0580..dfa36901e6 100644
--- a/common/cmd_fdc.c
+++ b/common/cmd_fdc.c
@@ -39,13 +39,6 @@
#define PRINTF(fmt,args...)
#endif
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
/*#if defined(CONFIG_CMD_DATE) */
/*#include <rtc.h> */
/*#endif */
@@ -214,9 +207,9 @@ int wait_for_fdc_int(void)
timeout--;
udelay(10);
if(timeout==0) /* timeout occured */
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
/* reads a byte from the FIFO of the FDC and checks direction and RQM bit
@@ -244,7 +237,7 @@ int fdc_need_more_output(void)
c=(unsigned char)read_fdc_byte();
printf("Error: more output: %x\n",c);
}
- return TRUE;
+ return true;
}
@@ -260,10 +253,10 @@ int write_fdc_byte(unsigned char val)
udelay(10);
fdc_need_more_output();
if(timeout==0) /* timeout occured */
- return FALSE;
+ return false;
}
write_fdc_reg(FDC_FIFO,val);
- return TRUE;
+ return true;
}
/* sets up all FDC commands and issues it to the FDC. If
@@ -344,9 +337,9 @@ int fdc_issue_cmd(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG)
}
for(i=0;i<pCMD->cmdlen;i++) {
/* PRINTF("write cmd%d = 0x%02X\n",i,pCMD->cmd[i]); */
- if(write_fdc_byte(pCMD->cmd[i])==FALSE) {
+ if (write_fdc_byte(pCMD->cmd[i]) == false) {
PRINTF("Error: timeout while issue cmd%d\n",i);
- return FALSE;
+ return false;
}
}
timeout=FDC_TIME_OUT;
@@ -355,12 +348,12 @@ int fdc_issue_cmd(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG)
timeout--;
if(timeout==0) {
PRINTF(" timeout while reading result%d MSR=0x%02X\n",i,read_fdc_reg(FDC_MSR));
- return FALSE;
+ return false;
}
}
pCMD->result[i]=(unsigned char)read_fdc_byte();
}
- return TRUE;
+ return true;
}
/* selects the drive assigned in the cmd structur and
@@ -391,9 +384,10 @@ void stop_fdc_drive(FDC_COMMAND_STRUCT *pCMD)
int fdc_recalibrate(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG)
{
pCMD->cmd[COMMAND]=FDC_CMD_RECALIBRATE;
- if(fdc_issue_cmd(pCMD,pFG)==FALSE)
- return FALSE;
- while(wait_for_fdc_int()!=TRUE);
+ if (fdc_issue_cmd(pCMD, pFG) == false)
+ return false;
+ while (wait_for_fdc_int() != true);
+
pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT;
return(fdc_issue_cmd(pCMD,pFG));
}
@@ -403,9 +397,10 @@ int fdc_recalibrate(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG)
int fdc_seek(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG)
{
pCMD->cmd[COMMAND]=FDC_CMD_SEEK;
- if(fdc_issue_cmd(pCMD,pFG)==FALSE)
- return FALSE;
- while(wait_for_fdc_int()!=TRUE);
+ if (fdc_issue_cmd(pCMD, pFG) == false)
+ return false;
+ while (wait_for_fdc_int() != true);
+
pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT;
return(fdc_issue_cmd(pCMD,pFG));
}
@@ -421,7 +416,7 @@ int fdc_terminate(FDC_COMMAND_STRUCT *pCMD)
for(i=0;i<7;i++) {
pCMD->result[i]=(unsigned char)read_fdc_byte();
}
- return TRUE;
+ return true;
}
/* reads data from FDC, seek commands are issued automatic */
@@ -440,18 +435,18 @@ int fdc_read_data(unsigned char *buffer, unsigned long blocks,FDC_COMMAND_STRUCT
retriesrw=0;
retriescal=0;
offset=0;
- if(fdc_seek(pCMD,pFG)==FALSE) {
+ if (fdc_seek(pCMD, pFG) == false) {
stop_fdc_drive(pCMD);
if (flags)
enable_interrupts();
- return FALSE;
+ return false;
}
if((pCMD->result[STATUS_0]&0x20)!=0x20) {
printf("Seek error Status: %02X\n",pCMD->result[STATUS_0]);
stop_fdc_drive(pCMD);
if (flags)
enable_interrupts();
- return FALSE;
+ return false;
}
/* now determine the next seek point */
/* lastblk=pCMD->blnr + blocks; */
@@ -466,11 +461,11 @@ int fdc_read_data(unsigned char *buffer, unsigned long blocks,FDC_COMMAND_STRUCT
retryrw:
len=sect_size * readblk;
pCMD->cmd[COMMAND]=FDC_CMD_READ;
- if(fdc_issue_cmd(pCMD,pFG)==FALSE) {
+ if (fdc_issue_cmd(pCMD, pFG) == false) {
stop_fdc_drive(pCMD);
if (flags)
enable_interrupts();
- return FALSE;
+ return false;
}
for (i=0;i<len;i++) {
timeout=FDC_TIME_OUT;
@@ -492,15 +487,15 @@ retryrw:
stop_fdc_drive(pCMD);
if (flags)
enable_interrupts();
- return FALSE;
+ return false;
}
else {
PRINTF(" trying to recalibrate Try %d\n",retriescal);
- if(fdc_recalibrate(pCMD,pFG)==FALSE) {
+ if (fdc_recalibrate(pCMD, pFG) == false) {
stop_fdc_drive(pCMD);
if (flags)
enable_interrupts();
- return FALSE;
+ return false;
}
retriesrw=0;
goto retrycal;
@@ -512,7 +507,7 @@ retryrw:
} /* else >FDC_RW_RETRIES */
}/* if output */
timeout--;
- }while(TRUE);
+ } while (true);
} /* for len */
/* the last sector of a track or all data has been read,
* we need to get the results */
@@ -530,22 +525,22 @@ retryrw:
readblk=blocks;
retrycal:
/* a seek is necessary */
- if(fdc_seek(pCMD,pFG)==FALSE) {
+ if (fdc_seek(pCMD, pFG) == false) {
stop_fdc_drive(pCMD);
if (flags)
enable_interrupts();
- return FALSE;
+ return false;
}
if((pCMD->result[STATUS_0]&0x20)!=0x20) {
PRINTF("Seek error Status: %02X\n",pCMD->result[STATUS_0]);
stop_fdc_drive(pCMD);
- return FALSE;
+ return false;
}
- }while(TRUE); /* start over */
+ } while (true); /* start over */
stop_fdc_drive(pCMD); /* switch off drive */
if (flags)
enable_interrupts();
- return TRUE;
+ return true;
}
/* Scan all drives and check if drive is present and disk is inserted */
@@ -559,20 +554,20 @@ int fdc_check_drive(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG)
pCMD->drive=drives;
select_fdc_drive(pCMD);
pCMD->blnr=0; /* set to the 1st block */
- if(fdc_recalibrate(pCMD,pFG)==FALSE)
+ if (fdc_recalibrate(pCMD, pFG) == false)
continue;
if((pCMD->result[STATUS_0]&0x10)==0x10)
continue;
/* ok drive connected check for disk */
state|=(1<<drives);
pCMD->blnr=pFG->size; /* set to the last block */
- if(fdc_seek(pCMD,pFG)==FALSE)
+ if (fdc_seek(pCMD, pFG) == false)
continue;
pCMD->blnr=0; /* set to the 1st block */
- if(fdc_recalibrate(pCMD,pFG)==FALSE)
+ if (fdc_recalibrate(pCMD, pFG) == false)
continue;
pCMD->cmd[COMMAND]=FDC_CMD_READ_ID;
- if(fdc_issue_cmd(pCMD,pFG)==FALSE)
+ if (fdc_issue_cmd(pCMD, pFG) == false)
continue;
state|=(0x10<<drives);
}
@@ -584,7 +579,7 @@ int fdc_check_drive(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG)
((state&(0x10<<i))==(0x10<<i)) ? pFG->name : "");
}
pCMD->flags=state;
- return TRUE;
+ return true;
}
@@ -611,9 +606,9 @@ int fdc_setup(int drive, FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG)
write_fdc_reg(FDC_CCR,pFG->rate);
/* then initialize the DSR */
write_fdc_reg(FDC_DSR,pFG->rate);
- if(wait_for_fdc_int()==FALSE) {
+ if (wait_for_fdc_int() == false) {
PRINTF("Time Out after writing CCR\n");
- return FALSE;
+ return false;
}
/* now issue sense Interrupt and status command
* assuming only one drive present (drive 0) */
@@ -621,7 +616,7 @@ int fdc_setup(int drive, FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG)
for(i=0;i<4;i++) {
/* issue sense interrupt for all 4 possible drives */
pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT;
- if(fdc_issue_cmd(pCMD,pFG)==FALSE) {
+ if (fdc_issue_cmd(pCMD, pFG) == false) {
PRINTF("Sense Interrupt for drive %d failed\n",i);
}
}
@@ -629,24 +624,24 @@ int fdc_setup(int drive, FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG)
pCMD->drive=drive;
select_fdc_drive(pCMD);
pCMD->cmd[COMMAND]=FDC_CMD_CONFIGURE;
- if(fdc_issue_cmd(pCMD,pFG)==FALSE) {
+ if (fdc_issue_cmd(pCMD, pFG) == false) {
PRINTF(" configure timeout\n");
stop_fdc_drive(pCMD);
- return FALSE;
+ return false;
}
/* issue specify command */
pCMD->cmd[COMMAND]=FDC_CMD_SPECIFY;
- if(fdc_issue_cmd(pCMD,pFG)==FALSE) {
+ if (fdc_issue_cmd(pCMD, pFG) == false) {
PRINTF(" specify timeout\n");
stop_fdc_drive(pCMD);
- return FALSE;
+ return false;
}
/* then, we clear the reset in the DOR */
/* fdc_check_drive(pCMD,pFG); */
/* write_fdc_reg(FDC_DOR,0x04); */
- return TRUE;
+ return true;
}
#if defined(CONFIG_CMD_FDOS)
@@ -664,30 +659,30 @@ int fdc_fdos_init (int drive)
FDC_COMMAND_STRUCT *pCMD = &cmd;
/* setup FDC and scan for drives */
- if(fdc_setup(drive,pCMD,pFG)==FALSE) {
+ if (fdc_setup(drive, pCMD, pFG) == false) {
printf("\n** Error in setup FDC **\n");
- return FALSE;
+ return false;
}
- if(fdc_check_drive(pCMD,pFG)==FALSE) {
+ if (fdc_check_drive(pCMD, pFG) == false) {
printf("\n** Error in check_drives **\n");
- return FALSE;
+ return false;
}
if((pCMD->flags&(1<<drive))==0) {
/* drive not available */
printf("\n** Drive %d not available **\n",drive);
- return FALSE;
+ return false;
}
if((pCMD->flags&(0x10<<drive))==0) {
/* no disk inserted */
printf("\n** No disk inserted in drive %d **\n",drive);
- return FALSE;
+ return false;
}
/* ok, we have a valid source */
pCMD->drive=drive;
/* read first block */
pCMD->blnr=0;
- return TRUE;
+ return true;
}
/**************************************************************************
* int fdc_fdos_seek
@@ -747,11 +742,11 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return CMD_RET_USAGE;
}
/* setup FDC and scan for drives */
- if(fdc_setup(boot_drive,pCMD,pFG)==FALSE) {
+ if (fdc_setup(boot_drive, pCMD, pFG) == false) {
printf("\n** Error in setup FDC **\n");
return 1;
}
- if(fdc_check_drive(pCMD,pFG)==FALSE) {
+ if (fdc_check_drive(pCMD, pFG) == false) {
printf("\n** Error in check_drives **\n");
return 1;
}
@@ -769,7 +764,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
pCMD->drive=boot_drive;
/* read first block */
pCMD->blnr=0;
- if(fdc_read_data((unsigned char *)addr,1,pCMD,pFG)==FALSE) {
+ if (fdc_read_data((unsigned char *)addr, 1, pCMD, pFG) == false) {
printf("\nRead error:");
for(i=0;i<7;i++)
printf("result%d: 0x%02X\n",i,pCMD->result[i]);
@@ -801,7 +796,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
nrofblk++;
printf("Loading %ld Bytes (%d blocks) at 0x%08lx..\n",imsize,nrofblk,addr);
pCMD->blnr=0;
- if(fdc_read_data((unsigned char *)addr,nrofblk,pCMD,pFG)==FALSE) {
+ if (fdc_read_data((unsigned char *)addr, nrofblk, pCMD, pFG) == false) {
/* read image block */
printf("\nRead error:");
for(i=0;i<7;i++)
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index 042c994a1b..64dd76a0f5 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -631,6 +631,7 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
#endif /* CONFIG_LOOPW */
+#ifdef CONFIG_CMD_MEMTEST
static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr,
vu_long *dummy)
{
@@ -1002,7 +1003,7 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
return ret; /* not reached */
}
-
+#endif /* CONFIG_CMD_MEMTEST */
/* Modify memory.
*
@@ -1240,11 +1241,13 @@ U_BOOT_CMD(
);
#endif /* CONFIG_LOOPW */
+#ifdef CONFIG_CMD_MEMTEST
U_BOOT_CMD(
mtest, 5, 1, do_mem_mtest,
"simple RAM read/write test",
"[start [end [pattern [iterations]]]]"
);
+#endif /* CONFIG_CMD_MEMTEST */
#ifdef CONFIG_MX_CYCLIC
U_BOOT_CMD(
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 8c53a10315..9f3d6c575b 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -164,8 +164,12 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
if (strcmp(argv[1], "rescan") == 0) {
- struct mmc *mmc = find_mmc_device(curr_device);
+ struct mmc *mmc;
+ if (argc != 2)
+ return CMD_RET_USAGE;
+
+ mmc = find_mmc_device(curr_device);
if (!mmc) {
printf("no mmc device at slot %x\n", curr_device);
return 1;
@@ -179,8 +183,12 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 0;
} else if (strncmp(argv[1], "part", 4) == 0) {
block_dev_desc_t *mmc_dev;
- struct mmc *mmc = find_mmc_device(curr_device);
+ struct mmc *mmc;
+
+ if (argc != 2)
+ return CMD_RET_USAGE;
+ mmc = find_mmc_device(curr_device);
if (!mmc) {
printf("no mmc device at slot %x\n", curr_device);
return 1;
@@ -196,6 +204,8 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
puts("get mmc type error!\n");
return 1;
} else if (strcmp(argv[1], "list") == 0) {
+ if (argc != 2)
+ return CMD_RET_USAGE;
print_mmc_devices('\n');
return 0;
} else if (strcmp(argv[1], "dev") == 0) {
diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c
index 0cfca0c46b..1c35f9dd60 100644
--- a/common/cmd_mtdparts.c
+++ b/common/cmd_mtdparts.c
@@ -106,6 +106,8 @@
#include <onenand_uboot.h>
#endif
+DECLARE_GLOBAL_DATA_PTR;
+
/* special size referring to all the remaining space in a partition */
#define SIZE_REMAINING 0xFFFFFFFF
@@ -1420,7 +1422,7 @@ static int delete_partition(const char *id)
return 1;
if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) {
- printf("generated mtdparts too long, reseting to null\n");
+ printf("generated mtdparts too long, resetting to null\n");
return 1;
}
return 0;
@@ -1518,7 +1520,7 @@ static int spread_partitions(void)
index_partitions();
if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) {
- printf("generated mtdparts too long, reseting to null\n");
+ printf("generated mtdparts too long, resetting to null\n");
return 1;
}
return 0;
@@ -1537,6 +1539,7 @@ static int parse_mtdparts(const char *const mtdparts)
const char *p = mtdparts;
struct mtd_device *dev;
int err = 1;
+ char tmp_parts[MTDPARTS_MAXLEN];
debug("\n---parse_mtdparts---\nmtdparts = %s\n\n", p);
@@ -1547,7 +1550,12 @@ static int parse_mtdparts(const char *const mtdparts)
}
/* re-read 'mtdparts' variable, mtd_devices_init may be updating env */
- p = getenv("mtdparts");
+ if (gd->flags & GD_FLG_ENV_READY) {
+ p = getenv("mtdparts");
+ } else {
+ p = tmp_parts;
+ getenv_f("mtdparts", tmp_parts, MTDPARTS_MAXLEN);
+ }
if (strncmp(p, "mtdparts=", 9) != 0) {
printf("mtdparts variable doesn't start with 'mtdparts='\n");
@@ -1705,6 +1713,7 @@ int mtdparts_init(void)
const char *current_partition;
int ids_changed;
char tmp_ep[PARTITION_MAXLEN];
+ char tmp_parts[MTDPARTS_MAXLEN];
debug("\n---mtdparts_init---\n");
if (!initialized) {
@@ -1718,7 +1727,17 @@ int mtdparts_init(void)
/* get variables */
ids = getenv("mtdids");
- parts = getenv("mtdparts");
+ /*
+ * The mtdparts variable tends to be long. If we need to access it
+ * before the env is relocated, then we need to use our own stack
+ * buffer. gd->env_buf will be too small.
+ */
+ if (gd->flags & GD_FLG_ENV_READY) {
+ parts = getenv("mtdparts");
+ } else {
+ parts = tmp_parts;
+ getenv_f("mtdparts", tmp_parts, MTDPARTS_MAXLEN);
+ }
current_partition = getenv("partition");
/* save it for later parsing, cannot rely on current partition pointer
@@ -2016,7 +2035,7 @@ static int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc,
}
if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) {
- printf("generated mtdparts too long, reseting to null\n");
+ printf("generated mtdparts too long, resetting to null\n");
return 1;
}
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 32348f3773..e9d3d3c1bf 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -137,7 +137,8 @@ static inline int str2long(const char *p, ulong *num)
return *p != '\0' && *endptr == '\0';
}
-static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size)
+static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size,
+ loff_t *maxsize)
{
#ifdef CONFIG_CMD_MTDPARTS
struct mtd_device *dev;
@@ -160,6 +161,7 @@ static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size)
*off = part->offset;
*size = part->size;
+ *maxsize = part->size;
*idx = dev->id->num;
ret = set_dev(*idx);
@@ -173,10 +175,11 @@ static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size)
#endif
}
-static int arg_off(const char *arg, int *idx, loff_t *off, loff_t *maxsize)
+static int arg_off(const char *arg, int *idx, loff_t *off, loff_t *size,
+ loff_t *maxsize)
{
if (!str2off(arg, off))
- return get_part(arg, idx, off, maxsize);
+ return get_part(arg, idx, off, size, maxsize);
if (*off >= nand_info[*idx].size) {
puts("Offset exceeds device limit\n");
@@ -184,36 +187,35 @@ static int arg_off(const char *arg, int *idx, loff_t *off, loff_t *maxsize)
}
*maxsize = nand_info[*idx].size - *off;
+ *size = *maxsize;
return 0;
}
static int arg_off_size(int argc, char *const argv[], int *idx,
- loff_t *off, loff_t *size)
+ loff_t *off, loff_t *size, loff_t *maxsize)
{
int ret;
- loff_t maxsize = 0;
if (argc == 0) {
*off = 0;
*size = nand_info[*idx].size;
+ *maxsize = *size;
goto print;
}
- ret = arg_off(argv[0], idx, off, &maxsize);
+ ret = arg_off(argv[0], idx, off, size, maxsize);
if (ret)
return ret;
- if (argc == 1) {
- *size = maxsize;
+ if (argc == 1)
goto print;
- }
if (!str2off(argv[1], size)) {
printf("'%s' is not a number\n", argv[1]);
return -1;
}
- if (*size > maxsize) {
+ if (*size > *maxsize) {
puts("Size exceeds partition or device limit\n");
return -1;
}
@@ -307,7 +309,8 @@ int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[])
if (argc < 3)
goto usage;
- if (arg_off(argv[2], &idx, &addr, &maxsize)) {
+ /* We don't care about size, or maxsize. */
+ if (arg_off(argv[2], &idx, &addr, &maxsize, &maxsize)) {
puts("Offset or partition name expected\n");
return 1;
}
@@ -426,7 +429,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int i, ret = 0;
ulong addr;
- loff_t off, size;
+ loff_t off, size, maxsize;
char *cmd, *s;
nand_info_t *nand;
#ifdef CONFIG_SYS_NAND_QUIET
@@ -551,7 +554,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
printf("\nNAND %s: ", cmd);
/* skip first two or three arguments, look for offset and size */
- if (arg_off_size(argc - o, argv + o, &dev, &off, &size) != 0)
+ if (arg_off_size(argc - o, argv + o, &dev, &off, &size,
+ &maxsize) != 0)
return 1;
nand = &nand_info[dev];
@@ -619,7 +623,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (s && !strcmp(s, ".raw")) {
raw = 1;
- if (arg_off(argv[3], &dev, &off, &size))
+ if (arg_off(argv[3], &dev, &off, &size, &maxsize))
return 1;
if (argc > 4 && !str2long(argv[4], &pagecount)) {
@@ -635,7 +639,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
rwsize = pagecount * (nand->writesize + nand->oobsize);
} else {
if (arg_off_size(argc - 3, argv + 3, &dev,
- &off, &size) != 0)
+ &off, &size, &maxsize) != 0)
return 1;
rwsize = size;
@@ -645,9 +649,11 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
!strcmp(s, ".e") || !strcmp(s, ".i")) {
if (read)
ret = nand_read_skip_bad(nand, off, &rwsize,
+ NULL, maxsize,
(u_char *)addr);
else
ret = nand_write_skip_bad(nand, off, &rwsize,
+ NULL, maxsize,
(u_char *)addr, 0);
#ifdef CONFIG_CMD_NAND_TRIMFFS
} else if (!strcmp(s, ".trimffs")) {
@@ -655,8 +661,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
printf("Unknown nand command suffix '%s'\n", s);
return 1;
}
- ret = nand_write_skip_bad(nand, off, &rwsize,
- (u_char *)addr,
+ ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
+ maxsize, (u_char *)addr,
WITH_DROP_FFS);
#endif
#ifdef CONFIG_CMD_NAND_YAFFS
@@ -665,9 +671,9 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
printf("Unknown nand command suffix '%s'.\n", s);
return 1;
}
- ret = nand_write_skip_bad(nand, off, &rwsize,
- (u_char *)addr,
- WITH_INLINE_OOB);
+ ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
+ maxsize, (u_char *)addr,
+ WITH_YAFFS_OOB);
#endif
} else if (!strcmp(s, ".oob")) {
/* out-of-band data */
@@ -775,7 +781,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (s && !strcmp(s, ".allexcept"))
allexcept = 1;
- if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size) < 0)
+ if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size,
+ &maxsize) < 0)
return 1;
if (!nand_unlock(&nand_info[dev], off, size, allexcept)) {
@@ -873,7 +880,8 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset);
cnt = nand->writesize;
- r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr);
+ r = nand_read_skip_bad(nand, offset, &cnt, NULL, nand->size,
+ (u_char *)addr);
if (r) {
puts("** Read error\n");
bootstage_error(BOOTSTAGE_ID_NAND_HDR_READ);
@@ -905,7 +913,8 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
}
bootstage_mark(BOOTSTAGE_ID_NAND_TYPE);
- r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr);
+ r = nand_read_skip_bad(nand, offset, &cnt, NULL, nand->size,
+ (u_char *)addr);
if (r) {
puts("** Read error\n");
bootstage_error(BOOTSTAGE_ID_NAND_READ);
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 3a05e60103..afa128ece2 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -62,9 +62,10 @@ DECLARE_GLOBAL_DATA_PTR;
!defined(CONFIG_ENV_IS_IN_ONENAND) && \
!defined(CONFIG_ENV_IS_IN_SPI_FLASH) && \
!defined(CONFIG_ENV_IS_IN_REMOTE) && \
+ !defined(CONFIG_ENV_IS_IN_UBI) && \
!defined(CONFIG_ENV_IS_NOWHERE)
# error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\
-SPI_FLASH|NVRAM|MMC|FAT|REMOTE} or CONFIG_ENV_IS_NOWHERE
+SPI_FLASH|NVRAM|MMC|FAT|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE
#endif
/*
@@ -273,6 +274,10 @@ int setenv(const char *varname, const char *varvalue)
{
const char * const argv[4] = { "setenv", varname, varvalue, NULL };
+ /* before import into hashtable */
+ if (!(gd->flags & GD_FLG_ENV_READY))
+ return 1;
+
if (varvalue == NULL || varvalue[0] == '\0')
return _do_env_set(0, 2, (char * const *)argv);
else
@@ -325,41 +330,50 @@ static int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
int do_env_ask(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
char message[CONFIG_SYS_CBSIZE];
- int size = CONFIG_SYS_CBSIZE - 1;
- int i, len, pos;
+ int i, len, pos, size;
char *local_args[4];
+ char *endptr;
local_args[0] = argv[0];
local_args[1] = argv[1];
local_args[2] = NULL;
local_args[3] = NULL;
- /* Check the syntax */
- switch (argc) {
- case 1:
+ /*
+ * Check the syntax:
+ *
+ * env_ask envname [message1 ...] [size]
+ */
+ if (argc == 1)
return CMD_RET_USAGE;
- case 2: /* env_ask envname */
- sprintf(message, "Please enter '%s':", argv[1]);
- break;
-
- case 3: /* env_ask envname size */
- sprintf(message, "Please enter '%s':", argv[1]);
- size = simple_strtoul(argv[2], NULL, 10);
- break;
+ /*
+ * We test the last argument if it can be converted
+ * into a decimal number. If yes, we assume it's
+ * the size. Otherwise we echo it as part of the
+ * message.
+ */
+ i = simple_strtoul(argv[argc - 1], &endptr, 10);
+ if (*endptr != '\0') { /* no size */
+ size = CONFIG_SYS_CBSIZE - 1;
+ } else { /* size given */
+ size = i;
+ --argc;
+ }
- default: /* env_ask envname message1 ... messagen size */
- for (i = 2, pos = 0; i < argc - 1; i++) {
+ if (argc <= 2) {
+ sprintf(message, "Please enter '%s': ", argv[1]);
+ } else {
+ /* env_ask envname message1 ... messagen [size] */
+ for (i = 2, pos = 0; i < argc; i++) {
if (pos)
message[pos++] = ' ';
strcpy(message + pos, argv[i]);
pos += strlen(argv[i]);
}
-
+ message[pos++] = ' ';
message[pos] = '\0';
- size = simple_strtoul(argv[argc - 1], NULL, 10);
- break;
}
if (size >= CONFIG_SYS_CBSIZE)
@@ -1168,14 +1182,7 @@ U_BOOT_CMD(
askenv, CONFIG_SYS_MAXARGS, 1, do_env_ask,
"get environment variables from stdin",
"name [message] [size]\n"
- " - get environment variable 'name' from stdin (max 'size' chars)\n"
- "askenv name\n"
- " - get environment variable 'name' from stdin\n"
- "askenv name size\n"
- " - get environment variable 'name' from stdin (max 'size' chars)\n"
- "askenv name [message] size\n"
- " - display 'message' string and get environment variable 'name'"
- "from stdin (max 'size' chars)"
+ " - get environment variable 'name' from stdin (max 'size' chars)"
);
#endif
diff --git a/common/cmd_part.c b/common/cmd_part.c
index d997597c1e..b79f074f84 100644
--- a/common/cmd_part.c
+++ b/common/cmd_part.c
@@ -96,7 +96,7 @@ int do_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
U_BOOT_CMD(
part, 5, 1, do_part,
"disk partition related commands",
- "part uuid <interface> <dev>:<part>\n"
+ "uuid <interface> <dev>:<part>\n"
" - print partition UUID\n"
"part uuid <interface> <dev>:<part> <varname>\n"
" - set environment variable to partition UUID\n"
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index ee75db9685..2dbd49cbd6 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -1280,7 +1280,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
/*
* Create a menu and add items for all the labels.
*/
- m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print);
+ m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print,
+ NULL, NULL);
if (!m)
return NULL;
diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c
index 266bfa6905..13b3d996f6 100644
--- a/common/cmd_scsi.c
+++ b/common/cmd_scsi.c
@@ -110,7 +110,7 @@ void scsi_scan(int mode)
scsi_dev_desc[i].vendor[0]=0;
scsi_dev_desc[i].product[0]=0;
scsi_dev_desc[i].revision[0]=0;
- scsi_dev_desc[i].removable=FALSE;
+ scsi_dev_desc[i].removable = false;
scsi_dev_desc[i].if_type=IF_TYPE_SCSI;
scsi_dev_desc[i].dev=i;
scsi_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
@@ -125,7 +125,7 @@ void scsi_scan(int mode)
pccb->pdata=(unsigned char *)&tempbuff;
pccb->datalen=512;
scsi_setup_inquiry(pccb);
- if(scsi_exec(pccb)!=TRUE) {
+ if (scsi_exec(pccb) != true) {
if(pccb->contr_stat==SCSI_SEL_TIME_OUT) {
debug ("Selection timeout ID %d\n",pccb->target);
continue; /* selection timeout => assuming no device present */
@@ -139,7 +139,7 @@ void scsi_scan(int mode)
continue; /* skip unknown devices */
}
if((modi&0x80)==0x80) /* drive is removable */
- scsi_dev_desc[scsi_max_devs].removable=TRUE;
+ scsi_dev_desc[scsi_max_devs].removable=true;
/* get info for this device */
scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].vendor[0],
&tempbuff[8], 8);
@@ -152,8 +152,8 @@ void scsi_scan(int mode)
pccb->datalen=0;
scsi_setup_test_unit_ready(pccb);
- if(scsi_exec(pccb)!=TRUE) {
- if(scsi_dev_desc[scsi_max_devs].removable==TRUE) {
+ if (scsi_exec(pccb) != true) {
+ if (scsi_dev_desc[scsi_max_devs].removable == true) {
scsi_dev_desc[scsi_max_devs].type=perq;
goto removable;
}
@@ -404,7 +404,7 @@ static ulong scsi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
debug("scsi_read_ext: startblk " LBAF
", blccnt %x buffer %lx\n",
start, smallblks, buf_addr);
- if(scsi_exec(pccb)!=TRUE) {
+ if (scsi_exec(pccb) != true) {
scsi_print_error(pccb);
blkcnt-=blks;
break;
@@ -458,7 +458,7 @@ static ulong scsi_write(int device, ulong blknr,
}
debug("%s: startblk " LBAF ", blccnt %x buffer %lx\n",
__func__, start, smallblks, buf_addr);
- if (scsi_exec(pccb) != TRUE) {
+ if (scsi_exec(pccb) != true) {
scsi_print_error(pccb);
blkcnt -= blks;
break;
@@ -521,7 +521,7 @@ int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz)
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
pccb->datalen = 8;
- if (scsi_exec(pccb) != TRUE)
+ if (scsi_exec(pccb) != true)
return 1;
*capacity = ((lbaint_t)pccb->pdata[0] << 24) |
@@ -547,7 +547,7 @@ int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz)
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
pccb->datalen = 16;
- if (scsi_exec(pccb) != TRUE)
+ if (scsi_exec(pccb) != true)
return 1;
*capacity = ((uint64_t)pccb->pdata[0] << 56) |
diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index b1753587d3..0a17782d66 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -5,8 +5,8 @@
* Licensed under the GPL-2 or later.
*/
-#include <div64.h>
#include <common.h>
+#include <div64.h>
#include <malloc.h>
#include <spi_flash.h>
@@ -369,8 +369,8 @@ static void spi_test_next_stage(struct test_info *test)
* @param vbuf Verification buffer
* @return 0 if ok, -1 on error
*/
-static int spi_flash_test(struct spi_flash *flash, char *buf, ulong len,
- ulong offset, char *vbuf)
+static int spi_flash_test(struct spi_flash *flash, uint8_t *buf, ulong len,
+ ulong offset, uint8_t *vbuf)
{
struct test_info test;
int i;
@@ -431,9 +431,9 @@ static int do_spi_flash_test(int argc, char * const argv[])
{
unsigned long offset;
unsigned long len;
- char *buf = (char *)CONFIG_SYS_TEXT_BASE;
+ uint8_t *buf = (uint8_t *)CONFIG_SYS_TEXT_BASE;
char *endp;
- char *vbuf;
+ uint8_t *vbuf;
int ret;
offset = simple_strtoul(argv[1], &endp, 16);
diff --git a/common/cmd_test.c b/common/cmd_test.c
index d4ec18672e..acc0ecf99b 100644
--- a/common/cmd_test.c
+++ b/common/cmd_test.c
@@ -21,6 +21,15 @@
* MA 02111-1307 USA
*/
+/*
+ * Define _STDBOOL_H here to avoid macro expansion of true and false.
+ * If the future code requires macro true or false, remove this define
+ * and undef true and false before U_BOOT_CMD. This define and comment
+ * shall be removed if change to U_BOOT_CMD is made to take string
+ * instead of stringifying it.
+ */
+#define _STDBOOL_H
+
#include <common.h>
#include <command.h>
diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c
index 35b1d31f9c..5ba4feb485 100644
--- a/common/cmd_ubi.c
+++ b/common/cmd_ubi.c
@@ -23,6 +23,9 @@
#include <asm/errno.h>
#include <jffs2/load_kernel.h>
+#undef ubi_msg
+#define ubi_msg(fmt, ...) printf("UBI: " fmt "\n", ##__VA_ARGS__)
+
#define DEV_TYPE_NONE 0
#define DEV_TYPE_NAND 1
#define DEV_TYPE_ONENAND 2
@@ -263,7 +266,7 @@ out_err:
return err;
}
-static int ubi_volume_write(char *volume, void *buf, size_t size)
+int ubi_volume_write(char *volume, void *buf, size_t size)
{
int err = 1;
int rsvd_bytes = 0;
@@ -308,12 +311,10 @@ static int ubi_volume_write(char *volume, void *buf, size_t size)
ubi_gluebi_updated(vol);
}
- printf("%d bytes written to volume %s\n", size, volume);
-
return 0;
}
-static int ubi_volume_read(char *volume, char *buf, size_t size)
+int ubi_volume_read(char *volume, char *buf, size_t size)
{
int err, lnum, off, len, tbuf_size;
void *tbuf;
@@ -325,8 +326,6 @@ static int ubi_volume_read(char *volume, char *buf, size_t size)
if (vol == NULL)
return ENODEV;
- printf("Read %d bytes from volume %s to %p\n", size, volume, buf);
-
if (vol->updating) {
printf("updating");
return EBUSY;
@@ -431,26 +430,82 @@ static int ubi_dev_scan(struct mtd_info *info, char *ubidev,
return 0;
}
-static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+int ubi_part(char *part_name, const char *vid_header_offset)
{
- size_t size = 0;
- ulong addr = 0;
int err = 0;
-
- if (argc < 2)
- return CMD_RET_USAGE;
+ char mtd_dev[16];
+ struct mtd_device *dev;
+ struct part_info *part;
+ u8 pnum;
if (mtdparts_init() != 0) {
printf("Error initializing mtdparts!\n");
return 1;
}
+#ifdef CONFIG_CMD_UBIFS
+ /*
+ * Automatically unmount UBIFS partition when user
+ * changes the UBI device. Otherwise the following
+ * UBIFS commands will crash.
+ */
+ if (ubifs_is_mounted())
+ cmd_ubifs_umount();
+#endif
+
+ /* todo: get dev number for NAND... */
+ ubi_dev.nr = 0;
+
+ /*
+ * Call ubi_exit() before re-initializing the UBI subsystem
+ */
+ if (ubi_initialized) {
+ ubi_exit();
+ del_mtd_partitions(ubi_dev.mtd_info);
+ }
+
+ /*
+ * Search the mtd device number where this partition
+ * is located
+ */
+ if (find_dev_and_part(part_name, &dev, &pnum, &part)) {
+ printf("Partition %s not found!\n", part_name);
+ return 1;
+ }
+ sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(dev->id->type), dev->id->num);
+ ubi_dev.mtd_info = get_mtd_device_nm(mtd_dev);
+ if (IS_ERR(ubi_dev.mtd_info)) {
+ printf("Partition %s not found on device %s!\n", part_name,
+ mtd_dev);
+ return 1;
+ }
+
+ ubi_dev.selected = 1;
+
+ strcpy(ubi_dev.part_name, part_name);
+ err = ubi_dev_scan(ubi_dev.mtd_info, ubi_dev.part_name,
+ vid_header_offset);
+ if (err) {
+ printf("UBI init error %d\n", err);
+ ubi_dev.selected = 0;
+ return err;
+ }
+
+ ubi = ubi_devices[0];
+
+ return 0;
+}
+
+static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ size_t size = 0;
+ ulong addr = 0;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
if (strcmp(argv[1], "part") == 0) {
- char mtd_dev[16];
- struct mtd_device *dev;
- struct part_info *part;
const char *vid_header_offset = NULL;
- u8 pnum;
/* Print current partition */
if (argc == 2) {
@@ -467,58 +522,10 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
if (argc < 3)
return CMD_RET_USAGE;
-#ifdef CONFIG_CMD_UBIFS
- /*
- * Automatically unmount UBIFS partition when user
- * changes the UBI device. Otherwise the following
- * UBIFS commands will crash.
- */
- if (ubifs_is_mounted())
- cmd_ubifs_umount();
-#endif
-
- /* todo: get dev number for NAND... */
- ubi_dev.nr = 0;
-
- /*
- * Call ubi_exit() before re-initializing the UBI subsystem
- */
- if (ubi_initialized) {
- ubi_exit();
- del_mtd_partitions(ubi_dev.mtd_info);
- }
-
- /*
- * Search the mtd device number where this partition
- * is located
- */
- if (find_dev_and_part(argv[2], &dev, &pnum, &part)) {
- printf("Partition %s not found!\n", argv[2]);
- return 1;
- }
- sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(dev->id->type), dev->id->num);
- ubi_dev.mtd_info = get_mtd_device_nm(mtd_dev);
- if (IS_ERR(ubi_dev.mtd_info)) {
- printf("Partition %s not found on device %s!\n", argv[2], mtd_dev);
- return 1;
- }
-
- ubi_dev.selected = 1;
-
if (argc > 3)
vid_header_offset = argv[3];
- strcpy(ubi_dev.part_name, argv[2]);
- err = ubi_dev_scan(ubi_dev.mtd_info, ubi_dev.part_name,
- vid_header_offset);
- if (err) {
- printf("UBI init error %d\n", err);
- ubi_dev.selected = 0;
- return err;
- }
-
- ubi = ubi_devices[0];
- return 0;
+ return ubi_part(argv[2], vid_header_offset);
}
if ((strcmp(argv[1], "part") != 0) && (!ubi_dev.selected)) {
@@ -571,6 +578,8 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
}
if (strncmp(argv[1], "write", 5) == 0) {
+ int ret;
+
if (argc < 5) {
printf("Please see usage\n");
return 1;
@@ -579,7 +588,13 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
addr = simple_strtoul(argv[2], NULL, 16);
size = simple_strtoul(argv[4], NULL, 16);
- return ubi_volume_write(argv[3], (void *)addr, size);
+ ret = ubi_volume_write(argv[3], (void *)addr, size);
+ if (!ret) {
+ printf("%d bytes written to volume %s\n", size,
+ argv[3]);
+ }
+
+ return ret;
}
if (strncmp(argv[1], "read", 4) == 0) {
@@ -597,8 +612,12 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
argc--;
}
- if (argc == 3)
+ if (argc == 3) {
+ printf("Read %d bytes from volume %s to %lx\n", size,
+ argv[3], addr);
+
return ubi_volume_read(argv[3], (char *)addr, size);
+ }
}
printf("Please see usage\n");
diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c
new file mode 100644
index 0000000000..87a5f2f3ad
--- /dev/null
+++ b/common/cmd_usb_mass_storage.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics
+ * Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * 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 <errno.h>
+#include <common.h>
+#include <command.h>
+#include <g_dnl.h>
+#include <usb_mass_storage.h>
+
+int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ char *ep;
+ unsigned int dev_num = 0, offset = 0, part_size = 0;
+ int rc;
+
+ struct ums_board_info *ums_info;
+ static char *s = "ums";
+
+ if (argc < 2) {
+ printf("usage: ums <dev> - e.g. ums 0\n");
+ return 0;
+ }
+
+ dev_num = (int)simple_strtoul(argv[1], &ep, 16);
+
+ if (dev_num) {
+ puts("\nSet eMMC device to 0! - e.g. ums 0\n");
+ goto fail;
+ }
+
+ board_usb_init();
+ ums_info = board_ums_init(dev_num, offset, part_size);
+
+ if (!ums_info) {
+ printf("MMC: %d -> NOT available\n", dev_num);
+ goto fail;
+ }
+ rc = fsg_init(ums_info);
+ if (rc) {
+ printf("cmd ums: fsg_init failed\n");
+ goto fail;
+ }
+
+ g_dnl_register(s);
+
+ while (1) {
+ /* Handle control-c and timeouts */
+ if (ctrlc()) {
+ printf("The remote end did not respond in time.\n");
+ goto exit;
+ }
+ usb_gadget_handle_interrupts();
+ /* Check if USB cable has been detached */
+ if (fsg_main_thread(NULL) == EIO)
+ goto exit;
+ }
+exit:
+ g_dnl_unregister();
+ return 0;
+
+fail:
+ return -1;
+}
+
+U_BOOT_CMD(ums, CONFIG_SYS_MAXARGS, 1, do_usb_mass_storage,
+ "Use the UMS [User Mass Storage]",
+ "ums - User Mass Storage Gadget"
+);
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index 2a9d169f92..3c70d5dede 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -201,7 +201,7 @@
MORECORE_FAILURE (default: -1)
The value returned upon failure of MORECORE.
MORECORE_CLEARS (default 1)
- True (1) if the routine mapped to MORECORE zeroes out memory (which
+ true (1) if the routine mapped to MORECORE zeroes out memory (which
holds for sbrk).
DEFAULT_TRIM_THRESHOLD
DEFAULT_TOP_PAD
diff --git a/common/dlmalloc.src b/common/dlmalloc.src
index 32a38bc70c..d86acffdea 100644
--- a/common/dlmalloc.src
+++ b/common/dlmalloc.src
@@ -198,7 +198,7 @@
MORECORE_FAILURE (default: -1)
The value returned upon failure of MORECORE.
MORECORE_CLEARS (default 1)
- True (1) if the routine mapped to MORECORE zeroes out memory (which
+ true (1) if the routine mapped to MORECORE zeroes out memory (which
holds for sbrk).
DEFAULT_TRIM_THRESHOLD
DEFAULT_TOP_PAD
diff --git a/common/env_callback.c b/common/env_callback.c
index 78ca3674f0..78aafb4f2c 100644
--- a/common/env_callback.c
+++ b/common/env_callback.c
@@ -31,7 +31,7 @@ DECLARE_GLOBAL_DATA_PTR;
/*
* Look up a callback function pointer by name
*/
-struct env_clbk_tbl *find_env_callback(const char *name)
+static struct env_clbk_tbl *find_env_callback(const char *name)
{
struct env_clbk_tbl *clbkp;
int i;
diff --git a/common/env_nand.c b/common/env_nand.c
index 5b69889c02..b745822be7 100644
--- a/common/env_nand.c
+++ b/common/env_nand.c
@@ -281,7 +281,8 @@ int readenv(size_t offset, u_char *buf)
} else {
char_ptr = &buf[amount_loaded];
if (nand_read_skip_bad(&nand_info[0], offset,
- &len, char_ptr))
+ &len, NULL,
+ nand_info[0].size, char_ptr))
return 1;
offset += blocksize;
diff --git a/common/env_ubi.c b/common/env_ubi.c
new file mode 100644
index 0000000000..1ed8b02e86
--- /dev/null
+++ b/common/env_ubi.c
@@ -0,0 +1,220 @@
+/*
+ * (c) Copyright 2012 by National Instruments,
+ * Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * 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 <command.h>
+#include <environment.h>
+#include <errno.h>
+#include <malloc.h>
+#include <search.h>
+#include <ubi_uboot.h>
+#undef crc32
+
+char *env_name_spec = "UBI";
+
+env_t *env_ptr;
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int env_init(void)
+{
+ /* use default */
+ gd->env_addr = (ulong)&default_environment[0];
+ gd->env_valid = 1;
+
+ return 0;
+}
+
+#ifdef CONFIG_CMD_SAVEENV
+#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
+static unsigned char env_flags;
+
+int saveenv(void)
+{
+ ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
+ ssize_t len;
+ char *res;
+
+ res = (char *)&env_new->data;
+ len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
+ if (len < 0) {
+ error("Cannot export environment: errno = %d\n", errno);
+ return 1;
+ }
+
+ if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
+ printf("\n** Cannot find mtd partition \"%s\"\n",
+ CONFIG_ENV_UBI_PART);
+ return 1;
+ }
+
+ env_new->crc = crc32(0, env_new->data, ENV_SIZE);
+ env_new->flags = ++env_flags; /* increase the serial */
+
+ if (gd->env_valid == 1) {
+ puts("Writing to redundant UBI... ");
+ if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
+ (void *)env_new, CONFIG_ENV_SIZE)) {
+ printf("\n** Unable to write env to %s:%s **\n",
+ CONFIG_ENV_UBI_PART,
+ CONFIG_ENV_UBI_VOLUME_REDUND);
+ return 1;
+ }
+ } else {
+ puts("Writing to UBI... ");
+ if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
+ (void *)env_new, CONFIG_ENV_SIZE)) {
+ printf("\n** Unable to write env to %s:%s **\n",
+ CONFIG_ENV_UBI_PART,
+ CONFIG_ENV_UBI_VOLUME);
+ return 1;
+ }
+ }
+
+ puts("done\n");
+
+ gd->env_valid = gd->env_valid == 2 ? 1 : 2;
+
+ return 0;
+}
+#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
+int saveenv(void)
+{
+ ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
+ ssize_t len;
+ char *res;
+
+ res = (char *)&env_new->data;
+ len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
+ if (len < 0) {
+ error("Cannot export environment: errno = %d\n", errno);
+ return 1;
+ }
+
+ if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
+ printf("\n** Cannot find mtd partition \"%s\"\n",
+ CONFIG_ENV_UBI_PART);
+ return 1;
+ }
+
+ env_new->crc = crc32(0, env_new->data, ENV_SIZE);
+
+ if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
+ CONFIG_ENV_SIZE)) {
+ printf("\n** Unable to write env to %s:%s **\n",
+ CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
+ return 1;
+ }
+
+ puts("done\n");
+ return 0;
+}
+#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
+#endif /* CONFIG_CMD_SAVEENV */
+
+#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
+void env_relocate_spec(void)
+{
+ ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
+ ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
+ int crc1_ok = 0, crc2_ok = 0;
+ env_t *ep, *tmp_env1, *tmp_env2;
+
+ tmp_env1 = (env_t *)env1_buf;
+ tmp_env2 = (env_t *)env2_buf;
+
+ if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
+ printf("\n** Cannot find mtd partition \"%s\"\n",
+ CONFIG_ENV_UBI_PART);
+ set_default_env(NULL);
+ return;
+ }
+
+ if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
+ CONFIG_ENV_SIZE)) {
+ printf("\n** Unable to read env from %s:%s **\n",
+ CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
+ }
+
+ if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, (void *)tmp_env2,
+ CONFIG_ENV_SIZE)) {
+ printf("\n** Unable to read redundant env from %s:%s **\n",
+ CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
+ }
+
+ crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc;
+ crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc;
+
+ if (!crc1_ok && !crc2_ok) {
+ set_default_env("!bad CRC");
+ return;
+ } else if (crc1_ok && !crc2_ok) {
+ gd->env_valid = 1;
+ } else if (!crc1_ok && crc2_ok) {
+ gd->env_valid = 2;
+ } else {
+ /* both ok - check serial */
+ if (tmp_env1->flags == 255 && tmp_env2->flags == 0)
+ gd->env_valid = 2;
+ else if (tmp_env2->flags == 255 && tmp_env1->flags == 0)
+ gd->env_valid = 1;
+ else if (tmp_env1->flags > tmp_env2->flags)
+ gd->env_valid = 1;
+ else if (tmp_env2->flags > tmp_env1->flags)
+ gd->env_valid = 2;
+ else /* flags are equal - almost impossible */
+ gd->env_valid = 1;
+ }
+
+ if (gd->env_valid == 1)
+ ep = tmp_env1;
+ else
+ ep = tmp_env2;
+
+ env_flags = ep->flags;
+ env_import((char *)ep, 0);
+}
+#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
+void env_relocate_spec(void)
+{
+ ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
+
+ if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
+ printf("\n** Cannot find mtd partition \"%s\"\n",
+ CONFIG_ENV_UBI_PART);
+ set_default_env(NULL);
+ return;
+ }
+
+ if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)&buf,
+ CONFIG_ENV_SIZE)) {
+ printf("\n** Unable to read env from %s:%s **\n",
+ CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
+ set_default_env(NULL);
+ return;
+ }
+
+ env_import(buf, 1);
+}
+#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
diff --git a/common/hash.c b/common/hash.c
index f5badcb930..c9ac33e2c4 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -25,6 +25,7 @@
#include <common.h>
#include <command.h>
+#include <hw_sha.h>
#include <hash.h>
#include <sha1.h>
#include <sha256.h>
@@ -37,6 +38,23 @@
*/
static struct hash_algo hash_algo[] = {
/*
+ * CONFIG_SHA_HW_ACCEL is defined if hardware acceleration is
+ * available.
+ */
+#ifdef CONFIG_SHA_HW_ACCEL
+ {
+ "sha1",
+ SHA1_SUM_LEN,
+ hw_sha1,
+ CHUNKSZ_SHA1,
+ }, {
+ "sha256",
+ SHA256_SUM_LEN,
+ hw_sha256,
+ CHUNKSZ_SHA256,
+ },
+#endif
+ /*
* This is CONFIG_CMD_SHA1SUM instead of CONFIG_SHA1 since otherwise
* it bloats the code for boards which use SHA1 but not the 'hash'
* or 'sha1sum' commands.
diff --git a/common/image.c b/common/image.c
index 6afbb40a98..60c2127039 100644
--- a/common/image.c
+++ b/common/image.c
@@ -108,6 +108,7 @@ static const table_entry_t uimage_os[] = {
#endif
{ IH_OS_NETBSD, "netbsd", "NetBSD", },
{ IH_OS_OSE, "ose", "Enea OSE", },
+ { IH_OS_PLAN9, "plan9", "Plan 9", },
{ IH_OS_RTEMS, "rtems", "RTEMS", },
{ IH_OS_U_BOOT, "u-boot", "U-Boot", },
#if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
diff --git a/common/lcd.c b/common/lcd.c
index 590bbb9301..edae835fb0 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -83,9 +83,35 @@
#define CONFIG_CONSOLE_SCROLL_LINES 1
#endif
-DECLARE_GLOBAL_DATA_PTR;
+/************************************************************************/
+/* ** CONSOLE DEFINITIONS & FUNCTIONS */
+/************************************************************************/
+#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
+# define CONSOLE_ROWS ((panel_info.vl_row-BMP_LOGO_HEIGHT) \
+ / VIDEO_FONT_HEIGHT)
+#else
+# define CONSOLE_ROWS (panel_info.vl_row / VIDEO_FONT_HEIGHT)
+#endif
+
+#define CONSOLE_COLS (panel_info.vl_col / VIDEO_FONT_WIDTH)
+#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length)
+#define CONSOLE_ROW_FIRST lcd_console_address
+#define CONSOLE_ROW_SECOND (lcd_console_address + CONSOLE_ROW_SIZE)
+#define CONSOLE_ROW_LAST (lcd_console_address + CONSOLE_SIZE \
+ - CONSOLE_ROW_SIZE)
+#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
+#define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
+
+#if LCD_BPP == LCD_MONOCHROME
+# define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \
+ (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)
+#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16)
+# define COLOR_MASK(c) (c)
+#else
+# error Unsupported LCD BPP.
+#endif
-ulong lcd_setmem (ulong addr);
+DECLARE_GLOBAL_DATA_PTR;
static void lcd_drawchars(ushort x, ushort y, uchar *str, int count);
static inline void lcd_puts_xy(ushort x, ushort y, uchar *s);
@@ -93,22 +119,25 @@ static inline void lcd_putc_xy(ushort x, ushort y, uchar c);
static int lcd_init(void *lcdbase);
-static void *lcd_logo (void);
+static void *lcd_logo(void);
static int lcd_getbgcolor(void);
static void lcd_setfgcolor(int color);
static void lcd_setbgcolor(int color);
+static int lcd_color_fg;
+static int lcd_color_bg;
+int lcd_line_length;
+
char lcd_is_enabled = 0;
-static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */
+static short console_col;
+static short console_row;
+static void *lcd_console_address;
+static void *lcd_base; /* Start of framebuffer memory */
-#ifdef NOT_USED_SO_FAR
-static void lcd_getcolreg(ushort regno,
- ushort *red, ushort *green, ushort *blue);
-static int lcd_getfgcolor(void);
-#endif /* NOT_USED_SO_FAR */
+static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */
/************************************************************************/
@@ -148,7 +177,7 @@ static void console_scrollup(void)
/* Clear the last rows */
memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
COLOR_MASK(lcd_color_bg),
- CONSOLE_ROW_SIZE * rows);
+ CONSOLE_ROW_SIZE * rows);
lcd_sync();
console_row -= rows;
@@ -160,9 +189,8 @@ static inline void console_back(void)
{
if (--console_col < 0) {
console_col = CONSOLE_COLS-1 ;
- if (--console_row < 0) {
+ if (--console_row < 0)
console_row = 0;
- }
}
lcd_putc_xy(console_col * VIDEO_FONT_WIDTH,
@@ -173,16 +201,13 @@ static inline void console_back(void)
static inline void console_newline(void)
{
- ++console_row;
console_col = 0;
/* Check if we need to scroll the terminal */
- if (console_row >= CONSOLE_ROWS) {
- /* Scroll everything up */
+ if (++console_row >= CONSOLE_ROWS)
console_scrollup();
- } else {
+ else
lcd_sync();
- }
}
/*----------------------------------------------------------------------*/
@@ -234,9 +259,9 @@ void lcd_puts(const char *s)
return;
}
- while (*s) {
+ while (*s)
lcd_putc(*s++);
- }
+
lcd_sync();
}
@@ -283,7 +308,7 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
#endif
#if LCD_BPP == LCD_MONOCHROME
- uchar rest = *d & -(1 << (8-off));
+ uchar rest = *d & -(1 << (8 - off));
uchar sym;
#endif
for (i = 0; i < count; ++i) {
@@ -313,7 +338,7 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
#endif
}
#if LCD_BPP == LCD_MONOCHROME
- *d = rest | (*d & ((1 << (8-off)) - 1));
+ *d = rest | (*d & ((1 << (8 - off)) - 1));
#endif
}
}
@@ -340,7 +365,7 @@ static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
#define N_BLK_VERT 2
#define N_BLK_HOR 3
-static int test_colors[N_BLK_HOR*N_BLK_VERT] = {
+static int test_colors[N_BLK_HOR * N_BLK_VERT] = {
CONSOLE_COLOR_RED, CONSOLE_COLOR_GREEN, CONSOLE_COLOR_YELLOW,
CONSOLE_COLOR_BLUE, CONSOLE_COLOR_MAGENTA, CONSOLE_COLOR_CYAN,
};
@@ -361,7 +386,7 @@ static void test_pattern(void)
for (v = 0; v < v_max; ++v) {
uchar iy = v / v_step;
for (h = 0; h < h_max; ++h) {
- uchar ix = N_BLK_HOR * iy + (h/h_step);
+ uchar ix = N_BLK_HOR * iy + h / h_step;
*pix++ = test_colors[ix];
}
}
@@ -379,14 +404,12 @@ int lcd_get_size(int *line_length)
return *line_length * panel_info.vl_row;
}
-int drv_lcd_init (void)
+int drv_lcd_init(void)
{
struct stdio_dev lcddev;
int rc;
- lcd_base = (void *)(gd->fb_base);
-
- lcd_get_size(&lcd_line_length);
+ lcd_base = (void *) gd->fb_base;
lcd_init(lcd_base); /* LCD initialization */
@@ -399,7 +422,7 @@ int drv_lcd_init (void)
lcddev.putc = lcd_putc; /* 'putc' function */
lcddev.puts = lcd_puts; /* 'puts' function */
- rc = stdio_register (&lcddev);
+ rc = stdio_register(&lcddev);
return (rc == 0) ? 1 : rc;
}
@@ -438,11 +461,11 @@ void lcd_clear(void)
/* set framebuffer to background color */
memset((char *)lcd_base,
COLOR_MASK(lcd_getbgcolor()),
- lcd_line_length*panel_info.vl_row);
+ lcd_line_length * panel_info.vl_row);
#endif
/* Paint the logo and retrieve LCD base address */
debug("[LCD] Drawing the logo...\n");
- lcd_console_address = lcd_logo ();
+ lcd_console_address = lcd_logo();
console_col = 0;
console_row = 0;
@@ -470,9 +493,23 @@ static int lcd_init(void *lcdbase)
debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
lcd_ctrl_init(lcdbase);
+
+ /*
+ * lcd_ctrl_init() of some drivers (i.e. bcm2835 on rpi_b) ignores
+ * the 'lcdbase' argument and uses custom lcd base address
+ * by setting up gd->fb_base. Check for this condition and fixup
+ * 'lcd_base' address.
+ */
+ if ((unsigned long)lcdbase != gd->fb_base)
+ lcd_base = (void *)gd->fb_base;
+
+ debug("[LCD] Using LCD frambuffer at %p\n", lcd_base);
+
+ lcd_get_size(&lcd_line_length);
+ lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
lcd_is_enabled = 1;
lcd_clear();
- lcd_enable ();
+ lcd_enable();
/* Initialize the console */
console_col = 0;
@@ -513,7 +550,8 @@ ulong lcd_setmem(ulong addr)
/* Allocate pages for the frame buffer. */
addr -= size;
- debug("Reserving %ldk for LCD Framebuffer at: %08lx\n", size>>10, addr);
+ debug("Reserving %ldk for LCD Framebuffer at: %08lx\n",
+ size >> 10, addr);
return addr;
}
@@ -534,12 +572,10 @@ static void lcd_setbgcolor(int color)
/*----------------------------------------------------------------------*/
-#ifdef NOT_USED_SO_FAR
-static int lcd_getfgcolor(void)
+int lcd_getfgcolor(void)
{
return lcd_color_fg;
}
-#endif /* NOT_USED_SO_FAR */
/*----------------------------------------------------------------------*/
@@ -548,8 +584,6 @@ static int lcd_getbgcolor(void)
return lcd_color_bg;
}
-/*----------------------------------------------------------------------*/
-
/************************************************************************/
/* ** Chipset depending Bitmap / Logo stuff... */
/************************************************************************/
@@ -566,13 +600,11 @@ static inline ushort *configuration_get_cmap(void)
return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0));
#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB)
return panel_info.cmap;
-#else
-#if defined(CONFIG_LCD_LOGO)
+#elif defined(CONFIG_LCD_LOGO)
return bmp_logo_palette;
#else
return NULL;
#endif
-#endif
}
#ifdef CONFIG_LCD_LOGO
@@ -591,15 +623,16 @@ void bitmap_plot(int x, int y)
immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
cpm8xx_t *cp = &(immr->im_cpm);
#endif
+ unsigned bpix = NBITS(panel_info.vl_bpix);
debug("Logo: width %d height %d colors %d cmap %d\n",
BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS,
ARRAY_SIZE(bmp_logo_palette));
bmap = &bmp_logo_bitmap[0];
- fb = (uchar *)(lcd_base + y * lcd_line_length + x);
+ fb = (uchar *)(lcd_base + y * lcd_line_length + x * bpix / 8);
- if (NBITS(panel_info.vl_bpix) < 12) {
+ if (bpix < 12) {
/* Leave room for default color map
* default case: generic system with no cmap (most likely 16bpp)
* cmap was set to the source palette, so no change is done.
@@ -645,12 +678,12 @@ void bitmap_plot(int x, int y)
for (i = 0; i < BMP_LOGO_HEIGHT; ++i) {
memcpy(fb, bmap, BMP_LOGO_WIDTH);
bmap += BMP_LOGO_WIDTH;
- fb += panel_info.vl_col;
+ fb += panel_info.vl_col;
}
}
else { /* true color mode */
u16 col16;
- fb16 = (ushort *)(lcd_base + y * lcd_line_length + x);
+ fb16 = (ushort *)fb;
for (i = 0; i < BMP_LOGO_HEIGHT; ++i) {
for (j = 0; j < BMP_LOGO_WIDTH; j++) {
col16 = bmp_logo_palette[(bmap[j]-16)];
@@ -736,12 +769,11 @@ static void draw_encoded_bitmap(ushort **fbp, ushort c, int cnt)
*fb++ = c;
cnt--;
}
- (*fbp) = fb;
+ *fbp = fb;
}
/*
- * Do not call this function directly, must be called from
- * lcd_display_bitmap.
+ * Do not call this function directly, must be called from lcd_display_bitmap.
*/
static void lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb,
int x_off, int y_off)
@@ -868,8 +900,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
unsigned long pwidth = panel_info.vl_col;
unsigned colors, bpix, bmp_bpix;
- if (!bmp || !((bmp->header.signature[0] == 'B') &&
- (bmp->header.signature[1] == 'M'))) {
+ if (!bmp || !(bmp->header.signature[0] == 'B' &&
+ bmp->header.signature[1] == 'M')) {
printf("Error: no valid bmp image at %lx\n", bmp_image);
return 1;
@@ -882,7 +914,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
bpix = NBITS(panel_info.vl_bpix);
- if ((bpix != 1) && (bpix != 8) && (bpix != 16) && (bpix != 32)) {
+ if (bpix != 1 && bpix != 8 && bpix != 16 && bpix != 32) {
printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
bpix, bmp_bpix);
@@ -950,7 +982,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
}
#endif
- padded_width = (width&0x3) ? ((width&~0x3)+4) : (width);
+ padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width);
#ifdef CONFIG_SPLASH_SCREEN_ALIGN
splash_align_axis(&x, pwidth, width);
@@ -962,7 +994,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
if ((y + height) > panel_info.vl_row)
height = panel_info.vl_row - y;
- bmap = (uchar *)bmp + le32_to_cpu(bmp->header.data_offset);
+ bmap = (uchar *) bmp + le32_to_cpu(bmp->header.data_offset);
fb = (uchar *) (lcd_base +
(y + height - 1) * lcd_line_length + x * bpix / 8);
@@ -997,7 +1029,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
}
}
bmap += (padded_width - width);
- fb -= (byte_width + lcd_line_length);
+ fb -= byte_width + lcd_line_length;
}
break;
@@ -1009,7 +1041,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
fb_put_word(&fb, &bmap);
bmap += (padded_width - width) * 2;
- fb -= (width * 2 + lcd_line_length);
+ fb -= width * 2 + lcd_line_length;
}
break;
#endif /* CONFIG_BMP_16BPP */
@@ -1023,7 +1055,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
*(fb++) = *(bmap++);
*(fb++) = *(bmap++);
}
- fb -= (lcd_line_length + width * (bpix / 8));
+ fb -= lcd_line_length + width * (bpix / 8);
}
break;
#endif /* CONFIG_BMP_32BPP */
@@ -1098,7 +1130,7 @@ static void *lcd_logo(void)
return (void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length);
#else
return (void *)lcd_base;
-#endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */
+#endif /* CONFIG_LCD_LOGO && !defined(CONFIG_LCD_INFO_BELOW_LOGO) */
}
#ifdef CONFIG_SPLASHIMAGE_GUARD
@@ -1150,6 +1182,3 @@ int lcd_get_screen_columns(void)
{
return CONSOLE_COLS;
}
-
-/************************************************************************/
-/************************************************************************/
diff --git a/common/main.c b/common/main.c
index e2d2e09bf9..a15f020830 100644
--- a/common/main.c
+++ b/common/main.c
@@ -95,7 +95,7 @@ extern void mdm_init(void); /* defined in board.c */
* Watch for 'delay' seconds for autoboot stop or autoboot delay string.
* returns: 0 - no key string, allow autoboot 1 - got key string, abort
*/
-#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+#if defined(CONFIG_BOOTDELAY)
# if defined(CONFIG_AUTOBOOT_KEYED)
#ifndef CONFIG_MENU
static inline
@@ -279,7 +279,7 @@ int abortboot(int bootdelay)
return abort;
}
# endif /* CONFIG_AUTOBOOT_KEYED */
-#endif /* CONFIG_BOOTDELAY >= 0 */
+#endif /* CONFIG_BOOTDELAY */
/*
* Runs the given boot command securely. Specifically:
@@ -295,8 +295,7 @@ int abortboot(int bootdelay)
* printing the error message to console.
*/
-#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) && \
- defined(CONFIG_OF_CONTROL)
+#if defined(CONFIG_BOOTDELAY) && defined(CONFIG_OF_CONTROL)
static void secure_boot_cmd(char *cmd)
{
cmd_tbl_t *cmdtp;
@@ -358,11 +357,10 @@ void main_loop (void)
int rc = 1;
int flag;
#endif
-#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) && \
- defined(CONFIG_OF_CONTROL)
+#if defined(CONFIG_BOOTDELAY) && defined(CONFIG_OF_CONTROL)
char *env;
#endif
-#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+#if defined(CONFIG_BOOTDELAY)
char *s;
int bootdelay;
#endif
@@ -378,6 +376,10 @@ void main_loop (void)
bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
+#if defined CONFIG_OF_CONTROL
+ set_working_fdt_addr((void *)gd->fdt_blob);
+#endif /* CONFIG_OF_CONTROL */
+
#ifdef CONFIG_BOOTCOUNT_LIMIT
bootcount = bootcount_load();
bootcount++;
@@ -431,7 +433,7 @@ void main_loop (void)
update_tftp (0UL);
#endif /* CONFIG_UPDATE_TFTP */
-#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+#if defined(CONFIG_BOOTDELAY)
s = getenv ("bootdelay");
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
@@ -500,10 +502,6 @@ void main_loop (void)
#endif /* CONFIG_MENUKEY */
#endif /* CONFIG_BOOTDELAY */
-#if defined CONFIG_OF_CONTROL
- set_working_fdt_addr((void *)gd->fdt_blob);
-#endif /* CONFIG_OF_CONTROL */
-
/*
* Main Loop for Monitor Command Processing
*/
diff --git a/common/menu.c b/common/menu.c
index 6b2a2db3e0..64b461abb4 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -47,6 +47,8 @@ struct menu {
char *title;
int prompt;
void (*item_data_print)(void *);
+ char *(*item_choice)(void *);
+ void *item_choice_data;
struct list_head items;
};
@@ -174,7 +176,7 @@ static inline struct menu_item *menu_item_by_key(struct menu *m,
* Set *choice to point to the default item's data, if any default item was
* set, and returns 1. If no default item was set, returns -ENOENT.
*/
-static inline int menu_default_choice(struct menu *m, void **choice)
+int menu_default_choice(struct menu *m, void **choice)
{
if (m->default_item) {
*choice = m->default_item->data;
@@ -204,18 +206,26 @@ static inline int menu_interactive_choice(struct menu *m, void **choice)
menu_display(m);
- readret = readline_into_buffer("Enter choice: ", cbuf,
- m->timeout / 10);
+ if (!m->item_choice) {
+ readret = readline_into_buffer("Enter choice: ", cbuf,
+ m->timeout / 10);
- if (readret >= 0) {
- choice_item = menu_item_by_key(m, cbuf);
-
- if (!choice_item) {
- printf("%s not found\n", cbuf);
- m->timeout = 0;
+ if (readret >= 0) {
+ choice_item = menu_item_by_key(m, cbuf);
+ if (!choice_item)
+ printf("%s not found\n", cbuf);
+ } else {
+ return menu_default_choice(m, choice);
}
- } else
- return menu_default_choice(m, choice);
+ } else {
+ char *key = m->item_choice(m->item_choice_data);
+
+ if (key)
+ choice_item = menu_item_by_key(m, key);
+ }
+
+ if (!choice_item)
+ m->timeout = 0;
}
*choice = choice_item->data;
@@ -348,11 +358,19 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data)
* what must be entered to select an item, the item_data_print function should
* make it obvious what the key for each entry is.
*
+ * item_choice - If not NULL, will be called when asking the user to choose an
+ * item. Returns a key string corresponding to the choosen item or NULL if
+ * no item has been selected.
+ *
+ * item_choice_data - Will be passed as the argument to the item_choice function
+ *
* Returns a pointer to the menu if successful, or NULL if there is
* insufficient memory available to create the menu.
*/
struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *))
+ void (*item_data_print)(void *),
+ char *(*item_choice)(void *),
+ void *item_choice_data)
{
struct menu *m;
@@ -365,6 +383,8 @@ struct menu *menu_create(char *title, int timeout, int prompt,
m->prompt = prompt;
m->timeout = timeout;
m->item_data_print = item_data_print;
+ m->item_choice = item_choice;
+ m->item_choice_data = item_choice_data;
if (title) {
m->title = strdup(title);