diff options
Diffstat (limited to 'common')
45 files changed, 3097 insertions, 673 deletions
diff --git a/common/Makefile b/common/Makefile index 54fcc81..1abf4ea 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 @@ -152,6 +156,7 @@ COBJS-$(CONFIG_CMD_PXE) += cmd_pxe.o COBJS-$(CONFIG_CMD_READ) += cmd_read.o COBJS-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o COBJS-$(CONFIG_CMD_REISER) += cmd_reiser.o +COBJS-$(CONFIG_SANDBOX) += cmd_sandbox.o COBJS-$(CONFIG_CMD_SATA) += cmd_sata.o COBJS-$(CONFIG_CMD_SF) += cmd_sf.o COBJS-$(CONFIG_CMD_SCSI) += cmd_scsi.o @@ -174,6 +179,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/board_f.c b/common/board_f.c new file mode 100644 index 0000000..29b49c3 --- /dev/null +++ b/common/board_f.c @@ -0,0 +1,1015 @@ +/* + * 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 +#if defined(CONFIG_BOARD_EARLY_INIT_F) + board_early_init_f, +#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 0000000..9605f80 --- /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_bootm.c b/common/cmd_bootm.c index f0338ba..5d2ce00 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -79,10 +79,16 @@ static int image_info(unsigned long addr); #include <flash.h> #include <mtd/cfi_flash.h> extern flash_info_t flash_info[]; /* info for FLASH chips */ +#endif + +#if defined(CONFIG_CMD_IMLS) || defined(CONFIG_CMD_IMLS_NAND) static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); #endif -#ifdef CONFIG_SILENT_CONSOLE +#include <linux/err.h> +#include <nand.h> + +#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) static void fixup_silent_linux(void); #endif @@ -446,9 +452,7 @@ static int bootm_start_standalone(ulong iflag, int argc, char * const argv[]) /* Don't start if "autostart" is set to "no" */ if (((s = getenv("autostart")) != NULL) && (strcmp(s, "no") == 0)) { - char buf[32]; - sprintf(buf, "%lX", images.os.image_len); - setenv("filesize", buf); + setenv_hex("filesize", images.os.image_len); return 0; } appl = (int (*)(int, char * const []))(ulong)ntohl(images.ep); @@ -523,17 +527,14 @@ static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc, case BOOTM_STATE_RAMDISK: { ulong rd_len = images.rd_end - images.rd_start; - char str[17]; ret = boot_ramdisk_high(&images.lmb, images.rd_start, rd_len, &images.initrd_start, &images.initrd_end); if (ret) return ret; - sprintf(str, "%lx", images.initrd_start); - setenv("initrd_start", str); - sprintf(str, "%lx", images.initrd_end); - setenv("initrd_end", str); + setenv_hex("initrd_start", images.initrd_start); + setenv_hex("initrd_end", images.initrd_end); } break; #endif @@ -693,7 +694,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 @@ -1055,7 +1056,7 @@ static char bootm_help_text[] = "issued in the order below (it's ok to not issue all sub-commands):\n" "\tstart [addr [arg ...]]\n" "\tloados - load OS image\n" -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#if defined(CONFIG_SYS_BOOT_RAMDISK_HIGH) "\tramdisk - relocate initrd, set env initrd_start/initrd_end\n" #endif #if defined(CONFIG_OF_LIBFDT) @@ -1192,7 +1193,7 @@ U_BOOT_CMD( /* imls - list all images found in flash */ /*******************************************************************/ #if defined(CONFIG_CMD_IMLS) -static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_imls_nor(void) { flash_info_t *info; int i, j; @@ -1241,6 +1242,161 @@ next_sector: ; } next_bank: ; } + return 0; +} +#endif + +#if defined(CONFIG_CMD_IMLS_NAND) +static int nand_imls_legacyimage(nand_info_t *nand, int nand_dev, loff_t off, + size_t len) +{ + void *imgdata; + int ret; + + imgdata = malloc(len); + if (!imgdata) { + printf("May be a Legacy Image at NAND device %d offset %08llX:\n", + nand_dev, off); + printf(" Low memory(cannot allocate memory for image)\n"); + return -ENOMEM; + } + + ret = nand_read_skip_bad(nand, off, &len, + imgdata); + if (ret < 0 && ret != -EUCLEAN) { + free(imgdata); + return ret; + } + + if (!image_check_hcrc(imgdata)) { + free(imgdata); + return 0; + } + + printf("Legacy Image at NAND device %d offset %08llX:\n", + nand_dev, off); + image_print_contents(imgdata); + + puts(" Verifying Checksum ... "); + if (!image_check_dcrc(imgdata)) + puts("Bad Data CRC\n"); + else + puts("OK\n"); + + free(imgdata); + + return 0; +} + +static int nand_imls_fitimage(nand_info_t *nand, int nand_dev, loff_t off, + size_t len) +{ + void *imgdata; + int ret; + + imgdata = malloc(len); + if (!imgdata) { + printf("May be a FIT Image at NAND device %d offset %08llX:\n", + nand_dev, off); + printf(" Low memory(cannot allocate memory for image)\n"); + return -ENOMEM; + } + + ret = nand_read_skip_bad(nand, off, &len, + imgdata); + if (ret < 0 && ret != -EUCLEAN) { + free(imgdata); + return ret; + } + + if (!fit_check_format(imgdata)) { + free(imgdata); + return 0; + } + + printf("FIT Image at NAND device %d offset %08llX:\n", nand_dev, off); + + fit_print_contents(imgdata); + free(imgdata); + + return 0; +} + +static int do_imls_nand(void) +{ + nand_info_t *nand; + int nand_dev = nand_curr_device; + size_t len; + loff_t off; + u32 buffer[16]; + + if (nand_dev < 0 || nand_dev >= CONFIG_SYS_MAX_NAND_DEVICE) { + puts("\nNo NAND devices available\n"); + return -ENODEV; + } + + printf("\n"); + + for (nand_dev = 0; nand_dev < CONFIG_SYS_MAX_NAND_DEVICE; nand_dev++) { + nand = &nand_info[nand_dev]; + if (!nand->name || !nand->size) + continue; + + for (off = 0; off < nand->size; off += nand->erasesize) { + const image_header_t *header; + int ret; + + if (nand_block_isbad(nand, off)) + continue; + + len = sizeof(buffer); + + ret = nand_read(nand, off, &len, (u8 *)buffer); + if (ret < 0 && ret != -EUCLEAN) { + printf("NAND read error %d at offset %08llX\n", + ret, off); + continue; + } + + switch (genimg_get_format(buffer)) { + case IMAGE_FORMAT_LEGACY: + header = (const image_header_t *)buffer; + + len = image_get_image_size(header); + nand_imls_legacyimage(nand, nand_dev, off, len); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + len = fit_get_size(buffer); + nand_imls_fitimage(nand, nand_dev, off, len); + break; +#endif + } + } + } + + return 0; +} +#endif + +#if defined(CONFIG_CMD_IMLS) || defined(CONFIG_CMD_IMLS_NAND) +static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int ret_nor = 0, ret_nand = 0; + +#if defined(CONFIG_CMD_IMLS) + ret_nor = do_imls_nor(); +#endif + +#if defined(CONFIG_CMD_IMLS_NAND) + ret_nand = do_imls_nand(); +#endif + + if (ret_nor) + return ret_nor; + + if (ret_nand) + return ret_nand; return (0); } @@ -1249,15 +1405,15 @@ U_BOOT_CMD( imls, 1, 1, do_imls, "list all images found in flash", "\n" - " - Prints information about all images found at sector\n" - " boundaries in flash." + " - Prints information about all images found at sector/block\n" + " boundaries in nor/nand flash." ); #endif /*******************************************************************/ /* 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; @@ -1650,7 +1806,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_cbfs.c b/common/cmd_cbfs.c index 3b6cfd8..f51534b 100644 --- a/common/cmd_cbfs.c +++ b/common/cmd_cbfs.c @@ -65,7 +65,6 @@ int do_cbfs_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) const struct cbfs_cachenode *file; unsigned long offset; unsigned long count; - char buf[12]; long size; if (argc < 3) { @@ -95,8 +94,7 @@ int do_cbfs_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) printf("\n%ld bytes read\n", size); - sprintf(buf, "%lX", size); - setenv("filesize", buf); + setenv_hex("filesize", size); return 0; } diff --git a/common/cmd_cramfs.c b/common/cmd_cramfs.c index e7f496e..0e43ab6 100644 --- a/common/cmd_cramfs.c +++ b/common/cmd_cramfs.c @@ -146,11 +146,9 @@ int do_cramfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) size = cramfs_load ((char *) offset, &part, filename); if (size > 0) { - char buf[10]; printf("### CRAMFS load complete: %d bytes loaded to 0x%lx\n", size, offset); - sprintf(buf, "%x", size); - setenv("filesize", buf); + setenv_hex("filesize", size); } else { printf("### CRAMFS LOAD ERROR<%x> for %s!\n", size, filename); } diff --git a/common/cmd_df.c b/common/cmd_df.c deleted file mode 100644 index f7e5df3..0000000 --- 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 01d6b3a..83ef324 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_elf.c b/common/cmd_elf.c index a667a46..ab9c7e3 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -198,7 +198,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * defaults to 0x4200 */ tmp = getenv("bootaddr"); - if (tmp) + if (!tmp) bootaddr = CONFIG_SYS_VXWORKS_BOOT_ADDR; else bootaddr = simple_strtoul(tmp, NULL, 16); diff --git a/common/cmd_fat.c b/common/cmd_fat.c index 86be044..0487438 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_fdos.c b/common/cmd_fdos.c index fbee861..8ea1140 100644 --- a/common/cmd_fdos.c +++ b/common/cmd_fdos.c @@ -40,7 +40,6 @@ int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char *name; char *ep; int size; - char buf [12]; int drive = CONFIG_SYS_FDC_DRIVE_NUMBER; /* pre-set load_addr */ @@ -91,8 +90,7 @@ int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } flush_cache (load_addr, size); - sprintf(buf, "%x", size); - setenv("filesize", buf); + setenv_hex("filesize", size); printf("Floppy DOS load complete: %d bytes loaded to 0x%lx\n", size, load_addr); diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 6eec947..ac77a08 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -55,12 +55,8 @@ struct fdt_header *working_fdt; void set_working_fdt_addr(void *addr) { - char buf[17]; - working_fdt = addr; - - sprintf(buf, "%lx", (unsigned long)addr); - setenv("fdtaddr", buf); + setenv_addr("fdtaddr", addr); } /* @@ -347,10 +343,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } if (subcmd[0] == 's') { /* get the num nodes at this level */ - char buf[11]; - - sprintf(buf, "%d", curIndex + 1); - setenv(var, buf); + setenv_ulong(var, curIndex + 1); } else { /* node index not found */ printf("libfdt node not found\n"); diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c index da7705d..efd7934 100644 --- a/common/cmd_gpt.c +++ b/common/cmd_gpt.c @@ -27,6 +27,7 @@ #include <part_efi.h> #include <exports.h> #include <linux/ctype.h> +#include <div64.h> #ifndef CONFIG_PARTITION_UUIDS #error CONFIG_PARTITION_UUIDS must be enabled for CONFIG_CMD_GPT to be enabled @@ -131,6 +132,7 @@ static int set_gpt_info(block_dev_desc_t *dev_desc, int p_count; disk_partition_t *parts; int errno = 0; + uint64_t size_ll, start_ll; debug("%s: MMC lba num: 0x%x %d\n", __func__, (unsigned int)dev_desc->lba, (unsigned int)dev_desc->lba); @@ -217,8 +219,8 @@ static int set_gpt_info(block_dev_desc_t *dev_desc, } if (extract_env(val, &p)) p = val; - parts[i].size = ustrtoul(p, &p, 0); - parts[i].size /= dev_desc->blksz; + size_ll = ustrtoull(p, &p, 0); + parts[i].size = lldiv(size_ll, dev_desc->blksz); free(val); /* start address */ @@ -226,8 +228,8 @@ static int set_gpt_info(block_dev_desc_t *dev_desc, if (val) { /* start address is optional */ if (extract_env(val, &p)) p = val; - parts[i].start = ustrtoul(p, &p, 0); - parts[i].start /= dev_desc->blksz; + start_ll = ustrtoull(p, &p, 0); + parts[i].start = lldiv(start_ll, dev_desc->blksz); free(val); } } diff --git a/common/cmd_hash.c b/common/cmd_hash.c index 689c608..4fe0e78 100644 --- a/common/cmd_hash.c +++ b/common/cmd_hash.c @@ -26,22 +26,30 @@ #include <common.h> #include <command.h> #include <hash.h> +#include <linux/ctype.h> static int do_hash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + char *s; #ifdef CONFIG_HASH_VERIFY - int verify = 0; + int flags = HASH_FLAG_ENV; + if (argc < 4) + return CMD_RET_USAGE; if (!strcmp(argv[1], "-v")) { - verify = 1; + flags |= HASH_FLAG_VERIFY; argc--; argv++; } +#else + const int flags = HASH_FLAG_ENV; #endif /* Move forward to 'algorithm' parameter */ argc--; argv++; - return hash_command(*argv, verify, cmdtp, flag, argc - 1, argv + 1); + for (s = *argv; *s; s++) + *s = tolower(*s); + return hash_command(*argv, flags, cmdtp, flag, argc - 1, argv + 1); } #ifdef CONFIG_HASH_VERIFY diff --git a/common/cmd_help.c b/common/cmd_help.c index f832a96..d9bdc4d 100644 --- a/common/cmd_help.c +++ b/common/cmd_help.c @@ -41,7 +41,7 @@ U_BOOT_CMD( ); /* This does not use the U_BOOT_CMD macro as ? can't be used in symbol names */ -ll_entry_declare(cmd_tbl_t, question_mark, cmd, cmd) = { +ll_entry_declare(cmd_tbl_t, question_mark, cmd) = { "?", CONFIG_SYS_MAXARGS, 1, do_help, "alias for 'help'", #ifdef CONFIG_SYS_LONGHELP diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index 27296dd..4a4a000 100644 --- a/common/cmd_jffs2.c +++ b/common/cmd_jffs2.c @@ -525,11 +525,9 @@ int do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } if (size > 0) { - char buf[10]; printf("### %s load complete: %d bytes loaded to 0x%lx\n", fsname, size, offset); - sprintf(buf, "%x", size); - setenv("filesize", buf); + setenv_hex("filesize", size); } else { printf("### %s LOAD ERROR<%x> for %s!\n", fsname, size, filename); } diff --git a/common/cmd_led.c b/common/cmd_led.c index 7f5ab43..84f79fa 100644 --- a/common/cmd_led.c +++ b/common/cmd_led.c @@ -110,13 +110,15 @@ int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (led_commands[i].on) led_commands[i].on(); else - __led_set(led_commands[i].mask, 1); + __led_set(led_commands[i].mask, + STATUS_LED_ON); break; case LED_OFF: if (led_commands[i].off) led_commands[i].off(); else - __led_set(led_commands[i].mask, 0); + __led_set(led_commands[i].mask, + STATUS_LED_OFF); break; case LED_TOGGLE: if (led_commands[i].toggle) diff --git a/common/cmd_load.c b/common/cmd_load.c index 2c8dab1..0832e92 100644 --- a/common/cmd_load.c +++ b/common/cmd_load.c @@ -149,7 +149,6 @@ static ulong load_serial(long offset) int type; /* return code for record type */ ulong addr; /* load address from S-Record */ ulong size; /* number of bytes transferred */ - char buf[32]; ulong store_addr; ulong start_addr = ~0; ulong end_addr = 0; @@ -198,8 +197,7 @@ static ulong load_serial(long offset) start_addr, end_addr, size, size ); flush_cache(start_addr, size); - sprintf(buf, "%lX", size); - setenv("filesize", buf); + setenv_hex("filesize", size); return (addr); case SREC_START: break; @@ -519,7 +517,6 @@ static int do_load_serial_bin(cmd_tbl_t *cmdtp, int flag, int argc, static ulong load_serial_bin(ulong offset) { int size, i; - char buf[32]; set_kerm_bin_mode((ulong *) offset); size = k_recv(); @@ -539,8 +536,7 @@ static ulong load_serial_bin(ulong offset) flush_cache(offset, size); printf("## Total Size = 0x%08x = %d Bytes\n", size, size); - sprintf(buf, "%X", size); - setenv("filesize", buf); + setenv_hex("filesize", size); return offset; } @@ -965,7 +961,6 @@ static int getcxmodem(void) { static ulong load_serial_ymodem(ulong offset) { int size; - char buf[32]; int err; int res; connection_info_t info; @@ -1012,8 +1007,7 @@ static ulong load_serial_ymodem(ulong offset) flush_cache(offset, size); printf("## Total Size = 0x%08x = %d Bytes\n", size, size); - sprintf(buf, "%X", size); - setenv("filesize", buf); + setenv_hex("filesize", size); return offset; } @@ -1064,8 +1058,8 @@ U_BOOT_CMD( " - save S-Record file over serial line with offset 'off' and size 'size'" ); #endif /* CONFIG_SYS_LOADS_BAUD_CHANGE */ -#endif -#endif +#endif /* CONFIG_CMD_SAVES */ +#endif /* CONFIG_CMD_LOADS */ #if defined(CONFIG_CMD_LOADB) @@ -1085,7 +1079,7 @@ U_BOOT_CMD( " with offset 'off' and baudrate 'baud'" ); -#endif +#endif /* CONFIG_CMD_LOADB */ /* -------------------------------------------------------------------- */ @@ -1115,4 +1109,4 @@ U_BOOT_CMD( "[on|off]" ); -#endif +#endif /* CONFIG_CMD_HWFLOW */ diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 0f3ffc8..64dd76a 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -32,11 +32,17 @@ #ifdef CONFIG_HAS_DATAFLASH #include <dataflash.h> #endif +#include <hash.h> #include <watchdog.h> +#include <asm/io.h> #include <linux/compiler.h> DECLARE_GLOBAL_DATA_PTR; +#ifndef CONFIG_SYS_MEMTEST_SCRATCH +#define CONFIG_SYS_MEMTEST_SCRATCH 0 +#endif + static int mod_mem(cmd_tbl_t *, int, int, int, char * const []); /* Display values from last command. @@ -138,9 +144,13 @@ static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) # endif { + ulong bytes = size * length; + const void *buf = map_sysmem(addr, bytes); + /* Print the lines. */ - print_buffer(addr, (void*)addr, size, length, DISP_LINE_LEN/size); - addr += size*length; + print_buffer(addr, buf, size, length, DISP_LINE_LEN / size); + addr += bytes; + unmap_sysmem(buf); } #endif @@ -163,6 +173,8 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr, writeval, count; int size; + void *buf; + ulong bytes; if ((argc < 3) || (argc > 4)) return CMD_RET_USAGE; @@ -188,15 +200,18 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) count = 1; } + bytes = size * count; + buf = map_sysmem(addr, bytes); while (count-- > 0) { if (size == 4) - *((ulong *)addr) = (ulong )writeval; + *((ulong *)buf) = (ulong)writeval; else if (size == 2) - *((ushort *)addr) = (ushort)writeval; + *((ushort *)buf) = (ushort)writeval; else - *((u_char *)addr) = (u_char)writeval; - addr += size; + *((u_char *)buf) = (u_char)writeval; + buf += size; } + unmap_sysmem(buf); return 0; } @@ -258,10 +273,11 @@ int do_mem_mwc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - ulong addr1, addr2, count, ngood; + ulong addr1, addr2, count, ngood, bytes; int size; int rcode = 0; const char *type; + const void *buf1, *buf2, *base; if (argc != 4) return CMD_RET_USAGE; @@ -294,33 +310,40 @@ static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #endif + bytes = size * count; + base = buf1 = map_sysmem(addr1, bytes); + buf2 = map_sysmem(addr2, bytes); for (ngood = 0; ngood < count; ++ngood) { ulong word1, word2; if (size == 4) { - word1 = *(ulong *)addr1; - word2 = *(ulong *)addr2; + word1 = *(ulong *)buf1; + word2 = *(ulong *)buf2; } else if (size == 2) { - word1 = *(ushort *)addr1; - word2 = *(ushort *)addr2; + word1 = *(ushort *)buf1; + word2 = *(ushort *)buf2; } else { - word1 = *(u_char *)addr1; - word2 = *(u_char *)addr2; + word1 = *(u_char *)buf1; + word2 = *(u_char *)buf2; } if (word1 != word2) { + ulong offset = buf1 - base; + printf("%s at 0x%08lx (%#0*lx) != %s at 0x%08lx (%#0*lx)\n", - type, addr1, size, word1, - type, addr2, size, word2); + type, (ulong)(addr1 + offset), size, word1, + type, (ulong)(addr2 + offset), size, word2); rcode = 1; break; } - addr1 += size; - addr2 += size; + buf1 += size; + buf2 += size; /* reset watchdog from time to time */ if ((ngood % (64 << 10)) == 0) WATCHDOG_RESET(); } + unmap_sysmem(buf1); + unmap_sysmem(buf2); printf("Total of %ld %s(s) were the same\n", ngood, type); return rcode; @@ -328,8 +351,10 @@ static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - ulong addr, dest, count; + ulong addr, dest, count, bytes; int size; + const void *src; + void *buf; if (argc != 4) return CMD_RET_USAGE; @@ -419,15 +444,18 @@ static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #endif + bytes = size * count; + buf = map_sysmem(addr, bytes); + src = map_sysmem(addr, bytes); while (count-- > 0) { if (size == 4) - *((ulong *)dest) = *((ulong *)addr); + *((ulong *)buf) = *((ulong *)src); else if (size == 2) - *((ushort *)dest) = *((ushort *)addr); + *((ushort *)buf) = *((ushort *)src); else - *((u_char *)dest) = *((u_char *)addr); - addr += size; - dest += size; + *((u_char *)buf) = *((u_char *)src); + src += size; + buf += size; /* reset watchdog from time to time */ if ((count % (64 << 10)) == 0) @@ -453,16 +481,18 @@ static int do_mem_base(cmd_tbl_t *cmdtp, int flag, int argc, static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - ulong addr, length, i; + ulong addr, length, i, bytes; int size; volatile uint *longp; volatile ushort *shortp; volatile u_char *cp; + const void *buf; if (argc < 3) return CMD_RET_USAGE; - /* Check for a size spefication. + /* + * Check for a size specification. * Defaults to long if no or incorrect specification. */ if ((size = cmd_get_data_size(argv[0], 4)) < 0) @@ -476,28 +506,31 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc, */ length = simple_strtoul(argv[2], NULL, 16); + bytes = size * length; + buf = map_sysmem(addr, bytes); + /* We want to optimize the loops to run as fast as possible. * If we have only one object, just run infinite loops. */ if (length == 1) { if (size == 4) { - longp = (uint *)addr; + longp = (uint *)buf; for (;;) i = *longp; } if (size == 2) { - shortp = (ushort *)addr; + shortp = (ushort *)buf; for (;;) i = *shortp; } - cp = (u_char *)addr; + cp = (u_char *)buf; for (;;) i = *cp; } if (size == 4) { for (;;) { - longp = (uint *)addr; + longp = (uint *)buf; i = length; while (i-- > 0) *longp++; @@ -505,33 +538,36 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc, } if (size == 2) { for (;;) { - shortp = (ushort *)addr; + shortp = (ushort *)buf; i = length; while (i-- > 0) *shortp++; } } for (;;) { - cp = (u_char *)addr; + cp = (u_char *)buf; i = length; while (i-- > 0) *cp++; } + unmap_sysmem(buf); } #ifdef CONFIG_LOOPW int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - ulong addr, length, i, data; + ulong addr, length, i, data, bytes; int size; volatile uint *longp; volatile ushort *shortp; volatile u_char *cp; + void *buf; if (argc < 4) return CMD_RET_USAGE; - /* Check for a size spefication. + /* + * Check for a size specification. * Defaults to long if no or incorrect specification. */ if ((size = cmd_get_data_size(argv[0], 4)) < 0) @@ -548,28 +584,31 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* data to write */ data = simple_strtoul(argv[3], NULL, 16); + bytes = size * length; + buf = map_sysmem(addr, bytes); + /* We want to optimize the loops to run as fast as possible. * If we have only one object, just run infinite loops. */ if (length == 1) { if (size == 4) { - longp = (uint *)addr; + longp = (uint *)buf; for (;;) *longp = data; } if (size == 2) { - shortp = (ushort *)addr; + shortp = (ushort *)buf; for (;;) *shortp = data; } - cp = (u_char *)addr; + cp = (u_char *)buf; for (;;) *cp = data; } if (size == 4) { for (;;) { - longp = (uint *)addr; + longp = (uint *)buf; i = length; while (i-- > 0) *longp++ = data; @@ -577,14 +616,14 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } if (size == 2) { for (;;) { - shortp = (ushort *)addr; + shortp = (ushort *)buf; i = length; while (i-- > 0) *shortp++ = data; } } for (;;) { - cp = (u_char *)addr; + cp = (u_char *)buf; i = length; while (i-- > 0) *cp++ = data; @@ -592,36 +631,20 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #endif /* CONFIG_LOOPW */ -/* - * Perform a memory test. A more complete alternative test can be - * configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until - * interrupted by ctrl-c or by a failure of one of the sub-tests. - */ -static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) +#ifdef CONFIG_CMD_MEMTEST +static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, + vu_long *dummy) { - vu_long *addr, *start, *end; - ulong val; - ulong readback; - ulong errs = 0; - int iterations = 1; - int iteration_limit; - -#if defined(CONFIG_SYS_ALT_MEMTEST) - vu_long len; - vu_long offset; - vu_long test_offset; - vu_long pattern; - vu_long temp; - vu_long anti_pattern; - vu_long num_words; -#if defined(CONFIG_SYS_MEMTEST_SCRATCH) - vu_long *dummy = (vu_long*)CONFIG_SYS_MEMTEST_SCRATCH; -#else - vu_long *dummy = NULL; /* yes, this is address 0x0, not NULL */ -#endif - int j; - + vu_long *addr; + ulong errs = 0; + ulong val, readback; + int j; + vu_long offset; + vu_long test_offset; + vu_long pattern; + vu_long temp; + vu_long anti_pattern; + vu_long num_words; static const ulong bitpattern[] = { 0x00000001, /* single bit */ 0x00000003, /* two adjacent bits */ @@ -632,322 +655,355 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, 0x00000055, /* four non-adjacent bits */ 0xaaaaaaaa, /* alternating 1/0 */ }; -#else - ulong incr; - ulong pattern; -#endif - - if (argc > 1) - start = (ulong *)simple_strtoul(argv[1], NULL, 16); - else - start = (ulong *)CONFIG_SYS_MEMTEST_START; - if (argc > 2) - end = (ulong *)simple_strtoul(argv[2], NULL, 16); - else - end = (ulong *)(CONFIG_SYS_MEMTEST_END); - - if (argc > 3) - pattern = (ulong)simple_strtoul(argv[3], NULL, 16); - else - pattern = 0; - - if (argc > 4) - iteration_limit = (ulong)simple_strtoul(argv[4], NULL, 16); - else - iteration_limit = 0; - -#if defined(CONFIG_SYS_ALT_MEMTEST) - printf ("Testing %08x ... %08x:\n", (uint)start, (uint)end); - debug("%s:%d: start 0x%p end 0x%p\n", - __FUNCTION__, __LINE__, start, end); - - for (;;) { - if (ctrlc()) { - putc ('\n'); - return 1; - } - - - if (iteration_limit && iterations > iteration_limit) { - printf("Tested %d iteration(s) with %lu errors.\n", - iterations-1, errs); - return errs != 0; - } - - printf("Iteration: %6d\r", iterations); - debug("\n"); - iterations++; - - /* - * Data line test: write a pattern to the first - * location, write the 1's complement to a 'parking' - * address (changes the state of the data bus so a - * floating bus doen't give a false OK), and then - * read the value back. Note that we read it back - * into a variable because the next time we read it, - * it might be right (been there, tough to explain to - * the quality guys why it prints a failure when the - * "is" and "should be" are obviously the same in the - * error message). - * - * Rather than exhaustively testing, we test some - * patterns by shifting '1' bits through a field of - * '0's and '0' bits through a field of '1's (i.e. - * pattern and ~pattern). - */ - addr = start; - for (j = 0; j < sizeof(bitpattern)/sizeof(bitpattern[0]); j++) { - val = bitpattern[j]; - for(; val != 0; val <<= 1) { - *addr = val; - *dummy = ~val; /* clear the test data off of the bus */ + num_words = (end_addr - start_addr) / sizeof(vu_long); + + /* + * Data line test: write a pattern to the first + * location, write the 1's complement to a 'parking' + * address (changes the state of the data bus so a + * floating bus doesn't give a false OK), and then + * read the value back. Note that we read it back + * into a variable because the next time we read it, + * it might be right (been there, tough to explain to + * the quality guys why it prints a failure when the + * "is" and "should be" are obviously the same in the + * error message). + * + * Rather than exhaustively testing, we test some + * patterns by shifting '1' bits through a field of + * '0's and '0' bits through a field of '1's (i.e. + * pattern and ~pattern). + */ + addr = buf; + for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) { + val = bitpattern[j]; + for (; val != 0; val <<= 1) { + *addr = val; + *dummy = ~val; /* clear the test data off the bus */ readback = *addr; - if(readback != val) { - printf ("FAILURE (data line): " - "expected %08lx, actual %08lx\n", - val, readback); - errs++; - if (ctrlc()) { - putc ('\n'); - return 1; - } + if (readback != val) { + printf("FAILURE (data line): " + "expected %08lx, actual %08lx\n", + val, readback); + errs++; + if (ctrlc()) + return -1; } *addr = ~val; *dummy = val; readback = *addr; - if(readback != ~val) { - printf ("FAILURE (data line): " - "Is %08lx, should be %08lx\n", - readback, ~val); - errs++; - if (ctrlc()) { - putc ('\n'); - return 1; - } + if (readback != ~val) { + printf("FAILURE (data line): " + "Is %08lx, should be %08lx\n", + readback, ~val); + errs++; + if (ctrlc()) + return -1; } - } } + } - /* - * Based on code whose Original Author and Copyright - * information follows: Copyright (c) 1998 by Michael - * Barr. This software is placed into the public - * domain and may be used for any purpose. However, - * this notice must not be changed or removed and no - * warranty is either expressed or implied by its - * publication or distribution. - */ + /* + * Based on code whose Original Author and Copyright + * information follows: Copyright (c) 1998 by Michael + * Barr. This software is placed into the public + * domain and may be used for any purpose. However, + * this notice must not be changed or removed and no + * warranty is either expressed or implied by its + * publication or distribution. + */ - /* - * Address line test - * - * Description: Test the address bus wiring in a - * memory region by performing a walking - * 1's test on the relevant bits of the - * address and checking for aliasing. - * This test will find single-bit - * address failures such as stuck -high, - * stuck-low, and shorted pins. The base - * address and size of the region are - * selected by the caller. - * - * Notes: For best results, the selected base - * address should have enough LSB 0's to - * guarantee single address bit changes. - * For example, to test a 64-Kbyte - * region, select a base address on a - * 64-Kbyte boundary. Also, select the - * region size as a power-of-two if at - * all possible. - * - * Returns: 0 if the test succeeds, 1 if the test fails. - */ - len = ((ulong)end - (ulong)start)/sizeof(vu_long); - pattern = (vu_long) 0xaaaaaaaa; - anti_pattern = (vu_long) 0x55555555; + /* + * Address line test + + * Description: Test the address bus wiring in a + * memory region by performing a walking + * 1's test on the relevant bits of the + * address and checking for aliasing. + * This test will find single-bit + * address failures such as stuck-high, + * stuck-low, and shorted pins. The base + * address and size of the region are + * selected by the caller. + + * Notes: For best results, the selected base + * address should have enough LSB 0's to + * guarantee single address bit changes. + * For example, to test a 64-Kbyte + * region, select a base address on a + * 64-Kbyte boundary. Also, select the + * region size as a power-of-two if at + * all possible. + * + * Returns: 0 if the test succeeds, 1 if the test fails. + */ + pattern = (vu_long) 0xaaaaaaaa; + anti_pattern = (vu_long) 0x55555555; - debug("%s:%d: length = 0x%.8lx\n", - __FUNCTION__, __LINE__, - len); - /* - * Write the default pattern at each of the - * power-of-two offsets. - */ - for (offset = 1; offset < len; offset <<= 1) { - start[offset] = pattern; - } + debug("%s:%d: length = 0x%.8lx\n", __func__, __LINE__, num_words); + /* + * Write the default pattern at each of the + * power-of-two offsets. + */ + for (offset = 1; offset < num_words; offset <<= 1) + addr[offset] = pattern; - /* - * Check for address bits stuck high. - */ - test_offset = 0; - start[test_offset] = anti_pattern; + /* + * Check for address bits stuck high. + */ + test_offset = 0; + addr[test_offset] = anti_pattern; - for (offset = 1; offset < len; offset <<= 1) { - temp = start[offset]; - if (temp != pattern) { - printf ("\nFAILURE: Address bit stuck high @ 0x%.8lx:" + for (offset = 1; offset < num_words; offset <<= 1) { + temp = addr[offset]; + if (temp != pattern) { + printf("\nFAILURE: Address bit stuck high @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx\n", - (ulong)&start[offset], pattern, temp); + start_addr + offset, pattern, temp); errs++; - if (ctrlc()) { - putc ('\n'); - return 1; - } - } + if (ctrlc()) + return -1; } - start[test_offset] = pattern; - WATCHDOG_RESET(); + } + addr[test_offset] = pattern; + WATCHDOG_RESET(); - /* - * Check for addr bits stuck low or shorted. - */ - for (test_offset = 1; test_offset < len; test_offset <<= 1) { - start[test_offset] = anti_pattern; + /* + * Check for addr bits stuck low or shorted. + */ + for (test_offset = 1; test_offset < num_words; test_offset <<= 1) { + addr[test_offset] = anti_pattern; - for (offset = 1; offset < len; offset <<= 1) { - temp = start[offset]; + for (offset = 1; offset < num_words; offset <<= 1) { + temp = addr[offset]; if ((temp != pattern) && (offset != test_offset)) { - printf ("\nFAILURE: Address bit stuck low or shorted @" - " 0x%.8lx: expected 0x%.8lx, actual 0x%.8lx\n", - (ulong)&start[offset], pattern, temp); - errs++; - if (ctrlc()) { - putc ('\n'); - return 1; - } + printf("\nFAILURE: Address bit stuck low or" + " shorted @ 0x%.8lx: expected 0x%.8lx," + " actual 0x%.8lx\n", + start_addr + offset, pattern, temp); + errs++; + if (ctrlc()) + return -1; } - } - start[test_offset] = pattern; } + addr[test_offset] = pattern; + } - /* - * Description: Test the integrity of a physical - * memory device by performing an - * increment/decrement test over the - * entire region. In the process every - * storage bit in the device is tested - * as a zero and a one. The base address - * and the size of the region are - * selected by the caller. - * - * Returns: 0 if the test succeeds, 1 if the test fails. - */ - num_words = ((ulong)end - (ulong)start)/sizeof(vu_long) + 1; + /* + * Description: Test the integrity of a physical + * memory device by performing an + * increment/decrement test over the + * entire region. In the process every + * storage bit in the device is tested + * as a zero and a one. The base address + * and the size of the region are + * selected by the caller. + * + * Returns: 0 if the test succeeds, 1 if the test fails. + */ + num_words++; - /* - * Fill memory with a known pattern. - */ - for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { - WATCHDOG_RESET(); - start[offset] = pattern; - } + /* + * Fill memory with a known pattern. + */ + for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { + WATCHDOG_RESET(); + addr[offset] = pattern; + } - /* - * Check each location and invert it for the second pass. - */ - for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { - WATCHDOG_RESET(); - temp = start[offset]; - if (temp != pattern) { - printf ("\nFAILURE (read/write) @ 0x%.8lx:" + /* + * Check each location and invert it for the second pass. + */ + for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { + WATCHDOG_RESET(); + temp = addr[offset]; + if (temp != pattern) { + printf("\nFAILURE (read/write) @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", - (ulong)&start[offset], pattern, temp); + start_addr + offset, pattern, temp); errs++; - if (ctrlc()) { - putc ('\n'); - return 1; - } - } - - anti_pattern = ~pattern; - start[offset] = anti_pattern; + if (ctrlc()) + return -1; } - /* - * Check each location for the inverted pattern and zero it. - */ - for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { - WATCHDOG_RESET(); - anti_pattern = ~pattern; - temp = start[offset]; - if (temp != anti_pattern) { - printf ("\nFAILURE (read/write): @ 0x%.8lx:" + anti_pattern = ~pattern; + addr[offset] = anti_pattern; + } + + /* + * Check each location for the inverted pattern and zero it. + */ + for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { + WATCHDOG_RESET(); + anti_pattern = ~pattern; + temp = addr[offset]; + if (temp != anti_pattern) { + printf("\nFAILURE (read/write): @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", - (ulong)&start[offset], anti_pattern, temp); + start_addr + offset, anti_pattern, temp); errs++; - if (ctrlc()) { - putc ('\n'); - return 1; - } - } - start[offset] = 0; + if (ctrlc()) + return -1; } + addr[offset] = 0; } -#else /* The original, quickie test */ - incr = 1; - for (;;) { - if (ctrlc()) { - putc ('\n'); - return 1; - } - - if (iteration_limit && iterations > iteration_limit) { - printf("Tested %d iteration(s) with %lu errors.\n", - iterations-1, errs); - return errs != 0; - } - ++iterations; - - printf ("\rPattern %08lX Writing..." - "%12s" - "\b\b\b\b\b\b\b\b\b\b", - pattern, ""); - - for (addr=start,val=pattern; addr<end; addr++) { - WATCHDOG_RESET(); - *addr = val; - val += incr; - } - - puts ("Reading..."); + return 0; +} - for (addr=start,val=pattern; addr<end; addr++) { - WATCHDOG_RESET(); - readback = *addr; - if (readback != val) { - printf ("\nMem error @ 0x%08X: " - "found %08lX, expected %08lX\n", - (uint)(uintptr_t)addr, readback, val); - errs++; - if (ctrlc()) { - putc ('\n'); - return 1; - } - } - val += incr; - } +static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr, + vu_long pattern, int iteration) +{ + vu_long *end; + vu_long *addr; + ulong errs = 0; + ulong incr, length; + ulong val, readback; + /* Alternate the pattern */ + incr = 1; + if (iteration & 1) { + incr = -incr; /* * Flip the pattern each time to make lots of zeros and * then, the next time, lots of ones. We decrement * the "negative" patterns and increment the "positive" * patterns to preserve this feature. */ - if(pattern & 0x80000000) { + if (pattern & 0x80000000) pattern = -pattern; /* complement & increment */ - } - else { + else pattern = ~pattern; + } + length = (end_addr - start_addr) / sizeof(ulong); + end = buf + length; + printf("\rPattern %08lX Writing..." + "%12s" + "\b\b\b\b\b\b\b\b\b\b", + pattern, ""); + + for (addr = buf, val = pattern; addr < end; addr++) { + WATCHDOG_RESET(); + *addr = val; + val += incr; + } + + puts("Reading..."); + + for (addr = buf, val = pattern; addr < end; addr++) { + WATCHDOG_RESET(); + readback = *addr; + if (readback != val) { + ulong offset = addr - buf; + + printf("\nMem error @ 0x%08X: " + "found %08lX, expected %08lX\n", + (uint)(uintptr_t)(start_addr + offset), + readback, val); + errs++; + if (ctrlc()) + return -1; } - incr = -incr; + val += incr; } -#endif - return 0; /* not reached */ + + return 0; } +/* + * Perform a memory test. A more complete alternative test can be + * configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until + * interrupted by ctrl-c or by a failure of one of the sub-tests. + */ +static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + ulong start, end; + vu_long *buf, *dummy; + int iteration_limit; + int ret; + ulong errs = 0; /* number of errors, or -1 if interrupted */ + ulong pattern; + int iteration; +#if defined(CONFIG_SYS_ALT_MEMTEST) + const int alt_test = 1; +#else + const int alt_test = 0; +#endif + + if (argc > 1) + start = simple_strtoul(argv[1], NULL, 16); + else + start = CONFIG_SYS_MEMTEST_START; + + if (argc > 2) + end = simple_strtoul(argv[2], NULL, 16); + else + end = CONFIG_SYS_MEMTEST_END; + + if (argc > 3) + pattern = (ulong)simple_strtoul(argv[3], NULL, 16); + else + pattern = 0; + + if (argc > 4) + iteration_limit = (ulong)simple_strtoul(argv[4], NULL, 16); + else + iteration_limit = 0; + + printf("Testing %08x ... %08x:\n", (uint)start, (uint)end); + debug("%s:%d: start %#08lx end %#08lx\n", __func__, __LINE__, + start, end); + + buf = map_sysmem(start, end - start); + dummy = map_sysmem(CONFIG_SYS_MEMTEST_SCRATCH, sizeof(vu_long)); + for (iteration = 0; + !iteration_limit || iteration < iteration_limit; + iteration++) { + if (ctrlc()) { + errs = -1UL; + break; + } + + printf("Iteration: %6d\r", iteration + 1); + debug("\n"); + if (alt_test) { + errs = mem_test_alt(buf, start, end, dummy); + } else { + errs = mem_test_quick(buf, start, end, pattern, + iteration); + } + if (errs == -1UL) + break; + } + + /* + * Work-around for eldk-4.2 which gives this warning if we try to + * case in the unmap_sysmem() call: + * warning: initialization discards qualifiers from pointer target type + */ + { + void *vbuf = (void *)buf; + void *vdummy = (void *)dummy; + + unmap_sysmem(vbuf); + unmap_sysmem(vdummy); + } + + if (errs == -1UL) { + /* Memory test was aborted - write a newline to finish off */ + putc('\n'); + ret = 1; + } else { + printf("Tested %d iteration(s) with %lu errors.\n", + iteration, errs); + ret = errs != 0; + } + + return ret; /* not reached */ +} +#endif /* CONFIG_CMD_MEMTEST */ /* Modify memory. * @@ -960,6 +1016,7 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) { ulong addr, i; int nbytes, size; + void *ptr = NULL; if (argc != 2) return CMD_RET_USAGE; @@ -1004,13 +1061,14 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) * the next value. A non-converted value exits. */ do { + ptr = map_sysmem(addr, size); printf("%08lx:", addr); if (size == 4) - printf(" %08x", *((uint *)addr)); + printf(" %08x", *((uint *)ptr)); else if (size == 2) - printf(" %04x", *((ushort *)addr)); + printf(" %04x", *((ushort *)ptr)); else - printf(" %02x", *((u_char *)addr)); + printf(" %02x", *((u_char *)ptr)); nbytes = readline (" ? "); if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) { @@ -1040,16 +1098,18 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) reset_cmd_timeout(); #endif if (size == 4) - *((uint *)addr) = i; + *((uint *)ptr) = i; else if (size == 2) - *((ushort *)addr) = i; + *((ushort *)ptr) = i; else - *((u_char *)addr) = i; + *((u_char *)ptr) = i; if (incrflag) addr += size; } } } while (nbytes); + if (ptr) + unmap_sysmem(ptr); mm_last_addr = addr; mm_last_size = size; @@ -1058,89 +1118,27 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) #ifdef CONFIG_CMD_CRC32 -#ifndef CONFIG_CRC32_VERIFY - static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - ulong addr, length; - ulong crc; - ulong *ptr; - - if (argc < 3) - return CMD_RET_USAGE; - - addr = simple_strtoul (argv[1], NULL, 16); - addr += base_address; - - length = simple_strtoul (argv[2], NULL, 16); - - crc = crc32_wd (0, (const uchar *) addr, length, CHUNKSZ_CRC32); - - printf ("CRC32 for %08lx ... %08lx ==> %08lx\n", - addr, addr + length - 1, crc); - - if (argc > 3) { - ptr = (ulong *) simple_strtoul (argv[3], NULL, 16); - *ptr = crc; - } - - return 0; -} - -#else /* CONFIG_CRC32_VERIFY */ - -int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - ulong addr, length; - ulong crc; - ulong *ptr; - ulong vcrc; - int verify; + int flags = 0; int ac; char * const *av; - if (argc < 3) { -usage: + if (argc < 3) return CMD_RET_USAGE; - } av = argv + 1; ac = argc - 1; +#ifdef CONFIG_HASH_VERIFY if (strcmp(*av, "-v") == 0) { - verify = 1; + flags |= HASH_FLAG_VERIFY; av++; ac--; - if (ac < 3) - goto usage; - } else - verify = 0; - - addr = simple_strtoul(*av++, NULL, 16); - addr += base_address; - length = simple_strtoul(*av++, NULL, 16); - - crc = crc32_wd (0, (const uchar *) addr, length, CHUNKSZ_CRC32); - - if (!verify) { - printf ("CRC32 for %08lx ... %08lx ==> %08lx\n", - addr, addr + length - 1, crc); - if (ac > 2) { - ptr = (ulong *) simple_strtoul (*av++, NULL, 16); - *ptr = crc; - } - } else { - vcrc = simple_strtoul(*av++, NULL, 16); - if (vcrc != crc) { - printf ("CRC32 for %08lx ... %08lx ==> %08lx != %08lx ** ERROR **\n", - addr, addr + length - 1, crc, vcrc); - return 1; - } } +#endif - return 0; - + return hash_command("crc32", flags, cmdtp, flag, ac, av); } -#endif /* CONFIG_CRC32_VERIFY */ #endif @@ -1243,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 7dacd51..8c53a10 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -282,6 +282,13 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) mmc_init(mmc); + if ((state == MMC_WRITE || state == MMC_ERASE)) { + if (mmc_getwp(mmc) == 1) { + printf("Error: card is write protected!\n"); + return 1; + } + } + switch (state) { case MMC_READ: n = mmc->block_dev.block_read(curr_device, blk, diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c index 06fc171..5192dee 100644 --- a/common/cmd_mtdparts.c +++ b/common/cmd_mtdparts.c @@ -230,7 +230,6 @@ static void memsize_format(char *buf, u32 size) */ static void index_partitions(void) { - char buf[16]; u16 mtddevnum; struct part_info *part; struct list_head *dentry; @@ -244,8 +243,7 @@ static void index_partitions(void) dev = list_entry(dentry, struct mtd_device, link); if (dev == current_mtd_dev) { mtddevnum += current_mtd_partnum; - sprintf(buf, "%d", mtddevnum); - setenv("mtddevnum", buf); + setenv_ulong("mtddevnum", mtddevnum); break; } mtddevnum += dev->num_parts; @@ -1422,7 +1420,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; @@ -1520,7 +1518,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; @@ -2018,7 +2016,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 1568594..32348f3 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -373,7 +373,6 @@ static void nand_print_and_set_info(int idx) { nand_info_t *nand = &nand_info[idx]; struct nand_chip *chip = nand->priv; - char buf[32]; printf("Device %d: ", idx); if (chip->numchips > 1) @@ -385,14 +384,9 @@ static void nand_print_and_set_info(int idx) printf(" Erase size %8d b\n", nand->erasesize); /* Set geometry info */ - sprintf(buf, "%x", nand->writesize); - setenv("nand_writesize", buf); - - sprintf(buf, "%x", nand->oobsize); - setenv("nand_oobsize", buf); - - sprintf(buf, "%x", nand->erasesize); - setenv("nand_erasesize", buf); + setenv_hex("nand_writesize", nand->writesize); + setenv_hex("nand_oobsize", nand->oobsize); + setenv_hex("nand_erasesize", nand->erasesize); } static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count, @@ -608,7 +602,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) size_t rwsize; ulong pagecount = 1; int read; - int raw; + int raw = 0; if (argc < 4) goto usage; diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 7633f0c..947d6c4 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -295,17 +295,17 @@ int setenv_ulong(const char *varname, ulong value) } /** - * Set an environment variable to an address in hex + * Set an environment variable to an value in hex * * @param varname Environmet variable to set - * @param addr Value to set it to + * @param value Value to set it to * @return 0 if ok, 1 on error */ -int setenv_addr(const char *varname, const void *addr) +int setenv_hex(const char *varname, ulong value) { char str[17]; - sprintf(str, "%lx", (uintptr_t)addr); + sprintf(str, "%lx", value); return setenv(varname, str); } @@ -325,41 +325,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) @@ -552,7 +561,8 @@ static int do_env_edit(cmd_tbl_t *cmdtp, int flag, int argc, else buffer[0] = '\0'; - readline_into_buffer("edit: ", buffer, 0); + if (readline_into_buffer("edit: ", buffer, 0) < 0) + return 1; return setenv(argv[1], buffer); } @@ -891,8 +901,7 @@ NXTARG: ; envp->flags = ACTIVE_FLAG; #endif } - sprintf(buf, "%zX", (size_t)(len + offsetof(env_t, data))); - setenv("filesize", buf); + setenv_hex("filesize", len + offsetof(env_t, data)); return 0; @@ -1168,14 +1177,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 d997597..b79f074 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_reginfo.c b/common/cmd_reginfo.c index 08a6563..b591bd3 100644 --- a/common/cmd_reginfo.c +++ b/common/cmd_reginfo.c @@ -191,7 +191,7 @@ static int do_reginfo(cmd_tbl_t *cmdtp, int flag, int argc, #elif defined(CONFIG_BLACKFIN) puts("\nSystem Configuration registers\n"); - +#ifndef __ADSPBF60x__ puts("\nPLL Registers\n"); printf("\tPLL_DIV: 0x%04x PLL_CTL: 0x%04x\n", bfin_read_PLL_DIV(), bfin_read_PLL_CTL()); @@ -227,7 +227,24 @@ static int do_reginfo(cmd_tbl_t *cmdtp, int flag, int argc, printf("\tEBIU_SDSTAT: 0x%04x EBIU_SDGCTL: 0x%08x\n", bfin_read_EBIU_SDSTAT(), bfin_read_EBIU_SDGCTL()); # endif +#else + puts("\nCGU Registers\n"); + printf("\tCGU_DIV: 0x%08x CGU_CTL: 0x%08x\n", + bfin_read_CGU_DIV(), bfin_read_CGU_CTL()); + printf("\tCGU_STAT: 0x%08x CGU_LOCKCNT: 0x%08x\n", + bfin_read_CGU_STAT(), bfin_read_CGU_CLKOUTSEL()); + puts("\nSMC DDR Registers\n"); + printf("\tDDR_CFG: 0x%08x DDR_TR0: 0x%08x\n", + bfin_read_DMC0_CFG(), bfin_read_DMC0_TR0()); + printf("\tDDR_TR1: 0x%08x DDR_TR2: 0x%08x\n", + bfin_read_DMC0_TR1(), bfin_read_DMC0_TR2()); + printf("\tDDR_MR: 0x%08x DDR_EMR1: 0x%08x\n", + bfin_read_DMC0_MR(), bfin_read_DMC0_EMR1()); + printf("\tDDR_CTL: 0x%08x DDR_STAT: 0x%08x\n", + bfin_read_DMC0_CTL(), bfin_read_DMC0_STAT()); + printf("\tDDR_DLLCTL:0x%08x\n", bfin_read_DMC0_DLLCTL()); +#endif #endif /* CONFIG_BLACKFIN */ return 0; diff --git a/common/cmd_reiser.c b/common/cmd_reiser.c index e658618..717c7f6 100644 --- a/common/cmd_reiser.c +++ b/common/cmd_reiser.c @@ -100,7 +100,6 @@ int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) ulong addr = 0, filelen; disk_partition_t info; block_dev_desc_t *dev_desc = NULL; - char buf [12]; unsigned long count; char *addr_str; @@ -175,8 +174,7 @@ int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) load_addr = addr; printf ("\n%ld bytes read\n", filelen); - sprintf(buf, "%lX", filelen); - setenv("filesize", buf); + setenv_hex("filesize", filelen); return filelen; } diff --git a/common/cmd_sandbox.c b/common/cmd_sandbox.c new file mode 100644 index 0000000..206a486 --- /dev/null +++ b/common/cmd_sandbox.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012, Google Inc. + * + * 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 <fs.h> + +static int do_sandbox_load(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return do_load(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX, 16); +} + +static int do_sandbox_ls(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX); +} + +static cmd_tbl_t cmd_sandbox_sub[] = { + U_BOOT_CMD_MKENT(load, 3, 0, do_sandbox_load, "", ""), + U_BOOT_CMD_MKENT(ls, 3, 0, do_sandbox_ls, "", ""), +}; + +static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + cmd_tbl_t *c; + + /* Skip past 'sandbox' */ + argc--; + argv++; + + c = find_cmd_tbl(argv[0], cmd_sandbox_sub, + ARRAY_SIZE(cmd_sandbox_sub)); + + if (c) + return c->cmd(cmdtp, flag, argc, argv); + else + return CMD_RET_USAGE; +} + +U_BOOT_CMD( + sb, 6, 1, do_sandbox, + "Miscellaneous sandbox commands", + "load host <addr> <filename> [<bytes> <offset>] - load a file from host\n" + "sb ls host <filename> - save a file to host" +); diff --git a/common/cmd_sata.c b/common/cmd_sata.c index b401bd1..8d57285 100644 --- a/common/cmd_sata.c +++ b/common/cmd_sata.c @@ -196,7 +196,7 @@ static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( sata, 5, 1, do_sata, "SATA sub system", - "sata init - init SATA sub system\n" + "init - init SATA sub system\n" "sata info - show available SATA devices\n" "sata device [dev] - show or set current device\n" "sata part [dev] - print partition table\n" diff --git a/common/cmd_setexpr.c b/common/cmd_setexpr.c index 5a04295..7a38e94 100644 --- a/common/cmd_setexpr.c +++ b/common/cmd_setexpr.c @@ -53,7 +53,7 @@ static ulong get_arg(char *s, int w) static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong a, b; - char buf[16]; + ulong value; int w; /* Validate arguments */ @@ -67,8 +67,7 @@ static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) a = get_arg(argv[2], w); if (argc == 3) { - sprintf(buf, "%lx", a); - setenv(argv[1], buf); + setenv_hex(argv[1], a); return 0; } @@ -76,20 +75,36 @@ static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) b = get_arg(argv[4], w); switch (argv[3][0]) { - case '|': sprintf(buf, "%lx", (a | b)); break; - case '&': sprintf(buf, "%lx", (a & b)); break; - case '+': sprintf(buf, "%lx", (a + b)); break; - case '^': sprintf(buf, "%lx", (a ^ b)); break; - case '-': sprintf(buf, "%lx", (a - b)); break; - case '*': sprintf(buf, "%lx", (a * b)); break; - case '/': sprintf(buf, "%lx", (a / b)); break; - case '%': sprintf(buf, "%lx", (a % b)); break; + case '|': + value = a | b; + break; + case '&': + value = a & b; + break; + case '+': + value = a + b; + break; + case '^': + value = a ^ b; + break; + case '-': + value = a - b; + break; + case '*': + value = a * b; + break; + case '/': + value = a / b; + break; + case '%': + value = a % b; + break; default: printf("invalid op\n"); return 1; } - setenv(argv[1], buf); + setenv_hex(argv[1], value); return 0; } diff --git a/common/cmd_sha1sum.c b/common/cmd_sha1sum.c index fe927ab..9f08629 100644 --- a/common/cmd_sha1sum.c +++ b/common/cmd_sha1sum.c @@ -31,7 +31,7 @@ int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int verify = 0; + int flags = HASH_FLAG_ENV; int ac; char * const *av; @@ -42,13 +42,13 @@ int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) ac = argc - 1; #ifdef CONFIG_SHA1SUM_VERIFY if (strcmp(*av, "-v") == 0) { - verify = 1; + flags |= HASH_FLAG_VERIFY; av++; ac--; } #endif - return hash_command("sha1", verify, cmdtp, flag, ac, av); + return hash_command("sha1", flags, cmdtp, flag, ac, av); } #ifdef CONFIG_SHA1SUM_VERIFY diff --git a/common/cmd_spl.c b/common/cmd_spl.c index e3c543b..94b0a17 100644 --- a/common/cmd_spl.c +++ b/common/cmd_spl.c @@ -184,7 +184,11 @@ static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( spl, 6 , 1, do_spl, "SPL configuration", - "export <img=atags|fdt> [kernel_addr] [initrd_addr] " - "[fdt_addr if <img> = fdt] - export a kernel parameter image\n" - "\t initrd_img can be set to \"-\" if fdt_addr without initrd img is" - "used"); + "export <img=atags|fdt> [kernel_addr] [initrd_addr] [fdt_addr]\n" + "\timg\t\t\"atags\" or \"fdt\"\n" + "\tkernel_addr\taddress where a kernel image is stored.\n" + "\t\t\tkernel is loaded as part of the boot process, but it is not started.\n" + "\tinitrd_addr\taddress of initial ramdisk\n" + "\t\t\tcan be set to \"-\" if fdt_addr without initrd_addr is used.\n" + "\tfdt_addr\tin case of fdt, the address of the device tree.\n" + ); diff --git a/common/cmd_unzip.c b/common/cmd_unzip.c index 43ed791..7470c2b 100644 --- a/common/cmd_unzip.c +++ b/common/cmd_unzip.c @@ -28,7 +28,6 @@ static int do_unzip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long src, dst; unsigned long src_len = ~0UL, dst_len = ~0UL; - char buf[32]; switch (argc) { case 4: @@ -46,8 +45,7 @@ static int do_unzip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; printf("Uncompressed size: %ld = 0x%lX\n", src_len, src_len); - sprintf(buf, "%lX", src_len); - setenv("filesize", buf); + setenv_hex("filesize", src_len); return 0; } diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c new file mode 100644 index 0000000..87a5f2f --- /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/cmd_ximg.c b/common/cmd_ximg.c index 42a7eba..ea0a26e 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -50,7 +50,6 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) ulong data, len, count; int verify; int part = 0; - char pbuf[10]; image_header_t *hdr; #if defined(CONFIG_FIT) const char *uname = NULL; @@ -256,10 +255,8 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) puts("OK\n"); } - sprintf(pbuf, "%8lx", data); - setenv("fileaddr", pbuf); - sprintf(pbuf, "%8lx", len); - setenv("filesize", pbuf); + setenv_hex("fileaddr", data); + setenv_hex("filesize", len); return 0; } diff --git a/common/cmd_zfs.c b/common/cmd_zfs.c index 1df0c4d..900e977 100644 --- a/common/cmd_zfs.c +++ b/common/cmd_zfs.c @@ -129,8 +129,7 @@ static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] load_addr = addr; printf("%llu bytes read\n", zfile.size); - sprintf(buf, "%llX", zfile.size); - setenv("filesize", buf); + setenv_hex("filesize", zfile.size); return 0; } diff --git a/common/cmd_zip.c b/common/cmd_zip.c index a73c86d..8607da8 100644 --- a/common/cmd_zip.c +++ b/common/cmd_zip.c @@ -28,7 +28,6 @@ static int do_zip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long src, dst; unsigned long src_len, dst_len = ~0UL; - char buf[32]; switch (argc) { case 5: @@ -47,8 +46,7 @@ static int do_zip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; printf("Compressed size: %ld = 0x%lX\n", dst_len, dst_len); - sprintf(buf, "%lX", dst_len); - setenv("filesize", buf); + setenv_hex("filesize", dst_len); return 0; } diff --git a/common/dlmalloc.c b/common/dlmalloc.c index b2f0a1a..2a9d169 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -1485,7 +1485,7 @@ static mbinptr av_[NAV * 2 + 2] = { }; #ifdef CONFIG_NEEDS_MANUAL_RELOC -void malloc_bin_reloc (void) +static void malloc_bin_reloc(void) { mbinptr *p = &av_[2]; size_t i; @@ -1493,6 +1493,8 @@ void malloc_bin_reloc (void) for (i = 2; i < ARRAY_SIZE(av_); ++i, ++p) *p = (mbinptr)((ulong)*p + gd->reloc_off); } +#else +static inline void malloc_bin_reloc(void) {} #endif ulong mem_malloc_start = 0; @@ -1526,6 +1528,8 @@ void mem_malloc_init(ulong start, ulong size) mem_malloc_brk = start; memset((void *)mem_malloc_start, 0, size); + + malloc_bin_reloc(); } /* field-extraction macros */ diff --git a/common/env_nand.c b/common/env_nand.c index 22e72a2..5b69889 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -331,6 +331,7 @@ int get_nand_env_oob(nand_info_t *nand, unsigned long *result) void env_relocate_spec(void) { #if !defined(ENV_IS_EMBEDDED) + int read1_fail = 0, read2_fail = 0; int crc1_ok = 0, crc2_ok = 0; env_t *ep, *tmp_env1, *tmp_env2; @@ -342,14 +343,19 @@ void env_relocate_spec(void) goto done; } - if (readenv(CONFIG_ENV_OFFSET, (u_char *) tmp_env1)) - puts("No Valid Environment Area found\n"); + read1_fail = readenv(CONFIG_ENV_OFFSET, (u_char *) tmp_env1); + read2_fail = readenv(CONFIG_ENV_OFFSET_REDUND, (u_char *) tmp_env2); - if (readenv(CONFIG_ENV_OFFSET_REDUND, (u_char *) tmp_env2)) - puts("No Valid Redundant Environment Area found\n"); + if (read1_fail && read2_fail) + puts("*** Error - No Valid Environment Area found\n"); + else if (read1_fail || read2_fail) + puts("*** Warning - some problems detected " + "reading environment; recovered successfully\n"); - crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc; - crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc; + crc1_ok = !read1_fail && + (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc); + crc2_ok = !read2_fail && + (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc); if (!crc1_ok && !crc2_ok) { set_default_env("!bad CRC"); diff --git a/common/hash.c b/common/hash.c index e3a6e43..f5badcb 100644 --- a/common/hash.c +++ b/common/hash.c @@ -28,49 +28,87 @@ #include <hash.h> #include <sha1.h> #include <sha256.h> +#include <asm/io.h> /* * These are the hash algorithms we support. Chips which support accelerated - * crypto could perhaps add named version of these algorithms here. + * crypto could perhaps add named version of these algorithms here. Note that + * algorithm names must be in lower case. */ static struct hash_algo hash_algo[] = { -#ifdef CONFIG_SHA1 + /* + * 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. + */ +#ifdef CONFIG_CMD_SHA1SUM { - "SHA1", + "sha1", SHA1_SUM_LEN, sha1_csum_wd, CHUNKSZ_SHA1, }, +#define MULTI_HASH #endif #ifdef CONFIG_SHA256 { - "SHA256", + "sha256", SHA256_SUM_LEN, sha256_csum_wd, CHUNKSZ_SHA256, }, +#define MULTI_HASH #endif + { + "crc32", + 4, + crc32_wd_buf, + CHUNKSZ_CRC32, + }, }; +#if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_CMD_HASH) +#define MULTI_HASH +#endif + +/* Try to minimize code size for boards that don't want much hashing */ +#ifdef MULTI_HASH +#define multi_hash() 1 +#else +#define multi_hash() 0 +#endif + /** * store_result: Store the resulting sum to an address or variable * * @algo: Hash algorithm being used * @sum: Hash digest (algo->digest_size bytes) * @dest: Destination, interpreted as a hex address if it starts - * with * or otherwise as an environment variable. + * with * (or allow_env_vars is 0) or otherwise as an + * environment variable. + * @allow_env_vars: non-zero to permit storing the result to an + * variable environment */ static void store_result(struct hash_algo *algo, const u8 *sum, - const char *dest) + const char *dest, int allow_env_vars) { unsigned int i; + int env_var = 0; - if (*dest == '*') { - u8 *ptr; + /* + * If environment variables are allowed, then we assume that 'dest' + * is an environment variable, unless it starts with *, in which + * case we assume it is an address. If not allowed, it is always an + * address. This is to support the crc32 command. + */ + if (allow_env_vars) { + if (*dest == '*') + dest++; + else + env_var = 1; + } - ptr = (u8 *)simple_strtoul(dest + 1, NULL, 16); - memcpy(ptr, sum, algo->digest_size); - } else { + if (env_var) { char str_output[HASH_MAX_DIGEST_SIZE * 2 + 1]; char *str_ptr = str_output; @@ -80,6 +118,14 @@ static void store_result(struct hash_algo *algo, const u8 *sum, } str_ptr = '\0'; setenv(dest, str_output); + } else { + ulong addr; + void *buf; + + addr = simple_strtoul(dest, NULL, 16); + buf = map_sysmem(addr, algo->digest_size); + memcpy(buf, sum, algo->digest_size); + unmap_sysmem(buf); } } @@ -94,15 +140,31 @@ static void store_result(struct hash_algo *algo, const u8 *sum, * Otherwise we assume it is an environment variable, and * look up its value (it must contain a hex digest). * @vsum: Returns binary digest value (algo->digest_size bytes) + * @allow_env_vars: non-zero to permit storing the result to an environment + * variable. If 0 then verify_str is assumed to be an + * address, and the * prefix is not expected. * @return 0 if ok, non-zero on error */ -static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum) +static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum, + int allow_env_vars) { - if (*verify_str == '*') { - u8 *ptr; + int env_var = 0; + + /* See comment above in store_result() */ + if (allow_env_vars) { + if (*verify_str == '*') + verify_str++; + else + env_var = 1; + } - ptr = (u8 *)simple_strtoul(verify_str + 1, NULL, 16); - memcpy(vsum, ptr, algo->digest_size); + if (env_var) { + ulong addr; + void *buf; + + addr = simple_strtoul(verify_str, NULL, 16); + buf = map_sysmem(addr, algo->digest_size); + memcpy(vsum, buf, algo->digest_size); } else { unsigned int i; char *vsum_str; @@ -141,7 +203,7 @@ static struct hash_algo *find_hash_algo(const char *name) int i; for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { - if (!strcasecmp(name, hash_algo[i].name)) + if (!strcmp(name, hash_algo[i].name)) return &hash_algo[i]; } @@ -158,63 +220,87 @@ static void show_hash(struct hash_algo *algo, ulong addr, ulong len, printf("%02x", output[i]); } -int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag, +int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - struct hash_algo *algo; ulong addr, len; - u8 output[HASH_MAX_DIGEST_SIZE]; - u8 vsum[HASH_MAX_DIGEST_SIZE]; if (argc < 2) return CMD_RET_USAGE; - algo = find_hash_algo(algo_name); - if (!algo) { - printf("Unknown hash algorithm '%s'\n", algo_name); - return CMD_RET_USAGE; - } addr = simple_strtoul(*argv++, NULL, 16); len = simple_strtoul(*argv++, NULL, 16); - argc -= 2; - if (algo->digest_size > HASH_MAX_DIGEST_SIZE) { - puts("HASH_MAX_DIGEST_SIZE exceeded\n"); - return 1; - } + if (multi_hash()) { + struct hash_algo *algo; + u8 output[HASH_MAX_DIGEST_SIZE]; + u8 vsum[HASH_MAX_DIGEST_SIZE]; + void *buf; - algo->hash_func_ws((const unsigned char *)addr, len, output, - algo->chunk_size); + algo = find_hash_algo(algo_name); + if (!algo) { + printf("Unknown hash algorithm '%s'\n", algo_name); + return CMD_RET_USAGE; + } + argc -= 2; - /* Try to avoid code bloat when verify is not needed */ + if (algo->digest_size > HASH_MAX_DIGEST_SIZE) { + puts("HASH_MAX_DIGEST_SIZE exceeded\n"); + return 1; + } + + buf = map_sysmem(addr, len); + algo->hash_func_ws(buf, len, output, algo->chunk_size); + unmap_sysmem(buf); + + /* Try to avoid code bloat when verify is not needed */ #ifdef CONFIG_HASH_VERIFY - if (verify) { + if (flags & HASH_FLAG_VERIFY) { #else - if (0) { + if (0) { #endif - if (!argc) - return CMD_RET_USAGE; - if (parse_verify_sum(algo, *argv, vsum)) { - printf("ERROR: %s does not contain a valid %s sum\n", - *argv, algo->name); - return 1; - } - if (memcmp(output, vsum, algo->digest_size) != 0) { - int i; + if (!argc) + return CMD_RET_USAGE; + if (parse_verify_sum(algo, *argv, vsum, + flags & HASH_FLAG_ENV)) { + printf("ERROR: %s does not contain a valid " + "%s sum\n", *argv, algo->name); + return 1; + } + if (memcmp(output, vsum, algo->digest_size) != 0) { + int i; + show_hash(algo, addr, len, output); + printf(" != "); + for (i = 0; i < algo->digest_size; i++) + printf("%02x", vsum[i]); + puts(" ** ERROR **\n"); + return 1; + } + } else { show_hash(algo, addr, len, output); - printf(" != "); - for (i = 0; i < algo->digest_size; i++) - printf("%02x", vsum[i]); - puts(" ** ERROR **\n"); - return 1; + printf("\n"); + + if (argc) { + store_result(algo, output, *argv, + flags & HASH_FLAG_ENV); + } } + + /* Horrible code size hack for boards that just want crc32 */ } else { - show_hash(algo, addr, len, output); - printf("\n"); + ulong crc; + ulong *ptr; + + crc = crc32_wd(0, (const uchar *)addr, len, CHUNKSZ_CRC32); - if (argc) - store_result(algo, output, *argv); + printf("CRC32 for %08lx ... %08lx ==> %08lx\n", + addr, addr + len - 1, crc); + + if (argc > 3) { + ptr = (ulong *)simple_strtoul(argv[3], NULL, 16); + *ptr = crc; + } } return 0; diff --git a/common/image.c b/common/image.c index ae1a9d3..6afbb40 100644 --- a/common/image.c +++ b/common/image.c @@ -74,6 +74,8 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, #include <image.h> #endif /* !USE_HOSTCC*/ +#include <u-boot/crc.h> + static const table_entry_t uimage_arch[] = { { IH_ARCH_INVALID, NULL, "Invalid ARCH", }, { IH_ARCH_ALPHA, "alpha", "Alpha", }, @@ -160,8 +162,6 @@ static const table_entry_t uimage_comp[] = { { -1, "", "", }, }; -uint32_t crc32(uint32_t, const unsigned char *, uint); -uint32_t crc32_wd(uint32_t, const unsigned char *, uint, uint); #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) static void genimg_print_time(time_t timestamp); #endif diff --git a/common/lcd.c b/common/lcd.c index 66d4f94..77914ad 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -33,6 +33,8 @@ #include <common.h> #include <command.h> #include <stdarg.h> +#include <search.h> +#include <env_callback.h> #include <linux/types.h> #include <stdio_dev.h> #if defined(CONFIG_POST) @@ -384,8 +386,6 @@ int drv_lcd_init (void) lcd_base = (void *)(gd->fb_base); - lcd_get_size(&lcd_line_length); - lcd_init(lcd_base); /* LCD initialization */ /* Device initialization */ @@ -468,6 +468,8 @@ static int lcd_init(void *lcdbase) debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase); lcd_ctrl_init(lcdbase); + 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 (); @@ -1034,6 +1036,18 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) } #endif +#ifdef CONFIG_SPLASH_SCREEN_PREPARE +static inline int splash_screen_prepare(void) +{ + return board_splash_screen_prepare(); +} +#else +static inline int splash_screen_prepare(void) +{ + return 0; +} +#endif + static void *lcd_logo(void) { #ifdef CONFIG_SPLASH_SCREEN @@ -1045,6 +1059,9 @@ static void *lcd_logo(void) int x = 0, y = 0; do_splash = 0; + if (splash_screen_prepare()) + return (void *)gd->fb_base; + addr = simple_strtoul (s, NULL, 16); #ifdef CONFIG_SPLASH_SCREEN_ALIGN s = getenv("splashpos"); @@ -1084,6 +1101,30 @@ static void *lcd_logo(void) #endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */ } +#ifdef CONFIG_SPLASHIMAGE_GUARD +static int on_splashimage(const char *name, const char *value, enum env_op op, + int flags) +{ + ulong addr; + int aligned; + + if (op == env_op_delete) + return 0; + + addr = simple_strtoul(value, NULL, 16); + /* See README.displaying-bmps */ + aligned = (addr % 4 == 2); + if (!aligned) { + printf("Invalid splashimage value. Value must be 16 bit aligned, but not 32 bit aligned\n"); + return -1; + } + + return 0; +} + +U_BOOT_ENV_CALLBACK(splashimage, on_splashimage); +#endif + void lcd_position_cursor(unsigned col, unsigned row) { console_col = min(col, CONSOLE_COLS - 1); diff --git a/common/main.c b/common/main.c index e2d2e09..a15f020 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/spl/Makefile b/common/spl/Makefile index 5698a23..da2afc1 100644 --- a/common/spl/Makefile +++ b/common/spl/Makefile @@ -18,6 +18,7 @@ COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o COBJS-$(CONFIG_SPL_NOR_SUPPORT) += spl_nor.o COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o COBJS-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o +COBJS-$(CONFIG_SPL_ONENAND_SUPPORT) += spl_onenand.o COBJS-$(CONFIG_SPL_NET_SUPPORT) += spl_net.o endif diff --git a/common/spl/spl.c b/common/spl/spl.c index ff9ba7b..6715e0d 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -197,6 +197,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2) spl_nand_load_image(); break; #endif +#ifdef CONFIG_SPL_ONENAND_SUPPORT + case BOOT_DEVICE_ONENAND: + spl_onenand_load_image(); + break; +#endif #ifdef CONFIG_SPL_NOR_SUPPORT case BOOT_DEVICE_NOR: spl_nor_load_image(); @@ -221,6 +226,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2) #endif break; #endif +#ifdef CONFIG_SPL_USBETH_SUPPORT + case BOOT_DEVICE_USBETH: + spl_net_load_image("usb_ether"); + break; +#endif default: debug("SPL: Un-supported Boot Device\n"); hang(); diff --git a/common/spl/spl_onenand.c b/common/spl/spl_onenand.c new file mode 100644 index 0000000..4349303 --- /dev/null +++ b/common/spl/spl_onenand.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2013 + * ISEE 2007 SL - Enric Balletbo i Serra <eballetbo@iseebcn.com> + * + * Based on common/spl/spl_nand.c + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.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 <config.h> +#include <spl.h> +#include <asm/io.h> +#include <onenand_uboot.h> + +void spl_onenand_load_image(void) +{ + struct image_header *header; + + debug("spl: onenand\n"); + + /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); + /* Load u-boot */ + onenand_spl_load_image(CONFIG_SYS_ONENAND_U_BOOT_OFFS, + CONFIG_SYS_ONENAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + onenand_spl_load_image(CONFIG_SYS_ONENAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); +} |