diff options
author | H. Nikolaus Schaller <hns@goldelico.com> | 2010-10-20 17:37:12 +0200 |
---|---|---|
committer | H. Nikolaus Schaller <hns@goldelico.com> | 2010-10-20 17:37:12 +0200 |
commit | f2ced98aa019f0c8e33fc93cc6fe4b4bb4f48777 (patch) | |
tree | 72ea4d8d6b39f43445690fb4978219299252488c /common | |
parent | cdcd85614eaf4f332e4f107e71560b13cd6cee6f (diff) | |
parent | 11c8dd36edcc82564a19dbd0103302df66d66db0 (diff) | |
download | bootable_bootloader_goldelico_gta04-f2ced98aa019f0c8e33fc93cc6fe4b4bb4f48777.zip bootable_bootloader_goldelico_gta04-f2ced98aa019f0c8e33fc93cc6fe4b4bb4f48777.tar.gz bootable_bootloader_goldelico_gta04-f2ced98aa019f0c8e33fc93cc6fe4b4bb4f48777.tar.bz2 |
merged with denx master
Diffstat (limited to 'common')
106 files changed, 4416 insertions, 2749 deletions
diff --git a/common/Makefile b/common/Makefile index 1d717ca..40facb5 100644 --- a/common/Makefile +++ b/common/Makefile @@ -58,6 +58,7 @@ COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_embedded.o COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_embedded.o COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o COBJS-$(CONFIG_ENV_IS_IN_MG_DISK) += env_mgdisk.o +COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o diff --git a/common/cmd_ambapp.c b/common/cmd_ambapp.c index bb20ab5..fa7d7e2 100644 --- a/common/cmd_ambapp.c +++ b/common/cmd_ambapp.c @@ -223,7 +223,7 @@ void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index) printf(" irq: %-2d (ver: %d)\n", irq, ver); } -int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { /* Print AHB Masters */ @@ -272,7 +272,8 @@ int ambapp_init_reloc(void) return 0; } -U_BOOT_CMD(ambapp, 1, 1, do_ambapp_print, +U_BOOT_CMD( + ambapp, 1, 1, do_ambapp_print, "list AMBA Plug&Play information", "ambapp\n" " - lists AMBA (AHB & APB) Plug&Play devices present on the system" diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index f8400bc..1326c8f 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -31,17 +31,18 @@ DECLARE_GLOBAL_DATA_PTR; static void print_num(const char *, ulong); -#if !defined(CONFIG_ARM) || defined(CONFIG_CMD_NET) +#if !(defined(CONFIG_ARM) || defined(CONFIG_M68K)) || defined(CONFIG_CMD_NET) static void print_eth(int idx); #endif -#ifndef CONFIG_ARM /* PowerPC and other */ +#if (!defined(CONFIG_ARM) && !defined(CONFIG_X86)) static void print_lnum(const char *, u64); +#endif -#ifdef CONFIG_PPC +#if defined(CONFIG_PPC) static void print_str(const char *, const char *); -int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { bd_t *bd = gd->bd; char buf[32]; @@ -119,28 +120,9 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -#elif defined(CONFIG_NIOS) /* NIOS*/ +#elif defined(CONFIG_NIOS2) -int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - bd_t *bd = gd->bd; - - print_num ("memstart", (ulong)bd->bi_memstart); - print_lnum ("memsize", (u64)bd->bi_memsize); - print_num ("flashstart", (ulong)bd->bi_flashstart); - print_num ("flashsize", (ulong)bd->bi_flashsize); - print_num ("flashoffset", (ulong)bd->bi_flashoffset); - - print_eth(0); - printf ("ip_addr = %pI4\n", &bd->bi_ip_addr); - printf ("baudrate = %ld bps\n", bd->bi_baudrate); - - return 0; -} - -#elif defined(CONFIG_NIOS2) /* Nios-II */ - -int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { bd_t *bd = gd->bd; @@ -164,9 +146,10 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -#elif defined(CONFIG_MICROBLAZE) /* ! PPC, which leaves Microblaze */ -int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +#elif defined(CONFIG_MICROBLAZE) + +int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { bd_t *bd = gd->bd; print_num ("mem start ", (ulong)bd->bi_memstart); @@ -186,8 +169,9 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -#elif defined(CONFIG_SPARC) /* SPARC */ -int do_bdinfo(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +#elif defined(CONFIG_SPARC) + +int do_bdinfo(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { bd_t *bd = gd->bd; @@ -218,10 +202,11 @@ int do_bdinfo(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 0; } -#elif defined(CONFIG_M68K) /* M68K */ +#elif defined(CONFIG_M68K) + static void print_str(const char *, const char *); -int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { bd_t *bd = gd->bd; char buf[32]; @@ -268,9 +253,10 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } #elif defined(CONFIG_BLACKFIN) + static void print_str(const char *, const char *); -int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { bd_t *bd = gd->bd; char buf[32]; @@ -296,9 +282,9 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -#else /* ! PPC, which leaves MIPS */ +#elif defined(CONFIG_MIPS) -int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { bd_t *bd = gd->bd; @@ -315,17 +301,35 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -#endif /* MIPS */ -#else /* ARM */ +#elif defined(CONFIG_AVR32) int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { + bd_t *bd = gd->bd; + + print_num ("boot_params", (ulong)bd->bi_boot_params); + print_num ("memstart", (ulong)bd->bi_memstart); + print_lnum ("memsize", (u64)bd->bi_memsize); + print_num ("flashstart", (ulong)bd->bi_flashstart); + print_num ("flashsize", (ulong)bd->bi_flashsize); + print_num ("flashoffset", (ulong)bd->bi_flashoffset); + + print_eth(0); + printf ("ip_addr = %pI4\n", &bd->bi_ip_addr); + printf ("baudrate = %lu bps\n", bd->bi_baudrate); + + return 0; +} + +#elif defined(CONFIG_ARM) + +int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ int i; bd_t *bd = gd->bd; print_num ("arch_number", bd->bi_arch_number); - print_num ("env_t", (ulong)bd->bi_env); print_num ("boot_params", (ulong)bd->bi_boot_params); for (i=0; i<CONFIG_NR_DRAM_BANKS; ++i) { @@ -339,18 +343,86 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf ("ip_addr = %pI4\n", &bd->bi_ip_addr); #endif printf ("baudrate = %d bps\n", bd->bi_baudrate); +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) +#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE)) + print_num ("TLB addr", gd->tlb_addr); +#endif + print_num ("relocaddr", gd->relocaddr); + print_num ("reloc off", gd->reloc_off); + print_num ("irq_sp", gd->irq_sp); /* irq stack pointer */ + print_num ("sp start ", gd->start_addr_sp); + print_num ("FB base ", gd->fb_base); +#endif + return 0; +} + +#elif defined(CONFIG_SH) + +int do_bdinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + bd_t *bd = gd->bd; + print_num ("mem start ", (ulong)bd->bi_memstart); + print_lnum ("mem size ", (u64)bd->bi_memsize); + print_num ("flash start ", (ulong)bd->bi_flashstart); + print_num ("flash size ", (ulong)bd->bi_flashsize); + print_num ("flash offset ", (ulong)bd->bi_flashoffset); + +#if defined(CONFIG_CMD_NET) + print_eth(0); + printf ("ip_addr = %pI4\n", &bd->bi_ip_addr); +#endif + printf ("baudrate = %ld bps\n", (ulong)bd->bi_baudrate); + return 0; +} + +#elif defined(CONFIG_X86) + +static void print_str(const char *, const char *); + +int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int i; + bd_t *bd = gd->bd; + char buf[32]; + + print_num ("boot_params", (ulong)bd->bi_boot_params); + print_num ("bi_memstart", bd->bi_memstart); + print_num ("bi_memsize", bd->bi_memsize); + print_num ("bi_flashstart", bd->bi_flashstart); + print_num ("bi_flashsize", bd->bi_flashsize); + print_num ("bi_flashoffset", bd->bi_flashoffset); + print_num ("bi_sramstart", bd->bi_sramstart); + print_num ("bi_sramsize", bd->bi_sramsize); + print_num ("bi_bootflags", bd->bi_bootflags); + print_str ("cpufreq", strmhz(buf, bd->bi_intfreq)); + print_str ("busfreq", strmhz(buf, bd->bi_busfreq)); + + for (i=0; i<CONFIG_NR_DRAM_BANKS; ++i) { + print_num("DRAM bank", i); + print_num("-> start", bd->bi_dram[i].start); + print_num("-> size", bd->bi_dram[i].size); + } + +#if defined(CONFIG_CMD_NET) + print_eth(0); + printf ("ip_addr = %pI4\n", &bd->bi_ip_addr); + print_str ("ethspeed", strmhz(buf, bd->bi_ethspeed)); +#endif + printf ("baudrate = %d bps\n", bd->bi_baudrate); return 0; } -#endif /* CONFIG_ARM XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +#else + #error "a case for this architecture does not exist!" +#endif static void print_num(const char *name, ulong value) { printf ("%-12s= 0x%08lX\n", name, value); } -#if !defined(CONFIG_ARM) || defined(CONFIG_CMD_NET) +#if !(defined(CONFIG_ARM) || defined(CONFIG_M68K)) || defined(CONFIG_CMD_NET) static void print_eth(int idx) { char name[10], *val; @@ -365,14 +437,17 @@ static void print_eth(int idx) } #endif -#ifndef CONFIG_ARM +#if (!defined(CONFIG_ARM) && !defined(CONFIG_X86)) static void print_lnum(const char *name, u64 value) { printf ("%-12s= 0x%.8llX\n", name, value); } #endif -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_BLACKFIN) +#if defined(CONFIG_PPC) || \ + defined(CONFIG_M68K) || \ + defined(CONFIG_BLACKFIN) || \ + defined(CONFIG_X86) static void print_str(const char *name, const char *str) { printf ("%-12s= %6s MHz\n", name, str); diff --git a/common/cmd_bedbug.c b/common/cmd_bedbug.c index 8be1c25..2bd62e2 100644 --- a/common/cmd_bedbug.c +++ b/common/cmd_bedbug.c @@ -73,7 +73,7 @@ void bedbug_init (void) * Entry point from the interpreter to the disassembler. Repeated calls * will resume from the last disassembled address. * ====================================================================== */ -int do_bedbug_dis (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_dis (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { ulong addr; /* Address to start disassembly from */ ulong len; /* # of instructions to disassemble */ @@ -84,10 +84,8 @@ int do_bedbug_dis (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) addr = dis_last_addr; len = dis_last_len; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); if ((flag & CMD_FLAG_REPEAT) == 0) { /* New command */ @@ -115,7 +113,7 @@ U_BOOT_CMD (ds, 3, 1, do_bedbug_dis, * instructions in consecutive memory locations until a '.' (period) is * entered on a line by itself. * ====================================================================== */ -int do_bedbug_asm (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_asm (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { long mem_addr; /* Address to assemble into */ unsigned long instr; /* Machine code for text */ @@ -125,10 +123,8 @@ int do_bedbug_asm (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /* -------------------------------------------------- */ int rcode = 0; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); printf ("\nEnter '.' when done\n"); mem_addr = simple_strtoul (argv[1], NULL, 16); @@ -167,7 +163,7 @@ U_BOOT_CMD (as, 2, 0, do_bedbug_asm, * CPU-specific break point set routine. * ====================================================================== */ -int do_bedbug_break (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_break (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { /* -------------------------------------------------- */ if (bug_ctx.do_break) @@ -263,7 +259,7 @@ void bedbug_main_loop (unsigned long addr, struct pt_regs *regs) * stopped flag in the context so that the breakpoint routine will * return. * ====================================================================== */ -int do_bedbug_continue (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_continue (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { /* -------------------------------------------------- */ @@ -286,7 +282,7 @@ U_BOOT_CMD (continue, 1, 0, do_bedbug_continue, * the address passes control to the CPU-specific set breakpoint routine * for the current breakpoint number. * ====================================================================== */ -int do_bedbug_step (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_step (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { unsigned long addr; /* Address to stop at */ @@ -317,7 +313,7 @@ U_BOOT_CMD (step, 1, 1, do_bedbug_step, * the address passes control to the CPU-specific set breakpoint routine * for the current breakpoint number. * ====================================================================== */ -int do_bedbug_next (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_next (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { unsigned long addr; /* Address to stop at */ @@ -346,7 +342,7 @@ U_BOOT_CMD (next, 1, 1, do_bedbug_next, * Interpreter command to print the current stack. This assumes an EABI * architecture, so it starts with GPR R1 and works back up the stack. * ====================================================================== */ -int do_bedbug_stack (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_stack (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { unsigned long sp; /* Stack pointer */ unsigned long func; /* LR from stack */ @@ -391,7 +387,7 @@ U_BOOT_CMD (where, 1, 1, do_bedbug_stack, * Interpreter command to dump the registers. Calls the CPU-specific * show registers routine. * ====================================================================== */ -int do_bedbug_rdump (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_bedbug_rdump (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { /* -------------------------------------------------- */ diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c index 74ab24c..6fa8a15 100644 --- a/common/cmd_bmp.c +++ b/common/cmd_bmp.c @@ -90,6 +90,58 @@ bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp) } #endif +static int do_bmp_info(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + ulong addr; + + switch (argc) { + case 1: /* use load_addr as default address */ + addr = load_addr; + break; + case 2: /* use argument */ + addr = simple_strtoul(argv[1], NULL, 16); + break; + default: + return cmd_usage(cmdtp); + } + + return (bmp_info(addr)); +} + +static int do_bmp_display(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + ulong addr; + int x = 0, y = 0; + + switch (argc) { + case 1: /* use load_addr as default address */ + addr = load_addr; + break; + case 2: /* use argument */ + addr = simple_strtoul(argv[1], NULL, 16); + break; + case 4: + addr = simple_strtoul(argv[1], NULL, 16); + x = simple_strtoul(argv[2], NULL, 10); + y = simple_strtoul(argv[3], NULL, 10); + break; + default: + return cmd_usage(cmdtp); + } + + return (bmp_display(addr, x, y)); +} + +static cmd_tbl_t cmd_bmp_sub[] = { + U_BOOT_CMD_MKENT(info, 3, 0, do_bmp_info, "", ""), + U_BOOT_CMD_MKENT(display, 5, 0, do_bmp_display, "", ""), +}; + +#ifndef CONFIG_RELOC_FIXUP_WORKS +void bmp_reloc(void) { + fixup_cmdtable(cmd_bmp_sub, ARRAY_SIZE(cmd_bmp_sub)); +} +#endif /* * Subroutine: do_bmp @@ -101,39 +153,20 @@ bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp) * Return: None * */ -int do_bmp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static int do_bmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - ulong addr; - int x = 0, y = 0; + cmd_tbl_t *c; - switch (argc) { - case 2: /* use load_addr as default address */ - addr = load_addr; - break; - case 3: /* use argument */ - addr = simple_strtoul(argv[2], NULL, 16); - break; - case 5: - addr = simple_strtoul(argv[2], NULL, 16); - x = simple_strtoul(argv[3], NULL, 10); - y = simple_strtoul(argv[4], NULL, 10); - break; - default: - cmd_usage(cmdtp); - return 1; - } + /* Strip off leading 'bmp' command argument */ + argc--; + argv++; - /* Allow for short names - * Adjust length if more sub-commands get added - */ - if (strncmp(argv[1],"info",1) == 0) { - return (bmp_info(addr)); - } else if (strncmp(argv[1],"display",1) == 0) { - return (bmp_display(addr, x, y)); - } else { - cmd_usage(cmdtp); - return 1; - } + c = find_cmd_tbl(argv[0], &cmd_bmp_sub[0], ARRAY_SIZE(cmd_bmp_sub)); + + if (c) + return c->cmd(cmdtp, flag, argc, argv); + else + return cmd_usage(cmdtp); } U_BOOT_CMD( diff --git a/common/cmd_boot.c b/common/cmd_boot.c index bfc1db2..72dacaa 100644 --- a/common/cmd_boot.c +++ b/common/cmd_boot.c @@ -30,20 +30,18 @@ /* Allow ports to override the default behavior */ __attribute__((weak)) -unsigned long do_go_exec (ulong (*entry)(int, char *[]), int argc, char *argv[]) +unsigned long do_go_exec (ulong (*entry)(int, char * const []), int argc, char * const argv[]) { return entry (argc, argv); } -int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr, rc; int rcode = 0; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); addr = simple_strtoul(argv[1], NULL, 16); @@ -69,7 +67,7 @@ U_BOOT_CMD( " passing 'arg' as arguments" ); -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); U_BOOT_CMD( reset, 1, 0, do_reset, diff --git a/common/cmd_bootldr.c b/common/cmd_bootldr.c index b2a8b0e..535b931 100644 --- a/common/cmd_bootldr.c +++ b/common/cmd_bootldr.c @@ -142,7 +142,7 @@ static void ldr_exec(void *addr) * to also add booting from SPI, or TWI, but this function does * not currently support that. */ -int do_bootldr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bootldr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { void *addr; @@ -167,7 +167,8 @@ int do_bootldr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -U_BOOT_CMD(bootldr, 2, 0, do_bootldr, +U_BOOT_CMD( + bootldr, 2, 0, do_bootldr, "boot ldr image from memory", "[addr]\n" "" diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 995e378..ce3c77c 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -77,8 +77,9 @@ static int image_info (unsigned long addr); #if defined(CONFIG_CMD_IMLS) #include <flash.h> +#include <mtd/cfi_flash.h> extern flash_info_t flash_info[]; /* info for FLASH chips */ -static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); #endif #ifdef CONFIG_SILENT_CONSOLE @@ -90,9 +91,9 @@ static image_header_t *image_get_kernel (ulong img_addr, int verify); static int fit_check_kernel (const void *fit, int os_noffset, int verify); #endif -static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char *argv[], +static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char * const argv[], bootm_headers_t *images, ulong *os_data, ulong *os_len); -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); /* * Continue booting an OS image; caller already has: @@ -102,7 +103,7 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); * - loaded (first part of) image to header load address, * - disabled interrupts. */ -typedef int boot_os_fn (int flag, int argc, char *argv[], +typedef int boot_os_fn (int flag, int argc, char * const argv[], bootm_headers_t *images); /* pointers to os/initrd/fdt */ #ifdef CONFIG_BOOTM_LINUX @@ -118,11 +119,14 @@ extern void lynxkdi_boot (image_header_t *); #ifdef CONFIG_BOOTM_RTEMS static boot_os_fn do_bootm_rtems; #endif +#if defined(CONFIG_BOOTM_OSE) +static boot_os_fn do_bootm_ose; +#endif #if defined(CONFIG_CMD_ELF) static boot_os_fn do_bootm_vxworks; static boot_os_fn do_bootm_qnxelf; -int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); -int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); #endif #if defined(CONFIG_INTEGRITY) static boot_os_fn do_bootm_integrity; @@ -141,6 +145,9 @@ static boot_os_fn *boot_os[] = { #ifdef CONFIG_BOOTM_RTEMS [IH_OS_RTEMS] = do_bootm_rtems, #endif +#if defined(CONFIG_BOOTM_OSE) + [IH_OS_OSE] = do_bootm_ose, +#endif #if defined(CONFIG_CMD_ELF) [IH_OS_VXWORKS] = do_bootm_vxworks, [IH_OS_QNX] = do_bootm_qnxelf, @@ -174,8 +181,6 @@ void arch_preboot_os(void) __attribute__((weak, alias("__arch_preboot_os"))); #define IH_INITRD_ARCH IH_ARCH_MICROBLAZE #elif defined(__mips__) #define IH_INITRD_ARCH IH_ARCH_MIPS -#elif defined(__nios__) - #define IH_INITRD_ARCH IH_ARCH_NIOS #elif defined(__nios2__) #define IH_INITRD_ARCH IH_ARCH_NIOS2 #elif defined(__PPC__) @@ -208,7 +213,7 @@ static void bootm_start_lmb(void) #endif } -static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { void *os_hdr; int ret; @@ -303,7 +308,6 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } #if defined(CONFIG_OF_LIBFDT) -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) /* find flattened device tree */ ret = boot_get_fdt (flag, argc, argv, &images, &images.ft_addr, &images.ft_len); @@ -314,7 +318,6 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) set_working_fdt_addr(images.ft_addr); #endif -#endif } images.os.start = (ulong)os_hdr; @@ -335,6 +338,9 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress) ulong image_start = os.image_start; ulong image_len = os.image_len; uint unc_len = CONFIG_SYS_BOOTM_LEN; +#if defined(CONFIG_LZMA) || defined(CONFIG_LZO) + int ret; +#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */ const char *type_name = genimg_get_type_name (os.type); @@ -344,11 +350,8 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress) printf (" XIP %s ... ", type_name); } else { printf (" Loading %s ... ", type_name); - - if (load != image_start) { - memmove_wd ((void *)load, - (void *)image_start, image_len, CHUNKSZ); - } + memmove_wd ((void *)load, (void *)image_start, + image_len, CHUNKSZ); } *load_end = load + image_len; puts("OK\n"); @@ -391,12 +394,14 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress) break; #endif /* CONFIG_BZIP2 */ #ifdef CONFIG_LZMA - case IH_COMP_LZMA: + case IH_COMP_LZMA: { + SizeT lzma_len = unc_len; printf (" Uncompressing %s ... ", type_name); - int ret = lzmaBuffToBuffDecompress( - (unsigned char *)load, &unc_len, + ret = lzmaBuffToBuffDecompress( + (unsigned char *)load, &lzma_len, (unsigned char *)image_start, image_len); + unc_len = lzma_len; if (ret != SZ_OK) { printf ("LZMA: uncompress or overwrite error %d " "- must RESET board to recover\n", ret); @@ -405,12 +410,13 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress) } *load_end = load + unc_len; break; + } #endif /* CONFIG_LZMA */ #ifdef CONFIG_LZO case IH_COMP_LZO: printf (" Uncompressing %s ... ", type_name); - int ret = lzop_decompress((const unsigned char *)image_start, + ret = lzop_decompress((const unsigned char *)image_start, image_len, (unsigned char *)load, &unc_len); if (ret != LZO_E_OK) { @@ -443,10 +449,10 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress) return 0; } -static int bootm_start_standalone(ulong iflag, int argc, char *argv[]) +static int bootm_start_standalone(ulong iflag, int argc, char * const argv[]) { char *s; - int (*appl)(int, char *[]); + int (*appl)(int, char * const []); /* Don't start if "autostart" is set to "no" */ if (((s = getenv("autostart")) != NULL) && (strcmp(s, "no") == 0)) { @@ -455,7 +461,7 @@ static int bootm_start_standalone(ulong iflag, int argc, char *argv[]) setenv("filesize", buf); return 0; } - appl = (int (*)(int, char *[]))ntohl(images.ep); + appl = (int (*)(int, char * const []))ntohl(images.ep); (*appl)(argc-1, &argv[1]); return 0; @@ -463,10 +469,10 @@ static int bootm_start_standalone(ulong iflag, int argc, char *argv[]) /* we overload the cmd field with our state machine info instead of a * function pointer */ -cmd_tbl_t cmd_bootm_sub[] = { +static cmd_tbl_t cmd_bootm_sub[] = { U_BOOT_CMD_MKENT(start, 0, 1, (void *)BOOTM_STATE_START, "", ""), U_BOOT_CMD_MKENT(loados, 0, 1, (void *)BOOTM_STATE_LOADOS, "", ""), -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH U_BOOT_CMD_MKENT(ramdisk, 0, 1, (void *)BOOTM_STATE_RAMDISK, "", ""), #endif #ifdef CONFIG_OF_LIBFDT @@ -478,7 +484,7 @@ cmd_tbl_t cmd_bootm_sub[] = { U_BOOT_CMD_MKENT(go, 0, 1, (void *)BOOTM_STATE_OS_GO, "", ""), }; -int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int ret = 0; int state; @@ -496,17 +502,14 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) argv++; return bootm_start(cmdtp, flag, argc, argv); } - } - /* Unrecognized command */ - else { - cmd_usage(cmdtp); - return 1; + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); } if (images.state >= state) { printf ("Trying to execute a command out of order\n"); - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } images.state |= state; @@ -525,7 +528,7 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); break; -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH case BOOTM_STATE_RAMDISK: { ulong rd_len = images.rd_end - images.rd_start; @@ -581,7 +584,7 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* bootm - boot application image from image in memory */ /*******************************************************************/ -int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong iflag; ulong load_end = 0; @@ -640,15 +643,6 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) usb_stop(); #endif -#ifdef CONFIG_AMIGAONEG3SE - /* - * We've possible left the caches enabled during - * bios emulation, so turn them off again - */ - icache_disable(); - dcache_disable(); -#endif - ret = bootm_load_os(images.os, &load_end, 1); if (ret < 0) { @@ -825,7 +819,7 @@ static int fit_check_kernel (const void *fit, int os_noffset, int verify) * pointer to image header if valid image was found, plus kernel start * address and length, otherwise NULL */ -static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], bootm_headers_t *images, ulong *os_data, ulong *os_len) { image_header_t *hdr; @@ -1026,7 +1020,7 @@ U_BOOT_CMD( /* bootd - boot default image */ /*******************************************************************/ #if defined(CONFIG_CMD_BOOTD) -int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int rcode = 0; @@ -1061,7 +1055,7 @@ U_BOOT_CMD( /* iminfo - print header info for a requested image */ /*******************************************************************/ #if defined(CONFIG_CMD_IMI) -int do_iminfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_iminfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int arg; ulong addr; @@ -1148,7 +1142,7 @@ U_BOOT_CMD( /* imls - list all images found in flash */ /*******************************************************************/ #if defined(CONFIG_CMD_IMLS) -int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { flash_info_t *info; int i, j; @@ -1251,7 +1245,7 @@ static void fixup_silent_linux () /*******************************************************************/ #ifdef CONFIG_BOOTM_NETBSD -static int do_bootm_netbsd (int flag, int argc, char *argv[], +static int do_bootm_netbsd (int flag, int argc, char * const argv[], bootm_headers_t *images) { void (*loader)(bd_t *, image_header_t *, char *, char *); @@ -1339,7 +1333,7 @@ static int do_bootm_netbsd (int flag, int argc, char *argv[], #endif /* CONFIG_BOOTM_NETBSD*/ #ifdef CONFIG_LYNXKDI -static int do_bootm_lynxkdi (int flag, int argc, char *argv[], +static int do_bootm_lynxkdi (int flag, int argc, char * const argv[], bootm_headers_t *images) { image_header_t *hdr = &images->legacy_hdr_os_copy; @@ -1361,7 +1355,7 @@ static int do_bootm_lynxkdi (int flag, int argc, char *argv[], #endif /* CONFIG_LYNXKDI */ #ifdef CONFIG_BOOTM_RTEMS -static int do_bootm_rtems (int flag, int argc, char *argv[], +static int do_bootm_rtems (int flag, int argc, char * const argv[], bootm_headers_t *images) { void (*entry_point)(bd_t *); @@ -1393,8 +1387,41 @@ static int do_bootm_rtems (int flag, int argc, char *argv[], } #endif /* CONFIG_BOOTM_RTEMS */ +#if defined(CONFIG_BOOTM_OSE) +static int do_bootm_ose (int flag, int argc, char * const argv[], + bootm_headers_t *images) +{ + void (*entry_point)(void); + + if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) + return 1; + +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("OSE"); + return 1; + } +#endif + + entry_point = (void (*)(void))images->ep; + + printf ("## Transferring control to OSE (at address %08lx) ...\n", + (ulong)entry_point); + + show_boot_progress (15); + + /* + * OSE Parameters: + * None + */ + (*entry_point)(); + + return 1; +} +#endif /* CONFIG_BOOTM_OSE */ + #if defined(CONFIG_CMD_ELF) -static int do_bootm_vxworks (int flag, int argc, char *argv[], +static int do_bootm_vxworks (int flag, int argc, char * const argv[], bootm_headers_t *images) { char str[80]; @@ -1416,7 +1443,7 @@ static int do_bootm_vxworks (int flag, int argc, char *argv[], return 1; } -static int do_bootm_qnxelf(int flag, int argc, char *argv[], +static int do_bootm_qnxelf(int flag, int argc, char * const argv[], bootm_headers_t *images) { char *local_args[2]; @@ -1442,7 +1469,7 @@ static int do_bootm_qnxelf(int flag, int argc, char *argv[], #endif #ifdef CONFIG_INTEGRITY -static int do_bootm_integrity (int flag, int argc, char *argv[], +static int do_bootm_integrity (int flag, int argc, char * const argv[], bootm_headers_t *images) { void (*entry_point)(void); diff --git a/common/cmd_cache.c b/common/cmd_cache.c index 1202258..5cdd834 100644 --- a/common/cmd_cache.c +++ b/common/cmd_cache.c @@ -29,15 +29,11 @@ static int on_off (const char *); -int do_icache ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_icache ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { switch (argc) { case 2: /* on / off */ switch (on_off(argv[1])) { -#if 0 /* prevented by varargs handling; FALLTROUGH is harmless, too */ - default: cmd_usage(cmdtp); - return; -#endif case 0: icache_disable(); break; case 1: icache_enable (); @@ -49,21 +45,16 @@ int do_icache ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) icache_status() ? "ON" : "OFF"); return 0; default: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } return 0; } -int do_dcache ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_dcache ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { switch (argc) { case 2: /* on / off */ switch (on_off(argv[1])) { -#if 0 /* prevented by varargs handling; FALLTROUGH is harmless, too */ - default: cmd_usage(cmdtp); - return; -#endif case 0: dcache_disable(); break; case 1: dcache_enable (); @@ -75,8 +66,7 @@ int do_dcache ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) dcache_status() ? "ON" : "OFF"); return 0; default: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } return 0; diff --git a/common/cmd_console.c b/common/cmd_console.c index 178fbfe..d8cad6b 100644 --- a/common/cmd_console.c +++ b/common/cmd_console.c @@ -29,7 +29,7 @@ #include <stdio_dev.h> extern void _do_coninfo (void); -int do_coninfo (cmd_tbl_t * cmd, int flag, int argc, char *argv[]) +int do_coninfo (cmd_tbl_t * cmd, int flag, int argc, char * const argv[]) { int l; struct list_head *list = stdio_get_list(); diff --git a/common/cmd_cplbinfo.c b/common/cmd_cplbinfo.c index 1a044d2..ab5b3b5 100644 --- a/common/cmd_cplbinfo.c +++ b/common/cmd_cplbinfo.c @@ -42,7 +42,7 @@ static void show_cplb_table(uint32_t *addr, uint32_t *data) /* * display current instruction and data cplb tables */ -int do_cplbinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_cplbinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { printf("%s CPLB table [%08x]:\n", "Instruction", *(uint32_t *)DMEM_CONTROL); show_cplb_table((uint32_t *)ICPLB_ADDR0, (uint32_t *)ICPLB_DATA0); @@ -53,7 +53,8 @@ int do_cplbinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -U_BOOT_CMD(cplbinfo, 1, 0, do_cplbinfo, +U_BOOT_CMD( + cplbinfo, 1, 0, do_cplbinfo, "display current CPLB tables", "" ); diff --git a/common/cmd_cramfs.c b/common/cmd_cramfs.c index 55e2d36..8c86dc5 100644 --- a/common/cmd_cramfs.c +++ b/common/cmd_cramfs.c @@ -98,7 +98,7 @@ extern int cramfs_info (struct part_info *info); * @param argv arguments list * @return 0 on success, 1 otherwise */ -int do_cramfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_cramfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename; int size; @@ -163,7 +163,7 @@ int do_cramfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * @param argv arguments list * @return 0 on success, 1 otherwise */ -int do_cramfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_cramfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = "/"; int ret; @@ -199,14 +199,14 @@ int do_cramfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /***************************************************/ U_BOOT_CMD( cramfsload, 3, 0, do_cramfs_load, - "cramfsload\t- load binary file from a filesystem image", + "load binary file from a filesystem image", "[ off ] [ filename ]\n" " - load binary file from address 'cramfsaddr'\n" " with offset 'off'\n" ); U_BOOT_CMD( cramfsls, 2, 1, do_cramfs_ls, - "cramfsls\t- list files in a directory (default /)", + "list files in a directory (default /)", "[ directory ]\n" " - list files in a directory.\n" ); diff --git a/common/cmd_dataflash_mmc_mux.c b/common/cmd_dataflash_mmc_mux.c index 97e303e..1678d6e 100644 --- a/common/cmd_dataflash_mmc_mux.c +++ b/common/cmd_dataflash_mmc_mux.c @@ -26,7 +26,7 @@ static int mmc_nspi (const char *); -int do_dataflash_mmc_mux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_dataflash_mmc_mux (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { switch (argc) { case 2: /* on / off */ @@ -41,8 +41,7 @@ int do_dataflash_mmc_mux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) AT91F_GetMuxStatus () ? "MMC" : "SPI"); return 0; default: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; + return cmd_usage(cmdtp); } return 0; } @@ -59,7 +58,7 @@ static int mmc_nspi (const char *s) U_BOOT_CMD( dataflash_mmc_mux, 2, 1, do_dataflash_mmc_mux, - "dataflash_mmc_mux\t- enable or disable MMC or SPI\n", + "enable or disable MMC or SPI\n", "[mmc, spi]\n" " - enable or disable MMC or SPI" ); diff --git a/common/cmd_date.c b/common/cmd_date.c index 3141a39..50b4240 100644 --- a/common/cmd_date.c +++ b/common/cmd_date.c @@ -43,7 +43,7 @@ const char *weekdays[] = { int mk_date (char *, struct rtc_time *); -int do_date (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_date (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct rtc_time tm; int rcode = 0; diff --git a/common/cmd_dcr.c b/common/cmd_dcr.c index 4f23b8d..45fe66a 100644 --- a/common/cmd_dcr.c +++ b/common/cmd_dcr.c @@ -36,7 +36,7 @@ unsigned long set_dcr (unsigned short, unsigned long); * Interpreter command to retrieve an AMCC PPC 4xx Device Control Register * ======================================================================= */ -int do_getdcr ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] ) +int do_getdcr ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] ) { unsigned short dcrn; /* Device Control Register Num */ unsigned long value; /* DCR's value */ @@ -44,10 +44,8 @@ int do_getdcr ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] ) unsigned long get_dcr (unsigned short); /* Validate arguments */ - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); /* Get a DCR */ dcrn = (unsigned short) simple_strtoul (argv[1], NULL, 16); @@ -63,7 +61,7 @@ int do_getdcr ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] ) * Interpreter command to set an AMCC PPC 4xx Device Control Register * ====================================================================== */ -int do_setdcr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_setdcr (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { unsigned short dcrn; /* Device Control Register Num */ unsigned long value; @@ -73,10 +71,8 @@ int do_setdcr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) extern char console_buffer[]; /* Validate arguments */ - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); /* Set a DCR */ dcrn = (unsigned short) simple_strtoul (argv[1], NULL, 16); @@ -110,7 +106,7 @@ int do_setdcr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) * Device Control Register inderect addressing. * ======================================================================= */ -int do_getidcr (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_getidcr (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned short adr_dcrn; /* Device Control Register Num for Address */ unsigned short dat_dcrn; /* Device Control Register Num for Data */ @@ -120,10 +116,8 @@ int do_getidcr (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char buf[80]; /* Validate arguments */ - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); /* Find out whether ther is '.' (dot) symbol in the first parameter. */ strncpy (buf, argv[1], sizeof(buf)-1); @@ -166,7 +160,7 @@ int do_getidcr (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * Device Control Register inderect addressing. * ======================================================================= */ -int do_setidcr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_setidcr (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { unsigned short adr_dcrn; /* Device Control Register Num for Address */ unsigned short dat_dcrn; /* Device Control Register Num for Data */ @@ -176,10 +170,8 @@ int do_setidcr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) char buf[80]; /* Validate arguments */ - if (argc < 4) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 4) + return cmd_usage(cmdtp); /* Find out whether ther is '.' (dot) symbol in the first parameter. */ strncpy (buf, argv[1], sizeof(buf)-1); diff --git a/common/cmd_df.c b/common/cmd_df.c index 7f957fe..9a3c84c 100644 --- a/common/cmd_df.c +++ b/common/cmd_df.c @@ -6,7 +6,7 @@ #include <common.h> #include <df.h> -static int do_df(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static int do_df(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { const char *cmd; @@ -27,8 +27,7 @@ static int do_df(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } usage: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } U_BOOT_CMD( diff --git a/common/cmd_diag.c b/common/cmd_diag.c index 0436c49..317ea66 100644 --- a/common/cmd_diag.c +++ b/common/cmd_diag.c @@ -28,7 +28,7 @@ #include <command.h> #include <post.h> -int do_diag (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_diag (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { unsigned int i; diff --git a/common/cmd_display.c b/common/cmd_display.c index 3422395..d5d5d8c 100644 --- a/common/cmd_display.c +++ b/common/cmd_display.c @@ -23,40 +23,32 @@ #include <common.h> #include <command.h> +#include <led-display.h> #undef DEBUG_DISP -#define DISP_SIZE 8 -#define CWORD_CLEAR 0x80 -#define CLEAR_DELAY (110 * 2) - -int do_display (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_display (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int i; - int pos; /* Clear display */ - *((volatile char*)(CONFIG_SYS_DISP_CWORD)) = CWORD_CLEAR; - udelay(1000 * CLEAR_DELAY); + display_set(DISPLAY_CLEAR | DISPLAY_HOME); if (argc < 2) return (0); - for (pos = 0, i = 1; i < argc && pos < DISP_SIZE; i++) { - char *p = argv[i], c; + for (i = 1; i < argc; i++) { + char *p = argv[i]; - if (i > 1) { - *((volatile uchar *) (CONFIG_SYS_DISP_CHR_RAM + pos++)) = ' '; -#ifdef DEBUG_DISP - putc(' '); -#endif + if (i > 1) { /* Insert a space between strings */ + display_putc(' '); } - while ((c = *p++) != '\0' && pos < DISP_SIZE) { - *((volatile uchar *) (CONFIG_SYS_DISP_CHR_RAM + pos++)) = c; + while ((*p)) { #ifdef DEBUG_DISP - putc(c); + putc(*p); #endif + display_putc(*p++); } } diff --git a/common/cmd_dtt.c b/common/cmd_dtt.c index 3cfd36e..3388e43 100644 --- a/common/cmd_dtt.c +++ b/common/cmd_dtt.c @@ -28,7 +28,7 @@ #include <dtt.h> #include <i2c.h> -int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { int i; unsigned char sensors[] = CONFIG_DTT_SENSORS; diff --git a/common/cmd_echo.c b/common/cmd_echo.c index 3ec4d48..43a6da5 100644 --- a/common/cmd_echo.c +++ b/common/cmd_echo.c @@ -24,7 +24,7 @@ #include <common.h> #include <command.h> -int do_echo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_echo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int i; int putnl = 1; diff --git a/common/cmd_eeprom.c b/common/cmd_eeprom.c index 519b510..9f4b22c 100644 --- a/common/cmd_eeprom.c +++ b/common/cmd_eeprom.c @@ -60,7 +60,7 @@ extern int eeprom_write_enable (unsigned dev_addr, int state); /* ------------------------------------------------------------------------- */ #if defined(CONFIG_CMD_EEPROM) -int do_eeprom ( cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_eeprom ( cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { const char *const fmt = "\nEEPROM @0x%lX %s: addr %08lx off %04lx count %ld ... "; @@ -104,8 +104,7 @@ int do_eeprom ( cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } } - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } #endif diff --git a/common/cmd_elf.c b/common/cmd_elf.c index 63f6fe7..bf32612 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -25,11 +25,13 @@ DECLARE_GLOBAL_DATA_PTR; #endif int valid_elf_image (unsigned long addr); -unsigned long load_elf_image (unsigned long addr); +static unsigned long load_elf_image_phdr(unsigned long addr); +static unsigned long load_elf_image_shdr(unsigned long addr); /* Allow ports to override the default behavior */ __attribute__((weak)) -unsigned long do_bootelf_exec (ulong (*entry)(int, char *[]), int argc, char *argv[]) +unsigned long do_bootelf_exec (ulong (*entry)(int, char * const[]), + int argc, char * const argv[]) { unsigned long ret; @@ -56,23 +58,38 @@ unsigned long do_bootelf_exec (ulong (*entry)(int, char *[]), int argc, char *ar /* ====================================================================== * Interpreter command to boot an arbitrary ELF image from memory. * ====================================================================== */ -int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long addr; /* Address of the ELF image */ unsigned long rc; /* Return value from user code */ + char *sload, *saddr; /* -------------------------------------------------- */ int rcode = 0; - if (argc < 2) - addr = load_addr; + sload = saddr = NULL; + if (argc == 3) { + sload = argv[1]; + saddr = argv[2]; + } else if (argc == 2) { + if (argv[1][0] == '-') + sload = argv[1]; + else + saddr = argv[1]; + } + + if (saddr) + addr = simple_strtoul(saddr, NULL, 16); else - addr = simple_strtoul (argv[1], NULL, 16); + addr = load_addr; if (!valid_elf_image (addr)) return 1; - addr = load_elf_image (addr); + if (sload && sload[1] == 'p') + addr = load_elf_image_phdr(addr); + else + addr = load_elf_image_shdr(addr); printf ("## Starting application at 0x%08lx ...\n", addr); @@ -93,7 +110,7 @@ int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * be either an ELF image or a raw binary. Will attempt to setup the * bootline and other parameters correctly. * ====================================================================== */ -int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long addr; /* Address of image */ unsigned long bootaddr; /* Address to put the bootline */ @@ -203,7 +220,7 @@ int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ if (valid_elf_image (addr)) { - addr = load_elf_image (addr); + addr = load_elf_image_shdr (addr); } else { puts ("## Not an ELF image, assuming binary\n"); /* leave addr as load_addr */ @@ -257,7 +274,33 @@ int valid_elf_image (unsigned long addr) * A very simple elf loader, assumes the image is valid, returns the * entry point address. * ====================================================================== */ -unsigned long load_elf_image (unsigned long addr) +static unsigned long load_elf_image_phdr(unsigned long addr) +{ + Elf32_Ehdr *ehdr; /* Elf header structure pointer */ + Elf32_Phdr *phdr; /* Program header structure pointer */ + int i; + + ehdr = (Elf32_Ehdr *) addr; + phdr = (Elf32_Phdr *) (addr + ehdr->e_phoff); + + /* Load each program header */ + for (i = 0; i < ehdr->e_phnum; ++i) { + void *dst = (void *) phdr->p_paddr; + void *src = (void *) addr + phdr->p_offset; + debug("Loading phdr %i to 0x%p (%i bytes)\n", + i, dst, phdr->p_filesz); + if (phdr->p_filesz) + memcpy(dst, src, phdr->p_filesz); + if (phdr->p_filesz != phdr->p_memsz) + memset(dst + phdr->p_filesz, 0x00, phdr->p_memsz - phdr->p_filesz); + flush_cache((unsigned long)dst, phdr->p_filesz); + ++phdr; + } + + return ehdr->e_entry; +} + +static unsigned long load_elf_image_shdr(unsigned long addr) { Elf32_Ehdr *ehdr; /* Elf header structure pointer */ Elf32_Shdr *shdr; /* Section header structure pointer */ @@ -311,9 +354,11 @@ unsigned long load_elf_image (unsigned long addr) /* ====================================================================== */ U_BOOT_CMD( - bootelf, 2, 0, do_bootelf, + bootelf, 3, 0, do_bootelf, "Boot from an ELF image in memory", - " [address] - load address of ELF image." + "[-p|-s] [address]\n" + "\t- load ELF image at [address] via program headers (-p)\n" + "\t or via section headers (-s)" ); U_BOOT_CMD( diff --git a/common/cmd_exit.c b/common/cmd_exit.c index ed876d8..f3fc8f5 100644 --- a/common/cmd_exit.c +++ b/common/cmd_exit.c @@ -24,7 +24,7 @@ #include <common.h> #include <command.h> -int do_exit(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_exit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int r; diff --git a/common/cmd_ext2.c b/common/cmd_ext2.c index b7e4048..35fb361 100644 --- a/common/cmd_ext2.c +++ b/common/cmd_ext2.c @@ -56,7 +56,7 @@ #define PRINTF(fmt,args...) #endif -int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = "/"; int dev=0; @@ -65,10 +65,9 @@ int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) block_dev_desc_t *dev_desc=NULL; int part_length; - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); + dev = (int)simple_strtoul (argv[2], &ep, 16); dev_desc = get_dev(argv[1],dev); @@ -123,7 +122,7 @@ U_BOOT_CMD( /****************************************************************************** * Ext2fs boot command intepreter. Derived from diskboot */ -int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = NULL; char *ep; @@ -164,8 +163,7 @@ int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; default: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } if (!filename) { diff --git a/common/cmd_fat.c b/common/cmd_fat.c index f3089a2..0220494 100644 --- a/common/cmd_fat.c +++ b/common/cmd_fat.c @@ -33,7 +33,7 @@ #include <fat.h> -int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { long size; unsigned long offset; @@ -45,39 +45,43 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *ep; if (argc < 5) { - printf ("usage: fatload <interface> <dev[:part]> <addr> <filename> [bytes]\n"); + printf( "usage: fatload <interface> <dev[:part]> " + "<addr> <filename> [bytes]\n"); return 1; } - dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc=get_dev(argv[1],dev); - if (dev_desc==NULL) { - puts ("\n** Invalid boot device **\n"); + + dev = (int)simple_strtoul(argv[2], &ep, 16); + dev_desc = get_dev(argv[1],dev); + if (dev_desc == NULL) { + puts("\n** Invalid boot device **\n"); return 1; } if (*ep) { if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); + puts("\n** Invalid boot device, use `dev[:part]' **\n"); return 1; } part = (int)simple_strtoul(++ep, NULL, 16); } if (fat_register_device(dev_desc,part)!=0) { - printf ("\n** Unable to use %s %d:%d for fatload **\n",argv[1],dev,part); + printf("\n** Unable to use %s %d:%d for fatload **\n", + argv[1], dev, part); return 1; } - offset = simple_strtoul (argv[3], NULL, 16); + offset = simple_strtoul(argv[3], NULL, 16); if (argc == 6) - count = simple_strtoul (argv[5], NULL, 16); + count = simple_strtoul(argv[5], NULL, 16); else count = 0; - size = file_fat_read (argv[4], (unsigned char *) offset, count); + size = file_fat_read(argv[4], (unsigned char *)offset, count); if(size==-1) { - printf("\n** Unable to read \"%s\" from %s %d:%d **\n",argv[4],argv[1],dev,part); + printf("\n** Unable to read \"%s\" from %s %d:%d **\n", + argv[4], argv[1], dev, part); return 1; } - printf ("\n%ld bytes read\n", size); + printf("\n%ld bytes read\n", size); sprintf(buf, "%lX", size); setenv("filesize", buf); @@ -94,7 +98,7 @@ U_BOOT_CMD( " to address 'addr' from dos filesystem" ); -int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = "/"; int ret; @@ -104,34 +108,35 @@ int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) block_dev_desc_t *dev_desc=NULL; if (argc < 3) { - printf ("usage: fatls <interface> <dev[:part]> [directory]\n"); - return (0); + printf("usage: fatls <interface> <dev[:part]> [directory]\n"); + return 0; } - dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc=get_dev(argv[1],dev); - if (dev_desc==NULL) { - puts ("\n** Invalid boot device **\n"); + dev = (int)simple_strtoul(argv[2], &ep, 16); + dev_desc = get_dev(argv[1],dev); + if (dev_desc == NULL) { + puts("\n** Invalid boot device **\n"); return 1; } if (*ep) { if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); + puts("\n** Invalid boot device, use `dev[:part]' **\n"); return 1; } part = (int)simple_strtoul(++ep, NULL, 16); } if (fat_register_device(dev_desc,part)!=0) { - printf ("\n** Unable to use %s %d:%d for fatls **\n",argv[1],dev,part); + printf("\n** Unable to use %s %d:%d for fatls **\n", + argv[1], dev, part); return 1; } if (argc == 4) - ret = file_fat_ls (argv[3]); + ret = file_fat_ls(argv[3]); else - ret = file_fat_ls (filename); + ret = file_fat_ls(filename); if(ret!=0) printf("No Fat FS detected\n"); - return (ret); + return ret; } U_BOOT_CMD( @@ -141,7 +146,7 @@ U_BOOT_CMD( " - list files from 'dev' on 'interface' in a 'directory'" ); -int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int dev=0; int part=1; @@ -149,27 +154,28 @@ int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) block_dev_desc_t *dev_desc=NULL; if (argc < 2) { - printf ("usage: fatinfo <interface> <dev[:part]>\n"); - return (0); + printf("usage: fatinfo <interface> <dev[:part]>\n"); + return 0; } - dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc=get_dev(argv[1],dev); - if (dev_desc==NULL) { - puts ("\n** Invalid boot device **\n"); + dev = (int)simple_strtoul(argv[2], &ep, 16); + dev_desc = get_dev(argv[1],dev); + if (dev_desc == NULL) { + puts("\n** Invalid boot device **\n"); return 1; } if (*ep) { if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); + puts("\n** Invalid boot device, use `dev[:part]' **\n"); return 1; } part = (int)simple_strtoul(++ep, NULL, 16); } if (fat_register_device(dev_desc,part)!=0) { - printf ("\n** Unable to use %s %d:%d for fatinfo **\n",argv[1],dev,part); + printf("\n** Unable to use %s %d:%d for fatinfo **\n", + argv[1], dev, part); return 1; } - return (file_fat_detectfs ()); + return file_fat_detectfs(); } U_BOOT_CMD( @@ -178,143 +184,3 @@ U_BOOT_CMD( "<interface> <dev[:part]>\n" " - print information about filesystem from 'dev' on 'interface'" ); - -#ifdef NOT_IMPLEMENTED_YET -/* find first device whose first partition is a DOS filesystem */ -int find_fat_partition (void) -{ - int i, j; - block_dev_desc_t *dev_desc; - unsigned char *part_table; - unsigned char buffer[ATA_BLOCKSIZE]; - - for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; i++) { - dev_desc = ide_get_dev (i); - if (!dev_desc) { - debug ("couldn't get ide device!\n"); - return (-1); - } - if (dev_desc->part_type == PART_TYPE_DOS) { - if (dev_desc-> - block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) { - debug ("can't perform block_read!\n"); - return (-1); - } - part_table = &buffer[0x1be]; /* start with partition #4 */ - for (j = 0; j < 4; j++) { - if ((part_table[4] == 1 || /* 12-bit FAT */ - part_table[4] == 4 || /* 16-bit FAT */ - part_table[4] == 6) && /* > 32Meg part */ - part_table[0] == 0x80) { /* bootable? */ - curr_dev = i; - part_offset = part_table[11]; - part_offset <<= 8; - part_offset |= part_table[10]; - part_offset <<= 8; - part_offset |= part_table[9]; - part_offset <<= 8; - part_offset |= part_table[8]; - debug ("found partition start at %ld\n", part_offset); - return (0); - } - part_table += 16; - } - } - } - - debug ("no valid devices found!\n"); - return (-1); -} - -int -do_fat_dump (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) -{ - __u8 block[1024]; - int ret; - int bknum; - - ret = 0; - - if (argc != 2) { - printf ("needs an argument!\n"); - return (0); - } - - bknum = simple_strtoul (argv[1], NULL, 10); - - if (disk_read (0, bknum, block) != 0) { - printf ("Error: reading block\n"); - return -1; - } - printf ("FAT dump: %d\n", bknum); - hexdump (512, block); - - return (ret); -} - -int disk_read (__u32 startblock, __u32 getsize, __u8 *bufptr) -{ - ulong tot; - block_dev_desc_t *dev_desc; - - if (curr_dev < 0) { - if (find_fat_partition () != 0) - return (-1); - } - - dev_desc = ide_get_dev (curr_dev); - if (!dev_desc) { - debug ("couldn't get ide device\n"); - return (-1); - } - - tot = dev_desc->block_read (0, startblock + part_offset, - getsize, (ulong *) bufptr); - - /* should we do this here? - flush_cache ((ulong)buf, cnt*ide_dev_desc[device].blksz); - */ - - if (tot == getsize) - return (0); - - debug ("unable to read from device!\n"); - - return (-1); -} - - -static int isprint (unsigned char ch) -{ - if (ch >= 32 && ch < 127) - return (1); - - return (0); -} - - -void hexdump (int cnt, unsigned char *data) -{ - int i; - int run; - int offset; - - offset = 0; - while (cnt) { - printf ("%04X : ", offset); - if (cnt >= 16) - run = 16; - else - run = cnt; - cnt -= run; - for (i = 0; i < run; i++) - printf ("%02X ", (unsigned int) data[i]); - printf (": "); - for (i = 0; i < run; i++) - printf ("%c", isprint (data[i]) ? data[i] : '.'); - printf ("\n"); - data = &data[16]; - offset += run; - } -} -#endif /* NOT_IMPLEMENTED_YET */ diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index 8e18c71..831a07f 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -183,31 +183,6 @@ static FDC_COMMAND_STRUCT cmd; /* global command struct */ #define CONFIG_SYS_ISA_IO_OFFSET 0 #endif - -#ifdef CONFIG_AMIGAONEG3SE -unsigned char INT6_Status; - -void fdc_interrupt(void) -{ - INT6_Status = 0x80; -} - -/* waits for an interrupt (polling) */ -int wait_for_fdc_int(void) -{ - unsigned long timeout; - timeout = FDC_TIME_OUT; - while(((volatile)INT6_Status & 0x80) == 0) { - timeout--; - udelay(10); - if(timeout == 0) /* timeout occured */ - return FALSE; - } - INT6_Status = 0; - return TRUE; -} -#endif - /* Supporting Functions */ /* reads a Register of the FDC */ unsigned char read_fdc_reg(unsigned int addr) @@ -230,7 +205,6 @@ void write_fdc_reg(unsigned int addr, unsigned char val) tmp[0]=val; } -#ifndef CONFIG_AMIGAONEG3SE /* waits for an interrupt (polling) */ int wait_for_fdc_int(void) { @@ -245,8 +219,6 @@ int wait_for_fdc_int(void) return TRUE; } -#endif - /* reads a byte from the FIFO of the FDC and checks direction and RQM bit of the MSR. returns -1 if timeout, or byte if ok */ int read_fdc_byte(void) @@ -438,7 +410,6 @@ int fdc_seek(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) return(fdc_issue_cmd(pCMD,pFG)); } -#ifndef CONFIG_AMIGAONEG3SE /* terminates current command, by not servicing the FIFO * waits for interrupt and fills in the result bytes */ int fdc_terminate(FDC_COMMAND_STRUCT *pCMD) @@ -452,27 +423,6 @@ int fdc_terminate(FDC_COMMAND_STRUCT *pCMD) } return TRUE; } -#endif -#ifdef CONFIG_AMIGAONEG3SE -int fdc_terminate(FDC_COMMAND_STRUCT *pCMD) -{ - int i; - for(i=0;i<100;i++) - udelay(500); /* wait 500usec for fifo overrun */ - while((INT6_Status&0x80)==0x00); /* wait as long as no int has occured */ - for(i=0;i<7;i++) { - pCMD->result[i]=(unsigned char)read_fdc_byte(); - } - INT6_Status = 0; - return TRUE; -} - -#endif - -#ifdef CONFIG_AMIGAONEG3SE -#define disable_interrupts() 0 -#define enable_interrupts() (void)0 -#endif /* reads data from FDC, seek commands are issued automatic */ int fdc_read_data(unsigned char *buffer, unsigned long blocks,FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) @@ -593,11 +543,6 @@ retrycal: return TRUE; } -#ifdef CONFIG_AMIGAONEG3SE -#undef disable_interrupts() -#undef enable_interrupts() -#endif - /* Scan all drives and check if drive is present and disk is inserted */ int fdc_check_drive(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) { @@ -647,11 +592,6 @@ int fdc_setup(int drive, FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) { int i; -#ifdef CONFIG_AMIGAONEG3SE - irq_install_handler(6, (interrupt_handler_t *)fdc_interrupt, NULL); - i8259_unmask_irq(6); -#endif - #ifdef CONFIG_SYS_FDC_HW_INIT fdc_hw_init (); #endif @@ -773,7 +713,7 @@ int fdc_fdos_read (void *buffer, int len) /**************************************************************************** * main routine do_fdcboot */ -int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type; FDC_COMMAND_STRUCT *pCMD = &cmd; @@ -801,8 +741,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) boot_drive=simple_strtoul(argv[2], NULL, 10); break; default: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } /* setup FDC and scan for drives */ if(fdc_setup(boot_drive,pCMD,pFG)==FALSE) { diff --git a/common/cmd_fdos.c b/common/cmd_fdos.c index 3cc6586..a8822d9 100644 --- a/common/cmd_fdos.c +++ b/common/cmd_fdos.c @@ -35,7 +35,7 @@ * do_fdosboot -- *----------------------------------------------------------------------------- */ -int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *name; char *ep; @@ -73,8 +73,7 @@ int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) name = argv [2]; break; default: - cmd_usage(cmdtp); - break; + return cmd_usage(cmdtp); } /* Init physical layer */ @@ -115,7 +114,7 @@ int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * do_fdosls -- *----------------------------------------------------------------------------- */ -int do_fdosls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_fdosls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *path = ""; int drive = CONFIG_SYS_FDC_DRIVE_NUMBER; diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 5df79ae..3d0c2b7 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -42,7 +42,7 @@ DECLARE_GLOBAL_DATA_PTR; static int fdt_valid(void); -static int fdt_parse_prop(char **newval, int count, char *data, int *len); +static int fdt_parse_prop(char *const*newval, int count, char *data, int *len); static int fdt_print(const char *pathp, char *prop, int depth); /* @@ -63,16 +63,14 @@ void set_working_fdt_addr(void *addr) /* * Flattened Device Tree command, see the help for parameter definitions. */ -int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); - /******************************************************************** + /* * Set the address of the fdt - ********************************************************************/ + */ if (argv[1][0] == 'a') { unsigned long addr; /* @@ -116,18 +114,16 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } } - /******************************************************************** + /* * Move the working_fdt - ********************************************************************/ + */ } else if (strncmp(argv[1], "mo", 2) == 0) { struct fdt_header *newaddr; int len; int err; - if (argc < 4) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 4) + return cmd_usage(cmdtp); /* * Set the address and length of the fdt. @@ -166,9 +162,9 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } working_fdt = newaddr; - /******************************************************************** + /* * Make a new node - ********************************************************************/ + */ } else if (strncmp(argv[1], "mk", 2) == 0) { char *pathp; /* path */ char *nodep; /* new node to add */ @@ -178,10 +174,8 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /* * Parameters: Node path, new node to be appended to the path. */ - if (argc < 4) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 4) + return cmd_usage(cmdtp); pathp = argv[2]; nodep = argv[3]; @@ -202,9 +196,9 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 1; } - /******************************************************************** + /* * Set the value of a property in the working_fdt. - ********************************************************************/ + */ } else if (argv[1][0] == 's') { char *pathp; /* path */ char *prop; /* property */ @@ -216,10 +210,8 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /* * Parameters: Node path, property, optional value. */ - if (argc < 4) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 4) + return cmd_usage(cmdtp); pathp = argv[2]; prop = argv[3]; @@ -247,9 +239,9 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 1; } - /******************************************************************** + /* * Print (recursive) / List (single level) - ********************************************************************/ + */ } else if ((argv[1][0] == 'p') || (argv[1][0] == 'l')) { int depth = MAX_LEVEL; /* how deep to print */ char *pathp; /* path */ @@ -281,9 +273,9 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (ret != 0) return ret; - /******************************************************************** + /* * Remove a property/node - ********************************************************************/ + */ } else if (strncmp(argv[1], "rm", 2) == 0) { int nodeoffset; /* node offset from libfdt */ int err; @@ -321,9 +313,9 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } } - /******************************************************************** + /* * Display header info - ********************************************************************/ + */ } else if (argv[1][0] == 'h') { u32 version = fdt_version(working_fdt); printf("magic:\t\t\t0x%x\n", fdt_magic(working_fdt)); @@ -351,16 +343,16 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) fdt_num_mem_rsv(working_fdt)); printf("\n"); - /******************************************************************** + /* * Set boot cpu id - ********************************************************************/ + */ } else if (strncmp(argv[1], "boo", 3) == 0) { unsigned long tmp = simple_strtoul(argv[2], NULL, 16); fdt_set_boot_cpuid_phys(working_fdt, tmp); - /******************************************************************** + /* * memory command - ********************************************************************/ + */ } else if (strncmp(argv[1], "me", 2) == 0) { uint64_t addr, size; int err; @@ -370,9 +362,9 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (err < 0) return err; - /******************************************************************** + /* * mem reserve commands - ********************************************************************/ + */ } else if (strncmp(argv[1], "rs", 2) == 0) { if (argv[2][0] == 'p') { uint64_t addr, size; @@ -417,8 +409,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } } else { /* Unrecognized command */ - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } } #ifdef CONFIG_OF_BOARD_SETUP @@ -430,10 +421,8 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) else if (argv[1][0] == 'c') { unsigned long initrd_start = 0, initrd_end = 0; - if ((argc != 2) && (argc != 4)) { - cmd_usage(cmdtp); - return 1; - } + if ((argc != 2) && (argc != 4)) + return cmd_usage(cmdtp); if (argc == 4) { initrd_start = simple_strtoul(argv[2], NULL, 16); @@ -449,8 +438,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } else { /* Unrecognized command */ - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } return 0; @@ -515,7 +503,7 @@ static int fdt_valid(void) * data: A bytestream to be placed in the property * len: The length of the resulting bytestream */ -static int fdt_parse_prop(char **newval, int count, char *data, int *len) +static int fdt_parse_prop(char * const *newval, int count, char *data, int *len) { char *cp; /* temporary char pointer */ char *newp; /* temporary newval char pointer */ diff --git a/common/cmd_flash.c b/common/cmd_flash.c index 3773412..4493948 100644 --- a/common/cmd_flash.c +++ b/common/cmd_flash.c @@ -31,10 +31,10 @@ #include <dataflash.h> #endif -#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_CMD_MTDPARTS) +#if defined(CONFIG_CMD_MTDPARTS) #include <jffs2/jffs2.h> -/* parition handling routines */ +/* partition handling routines */ int mtdparts_init(void); int mtd_id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num); int find_dev_and_part(const char *id, struct mtd_device **dev, @@ -42,6 +42,8 @@ int find_dev_and_part(const char *id, struct mtd_device **dev, #endif #ifndef CONFIG_SYS_NO_FLASH +#include <flash.h> +#include <mtd/cfi_flash.h> extern flash_info_t flash_info[]; /* info for FLASH chips */ /* @@ -287,7 +289,7 @@ flash_fill_sect_ranges (ulong addr_first, ulong addr_last, } #endif /* CONFIG_SYS_NO_FLASH */ -int do_flinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_flinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #ifndef CONFIG_SYS_NO_FLASH ulong bank; @@ -319,23 +321,21 @@ int do_flinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #ifndef CONFIG_SYS_NO_FLASH flash_info_t *info; ulong bank, addr_first, addr_last; int n, sect_first, sect_last; -#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_CMD_MTDPARTS) +#if defined(CONFIG_CMD_MTDPARTS) struct mtd_device *dev; struct part_info *part; u8 dev_type, dev_num, pnum; #endif int rcode = 0; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); if (strcmp(argv[1], "all") == 0) { for (bank=1; bank<=CONFIG_SYS_MAX_FLASH_BANKS; ++bank) { @@ -357,7 +357,7 @@ int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return rcode; } -#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_CMD_MTDPARTS) +#if defined(CONFIG_CMD_MTDPARTS) /* erase <part-id> - erase partition */ if ((argc == 2) && (mtd_id_parse(argv[1], NULL, &dev_type, &dev_num) == 0)) { mtdparts_init(); @@ -368,7 +368,7 @@ int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) addr_first = part->offset + info->start[0]; addr_last = addr_first + part->size - 1; - printf ("Erase Flash Parition %s, " + printf ("Erase Flash Partition %s, " "bank %ld, 0x%08lx - 0x%08lx ", argv[1], bank, addr_first, addr_last); @@ -383,10 +383,8 @@ int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } #endif - if (argc != 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc != 3) + return cmd_usage(cmdtp); if (strcmp(argv[1], "bank") == 0) { bank = simple_strtoul(argv[2], NULL, 16); @@ -406,10 +404,8 @@ int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - if (addr_first >= addr_last) { - cmd_usage(cmdtp); - return 1; - } + if (addr_first >= addr_last) + return cmd_usage(cmdtp); rcode = flash_sect_erase(addr_first, addr_last); return rcode; @@ -423,11 +419,7 @@ int flash_sect_erase (ulong addr_first, ulong addr_last) { flash_info_t *info; ulong bank; -#ifdef CONFIG_SYS_MAX_FLASH_BANKS_DETECT - int s_first[CONFIG_SYS_MAX_FLASH_BANKS_DETECT], s_last[CONFIG_SYS_MAX_FLASH_BANKS_DETECT]; -#else int s_first[CONFIG_SYS_MAX_FLASH_BANKS], s_last[CONFIG_SYS_MAX_FLASH_BANKS]; -#endif int erased = 0; int planned; int rcode = 0; @@ -461,7 +453,7 @@ int flash_sect_erase (ulong addr_first, ulong addr_last) } #endif /* CONFIG_SYS_NO_FLASH */ -int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #ifndef CONFIG_SYS_NO_FLASH flash_info_t *info; @@ -471,7 +463,7 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #if !defined(CONFIG_SYS_NO_FLASH) || defined(CONFIG_HAS_DATAFLASH) ulong addr_first, addr_last; #endif -#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_CMD_MTDPARTS) +#if defined(CONFIG_CMD_MTDPARTS) struct mtd_device *dev; struct part_info *part; u8 dev_type, dev_num, pnum; @@ -482,19 +474,15 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int p; int rcode = 0; - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); - if (strcmp(argv[1], "off") == 0) { + if (strcmp(argv[1], "off") == 0) p = 0; - } else if (strcmp(argv[1], "on") == 0) { + else if (strcmp(argv[1], "on") == 0) p = 1; - } else { - cmd_usage(cmdtp); - return 1; - } + else + return cmd_usage(cmdtp); #ifdef CONFIG_HAS_DATAFLASH if ((strcmp(argv[2], "all") != 0) && (strcmp(argv[2], "bank") != 0)) { @@ -565,7 +553,7 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return rcode; } -#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_CMD_MTDPARTS) +#if defined(CONFIG_CMD_MTDPARTS) /* protect on/off <part-id> */ if ((argc == 3) && (mtd_id_parse(argv[2], NULL, &dev_type, &dev_num) == 0)) { mtdparts_init(); @@ -576,7 +564,7 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) addr_first = part->offset + info->start[0]; addr_last = addr_first + part->size - 1; - printf ("%sProtect Flash Parition %s, " + printf ("%sProtect Flash Partition %s, " "bank %ld, 0x%08lx - 0x%08lx\n", p ? "" : "Un", argv[1], bank, addr_first, addr_last); @@ -592,10 +580,8 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } #endif - if (argc != 4) { - cmd_usage(cmdtp); - return 1; - } + if (argc != 4) + return cmd_usage(cmdtp); if (strcmp(argv[2], "bank") == 0) { bank = simple_strtoul(argv[3], NULL, 16); @@ -634,10 +620,9 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - if (addr_first >= addr_last) { - cmd_usage(cmdtp); - return 1; - } + if (addr_first >= addr_last) + return cmd_usage(cmdtp); + rcode = flash_sect_protect (p, addr_first, addr_last); #endif /* CONFIG_SYS_NO_FLASH */ return rcode; @@ -648,11 +633,7 @@ int flash_sect_protect (int p, ulong addr_first, ulong addr_last) { flash_info_t *info; ulong bank; -#ifdef CONFIG_SYS_MAX_FLASH_BANKS_DETECT - int s_first[CONFIG_SYS_MAX_FLASH_BANKS_DETECT], s_last[CONFIG_SYS_MAX_FLASH_BANKS_DETECT]; -#else int s_first[CONFIG_SYS_MAX_FLASH_BANKS], s_last[CONFIG_SYS_MAX_FLASH_BANKS]; -#endif int protected, i; int planned; int rcode; @@ -700,7 +681,7 @@ int flash_sect_protect (int p, ulong addr_first, ulong addr_last) /**************************************************/ -#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_CMD_MTDPARTS) +#if defined(CONFIG_CMD_MTDPARTS) # define TMP_ERASE "erase <part-id>\n - erase partition\n" # define TMP_PROT_ON "protect on <part-id>\n - protect partition\n" # define TMP_PROT_OFF "protect off <part-id>\n - make partition writable\n" diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index 2e017b8..0ad310f 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -44,7 +44,6 @@ #endif /* Local functions */ -static void fpga_usage (cmd_tbl_t * cmdtp); static int fpga_get_op (char *opstr); /* Local defines */ @@ -156,7 +155,7 @@ int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size) * If there is no data addr field, the fpgadata environment variable is used. * The info command requires no data address field. */ -int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { int op, dev = FPGA_INVALID_DEVICE; size_t data_size = 0; @@ -164,6 +163,7 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) char *devstr = getenv ("fpga"); char *datastr = getenv ("fpgadata"); int rc = FPGA_FAIL; + int wrong_parms = 0; #if defined (CONFIG_FIT) const char *fit_uname = NULL; ulong fit_addr; @@ -230,10 +230,35 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) break; } + if (dev == FPGA_INVALID_DEVICE) { + puts("FPGA device not specified\n"); + op = FPGA_NONE; + } + switch (op) { case FPGA_NONE: - fpga_usage (cmdtp); + case FPGA_INFO: + break; + case FPGA_LOAD: + case FPGA_LOADB: + case FPGA_DUMP: + if (!fpga_data || !data_size) + wrong_parms = 1; break; + case FPGA_LOADMK: + if (!fpga_data) + wrong_parms = 1; + break; + } + + if (wrong_parms) { + puts("Wrong parameters for FPGA request\n"); + op = FPGA_NONE; + } + + switch (op) { + case FPGA_NONE: + return cmd_usage(cmdtp); case FPGA_INFO: rc = fpga_info (dev); @@ -312,17 +337,11 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) default: printf ("Unknown operation\n"); - fpga_usage (cmdtp); - break; + return cmd_usage(cmdtp); } return (rc); } -static void fpga_usage (cmd_tbl_t * cmdtp) -{ - cmd_usage(cmdtp); -} - /* * Map op to supported operations. We don't use a table since we * would just have to relocate it from flash anyway. @@ -350,17 +369,18 @@ static int fpga_get_op (char *opstr) } U_BOOT_CMD (fpga, 6, 1, do_fpga, - "loadable FPGA image support", - "fpga [operation type] [device number] [image address] [image size]\n" - "fpga operations:\n" - "\tinfo\tlist known device information\n" - "\tload\tLoad device from memory buffer\n" - "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n" - "\tloadmk\tLoad device generated with mkimage\n" - "\tdump\tLoad device to memory buffer" + "loadable FPGA image support", + "[operation type] [device number] [image address] [image size]\n" + "fpga operations:\n" + " dump\t[dev]\t\t\tLoad device to memory buffer\n" + " info\t[dev]\t\t\tlist known device information\n" + " load\t[dev] [address] [size]\tLoad device from memory buffer\n" + " loadb\t[dev] [address] [size]\t" + "Load device from bitstream buffer (Xilinx only)\n" + " loadmk [dev] [address]\tLoad device generated with mkimage" #if defined(CONFIG_FIT) - "\n" - "\tFor loadmk operating on FIT format uImage address must include\n" - "\tsubimage unit name in the form of addr:<subimg_uname>" + "\n" + "\tFor loadmk operating on FIT format uImage address must include\n" + "\tsubimage unit name in the form of addr:<subimg_uname>" #endif ); diff --git a/common/cmd_help.c b/common/cmd_help.c index e860dfb..8c8178e 100644 --- a/common/cmd_help.c +++ b/common/cmd_help.c @@ -24,7 +24,7 @@ #include <common.h> #include <command.h> -int do_help(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_help(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { return _do_help(&__u_boot_cmd_start, &__u_boot_cmd_end - &__u_boot_cmd_start, diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 62cbd33..0a0cfce 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -130,6 +130,8 @@ DECLARE_GLOBAL_DATA_PTR; #endif +#define DISP_LINE_LEN 16 + /* TODO: Implement architecture-specific get/set functions */ unsigned int __def_i2c_get_bus_speed(void) { @@ -149,12 +151,75 @@ int i2c_set_bus_speed(unsigned int) __attribute__((weak, alias("__def_i2c_set_bus_speed"))); /* + * get_alen: small parser helper function to get address length + * returns the address length + */ +static uint get_alen(char *arg) +{ + int j; + int alen; + + alen = 1; + for (j = 0; j < 8; j++) { + if (arg[j] == '.') { + alen = arg[j+1] - '0'; + break; + } else if (arg[j] == '\0') + break; + } + return alen; +} + +/* * Syntax: - * i2c md {i2c_chip} {addr}{.0, .1, .2} {len} + * i2c read {i2c_chip} {devaddr}{.0, .1, .2} {len} {memaddr} */ -#define DISP_LINE_LEN 16 -int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + u_char chip; + uint devaddr, alen, length; + u_char *memaddr; + + if (argc != 5) + return cmd_usage(cmdtp); + + /* + * I2C chip address + */ + chip = simple_strtoul(argv[1], NULL, 16); + + /* + * I2C data address within the chip. This can be 1 or + * 2 bytes long. Some day it might be 3 bytes long :-). + */ + devaddr = simple_strtoul(argv[2], NULL, 16); + alen = get_alen(argv[2]); + if (alen > 3) + return cmd_usage(cmdtp); + + /* + * Length is the number of objects, not number of bytes. + */ + length = simple_strtoul(argv[3], NULL, 16); + + /* + * memaddr is the address where to store things in memory + */ + memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16); + + if (i2c_read(chip, devaddr, alen, memaddr, length) != 0) { + puts ("Error reading the chip.\n"); + return 1; + } + return 0; +} + +/* + * Syntax: + * i2c md {i2c_chip} {addr}{.0, .1, .2} {len} + */ +static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { u_char chip; uint addr, alen, length; @@ -168,16 +233,13 @@ int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) alen = i2c_dp_last_alen; length = i2c_dp_last_length; - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); if ((flag & CMD_FLAG_REPEAT) == 0) { /* * New command specified. */ - alen = 1; /* * I2C chip address @@ -189,18 +251,9 @@ int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * 2 bytes long. Some day it might be 3 bytes long :-). */ addr = simple_strtoul(argv[2], NULL, 16); - alen = 1; - for (j = 0; j < 8; j++) { - if (argv[2][j] == '.') { - alen = argv[2][j+1] - '0'; - if (alen > 4) { - cmd_usage(cmdtp); - return 1; - } - break; - } else if (argv[2][j] == '\0') - break; - } + alen = get_alen(argv[2]); + if (alen > 3) + return cmd_usage(cmdtp); /* * If another parameter, it is the length to display. @@ -260,19 +313,16 @@ int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * Syntax: * i2c mw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}] */ -int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uchar chip; ulong addr; uint alen; uchar byte; int count; - int j; - if ((argc < 4) || (argc > 5)) { - cmd_usage(cmdtp); - return 1; - } + if ((argc < 4) || (argc > 5)) + return cmd_usage(cmdtp); /* * Chip is always specified. @@ -283,18 +333,9 @@ int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * Address is always specified. */ addr = simple_strtoul(argv[2], NULL, 16); - alen = 1; - for (j = 0; j < 8; j++) { - if (argv[2][j] == '.') { - alen = argv[2][j+1] - '0'; - if (alen > 4) { - cmd_usage(cmdtp); - return 1; - } - break; - } else if (argv[2][j] == '\0') - break; - } + alen = get_alen(argv[2]); + if (alen > 3) + return cmd_usage(cmdtp); /* * Value to write is always specified. @@ -332,7 +373,7 @@ int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * Syntax: * i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count} */ -int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uchar chip; ulong addr; @@ -341,12 +382,9 @@ int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) uchar byte; ulong crc; ulong err; - int j; - if (argc < 4) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 4) + return cmd_usage(cmdtp); /* * Chip is always specified. @@ -357,18 +395,9 @@ int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * Address is always specified. */ addr = simple_strtoul(argv[2], NULL, 16); - alen = 1; - for (j = 0; j < 8; j++) { - if (argv[2][j] == '.') { - alen = argv[2][j+1] - '0'; - if (alen > 4) { - cmd_usage(cmdtp); - return 1; - } - break; - } else if (argv[2][j] == '\0') - break; - } + alen = get_alen(argv[2]); + if (alen > 3) + return cmd_usage(cmdtp); /* * Count is always specified @@ -404,7 +433,7 @@ int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ static int -mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) +mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) { uchar chip; ulong addr; @@ -412,13 +441,10 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) ulong data; int size = 1; int nbytes; - int j; extern char console_buffer[]; - if (argc != 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc != 3) + return cmd_usage(cmdtp); #ifdef CONFIG_BOOT_RETRY_TIME reset_cmd_timeout(); /* got a good command to get here */ @@ -447,18 +473,9 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) * Address is always specified. */ addr = simple_strtoul(argv[2], NULL, 16); - alen = 1; - for (j = 0; j < 8; j++) { - if (argv[2][j] == '.') { - alen = argv[2][j+1] - '0'; - if (alen > 4) { - cmd_usage(cmdtp); - return 1; - } - break; - } else if (argv[2][j] == '\0') - break; - } + alen = get_alen(argv[2]); + if (alen > 3) + return cmd_usage(cmdtp); } /* @@ -535,7 +552,7 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) * Syntax: * i2c probe {addr}{.0, .1, .2} */ -int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int j; #if defined(CONFIG_SYS_I2C_NOPROBES) @@ -579,7 +596,7 @@ int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * {length} - Number of bytes to read * {delay} - A DECIMAL number and defaults to 1000 uSec */ -int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { u_char chip; ulong alen; @@ -587,12 +604,9 @@ int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) uint length; u_char bytes[16]; int delay; - int j; - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); /* * Chip is always specified. @@ -603,18 +617,9 @@ int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * Address is always specified. */ addr = simple_strtoul(argv[2], NULL, 16); - alen = 1; - for (j = 0; j < 8; j++) { - if (argv[2][j] == '.') { - alen = argv[2][j+1] - '0'; - if (alen > 4) { - cmd_usage(cmdtp); - return 1; - } - break; - } else if (argv[2][j] == '\0') - break; - } + alen = get_alen(argv[2]); + if (alen > 3) + return cmd_usage(cmdtp); /* * Length is the number of objects, not number of bytes. @@ -699,7 +704,7 @@ static void decode_bits (u_char const b, char const *str[], int const do_once) * Syntax: * i2c sdram {i2c_chip} */ -int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { enum { unknown, EDO, SDRAM, DDR2 } type; @@ -752,10 +757,9 @@ int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) "32 MiB", "16 MiB", "8 MiB", "4 MiB" }; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); + /* * Chip is always specified. */ @@ -1176,7 +1180,7 @@ int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) #endif #if defined(CONFIG_I2C_MUX) -int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { int ret=0; @@ -1207,7 +1211,7 @@ int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) #endif /* CONFIG_I2C_MUX */ #if defined(CONFIG_I2C_MULTI_BUS) -int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { int bus_idx, ret=0; @@ -1225,7 +1229,7 @@ int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } #endif /* CONFIG_I2C_MULTI_BUS */ -int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { int speed, ret=0; @@ -1242,46 +1246,67 @@ int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return ret; } -int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int do_i2c_mm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - /* Strip off leading 'i2c' command argument */ - argc--; - argv++; + return mod_i2c_mem (cmdtp, 1, flag, argc, argv); +} + +static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + return mod_i2c_mem (cmdtp, 0, flag, argc, argv); +} +static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + return 0; +} + +static cmd_tbl_t cmd_i2c_sub[] = { #if defined(CONFIG_I2C_MUX) - if (!strncmp(argv[0], "bu", 2)) - return do_i2c_add_bus(cmdtp, flag, argc, argv); + U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_add_bus, "", ""), #endif /* CONFIG_I2C_MUX */ - if (!strncmp(argv[0], "sp", 2)) - return do_i2c_bus_speed(cmdtp, flag, argc, argv); + U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""), #if defined(CONFIG_I2C_MULTI_BUS) - if (!strncmp(argv[0], "de", 2)) - return do_i2c_bus_num(cmdtp, flag, argc, argv); + U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""), #endif /* CONFIG_I2C_MULTI_BUS */ - if (!strncmp(argv[0], "md", 2)) - return do_i2c_md(cmdtp, flag, argc, argv); - if (!strncmp(argv[0], "mm", 2)) - return mod_i2c_mem (cmdtp, 1, flag, argc, argv); - if (!strncmp(argv[0], "mw", 2)) - return do_i2c_mw(cmdtp, flag, argc, argv); - if (!strncmp(argv[0], "nm", 2)) - return mod_i2c_mem (cmdtp, 0, flag, argc, argv); - if (!strncmp(argv[0], "cr", 2)) - return do_i2c_crc(cmdtp, flag, argc, argv); - if (!strncmp(argv[0], "pr", 2)) - return do_i2c_probe(cmdtp, flag, argc, argv); - if (!strncmp(argv[0], "re", 2)) { - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); - return 0; - } - if (!strncmp(argv[0], "lo", 2)) - return do_i2c_loop(cmdtp, flag, argc, argv); + U_BOOT_CMD_MKENT(loop, 3, 1, do_i2c_loop, "", ""), + U_BOOT_CMD_MKENT(md, 3, 1, do_i2c_md, "", ""), + U_BOOT_CMD_MKENT(mm, 2, 1, do_i2c_mm, "", ""), + U_BOOT_CMD_MKENT(mw, 3, 1, do_i2c_mw, "", ""), + U_BOOT_CMD_MKENT(nm, 2, 1, do_i2c_nm, "", ""), + U_BOOT_CMD_MKENT(probe, 0, 1, do_i2c_probe, "", ""), + U_BOOT_CMD_MKENT(read, 5, 1, do_i2c_read, "", ""), + U_BOOT_CMD_MKENT(reset, 0, 1, do_i2c_reset, "", ""), #if defined(CONFIG_CMD_SDRAM) - if (!strncmp(argv[0], "sd", 2)) - return do_sdram(cmdtp, flag, argc, argv); + U_BOOT_CMD_MKENT(sdram, 1, 1, do_sdram, "", ""), #endif - cmd_usage(cmdtp); - return 0; + U_BOOT_CMD_MKENT(speed, 1, 1, do_i2c_bus_speed, "", ""), +}; + +#ifndef CONFIG_RELOC_FIXUP_WORKS +void i2c_reloc(void) { + fixup_cmdtable(cmd_i2c_sub, ARRAY_SIZE(cmd_i2c_sub)); +} +#endif + +static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *c; + + if (argc < 2) + return cmd_usage(cmdtp); + + /* Strip off leading 'i2c' command argument */ + argc--; + argv++; + + c = find_cmd_tbl(argv[0], &cmd_i2c_sub[0], ARRAY_SIZE(cmd_i2c_sub)); + + if (c) + return c->cmd(cmdtp, flag, argc, argv); + else + return cmd_usage(cmdtp); } /***************************************************/ @@ -1289,30 +1314,29 @@ int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD( i2c, 6, 1, do_i2c, "I2C sub-system", - "speed [speed] - show or set I2C bus speed\n" #if defined(CONFIG_I2C_MUX) - "i2c bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\n" + "bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\ni2c " #endif /* CONFIG_I2C_MUX */ + "crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n" #if defined(CONFIG_I2C_MULTI_BUS) "i2c dev [dev] - show or set current I2C bus\n" #endif /* CONFIG_I2C_MULTI_BUS */ + "i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n" "i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n" "i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n" "i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n" "i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n" - "i2c crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n" "i2c probe - show devices on the I2C bus\n" + "i2c read chip address[.0, .1, .2] length memaddress - read to memory \n" "i2c reset - re-init the I2C Controller\n" - "i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device" #if defined(CONFIG_CMD_SDRAM) - "\n" - "i2c sdram chip - print SDRAM configuration information" + "i2c sdram chip - print SDRAM configuration information\n" #endif + "i2c speed [speed] - show or set I2C bus speed" ); #if defined(CONFIG_I2C_MUX) - -int i2c_mux_add_device(I2C_MUX_DEVICE *dev) +static int i2c_mux_add_device(I2C_MUX_DEVICE *dev) { I2C_MUX_DEVICE *devtmp = i2c_mux_devices; diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 093ca9f..ea0f4a7 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -25,6 +25,7 @@ /* * IDE support */ + #include <common.h> #include <config.h> #include <watchdog.h> @@ -45,6 +46,12 @@ #include <mpc5xxx.h> #endif +#ifdef CONFIG_ORION5X +#include <asm/arch/orion5x.h> +#elif defined CONFIG_KIRKWOOD +#include <asm/arch/kirkwood.h> +#endif + #include <ide.h> #include <ata.h> @@ -119,31 +126,22 @@ ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS] = { }; -#ifndef CONFIG_AMIGAONEG3SE static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS]; -#else -static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS] = {0,}; -#endif block_dev_desc_t ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE]; /* ------------------------------------------------------------------------- */ #ifdef CONFIG_IDE_LED -#if !defined(CONFIG_KUP4K) && !defined(CONFIG_KUP4X) &&!defined(CONFIG_BMS2003) &&!defined(CONFIG_CPC45) +# if !defined(CONFIG_BMS2003) && \ + !defined(CONFIG_CPC45) && \ + !defined(CONFIG_KUP4K) && \ + !defined(CONFIG_KUP4X) static void ide_led (uchar led, uchar status); #else extern void ide_led (uchar led, uchar status); #endif #else -#ifndef CONFIG_AMIGAONEG3SE #define ide_led(a,b) /* dummy */ -#else -extern void ide_led(uchar led, uchar status); -#define LED_IDE1 1 -#define LED_IDE2 2 -#define CONFIG_IDE_LED 1 -#define DEVICE_LED(x) 1 -#endif #endif #ifdef CONFIG_IDE_RESET @@ -181,15 +179,14 @@ static void set_pcmcia_timing (int pmode); /* ------------------------------------------------------------------------- */ -int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int rcode = 0; switch (argc) { case 0: case 1: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); case 2: if (strncmp(argv[1],"res",3) == 0) { puts ("\nReset IDE" @@ -238,8 +235,7 @@ int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } return rcode; } - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); case 3: if (strncmp(argv[1],"dev",3) == 0) { int dev = (int)simple_strtoul(argv[2], NULL, 10); @@ -287,8 +283,7 @@ int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #endif } - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); default: /* at least 4 args */ @@ -341,21 +336,19 @@ int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf ("%ld blocks written: %s\n", n, (n==cnt) ? "OK" : "ERROR"); - if (n==cnt) { + if (n==cnt) return 0; - } else { + else return 1; - } } else { - cmd_usage(cmdtp); - rcode = 1; + return cmd_usage(cmdtp); } return rcode; } } -int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *boot_device = NULL; char *ep; @@ -383,9 +376,8 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) boot_device = argv[2]; break; default: - cmd_usage(cmdtp); show_boot_progress (-42); - return 1; + return cmd_usage(cmdtp); } show_boot_progress (42); @@ -562,12 +554,8 @@ void ide_init (void) #endif unsigned char c; int i, bus; -#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3) +#if defined(CONFIG_SC3) unsigned int ata_reset_time = ATA_RESET_TIME; - char *s; -#endif -#ifdef CONFIG_AMIGAONEG3SE - unsigned int max_bus_scan; #endif #ifdef CONFIG_IDE_8xx_PCCARD extern int pcmcia_on (void); @@ -638,19 +626,8 @@ void ide_init (void) * Wait for IDE to get ready. * According to spec, this can take up to 31 seconds! */ -#ifndef CONFIG_AMIGAONEG3SE for (bus=0; bus<CONFIG_SYS_IDE_MAXBUS; ++bus) { int dev = bus * (CONFIG_SYS_IDE_MAXDEVICE / CONFIG_SYS_IDE_MAXBUS); -#else - s = getenv("ide_maxbus"); - if (s) - max_bus_scan = simple_strtol(s, NULL, 10); - else - max_bus_scan = CONFIG_SYS_IDE_MAXBUS; - - for (bus=0; bus<max_bus_scan; ++bus) { - int dev = bus * (CONFIG_SYS_IDE_MAXDEVICE / max_bus_scan); -#endif #ifdef CONFIG_IDE_8xx_PCCARD /* Skip non-ide devices from probing */ @@ -668,30 +645,19 @@ void ide_init (void) udelay (100000); /* 100 ms */ ide_outb (dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev)); udelay (100000); /* 100 ms */ -#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3) - if ((s = getenv("ide_reset_timeout")) != NULL) - ata_reset_time = simple_strtol(s, NULL, 10); -#endif i = 0; do { udelay (10000); /* 10 ms */ c = ide_inb (dev, ATA_STATUS); i++; -#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3) +#if defined(CONFIG_SC3) if (i > (ata_reset_time * 100)) { #else if (i > (ATA_RESET_TIME * 100)) { #endif puts ("** Timeout **\n"); ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */ -#ifdef CONFIG_AMIGAONEG3SE - /* If this is the second bus, the first one was OK */ - if (bus != 0) { - ide_bus_ok[bus] = 0; - goto skip_bus; - } -#endif return; } if ((i >= 100) && ((i%100)==0)) { @@ -714,9 +680,6 @@ void ide_init (void) WATCHDOG_RESET(); } -#ifdef CONFIG_AMIGAONEG3SE - skip_bus: -#endif putc ('\n'); ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */ @@ -855,7 +818,7 @@ set_pcmcia_timing (int pmode) static void input_swap_data(int dev, ulong *sect_buf, int words) { -#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) +#if defined(CONFIG_CPC45) uchar i; volatile uchar *pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN); volatile uchar *pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); @@ -891,11 +854,11 @@ input_swap_data(int dev, ulong *sect_buf, int words) #endif /* __LITTLE_ENDIAN || CONFIG_AU1X00 */ -#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) || defined(CONFIG_SH) +#if defined(CONFIG_IDE_SWAP_IO) static void output_data(int dev, ulong *sect_buf, int words) { -#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) +#if defined(CONFIG_CPC45) uchar *dbuf; volatile uchar *pbuf_even; volatile uchar *pbuf_odd; @@ -935,19 +898,19 @@ output_data(int dev, ulong *sect_buf, int words) } #endif } -#else /* ! __PPC__ */ +#else /* ! CONFIG_IDE_SWAP_IO */ static void output_data(int dev, ulong *sect_buf, int words) { outsw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words<<1); } -#endif /* __PPC__ */ +#endif /* CONFIG_IDE_SWAP_IO */ -#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) || defined(CONFIG_SH) +#if defined(CONFIG_IDE_SWAP_IO) static void input_data(int dev, ulong *sect_buf, int words) { -#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) +#if defined(CONFIG_CPC45) uchar *dbuf; volatile uchar *pbuf_even; volatile uchar *pbuf_odd; @@ -993,14 +956,14 @@ input_data(int dev, ulong *sect_buf, int words) } #endif } -#else /* ! __PPC__ */ +#else /* ! CONFIG_IDE_SWAP_IO */ static void input_data(int dev, ulong *sect_buf, int words) { insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words << 1); } -#endif /* __PPC__ */ +#endif /* CONFIG_IDE_SWAP_IO */ /* ------------------------------------------------------------------------- */ @@ -1010,10 +973,6 @@ static void ide_ident (block_dev_desc_t *dev_desc) unsigned char c; hd_driveid_t *iop = (hd_driveid_t *)iobuf; -#ifdef CONFIG_AMIGAONEG3SE - int max_bus_scan; - char *s; -#endif #ifdef CONFIG_ATAPI int retries = 0; int do_retry = 0; @@ -1030,19 +989,6 @@ static void ide_ident (block_dev_desc_t *dev_desc) device=dev_desc->dev; printf (" Device %d: ", device); -#ifdef CONFIG_AMIGAONEG3SE - s = getenv("ide_maxbus"); - if (s) { - max_bus_scan = simple_strtol(s, NULL, 10); - } else { - max_bus_scan = CONFIG_SYS_IDE_MAXBUS; - } - if (device >= max_bus_scan*2) { - dev_desc->type=DEV_TYPE_UNKNOWN; - return; - } -#endif - ide_led (DEVICE_LED(device), 1); /* LED on */ /* Select device */ @@ -1086,10 +1032,6 @@ static void ide_ident (block_dev_desc_t *dev_desc) if (((c & ATA_STAT_DRQ) == 0) || ((c & (ATA_STAT_FAULT|ATA_STAT_ERR)) != 0) ) { #ifdef CONFIG_ATAPI -#ifdef CONFIG_AMIGAONEG3SE - s = getenv("ide_doreset"); - if (s && strcmp(s, "on") == 0) -#endif { /* Need to soft reset the device in case it's an ATAPI... */ debug ("Retrying...\n"); @@ -1601,9 +1543,7 @@ static void ide_reset (void) /* ------------------------------------------------------------------------- */ #if defined(CONFIG_IDE_LED) && \ - !defined(CONFIG_AMIGAONEG3SE)&& \ !defined(CONFIG_CPC45) && \ - !defined(CONFIG_HMI10) && \ !defined(CONFIG_KUP4K) && \ !defined(CONFIG_KUP4X) @@ -1639,13 +1579,13 @@ int ide_device_present(int dev) * ATAPI Support */ -#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) +#if defined(CONFIG_IDE_SWAP_IO) /* since ATAPI may use commands with not 4 bytes alligned length * we have our own transfer functions, 2 bytes alligned */ static void output_data_shorts(int dev, ushort *sect_buf, int shorts) { -#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) +#if defined(CONFIG_CPC45) uchar *dbuf; volatile uchar *pbuf_even; volatile uchar *pbuf_odd; @@ -1677,7 +1617,7 @@ output_data_shorts(int dev, ushort *sect_buf, int shorts) static void input_data_shorts(int dev, ushort *sect_buf, int shorts) { -#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) +#if defined(CONFIG_CPC45) uchar *dbuf; volatile uchar *pbuf_even; volatile uchar *pbuf_odd; @@ -1706,7 +1646,7 @@ input_data_shorts(int dev, ushort *sect_buf, int shorts) #endif } -#else /* ! __PPC__ */ +#else /* ! CONFIG_IDE_SWAP_IO */ static void output_data_shorts(int dev, ushort *sect_buf, int shorts) { @@ -1719,7 +1659,7 @@ input_data_shorts(int dev, ushort *sect_buf, int shorts) insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, shorts); } -#endif /* __PPC__ */ +#endif /* CONFIG_IDE_SWAP_IO */ /* * Wait until (Status & mask) == res, or timeout (in ms) @@ -1758,9 +1698,6 @@ unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned cha */ mask = ATA_STAT_BUSY|ATA_STAT_DRQ; res = 0; -#ifdef CONFIG_AMIGAONEG3SE -# warning THF: Removed LBA mode ??? -#endif ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res); if ((c & mask) != res) { @@ -1774,9 +1711,6 @@ unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned cha ide_outb (device, ATA_SECT_NUM, 0); ide_outb (device, ATA_CYL_LOW, (unsigned char)(buflen & 0xFF)); ide_outb (device, ATA_CYL_HIGH, (unsigned char)((buflen>>8) & 0xFF)); -#ifdef CONFIG_AMIGAONEG3SE -# warning THF: Removed LBA mode ??? -#endif ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); ide_outb (device, ATA_COMMAND, ATAPI_CMD_PACKET); @@ -1875,16 +1809,6 @@ unsigned char atapi_issue_autoreq (int device, unsigned char res,key,asc,ascq; int notready,unitattn; -#ifdef CONFIG_AMIGAONEG3SE - char *s; - unsigned int timeout, retrycnt; - - s = getenv("ide_cd_timeout"); - timeout = s ? (simple_strtol(s, NULL, 10)*1000000)/5 : 0; - - retrycnt = 0; -#endif - unitattn=ATAPI_UNIT_ATTN; notready=ATAPI_DRIVE_NOT_READY; @@ -1939,25 +1863,6 @@ retry: goto error; } -#ifdef CONFIG_AMIGAONEG3SE - if ((sense_data[2]&0xF)==0x0B) { - debug ("ABORTED COMMAND...retry\n"); - if (retrycnt++ < 4) - goto retry; - return (0xFF); - } - - if ((sense_data[2]&0xf) == 0x02 && - sense_data[12] == 0x04 && - sense_data[13] == 0x01 ) { - debug ("Waiting for unit to become active\n"); - udelay(timeout); - if (retrycnt++ < 4) - goto retry; - return 0xFF; - } -#endif /* CONFIG_AMIGAONEG3SE */ - printf ("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq); error: debug ("ERROR Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq); diff --git a/common/cmd_immap.c b/common/cmd_immap.c index 37e6058..1f59c1e 100644 --- a/common/cmd_immap.c +++ b/common/cmd_immap.c @@ -43,14 +43,14 @@ DECLARE_GLOBAL_DATA_PTR; static void -unimplemented ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +unimplemented ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { printf ("Sorry, but the '%s' command has not been implemented\n", cmdtp->name); } int -do_siuinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_siuinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; @@ -81,7 +81,7 @@ do_siuinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } int -do_memcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_memcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; @@ -133,7 +133,7 @@ do_memcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } int -do_sitinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_sitinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unimplemented (cmdtp, flag, argc, argv); return 0; @@ -141,7 +141,7 @@ do_sitinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #ifdef CONFIG_8260 int -do_icinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_icinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unimplemented (cmdtp, flag, argc, argv); return 0; @@ -149,7 +149,7 @@ do_icinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #endif int -do_carinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_carinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; @@ -233,7 +233,7 @@ static void binary (char *label, uint value, int nbits) #endif int -do_iopinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_iopinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; @@ -316,7 +316,7 @@ do_iopinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * use *uint and set the address based on cmd + port */ int -do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint rcode = 0; iopin_t iopin; @@ -431,14 +431,14 @@ do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } int -do_dmainfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_dmainfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unimplemented (cmdtp, flag, argc, argv); return 0; } int -do_fccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_fccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unimplemented (cmdtp, flag, argc, argv); return 0; @@ -498,7 +498,7 @@ static void prbrg (int n, uint val) } int -do_brginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_brginfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; @@ -522,7 +522,7 @@ do_brginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } int -do_i2cinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_i2cinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; @@ -569,42 +569,42 @@ do_i2cinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } int -do_sccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_sccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unimplemented (cmdtp, flag, argc, argv); return 0; } int -do_smcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_smcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unimplemented (cmdtp, flag, argc, argv); return 0; } int -do_spiinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_spiinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unimplemented (cmdtp, flag, argc, argv); return 0; } int -do_muxinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_muxinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unimplemented (cmdtp, flag, argc, argv); return 0; } int -do_siinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_siinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unimplemented (cmdtp, flag, argc, argv); return 0; } int -do_mccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_mccinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unimplemented (cmdtp, flag, argc, argv); return 0; diff --git a/common/cmd_irq.c b/common/cmd_irq.c index 2c7e6bb..d35a43f 100644 --- a/common/cmd_irq.c +++ b/common/cmd_irq.c @@ -24,20 +24,17 @@ #include <config.h> #include <command.h> -int do_interrupts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_interrupts(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - if (argc != 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc != 2) + return cmd_usage(cmdtp); /* on */ - if (strncmp(argv[1], "on", 2) == 0) { + if (strncmp(argv[1], "on", 2) == 0) enable_interrupts(); - } else { + else disable_interrupts(); - } return 0; } @@ -49,7 +46,7 @@ U_BOOT_CMD( ); /* Implemented in $(CPU)/interrupts.c */ -int do_irqinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +int do_irqinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); U_BOOT_CMD( irqinfo, 1, 1, do_irqinfo, diff --git a/common/cmd_itest.c b/common/cmd_itest.c index 58c5e7b..8dd8927 100644 --- a/common/cmd_itest.c +++ b/common/cmd_itest.c @@ -160,15 +160,13 @@ int binary_test (char *op, char *arg1, char *arg2, int w) } /* command line interface to the shell test */ -int do_itest ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] ) +int do_itest ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] ) { int value, w; /* Validate arguments */ - if ((argc != 4)){ - cmd_usage(cmdtp); - return 1; - } + if ((argc != 4)) + return cmd_usage(cmdtp); /* Check for a data width specification. * Defaults to long (4) if no specification. diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index 6799cca..0e7a6b0 100644 --- a/common/cmd_jffs2.c +++ b/common/cmd_jffs2.c @@ -485,7 +485,7 @@ static struct part_info* jffs2_part_info(struct mtd_device *dev, unsigned int pa * @param argv arguments list * @return 0 on success, 1 otherwise */ -int do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *fsname; char *filename; @@ -549,7 +549,7 @@ int do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * @param argv arguments list * @return 0 on success, 1 otherwise */ -int do_jffs2_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_jffs2_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = "/"; int ret; @@ -587,7 +587,7 @@ int do_jffs2_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * @param argv arguments list * @return 0 on success, 1 otherwise */ -int do_jffs2_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_jffs2_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct part_info *part; char *fsname; diff --git a/common/cmd_license.c b/common/cmd_license.c index 85a4871..70645d5 100644 --- a/common/cmd_license.c +++ b/common/cmd_license.c @@ -30,7 +30,7 @@ #include <malloc.h> #include <license.h> -int do_license(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_license(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *tok, *dst = malloc(LICENSE_MAX); unsigned long len = LICENSE_MAX; @@ -49,7 +49,8 @@ int do_license(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -U_BOOT_CMD(license, 1, 1, do_license, +U_BOOT_CMD( + license, 1, 1, do_license, "print GPL license text", "" ); diff --git a/common/cmd_load.c b/common/cmd_load.c index d6bbb78..dad0303 100644 --- a/common/cmd_load.c +++ b/common/cmd_load.c @@ -51,7 +51,7 @@ static int do_echo = 1; /* -------------------------------------------------------------------- */ #if defined(CONFIG_CMD_LOADS) -int do_load_serial (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_load_serial (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { long offset = 0; ulong addr; @@ -255,7 +255,7 @@ read_record (char *buf, ulong len) #if defined(CONFIG_CMD_SAVES) -int do_save_serial (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_save_serial (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong offset = 0; ulong size = 0; @@ -433,7 +433,7 @@ int his_pad_count; /* number of pad chars he needs */ char his_pad_char; /* pad chars he needs */ char his_quote; /* quote chars he'll use */ -int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong offset = 0; ulong addr; @@ -1091,7 +1091,7 @@ U_BOOT_CMD( /* -------------------------------------------------------------------- */ #if defined(CONFIG_CMD_HWFLOW) -int do_hwflow (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_hwflow (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { extern int hwflow_onoff(int); @@ -1102,7 +1102,7 @@ int do_hwflow (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (strcmp(argv[1], "on") == 0) hwflow_onoff(1); else - cmd_usage(cmdtp); + return cmd_usage(cmdtp); } printf("RTS/CTS hardware flow control: %s\n", hwflow_onoff(0) ? "on" : "off"); return 0; diff --git a/common/cmd_log.c b/common/cmd_log.c index 3653fe1..0e89357 100644 --- a/common/cmd_log.c +++ b/common/cmd_log.c @@ -193,7 +193,7 @@ void logbuff_log(char *msg) * Return: None * */ -int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *s; unsigned long i, start, size; @@ -241,12 +241,10 @@ int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } return 0; } - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); default: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } } diff --git a/common/cmd_mac.c b/common/cmd_mac.c index 20403da..1884c2a 100644 --- a/common/cmd_mac.c +++ b/common/cmd_mac.c @@ -24,7 +24,7 @@ #include <common.h> #include <command.h> -extern int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); U_BOOT_CMD( mac, 3, 1, do_mac, diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 1839330..f7a442a 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -43,7 +43,7 @@ #define PRINTF(fmt,args...) #endif -static int mod_mem(cmd_tbl_t *, int, int, int, char *[]); +static int mod_mem(cmd_tbl_t *, int, int, int, char * const []); /* Display values from last command. * Memory modify remembered values are different from display memory. @@ -60,7 +60,7 @@ static ulong base_address = 0; * md{.b, .w, .l} {addr} {len} */ #define DISP_LINE_LEN 16 -int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr, length; #if defined(CONFIG_HAS_DATAFLASH) @@ -76,10 +76,8 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) size = dp_last_size; length = dp_last_length; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); if ((flag & CMD_FLAG_REPEAT) == 0) { /* New command specified. Check for a size specification. @@ -158,24 +156,22 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return (rc); } -int do_mem_mm ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_mm ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { return mod_mem (cmdtp, 1, flag, argc, argv); } -int do_mem_nm ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_nm ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { return mod_mem (cmdtp, 0, flag, argc, argv); } -int do_mem_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr, writeval, count; int size; - if ((argc < 3) || (argc > 4)) { - cmd_usage(cmdtp); - return 1; - } + if ((argc < 3) || (argc > 4)) + return cmd_usage(cmdtp); /* Check for size specification. */ @@ -211,15 +207,13 @@ int do_mem_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } #ifdef CONFIG_MX_CYCLIC -int do_mem_mdc ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_mdc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int i; ulong count; - if (argc < 4) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 4) + return cmd_usage(cmdtp); count = simple_strtoul(argv[3], NULL, 10); @@ -240,15 +234,13 @@ int do_mem_mdc ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -int do_mem_mwc ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_mwc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int i; ulong count; - if (argc < 4) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 4) + return cmd_usage(cmdtp); count = simple_strtoul(argv[3], NULL, 10); @@ -270,16 +262,14 @@ int do_mem_mwc ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } #endif /* CONFIG_MX_CYCLIC */ -int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr1, addr2, count, ngood; int size; int rcode = 0; - if (argc != 4) { - cmd_usage(cmdtp); - return 1; - } + if (argc != 4) + return cmd_usage(cmdtp); /* Check for size specification. */ @@ -347,6 +337,10 @@ int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ngood++; addr1 += size; addr2 += size; + + /* reset watchdog from time to time */ + if ((count % (64 << 10)) == 0) + WATCHDOG_RESET(); } printf("Total of %ld %s%s were the same\n", @@ -355,15 +349,13 @@ int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return rcode; } -int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr, dest, count; int size; - if (argc != 4) { - cmd_usage(cmdtp); - return 1; - } + if (argc != 4) + return cmd_usage(cmdtp); /* Check for size specification. */ @@ -459,11 +451,15 @@ int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) *((u_char *)dest) = *((u_char *)addr); addr += size; dest += size; + + /* reset watchdog from time to time */ + if ((count % (64 << 10)) == 0) + WATCHDOG_RESET(); } return 0; } -int do_mem_base (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_base (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { if (argc > 1) { /* Set new base address. @@ -476,7 +472,7 @@ int do_mem_base (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -int do_mem_loop (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_loop (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr, length, i, junk; int size; @@ -484,10 +480,8 @@ int do_mem_loop (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) volatile ushort *shortp; volatile u_char *cp; - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); /* Check for a size spefication. * Defaults to long if no or incorrect specification. @@ -547,7 +541,7 @@ int do_mem_loop (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } #ifdef CONFIG_LOOPW -int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr, length, i, data; int size; @@ -555,10 +549,8 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) volatile ushort *shortp; volatile u_char *cp; - if (argc < 4) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 4) + return cmd_usage(cmdtp); /* Check for a size spefication. * Defaults to long if no or incorrect specification. @@ -626,7 +618,7 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * 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. */ -int do_mem_mtest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_mtest (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { vu_long *addr, *start, *end; ulong val; @@ -984,16 +976,14 @@ int do_mem_mtest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * nm{.b, .w, .l} {addr} */ static int -mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) +mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) { ulong addr, i; int nbytes, size; extern char console_buffer[]; - if (argc != 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc != 2) + return cmd_usage(cmdtp); #ifdef CONFIG_BOOT_RETRY_TIME reset_cmd_timeout(); /* got a good command to get here */ @@ -1089,16 +1079,14 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) #ifndef CONFIG_CRC32_VERIFY -int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +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) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); addr = simple_strtoul (argv[1], NULL, 16); addr += base_address; @@ -1120,7 +1108,7 @@ int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #else /* CONFIG_CRC32_VERIFY */ -int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr, length; ulong crc; @@ -1128,12 +1116,11 @@ int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong vcrc; int verify; int ac; - char **av; + char * const *av; if (argc < 3) { - usage: - cmd_usage(cmdtp); - return 1; +usage: + return cmd_usage(cmdtp); } av = argv + 1; @@ -1175,16 +1162,14 @@ int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #endif /* CONFIG_CRC32_VERIFY */ #ifdef CONFIG_CMD_MD5SUM -int do_md5sum(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_md5sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long addr, len; unsigned int i; u8 output[16]; - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); addr = simple_strtoul(argv[1], NULL, 16); len = simple_strtoul(argv[2], NULL, 16); @@ -1200,16 +1185,14 @@ int do_md5sum(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #endif #ifdef CONFIG_CMD_SHA1 -int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long addr, len; unsigned int i; u8 output[20]; - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); addr = simple_strtoul(argv[1], NULL, 16); len = simple_strtoul(argv[2], NULL, 16); @@ -1225,7 +1208,7 @@ int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #endif #ifdef CONFIG_CMD_UNZIP -int do_unzip ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +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; @@ -1239,8 +1222,7 @@ int do_unzip ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) dst = simple_strtoul(argv[2], NULL, 16); break; default: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } return !!gunzip((void *) dst, dst_len, (void *) src, &src_len); diff --git a/common/cmd_mfsl.c b/common/cmd_mfsl.c index b19ad0e..00180b0 100644 --- a/common/cmd_mfsl.c +++ b/common/cmd_mfsl.c @@ -31,23 +31,20 @@ #include <command.h> #include <asm/asm.h> -int do_frd (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_frd (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { unsigned int fslnum; unsigned int num; unsigned int blocking; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16); blocking = (unsigned int)simple_strtoul (argv[2], NULL, 16); if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER) { puts ("Bad number of FSL\n"); - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } switch (fslnum) { @@ -189,24 +186,20 @@ int do_frd (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 0; } -int do_fwr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_fwr (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { unsigned int fslnum; unsigned int num; unsigned int blocking; - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16); num = (unsigned int)simple_strtoul (argv[2], NULL, 16); blocking = (unsigned int)simple_strtoul (argv[3], NULL, 16); - if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER) { - cmd_usage(cmdtp); - return 1; - } + if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER) + return cmd_usage(cmdtp); switch (fslnum) { #if (XILINX_FSL_NUMBER > 0) @@ -348,15 +341,14 @@ int do_fwr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } -int do_rspr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_rspr (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { unsigned int reg = 0; unsigned int val = 0; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); + reg = (unsigned int)simple_strtoul (argv[1], NULL, 16); val = (unsigned int)simple_strtoul (argv[2], NULL, 16); switch (reg) { diff --git a/common/cmd_mgdisk.c b/common/cmd_mgdisk.c index 3ba62f6..d99af2d 100644 --- a/common/cmd_mgdisk.c +++ b/common/cmd_mgdisk.c @@ -26,7 +26,7 @@ #include <mg_disk.h> -int do_mg_disk_cmd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mg_disk_cmd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { u32 from, to, size; @@ -54,15 +54,14 @@ int do_mg_disk_cmd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; break; default: - printf("Usage:\n%s\n", cmdtp->usage); - return 1; + return cmd_usage(cmdtp); } return 0; } U_BOOT_CMD( mgd, 5, 0, do_mg_disk_cmd, - "mgd - mgine m[g]flash command\n", + "mgine m[g]flash command\n", ": mgine mflash IO mode (disk) command\n" " - initialize : mgd init\n" " - random read : mgd read [from] [to] [size]\n" diff --git a/common/cmd_mii.c b/common/cmd_mii.c index 65e13c3..3ea493b 100644 --- a/common/cmd_mii.c +++ b/common/cmd_mii.c @@ -292,19 +292,17 @@ static void extract_range( } /* ---------------------------------------------------------------- */ -int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { char op[2]; unsigned char addrlo, addrhi, reglo, reghi; unsigned char addr, reg; unsigned short data; int rcode = 0; - char *devname; + const char *devname; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); #if defined(CONFIG_MII_INIT) mii_init (); @@ -431,8 +429,7 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) else miiphy_set_current_dev (argv[2]); } else { - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } /* diff --git a/common/cmd_misc.c b/common/cmd_misc.c index b0ced2f..061b1bb 100644 --- a/common/cmd_misc.c +++ b/common/cmd_misc.c @@ -27,22 +27,20 @@ #include <common.h> #include <command.h> -int do_sleep (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_sleep (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong start = get_timer(0); ulong delay; - if (argc != 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc != 2) + return cmd_usage(cmdtp); delay = simple_strtoul(argv[1], NULL, 10) * CONFIG_SYS_HZ; while (get_timer(start) < delay) { - if (ctrlc ()) { + if (ctrlc ()) return (-1); - } + udelay (100); } diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index c67c9cf..4323f76 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -28,14 +28,12 @@ #ifndef CONFIG_GENERIC_MMC static int curr_device = -1; -int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int dev; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); if (strcmp(argv[1], "init") == 0) { if (argc == 2) { @@ -46,8 +44,7 @@ int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } else if (argc == 3) { dev = (int)simple_strtoul(argv[2], NULL, 10); } else { - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } if (mmc_legacy_init(dev) != 0) { @@ -72,14 +69,12 @@ int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #endif curr_device = dev; } else { - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } printf("mmc%d is current device\n", curr_device); } else { - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } return 0; @@ -114,7 +109,7 @@ static void print_mmcinfo(struct mmc *mmc) printf("Bus Width: %d-bit\n", mmc->bus_width); } -int do_mmcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mmcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct mmc *mmc; int dev_num; @@ -135,12 +130,15 @@ int do_mmcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -U_BOOT_CMD(mmcinfo, 2, 0, do_mmcinfo, - "mmcinfo <dev num>-- display MMC info", +U_BOOT_CMD( + mmcinfo, 2, 0, do_mmcinfo, + "display MMC info", + "<dev num>\n" + " - device number of the device to dislay info of\n" "" ); -int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int rc = 0; @@ -156,13 +154,31 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) mmc_init(mmc); return 0; + } else if (strncmp(argv[1], "part", 4) == 0) { + int dev = simple_strtoul(argv[2], NULL, 10); + block_dev_desc_t *mmc_dev; + struct mmc *mmc = find_mmc_device(dev); + + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + mmc_init(mmc); + mmc_dev = mmc_get_dev(dev); + if (mmc_dev != NULL && + mmc_dev->type != DEV_TYPE_UNKNOWN) { + print_part(mmc_dev); + return 0; + } + + puts("get mmc type error!\n"); + return 1; } case 0: case 1: case 4: - printf("Usage:\n%s\n", cmdtp->usage); - return 1; + return cmd_usage(cmdtp); case 2: if (!strcmp(argv[1], "list")) { @@ -217,10 +233,8 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); return (n == cnt) ? 0 : 1; - } else { - printf("Usage:\n%s\n", cmdtp->usage); - rc = 1; - } + } else + rc = cmd_usage(cmdtp); return rc; } @@ -232,5 +246,6 @@ U_BOOT_CMD( "read <device num> addr blk# cnt\n" "mmc write <device num> addr blk# cnt\n" "mmc rescan <device num>\n" + "mmc part <device num> - lists available partition on mmc\n" "mmc list - lists available devices"); #endif diff --git a/common/cmd_mp.c b/common/cmd_mp.c index d78c209..f19bf41 100644 --- a/common/cmd_mp.c +++ b/common/cmd_mp.c @@ -24,14 +24,12 @@ #include <command.h> int -cpu_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +cpu_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long cpuid; - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); cpuid = simple_strtoul(argv[1], NULL, 10); if (cpuid >= cpu_numcores()) { @@ -42,29 +40,24 @@ cpu_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (argc == 3) { - if (strncmp(argv[2], "reset", 5) == 0) { + if (strncmp(argv[2], "reset", 5) == 0) cpu_reset(cpuid); - } else if (strncmp(argv[2], "status", 6) == 0) { + else if (strncmp(argv[2], "status", 6) == 0) cpu_status(cpuid); - } else if (strncmp(argv[2], "disable", 7) == 0) { + else if (strncmp(argv[2], "disable", 7) == 0) return cpu_disable(cpuid); - } else { - cmd_usage(cmdtp); - return 1; - } + else + return cmd_usage(cmdtp); + return 0; } /* 4 or greater, make sure its release */ - if (strncmp(argv[2], "release", 7) != 0) { - cmd_usage(cmdtp); - return 1; - } + if (strncmp(argv[2], "release", 7) != 0) + return cmd_usage(cmdtp); - if (cpu_release(cpuid, argc - 3, argv + 3)) { - cmd_usage(cmdtp); - return 1; - } + if (cpu_release(cpuid, argc - 3, argv + 3)) + return cmd_usage(cmdtp); return 0; } diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c index 20fed2a..5481c88 100644 --- a/common/cmd_mtdparts.c +++ b/common/cmd_mtdparts.c @@ -15,6 +15,9 @@ * Parsing routines are based on driver/mtd/cmdline.c from the linux 2.4 * kernel tree. * + * (C) Copyright 2008 + * Harald Welte, OpenMoko, Inc., Harald Welte <laforge@openmoko.org> + * * $Id: cmdlinepart.c,v 1.17 2004/11/26 11:18:47 lavinen Exp $ * Copyright 2002 SYSGO Real-Time Solutions GmbH * @@ -103,16 +106,6 @@ #include <onenand_uboot.h> #endif -/* enable/disable debugging messages */ -#define DEBUG_MTDPARTS -#undef DEBUG_MTDPARTS - -#ifdef DEBUG_MTDPARTS -# define DEBUGF(fmt, args...) printf(fmt ,##args) -#else -# define DEBUGF(fmt, args...) -#endif - /* special size referring to all the remaining space in a partition */ #define SIZE_REMAINING 0xFFFFFFFF @@ -243,7 +236,7 @@ static void index_partitions(void) struct list_head *dentry; struct mtd_device *dev; - DEBUGF("--- index partitions ---\n"); + debug("--- index partitions ---\n"); if (current_mtd_dev) { mtddevnum = 0; @@ -261,12 +254,12 @@ static void index_partitions(void) part = mtd_part_info(current_mtd_dev, current_mtd_partnum); setenv("mtddevname", part->name); - DEBUGF("=> mtddevnum %d,\n=> mtddevname %s\n", mtddevnum, part->name); + debug("=> mtddevnum %d,\n=> mtddevname %s\n", mtddevnum, part->name); } else { setenv("mtddevnum", NULL); setenv("mtddevname", NULL); - DEBUGF("=> mtddevnum NULL\n=> mtddevname NULL\n"); + debug("=> mtddevnum NULL\n=> mtddevname NULL\n"); } } @@ -277,7 +270,7 @@ static void current_save(void) { char buf[16]; - DEBUGF("--- current_save ---\n"); + debug("--- current_save ---\n"); if (current_mtd_dev) { sprintf(buf, "%s%d,%d", MTD_DEV_TYPE(current_mtd_dev->id->type), @@ -286,16 +279,39 @@ static void current_save(void) setenv("partition", buf); strncpy(last_partition, buf, 16); - DEBUGF("=> partition %s\n", buf); + debug("=> partition %s\n", buf); } else { setenv("partition", NULL); last_partition[0] = '\0'; - DEBUGF("=> partition NULL\n"); + debug("=> partition NULL\n"); } index_partitions(); } + +/** + * Produce a mtd_info given a type and num. + * + * @param type mtd type + * @param num mtd number + * @param mtd a pointer to an mtd_info instance (output) + * @return 0 if device is valid, 1 otherwise + */ +static int get_mtd_info(u8 type, u8 num, struct mtd_info **mtd) +{ + char mtd_dev[16]; + + sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(type), num); + *mtd = get_mtd_device_nm(mtd_dev); + if (IS_ERR(*mtd)) { + printf("Device %s not found!\n", mtd_dev); + return 1; + } + + return 0; +} + /** * Performs sanity check for supplied flash partition. * Table of existing MTD flash devices is searched and partition device @@ -307,17 +323,12 @@ static void current_save(void) */ static int part_validate_eraseblock(struct mtdids *id, struct part_info *part) { - struct mtd_info *mtd; - char mtd_dev[16]; + struct mtd_info *mtd = NULL; int i, j; ulong start; - sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(id->type), id->num); - mtd = get_mtd_device_nm(mtd_dev); - if (IS_ERR(mtd)) { - printf("Partition %s not found on device %s!\n", part->name, mtd_dev); + if (get_mtd_info(id->type, id->num, &mtd)) return 1; - } part->sector_size = mtd->erasesize; @@ -505,7 +516,7 @@ static int part_sort_add(struct mtd_device *dev, struct part_info *part) part->dev = dev; if (list_empty(&dev->parts)) { - DEBUGF("part_sort_add: list empty\n"); + debug("part_sort_add: list empty\n"); list_add(&part->link, &dev->parts); dev->num_parts++; index_partitions(); @@ -598,7 +609,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i /* fetch the partition size */ if (*p == '-') { /* assign all remaining space to this partition */ - DEBUGF("'-': remaining size assigned\n"); + debug("'-': remaining size assigned\n"); size = SIZE_REMAINING; p++; } else { @@ -683,7 +694,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i part->name[name_len - 1] = '\0'; INIT_LIST_HEAD(&part->link); - DEBUGF("+ partition: name %-22s size 0x%08x offset 0x%08x mask flags %d\n", + debug("+ partition: name %-22s size 0x%08x offset 0x%08x mask flags %d\n", part->name, part->size, part->offset, part->mask_flags); @@ -694,20 +705,17 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i /** * Check device number to be within valid range for given device type. * - * @param dev device to validate + * @param type mtd type + * @param num mtd number + * @param size a pointer to the size of the mtd device (output) * @return 0 if device is valid, 1 otherwise */ int mtd_device_validate(u8 type, u8 num, u32 *size) { - struct mtd_info *mtd; - char mtd_dev[16]; + struct mtd_info *mtd = NULL; - sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(type), num); - mtd = get_mtd_device_nm(mtd_dev); - if (IS_ERR(mtd)) { - printf("Device %s not found!\n", mtd_dev); + if (get_mtd_info(type, num, &mtd)) return 1; - } *size = mtd->size; @@ -776,7 +784,7 @@ static int device_del(struct mtd_device *dev) * @param num device number * @return NULL if requested device does not exist */ -static struct mtd_device* device_find(u8 type, u8 num) +struct mtd_device *device_find(u8 type, u8 num) { struct list_head *entry; struct mtd_device *dev_tmp; @@ -837,14 +845,16 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ u32 offset; int err = 1; - p = mtd_dev; + debug("===device_parse===\n"); + + assert(retdev); *retdev = NULL; - *ret = NULL; - DEBUGF("===device_parse===\n"); + if (ret) + *ret = NULL; /* fetch <mtd-id> */ - mtd_id = p; + mtd_id = p = mtd_dev; if (!(p = strchr(mtd_id, ':'))) { printf("no <mtd-id> identifier\n"); return 1; @@ -858,11 +868,11 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ return 1; } - DEBUGF("dev type = %d (%s), dev num = %d, mtd-id = %s\n", + debug("dev type = %d (%s), dev num = %d, mtd-id = %s\n", id->type, MTD_DEV_TYPE(id->type), id->num, id->mtd_id); pend = strchr(p, ';'); - DEBUGF("parsing partitions %.*s\n", (pend ? pend - p : strlen(p)), p); + debug("parsing partitions %.*s\n", (pend ? pend - p : strlen(p)), p); /* parse partitions */ @@ -908,17 +918,20 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ return 1; } - DEBUGF("\ntotal partitions: %d\n", num_parts); + debug("\ntotal partitions: %d\n", num_parts); /* check for next device presence */ if (p) { if (*p == ';') { - *ret = ++p; + if (ret) + *ret = ++p; } else if (*p == '\0') { - *ret = p; + if (ret) + *ret = p; } else { printf("unexpected character '%c' at the end of device\n", *p); - *ret = NULL; + if (ret) + *ret = NULL; return 1; } } @@ -946,7 +959,7 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ *retdev = dev; - DEBUGF("===\n\n"); + debug("===\n\n"); return 0; } @@ -998,13 +1011,13 @@ static struct mtdids* id_find_by_mtd_id(const char *mtd_id, unsigned int mtd_id_ struct list_head *entry; struct mtdids *id; - DEBUGF("--- id_find_by_mtd_id: '%.*s' (len = %d)\n", + debug("--- id_find_by_mtd_id: '%.*s' (len = %d)\n", mtd_id_len, mtd_id, mtd_id_len); list_for_each(entry, &mtdids) { id = list_entry(entry, struct mtdids, link); - DEBUGF("entry: '%s' (len = %d)\n", + debug("entry: '%s' (len = %d)\n", id->mtd_id, strlen(id->mtd_id)); if (mtd_id_len != strlen(id->mtd_id)) @@ -1074,7 +1087,7 @@ static int generate_mtdparts(char *buf, u32 buflen) u32 size, offset, len, part_cnt; u32 maxlen = buflen - 1; - DEBUGF("--- generate_mtdparts ---\n"); + debug("--- generate_mtdparts ---\n"); if (list_empty(&devices)) { buf[0] = '\0'; @@ -1205,38 +1218,93 @@ static int generate_mtdparts_save(char *buf, u32 buflen) return ret; } +#if defined(CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES) /** - * Format and print out a partition list for each device from global device - * list. + * Get the net size (w/o bad blocks) of the given partition. + * + * @param mtd the mtd info + * @param part the partition + * @return the calculated net size of this partition */ -static void list_partitions(void) +static uint64_t net_part_size(struct mtd_info *mtd, struct part_info *part) +{ + uint64_t i, net_size = 0; + + if (!mtd->block_isbad) + return part->size; + + for (i = 0; i < part->size; i += mtd->erasesize) { + if (!mtd->block_isbad(mtd, part->offset + i)) + net_size += mtd->erasesize; + } + + return net_size; +} +#endif + +static void print_partition_table(void) { struct list_head *dentry, *pentry; struct part_info *part; struct mtd_device *dev; int part_num; - DEBUGF("\n---list_partitions---\n"); list_for_each(dentry, &devices) { dev = list_entry(dentry, struct mtd_device, link); + /* list partitions for given device */ + part_num = 0; +#if defined(CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES) + struct mtd_info *mtd; + + if (get_mtd_info(dev->id->type, dev->id->num, &mtd)) + return; + + printf("\ndevice %s%d <%s>, # parts = %d\n", + MTD_DEV_TYPE(dev->id->type), dev->id->num, + dev->id->mtd_id, dev->num_parts); + printf(" #: name\t\tsize\t\tnet size\toffset\t\tmask_flags\n"); + + list_for_each(pentry, &dev->parts) { + u32 net_size; + char *size_note; + + part = list_entry(pentry, struct part_info, link); + net_size = net_part_size(mtd, part); + size_note = part->size == net_size ? " " : " (!)"; + printf("%2d: %-20s0x%08x\t0x%08x%s\t0x%08x\t%d\n", + part_num, part->name, part->size, + net_size, size_note, part->offset, + part->mask_flags); +#else /* !defined(CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES) */ printf("\ndevice %s%d <%s>, # parts = %d\n", MTD_DEV_TYPE(dev->id->type), dev->id->num, dev->id->mtd_id, dev->num_parts); printf(" #: name\t\tsize\t\toffset\t\tmask_flags\n"); - /* list partitions for given device */ - part_num = 0; list_for_each(pentry, &dev->parts) { part = list_entry(pentry, struct part_info, link); printf("%2d: %-20s0x%08x\t0x%08x\t%d\n", part_num, part->name, part->size, part->offset, part->mask_flags); - +#endif /* defined(CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES) */ part_num++; } } + if (list_empty(&devices)) printf("no partitions defined\n"); +} + +/** + * Format and print out a partition list for each device from global device + * list. + */ +static void list_partitions(void) +{ + struct part_info *part; + + debug("\n---list_partitions---\n"); + print_partition_table(); /* current_mtd_dev is not NULL only when we have non empty device list */ if (current_mtd_dev) { @@ -1281,7 +1349,7 @@ int find_dev_and_part(const char *id, struct mtd_device **dev, u8 type, dnum, pnum; const char *p; - DEBUGF("--- find_dev_and_part ---\nid = %s\n", id); + debug("--- find_dev_and_part ---\nid = %s\n", id); list_for_each(dentry, &devices) { *part_num = 0; @@ -1342,7 +1410,7 @@ static int delete_partition(const char *id) if (find_dev_and_part(id, &dev, &pnum, &part) == 0) { - DEBUGF("delete_partition: device = %s%d, partition %d = (%s) 0x%08x@0x%08x\n", + debug("delete_partition: device = %s%d, partition %d = (%s) 0x%08x@0x%08x\n", MTD_DEV_TYPE(dev->id->type), dev->id->num, pnum, part->name, part->size, part->offset); @@ -1360,6 +1428,101 @@ static int delete_partition(const char *id) return 1; } +#if defined(CONFIG_CMD_MTDPARTS_SPREAD) +/** + * Increase the size of the given partition so that it's net size is at least + * as large as the size member and such that the next partition would start on a + * good block if it were adjacent to this partition. + * + * @param mtd the mtd device + * @param part the partition + * @param next_offset pointer to the offset of the next partition after this + * partition's size has been modified (output) + */ +static void spread_partition(struct mtd_info *mtd, struct part_info *part, + uint64_t *next_offset) +{ + uint64_t net_size, padding_size = 0; + int truncated; + + mtd_get_len_incl_bad(mtd, part->offset, part->size, &net_size, + &truncated); + + /* + * Absorb bad blocks immediately following this + * partition also into the partition, such that + * the next partition starts with a good block. + */ + if (!truncated) { + mtd_get_len_incl_bad(mtd, part->offset + net_size, + mtd->erasesize, &padding_size, &truncated); + if (truncated) + padding_size = 0; + else + padding_size -= mtd->erasesize; + } + + if (truncated) { + printf("truncated partition %s to %lld bytes\n", part->name, + (uint64_t) net_size + padding_size); + } + + part->size = net_size + padding_size; + *next_offset = part->offset + part->size; +} + +/** + * Adjust all of the partition sizes, such that all partitions are at least + * as big as their mtdparts environment variable sizes and they each start + * on a good block. + * + * @return 0 on success, 1 otherwise + */ +static int spread_partitions(void) +{ + struct list_head *dentry, *pentry; + struct mtd_device *dev; + struct part_info *part; + struct mtd_info *mtd; + int part_num; + uint64_t cur_offs; + + list_for_each(dentry, &devices) { + dev = list_entry(dentry, struct mtd_device, link); + + if (get_mtd_info(dev->id->type, dev->id->num, &mtd)) + return 1; + + part_num = 0; + cur_offs = 0; + list_for_each(pentry, &dev->parts) { + part = list_entry(pentry, struct part_info, link); + + debug("spread_partitions: device = %s%d, partition %d =" + " (%s) 0x%08x@0x%08x\n", + MTD_DEV_TYPE(dev->id->type), dev->id->num, + part_num, part->name, part->size, + part->offset); + + if (cur_offs > part->offset) + part->offset = cur_offs; + + spread_partition(mtd, part, &cur_offs); + + part_num++; + } + } + + index_partitions(); + + if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) { + printf("generated mtdparts too long, reseting to null\n"); + return 1; + } + return 0; +} +#endif /* CONFIG_CMD_MTDPARTS_SPREAD */ + /** * Accept character string describing mtd partitions and call device_parse() * for each entry. Add created devices to the global devices list. @@ -1373,7 +1536,7 @@ static int parse_mtdparts(const char *const mtdparts) struct mtd_device *dev; int err = 1; - DEBUGF("\n---parse_mtdparts---\nmtdparts = %s\n\n", p); + debug("\n---parse_mtdparts---\nmtdparts = %s\n\n", p); /* delete all devices and partitions */ if (mtd_devices_init() != 0) { @@ -1395,7 +1558,7 @@ static int parse_mtdparts(const char *const mtdparts) if ((device_parse(p, &p, &dev) != 0) || (!dev)) break; - DEBUGF("+ device: %s\t%d\t%s\n", MTD_DEV_TYPE(dev->id->type), + debug("+ device: %s\t%d\t%s\n", MTD_DEV_TYPE(dev->id->type), dev->id->num, dev->id->mtd_id); /* check if parsed device is already on the list */ @@ -1436,12 +1599,12 @@ static int parse_mtdids(const char *const ids) u32 size; int ret = 1; - DEBUGF("\n---parse_mtdids---\nmtdids = %s\n\n", ids); + debug("\n---parse_mtdids---\nmtdids = %s\n\n", ids); /* clean global mtdids list */ list_for_each_safe(entry, n, &mtdids) { id_tmp = list_entry(entry, struct mtdids, link); - DEBUGF("mtdids del: %d %d\n", id_tmp->type, id_tmp->num); + debug("mtdids del: %d %d\n", id_tmp->type, id_tmp->num); list_del(entry); free(id_tmp); } @@ -1507,7 +1670,7 @@ static int parse_mtdids(const char *const ids) id->mtd_id[mtd_id_len - 1] = '\0'; INIT_LIST_HEAD(&id->link); - DEBUGF("+ id %s%d\t%16d bytes\t%s\n", + debug("+ id %s%d\t%16d bytes\t%s\n", MTD_DEV_TYPE(id->type), id->num, id->size, id->mtd_id); @@ -1541,7 +1704,7 @@ int mtdparts_init(void) int ids_changed; char tmp_ep[PARTITION_MAXLEN]; - DEBUGF("\n---mtdparts_init---\n"); + debug("\n---mtdparts_init---\n"); if (!initialized) { INIT_LIST_HEAD(&mtdids); INIT_LIST_HEAD(&devices); @@ -1562,18 +1725,18 @@ int mtdparts_init(void) if (current_partition) strncpy(tmp_ep, current_partition, PARTITION_MAXLEN); - DEBUGF("last_ids : %s\n", last_ids); - DEBUGF("env_ids : %s\n", ids); - DEBUGF("last_parts: %s\n", last_parts); - DEBUGF("env_parts : %s\n\n", parts); + debug("last_ids : %s\n", last_ids); + debug("env_ids : %s\n", ids); + debug("last_parts: %s\n", last_parts); + debug("env_parts : %s\n\n", parts); - DEBUGF("last_partition : %s\n", last_partition); - DEBUGF("env_partition : %s\n", current_partition); + debug("last_partition : %s\n", last_partition); + debug("env_partition : %s\n", current_partition); /* if mtdids varible is empty try to use defaults */ if (!ids) { if (mtdids_default) { - DEBUGF("mtdids variable not defined, using default\n"); + debug("mtdids variable not defined, using default\n"); ids = mtdids_default; setenv("mtdids", (char *)ids); } else { @@ -1629,7 +1792,7 @@ int mtdparts_init(void) current_mtd_partnum = 0; current_save(); - DEBUGF("mtdparts_init: current_mtd_dev = %s%d, current_mtd_partnum = %d\n", + debug("mtdparts_init: current_mtd_dev = %s%d, current_mtd_partnum = %d\n", MTD_DEV_TYPE(current_mtd_dev->id->type), current_mtd_dev->id->num, current_mtd_partnum); } @@ -1648,7 +1811,7 @@ int mtdparts_init(void) struct mtd_device *cdev; u8 pnum; - DEBUGF("--- getting current partition: %s\n", tmp_ep); + debug("--- getting current partition: %s\n", tmp_ep); if (find_dev_and_part(tmp_ep, &cdev, &pnum, &p) == 0) { current_mtd_dev = cdev; @@ -1656,7 +1819,7 @@ int mtdparts_init(void) current_save(); } } else if (getenv("partition") == NULL) { - DEBUGF("no partition variable set, setting...\n"); + debug("no partition variable set, setting...\n"); current_save(); } @@ -1680,7 +1843,7 @@ static struct part_info* mtd_part_info(struct mtd_device *dev, unsigned int part if (!dev) return NULL; - DEBUGF("\n--- mtd_part_info: partition number %d for device %s%d (%s)\n", + debug("\n--- mtd_part_info: partition number %d for device %s%d (%s)\n", part_num, MTD_DEV_TYPE(dev->id->type), dev->id->num, dev->id->mtd_id); @@ -1718,7 +1881,7 @@ static struct part_info* mtd_part_info(struct mtd_device *dev, unsigned int part * @param argv arguments list * @return 0 on success, 1 otherwise */ -int do_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { /* command line only */ struct mtd_device *dev; @@ -1756,7 +1919,7 @@ int do_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * @param argv arguments list * @return 0 on success, 1 otherwise */ -int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { if (argc == 2) { if (strcmp(argv[1], "default") == 0) { @@ -1787,9 +1950,13 @@ int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } /* mtdparts add <mtd-dev> <size>[@<offset>] <name> [ro] */ - if (((argc == 5) || (argc == 6)) && (strcmp(argv[1], "add") == 0)) { + if (((argc == 5) || (argc == 6)) && (strncmp(argv[1], "add", 3) == 0)) { #define PART_ADD_DESC_MAXLEN 64 char tmpbuf[PART_ADD_DESC_MAXLEN]; +#if defined(CONFIG_CMD_MTDPARTS_SPREAD) + struct mtd_info *mtd; + uint64_t next_offset; +#endif u8 type, num, len; struct mtd_device *dev; struct mtd_device *dev_tmp; @@ -1816,23 +1983,33 @@ int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } sprintf(tmpbuf, "%s:%s(%s)%s", id->mtd_id, argv[3], argv[4], argv[5] ? argv[5] : ""); - DEBUGF("add tmpbuf: %s\n", tmpbuf); + debug("add tmpbuf: %s\n", tmpbuf); if ((device_parse(tmpbuf, NULL, &dev) != 0) || (!dev)) return 1; - DEBUGF("+ %s\t%d\t%s\n", MTD_DEV_TYPE(dev->id->type), + debug("+ %s\t%d\t%s\n", MTD_DEV_TYPE(dev->id->type), dev->id->num, dev->id->mtd_id); - if ((dev_tmp = device_find(dev->id->type, dev->id->num)) == NULL) { + p = list_entry(dev->parts.next, struct part_info, link); + +#if defined(CONFIG_CMD_MTDPARTS_SPREAD) + if (get_mtd_info(dev->id->type, dev->id->num, &mtd)) + return 1; + + if (!strcmp(&argv[1][3], ".spread")) { + spread_partition(mtd, p, &next_offset); + debug("increased %s to %d bytes\n", p->name, p->size); + } +#endif + + dev_tmp = device_find(dev->id->type, dev->id->num); + if (dev_tmp == NULL) { device_add(dev); - } else { + } else if (part_add(dev_tmp, p) != 0) { /* merge new partition with existing ones*/ - p = list_entry(dev->parts.next, struct part_info, link); - if (part_add(dev_tmp, p) != 0) { - device_del(dev); - return 1; - } + device_del(dev); + return 1; } if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) { @@ -1845,13 +2022,17 @@ int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* mtdparts del part-id */ if ((argc == 3) && (strcmp(argv[1], "del") == 0)) { - DEBUGF("del: part-id = %s\n", argv[2]); + debug("del: part-id = %s\n", argv[2]); return delete_partition(argv[2]); } - cmd_usage(cmdtp); - return 1; +#if defined(CONFIG_CMD_MTDPARTS_SPREAD) + if ((argc == 2) && (strcmp(argv[1], "spread") == 0)) + return spread_partitions(); +#endif /* CONFIG_CMD_MTDPARTS_SPREAD */ + + return cmd_usage(cmdtp); } /***************************************************/ @@ -1873,8 +2054,20 @@ U_BOOT_CMD( " - delete partition (e.g. part-id = nand0,1)\n" "mtdparts add <mtd-dev> <size>[@<offset>] [<name>] [ro]\n" " - add partition\n" +#if defined(CONFIG_CMD_MTDPARTS_SPREAD) + "mtdparts add.spread <mtd-dev> <size>[@<offset>] [<name>] [ro]\n" + " - add partition, padding size by skipping bad blocks\n" +#endif "mtdparts default\n" - " - reset partition table to defaults\n\n" + " - reset partition table to defaults\n" +#if defined(CONFIG_CMD_MTDPARTS_SPREAD) + "mtdparts spread\n" + " - adjust the sizes of the partitions so they are\n" + " at least as big as the mtdparts variable specifies\n" + " and they each start on a good block\n\n" +#else + "\n" +#endif /* CONFIG_CMD_MTDPARTS_SPREAD */ "-----\n\n" "this command uses three environment variables:\n\n" "'partition' - keeps current partition identifier\n\n" diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 075a8af..634d036 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -4,8 +4,19 @@ * (c) 1999 Machine Vision Holdings, Inc. * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> * + * Ported 'dynenv' to 'nand env.oob' command + * (C) 2010 Nanometrics, Inc. + * 'dynenv' -- Dynamic environment offset in NAND OOB + * (C) Copyright 2006-2007 OpenMoko, Inc. * Added 16-bit nand support * (C) 2004 Texas Instruments + * + * Copyright 2010 Freescale Semiconductor + * The portions of this file whose copyright is held by Freescale and which + * are not considered a derived work of GPL v2-only code may be distributed + * and/or modified 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. */ #include <common.h> @@ -19,17 +30,23 @@ #if defined(CONFIG_CMD_MTDPARTS) -/* parition handling routines */ +/* partition handling routines */ int mtdparts_init(void); int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num); int find_dev_and_part(const char *id, struct mtd_device **dev, u8 *part_num, struct part_info **part); #endif -static int nand_dump(nand_info_t *nand, ulong off, int only_oob) +static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat) { int i; u_char *datbuf, *oobbuf, *p; + static loff_t last; + + if (repeat) + off = last + nand->writesize; + + last = off; datbuf = malloc(nand->writesize + nand->oobsize); oobbuf = malloc(nand->oobsize); @@ -81,74 +98,132 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob) /* ------------------------------------------------------------------------- */ -static inline int str2long(char *p, ulong *num) +static int set_dev(int dev) +{ + if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE || + !nand_info[dev].name) { + puts("No such device\n"); + return -1; + } + + if (nand_curr_device == dev) + return 0; + + printf("Device %d: %s", dev, nand_info[dev].name); + puts("... is now current device\n"); + nand_curr_device = dev; + +#ifdef CONFIG_SYS_NAND_SELECT_DEVICE + board_nand_select_device(nand_info[dev].priv, dev); +#endif + + return 0; +} + +static inline int str2off(const char *p, loff_t *num) +{ + char *endptr; + + *num = simple_strtoull(p, &endptr, 16); + return *p != '\0' && *endptr == '\0'; +} + +static inline int str2long(const char *p, ulong *num) { char *endptr; *num = simple_strtoul(p, &endptr, 16); - return (*p != '\0' && *endptr == '\0') ? 1 : 0; + return *p != '\0' && *endptr == '\0'; } -static int -arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, size_t *size) +static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size) { - int idx = nand_curr_device; -#if defined(CONFIG_CMD_MTDPARTS) +#ifdef CONFIG_CMD_MTDPARTS struct mtd_device *dev; struct part_info *part; u8 pnum; + int ret; - if (argc >= 1 && !(str2long(argv[0], off))) { - if ((mtdparts_init() == 0) && - (find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) { - if (dev->id->type != MTD_DEV_TYPE_NAND) { - puts("not a NAND device\n"); - return -1; - } - *off = part->offset; - if (argc >= 2) { - if (!(str2long(argv[1], (ulong *)size))) { - printf("'%s' is not a number\n", argv[1]); - return -1; - } - if (*size > part->size) - *size = part->size; - } else { - *size = part->size; - } - idx = dev->id->num; - *nand = nand_info[idx]; - goto out; - } + ret = mtdparts_init(); + if (ret) + return ret; + + ret = find_dev_and_part(partname, &dev, &pnum, &part); + if (ret) + return ret; + + if (dev->id->type != MTD_DEV_TYPE_NAND) { + puts("not a NAND device\n"); + return -1; } + + *off = part->offset; + *size = part->size; + *idx = dev->id->num; + + ret = set_dev(*idx); + if (ret) + return ret; + + return 0; +#else + puts("offset is not a number\n"); + return -1; #endif +} - if (argc >= 1) { - if (!(str2long(argv[0], off))) { - printf("'%s' is not a number\n", argv[0]); - return -1; - } - } else { +static int arg_off(const char *arg, int *idx, loff_t *off, loff_t *maxsize) +{ + if (!str2off(arg, off)) + return get_part(arg, idx, off, maxsize); + + if (*off >= nand_info[*idx].size) { + puts("Offset exceeds device limit\n"); + return -1; + } + + *maxsize = nand_info[*idx].size - *off; + return 0; +} + +static int arg_off_size(int argc, char *const argv[], int *idx, + loff_t *off, loff_t *size) +{ + int ret; + loff_t maxsize; + + if (argc == 0) { *off = 0; + *size = nand_info[*idx].size; + goto print; } - if (argc >= 2) { - if (!(str2long(argv[1], (ulong *)size))) { - printf("'%s' is not a number\n", argv[1]); - return -1; - } - } else { - *size = nand->size - *off; + ret = arg_off(argv[0], idx, off, &maxsize); + if (ret) + return ret; + + if (argc == 1) { + *size = maxsize; + goto print; } -#if defined(CONFIG_CMD_MTDPARTS) -out: -#endif - printf("device %d ", idx); - if (*size == nand->size) + if (!str2off(argv[1], size)) { + printf("'%s' is not a number\n", argv[1]); + return -1; + } + + if (*size > maxsize) { + puts("Size exceeds partition or device limit\n"); + return -1; + } + +print: + printf("device %d ", *idx); + if (*size == nand_info[*idx].size) puts("whole chip\n"); else - printf("offset 0x%lx, size 0x%zx\n", *off, *size); + printf("offset 0x%llx, size 0x%llx\n", + (unsigned long long)*off, (unsigned long long)*size); return 0; } @@ -193,6 +268,100 @@ static void do_nand_status(nand_info_t *nand) } #endif +#ifdef CONFIG_ENV_OFFSET_OOB +unsigned long nand_env_oob_offset; + +int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[]) +{ + int ret; + uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)]; + nand_info_t *nand = &nand_info[0]; + char *cmd = argv[1]; + + if (CONFIG_SYS_MAX_NAND_DEVICE == 0 || !nand->name) { + puts("no devices available\n"); + return 1; + } + + set_dev(0); + + if (!strcmp(cmd, "get")) { + ret = get_nand_env_oob(nand, &nand_env_oob_offset); + if (ret) + return 1; + + printf("0x%08lx\n", nand_env_oob_offset); + } else if (!strcmp(cmd, "set")) { + loff_t addr; + loff_t maxsize; + struct mtd_oob_ops ops; + int idx = 0; + + if (argc < 3) + goto usage; + + if (arg_off(argv[2], &idx, &addr, &maxsize)) { + puts("Offset or partition name expected\n"); + return 1; + } + + if (idx != 0) { + puts("Partition not on first NAND device\n"); + return 1; + } + + if (nand->oobavail < ENV_OFFSET_SIZE) { + printf("Insufficient available OOB bytes:\n" + "%d OOB bytes available but %d required for " + "env.oob support\n", + nand->oobavail, ENV_OFFSET_SIZE); + return 1; + } + + if ((addr & (nand->erasesize - 1)) != 0) { + printf("Environment offset must be block-aligned\n"); + return 1; + } + + ops.datbuf = NULL; + ops.mode = MTD_OOB_AUTO; + ops.ooboffs = 0; + ops.ooblen = ENV_OFFSET_SIZE; + ops.oobbuf = (void *) oob_buf; + + oob_buf[0] = ENV_OOB_MARKER; + oob_buf[1] = addr / nand->erasesize; + + ret = nand->write_oob(nand, ENV_OFFSET_SIZE, &ops); + if (ret) { + printf("Error writing OOB block 0\n"); + return ret; + } + + ret = get_nand_env_oob(nand, &nand_env_oob_offset); + if (ret) { + printf("Error reading env offset in OOB\n"); + return ret; + } + + if (addr != nand_env_oob_offset) { + printf("Verification of env offset in OOB failed: " + "0x%08llx expected but got 0x%08lx\n", + (unsigned long long)addr, nand_env_oob_offset); + return 1; + } + } else { + goto usage; + } + + return ret; + +usage: + return cmd_usage(cmdtp); +} + +#endif + static void nand_print_info(int idx) { nand_info_t *nand = &nand_info[idx]; @@ -204,11 +373,11 @@ static void nand_print_info(int idx) nand->name, nand->erasesize >> 10); } -int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - int i, dev, ret = 0; - ulong addr, off; - size_t size; + int i, ret = 0; + ulong addr; + loff_t off, size; char *cmd, *s; nand_info_t *nand; #ifdef CONFIG_SYS_NAND_QUIET @@ -217,6 +386,8 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) int quiet = 0; #endif const char *quiet_str = getenv("quiet"); + int dev = nand_curr_device; + int repeat = flag & CMD_FLAG_REPEAT; /* at least two arguments please */ if (argc < 2) @@ -227,6 +398,10 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) cmd = argv[1]; + /* Only "dump" is repeatable. */ + if (repeat && strcmp(cmd, "dump")) + return 0; + if (strcmp(cmd, "info") == 0) { putc('\n'); @@ -238,56 +413,45 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } if (strcmp(cmd, "device") == 0) { - if (argc < 3) { putc('\n'); - if ((nand_curr_device < 0) || - (nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE)) + if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE) puts("no devices available\n"); else - nand_print_info(nand_curr_device); + nand_print_info(dev); return 0; } - dev = (int)simple_strtoul(argv[2], NULL, 10); - if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[dev].name) { - puts("No such device\n"); - return 1; - } - printf("Device %d: %s", dev, nand_info[dev].name); - puts("... is now current device\n"); - nand_curr_device = dev; -#ifdef CONFIG_SYS_NAND_SELECT_DEVICE - /* - * Select the chip in the board/cpu specific driver - */ - board_nand_select_device(nand_info[dev].priv, dev); -#endif + dev = (int)simple_strtoul(argv[2], NULL, 10); + set_dev(dev); return 0; } - if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && - strncmp(cmd, "dump", 4) != 0 && - strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 && - strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 && - strcmp(cmd, "biterr") != 0 && - strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 ) - goto usage; +#ifdef CONFIG_ENV_OFFSET_OOB + /* this command operates only on the first nand device */ + if (strcmp(cmd, "env.oob") == 0) + return do_nand_env_oob(cmdtp, argc - 1, argv + 1); +#endif - /* the following commands operate on the current device */ - if (nand_curr_device < 0 || nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE || - !nand_info[nand_curr_device].name) { + /* The following commands operate on the current device, unless + * overridden by a partition specifier. Note that if somehow the + * current device is invalid, it will have to be changed to a valid + * one before these commands can run, even if a partition specifier + * for another device is to be used. + */ + if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE || + !nand_info[dev].name) { puts("\nno devices available\n"); return 1; } - nand = &nand_info[nand_curr_device]; + nand = &nand_info[dev]; if (strcmp(cmd, "bad") == 0) { - printf("\nDevice %d bad blocks:\n", nand_curr_device); + printf("\nDevice %d bad blocks:\n", dev); for (off = 0; off < nand->size; off += nand->erasesize) if (nand_block_isbad(nand, off)) - printf(" %08lx\n", off); + printf(" %08llx\n", (unsigned long long)off); return 0; } @@ -296,23 +460,52 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) * 0 1 2 3 4 * nand erase [clean] [off size] */ - if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) { + if (strncmp(cmd, "erase", 5) == 0 || strncmp(cmd, "scrub", 5) == 0) { nand_erase_options_t opts; /* "clean" at index 2 means request to write cleanmarker */ int clean = argc > 2 && !strcmp("clean", argv[2]); int o = clean ? 3 : 2; - int scrub = !strcmp(cmd, "scrub"); + int scrub = !strncmp(cmd, "scrub", 5); + int part = 0; + int chip = 0; + int spread = 0; + int args = 2; + + if (cmd[5] != 0) { + if (!strcmp(&cmd[5], ".spread")) { + spread = 1; + } else if (!strcmp(&cmd[5], ".part")) { + part = 1; + args = 1; + } else if (!strcmp(&cmd[5], ".chip")) { + chip = 1; + args = 0; + } else { + goto usage; + } + } - printf("\nNAND %s: ", scrub ? "scrub" : "erase"); + /* + * Don't allow missing arguments to cause full chip/partition + * erases -- easy to do accidentally, e.g. with a misspelled + * variable name. + */ + if (argc != o + args) + goto usage; + + printf("\nNAND %s: ", cmd); /* skip first two or three arguments, look for offset and size */ - if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0) + if (arg_off_size(argc - o, argv + o, &dev, &off, &size) != 0) return 1; + nand = &nand_info[dev]; + memset(&opts, 0, sizeof(opts)); opts.offset = off; opts.length = size; opts.jffs2 = clean; opts.quiet = quiet; + opts.spread = spread; if (scrub) { puts("Warning: " @@ -327,8 +520,14 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) "are sure of what you are doing!\n" "\nReally scrub this NAND flash? <y/N>\n"); - if (getc() == 'y' && getc() == '\r') { - opts.scrub = 1; + if (getc() == 'y') { + puts("y"); + if (getc() == '\r') + opts.scrub = 1; + else { + puts("scrub aborted\n"); + return -1; + } } else { puts("scrub aborted\n"); return -1; @@ -344,19 +543,14 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (argc < 3) goto usage; - s = strchr(cmd, '.'); off = (int)simple_strtoul(argv[2], NULL, 16); - - if (s != NULL && strcmp(s, ".oob") == 0) - ret = nand_dump(nand, off, 1); - else - ret = nand_dump(nand, off, 0); + ret = nand_dump(nand, off, !strcmp(&cmd[4], ".oob"), repeat); return ret == 0 ? 1 : 0; - } if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { + size_t rwsize; int read; if (argc < 4) @@ -366,23 +560,26 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ printf("\nNAND %s: ", read ? "read" : "write"); - if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0) + if (arg_off_size(argc - 3, argv + 3, &dev, &off, &size) != 0) return 1; + nand = &nand_info[dev]; + rwsize = size; + s = strchr(cmd, '.'); if (!s || !strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i")) { if (read) - ret = nand_read_skip_bad(nand, off, &size, + ret = nand_read_skip_bad(nand, off, &rwsize, (u_char *)addr); else - ret = nand_write_skip_bad(nand, off, &size, + ret = nand_write_skip_bad(nand, off, &rwsize, (u_char *)addr); } else if (!strcmp(s, ".oob")) { /* out-of-band data */ mtd_oob_ops_t ops = { .oobbuf = (u8 *)addr, - .ooblen = size, + .ooblen = rwsize, .mode = MTD_OOB_RAW }; @@ -395,7 +592,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 1; } - printf(" %zu bytes %s: %s\n", size, + printf(" %zu bytes %s: %s\n", rwsize, read ? "read" : "written", ret ? "ERROR" : "OK"); return ret == 0 ? 0 : 1; @@ -456,10 +653,10 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } if (strcmp(cmd, "unlock") == 0) { - if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0) + if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size) < 0) return 1; - if (!nand_unlock(nand, off, size)) { + if (!nand_unlock(&nand_info[dev], off, size)) { puts("NAND flash successfully unlocked\n"); } else { puts("Error unlocking NAND flash, " @@ -471,11 +668,11 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) #endif usage: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } -U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand, +U_BOOT_CMD( + nand, CONFIG_SYS_MAXARGS, 1, do_nand, "NAND sub-system", "info - show available NAND devices\n" "nand device [dev] - show or set current device\n" @@ -483,11 +680,16 @@ U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand, "nand write - addr off|partition size\n" " read/write 'size' bytes starting at offset 'off'\n" " to/from memory address 'addr', skipping bad blocks.\n" - "nand erase [clean] [off size] - erase 'size' bytes from\n" - " offset 'off' (entire device if not specified)\n" + "nand erase[.spread] [clean] [off [size]] - erase 'size' bytes " + "from offset 'off'\n" + " With '.spread', erase enough for given file size, otherwise,\n" + " 'size' includes skipped bad blocks.\n" + "nand erase.part [clean] partition - erase entire mtd partition'\n" + "nand erase.chip [clean] - erase entire chip'\n" "nand bad - show bad blocks\n" "nand dump[.oob] off - dump page\n" - "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n" + "nand scrub off size | scrub.part partition | scrub.chip\n" + " really clean NAND erasing bad blocks (UNSAFE)\n" "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n" "nand biterr off - make a bit error at offset (UNSAFE)" #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK @@ -496,6 +698,13 @@ U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand, " bring nand to lock state or display locked pages\n" "nand unlock [offset] [size] - unlock section" #endif +#ifdef CONFIG_ENV_OFFSET_OOB + "\n" + "nand env.oob - environment offset in OOB of block 0 of" + " first device.\n" + "nand env.oob set off|partition - set enviromnent offset\n" + "nand env.oob get - get environment offset" +#endif ); static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, @@ -593,7 +802,7 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, return 0; } -int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { char *boot_device = NULL; int idx; @@ -646,9 +855,8 @@ int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) #if defined(CONFIG_CMD_MTDPARTS) usage: #endif - cmd_usage(cmdtp); show_boot_progress(-53); - return 1; + return cmd_usage(cmdtp); } show_boot_progress(53); diff --git a/common/cmd_net.c b/common/cmd_net.c index b80a7ad..44d17db 100644 --- a/common/cmd_net.c +++ b/common/cmd_net.c @@ -28,11 +28,11 @@ #include <command.h> #include <net.h> -extern int do_bootm (cmd_tbl_t *, int, int, char *[]); +extern int do_bootm (cmd_tbl_t *, int, int, char * const []); -static int netboot_common (proto_t, cmd_tbl_t *, int , char *[]); +static int netboot_common (proto_t, cmd_tbl_t *, int , char * const []); -int do_bootp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bootp (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { return netboot_common (BOOTP, cmdtp, argc, argv); } @@ -43,7 +43,7 @@ U_BOOT_CMD( "[loadAddress] [[hostIPaddr:]bootfilename]" ); -int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { return netboot_common (TFTP, cmdtp, argc, argv); } @@ -54,7 +54,8 @@ U_BOOT_CMD( "[loadAddress] [[hostIPaddr:]bootfilename]" ); -int do_rarpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +#ifdef CONFIG_CMD_RARP +int do_rarpb (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { return netboot_common (RARP, cmdtp, argc, argv); } @@ -64,9 +65,10 @@ U_BOOT_CMD( "boot image via network using RARP/TFTP protocol", "[loadAddress] [[hostIPaddr:]bootfilename]" ); +#endif #if defined(CONFIG_CMD_DHCP) -int do_dhcp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_dhcp (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { return netboot_common(DHCP, cmdtp, argc, argv); } @@ -79,7 +81,7 @@ U_BOOT_CMD( #endif #if defined(CONFIG_CMD_NFS) -int do_nfs (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_nfs (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { return netboot_common(NFS, cmdtp, argc, argv); } @@ -151,7 +153,7 @@ static void netboot_update_env (void) } static int -netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[]) +netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char * const argv[]) { char *s; char *end; @@ -186,9 +188,9 @@ netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[]) break; - default: cmd_usage(cmdtp); + default: show_boot_progress (-80); - return 1; + return cmd_usage(cmdtp); } show_boot_progress (80); @@ -230,16 +232,14 @@ netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[]) } #if defined(CONFIG_CMD_PING) -int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { if (argc < 2) return -1; NetPingIP = string_to_ip(argv[1]); - if (NetPingIP == 0) { - cmd_usage(cmdtp); - return -1; - } + if (NetPingIP == 0) + return cmd_usage(cmdtp); if (NetLoop(PING) < 0) { printf("ping failed; host %s is not alive\n", argv[1]); @@ -280,7 +280,7 @@ static void cdp_update_env(void) } -int do_cdp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_cdp (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int r; @@ -302,7 +302,7 @@ U_BOOT_CMD( #endif #if defined(CONFIG_CMD_SNTP) -int do_sntp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_sntp (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *toff; @@ -340,12 +340,10 @@ U_BOOT_CMD( #endif #if defined(CONFIG_CMD_DNS) -int do_dns(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_dns(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - if (argc == 1) { - cmd_usage(cmdtp); - return -1; - } + if (argc == 1) + return cmd_usage(cmdtp); /* * We should check for a valid hostname: diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index eb89e9e..3d30c32 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2002 + * (C) Copyright 2000-2010 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> @@ -24,27 +24,26 @@ * MA 02111-1307 USA */ -/************************************************************************** - * +/* * Support for persistent environment data * - * The "environment" is stored as a list of '\0' terminated - * "name=value" strings. The end of the list is marked by a double - * '\0'. New entries are always added at the end. Deleting an entry - * shifts the remaining entries to the front. Replacing an entry is a - * combination of deleting the old value and adding the new one. + * The "environment" is stored on external storage as a list of '\0' + * terminated "name=value" strings. The end of the list is marked by + * a double '\0'. The environment is preceeded by a 32 bit CRC over + * the data part and, in case of redundant environment, a byte of + * flags. * - * The environment is preceeded by a 32 bit CRC over the data part. - * - ************************************************************************** + * This linearized representation will also be used before + * relocation, i. e. as long as we don't have a full C runtime + * environment. After that, we use a hash table. */ #include <common.h> #include <command.h> #include <environment.h> -#if defined(CONFIG_CMD_EDITENV) +#include <search.h> +#include <errno.h> #include <malloc.h> -#endif #include <watchdog.h> #include <serial.h> #include <linux/stddef.h> @@ -59,20 +58,23 @@ DECLARE_GLOBAL_DATA_PTR; !defined(CONFIG_ENV_IS_IN_FLASH) && \ !defined(CONFIG_ENV_IS_IN_DATAFLASH) && \ !defined(CONFIG_ENV_IS_IN_MG_DISK) && \ + !defined(CONFIG_ENV_IS_IN_MMC) && \ !defined(CONFIG_ENV_IS_IN_NAND) && \ !defined(CONFIG_ENV_IS_IN_NVRAM) && \ !defined(CONFIG_ENV_IS_IN_ONENAND) && \ !defined(CONFIG_ENV_IS_IN_SPI_FLASH) && \ !defined(CONFIG_ENV_IS_NOWHERE) # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\ -SPI_FLASH|MG_DISK|NVRAM|NOWHERE} +SPI_FLASH|MG_DISK|NVRAM|MMC|NOWHERE} #endif #define XMK_STR(x) #x #define MK_STR(x) XMK_STR(x) -/************************************************************************ -************************************************************************/ +/* + * Maximum expected input data size for import command + */ +#define MAX_ENV_SIZE (1 << 20) /* 1 MiB */ /* * Table with supported baudrates (defined in config_xyz.h) @@ -81,7 +83,7 @@ static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE; #define N_BAUDRATES (sizeof(baudrate_table) / sizeof(baudrate_table[0])) /* - * This variable is incremented on each do_setenv (), so it can + * This variable is incremented on each do_env_set(), so it can * be used via get_env_id() as an indication, if the environment * has changed or not. So it is possible to reread an environment * variable only if the environment was changed ... done so for @@ -93,61 +95,51 @@ int get_env_id (void) { return env_id; } -/************************************************************************ - * Command interface: print one or all environment variables - */ /* - * state 0: finish printing this string and return (matched!) - * state 1: no matching to be done; print everything - * state 2: continue searching for matched name + * Command interface: print one or all environment variables + * + * Returns 0 in case of error, or length of printed string */ -static int printenv(char *name, int state) +static int env_print(char *name) { - int i, j; - char c, buf[17]; - - i = 0; - buf[16] = '\0'; - - while (state && env_get_char(i) != '\0') { - if (state == 2 && envmatch((uchar *)name, i) >= 0) - state = 0; - - j = 0; - do { - buf[j++] = c = env_get_char(i++); - if (j == sizeof(buf) - 1) { - if (state <= 1) - puts(buf); - j = 0; - } - } while (c != '\0'); + char *res = NULL; + size_t len; + + if (name) { /* print a single name */ + ENTRY e, *ep; + + e.key = name; + e.data = NULL; + ep = hsearch (e, FIND); + if (ep == NULL) + return 0; + len = printf ("%s=%s\n", ep->key, ep->data); + return len; + } - if (state <= 1) { - if (j) - puts(buf); - putc('\n'); - } + /* print whole list */ + len = hexport('\n', &res, 0); - if (ctrlc()) - return -1; + if (len > 0) { + puts(res); + free(res); + return len; } - if (state == 0) - i = 0; - return i; + /* should never happen */ + return 0; } -int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_env_print (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int i; int rcode = 0; if (argc == 1) { /* print all env vars */ - rcode = printenv(NULL, 1); - if (rcode < 0) + rcode = env_print(NULL); + if (!rcode) return 1; printf("\nEnvironment size: %d/%ld bytes\n", rcode, (ulong)ENV_SIZE); @@ -156,9 +148,9 @@ int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* print selected env vars */ for (i = 1; i < argc; ++i) { - char *name = argv[i]; - if (printenv(name, 2)) { - printf("## Error: \"%s\" not defined\n", name); + int rc = env_print(argv[i]); + if (!rc) { + printf("## Error: \"%s\" not defined\n", argv[i]); ++rcode; } } @@ -166,25 +158,18 @@ int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return rcode; } -/************************************************************************ +/* * Set a new environment variable, * or replace or delete an existing one. - * - * This function will ONLY work with a in-RAM copy of the environment */ -int _do_setenv (int flag, int argc, char *argv[]) +int _do_env_set (int flag, int argc, char * const argv[]) { - int i, len, oldval; + bd_t *bd = gd->bd; + int i, len; int console = -1; - uchar *env, *nxt = NULL; - char *name; - bd_t *bd = gd->bd; - - uchar *env_data = env_get_addr(0); - - if (!env_data) /* need copy in RAM */ - return 1; + char *name, *value, *s; + ENTRY e, *ep; name = argv[1]; @@ -197,13 +182,9 @@ int _do_setenv (int flag, int argc, char *argv[]) /* * search if variable with this name already exists */ - oldval = -1; - for (env=env_data; *env; env=nxt+1) { - for (nxt=env; *nxt; ++nxt) - ; - if ((oldval = envmatch((uchar *)name, env-env_data)) >= 0) - break; - } + e.key = name; + e.data = NULL; + ep = hsearch (e, FIND); /* Check for console redirection */ if (strcmp(name,"stdin") == 0) { @@ -237,36 +218,25 @@ int _do_setenv (int flag, int argc, char *argv[]) } /* - * Delete any existing definition + * Some variables like "ethaddr" and "serial#" can be set only + * once and cannot be deleted; also, "ver" is readonly. */ - if (oldval >= 0) { + if (ep) { /* variable exists */ #ifndef CONFIG_ENV_OVERWRITE - - /* - * Ethernet Address and serial# can be set only once, - * ver is readonly. - */ - if ( -#ifdef CONFIG_HAS_UID - /* Allow serial# forced overwrite with 0xdeaf4add flag */ - ((strcmp (name, "serial#") == 0) && (flag != 0xdeaf4add)) || -#else - (strcmp (name, "serial#") == 0) || -#endif + if ((strcmp (name, "serial#") == 0) || ((strcmp (name, "ethaddr") == 0) #if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR) - && (strcmp ((char *)env_get_addr(oldval),MK_STR(CONFIG_ETHADDR)) != 0) + && (strcmp (ep->data,MK_STR(CONFIG_ETHADDR)) != 0) #endif /* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */ ) ) { printf ("Can't overwrite \"%s\"\n", name); return 1; } #endif - /* * Switch to new baudrate if new baudrate is supported */ - if (strcmp(argv[1],"baudrate") == 0) { + if (strcmp(name,"baudrate") == 0) { int baudrate = simple_strtoul(argv[2], NULL, 10); int i; for (i=0; i<N_BAUDRATES; ++i) { @@ -293,75 +263,50 @@ int _do_setenv (int flag, int argc, char *argv[]) break; } } - - if (*++nxt == '\0') { - if (env > env_data) { - env--; - } else { - *env = '\0'; - } - } else { - for (;;) { - *env = *nxt++; - if ((*env == '\0') && (*nxt == '\0')) - break; - ++env; - } - } - *++env = '\0'; } /* Delete only ? */ if ((argc < 3) || argv[2] == NULL) { - env_crc_update (); - return 0; + int rc = hdelete(name); + return !rc; } /* - * Append new definition at the end - */ - for (env=env_data; *env || *(env+1); ++env) - ; - if (env > env_data) - ++env; - /* - * Overflow when: - * "name" + "=" + "val" +"\0\0" > ENV_SIZE - (env-env_data) + * Insert / replace new value */ - len = strlen(name) + 2; - /* add '=' for first arg, ' ' for all others */ - for (i=2; i<argc; ++i) { + for (i=2,len=0; i<argc; ++i) { len += strlen(argv[i]) + 1; } - if (len > (&env_data[ENV_SIZE]-env)) { - printf ("## Error: environment overflow, \"%s\" deleted\n", name); + if ((value = malloc(len)) == NULL) { + printf("## Can't malloc %d bytes\n", len); return 1; } - while ((*env = *name++) != '\0') - env++; - for (i=2; i<argc; ++i) { - char *val = argv[i]; + for (i=2,s=value; i<argc; ++i) { + char *v = argv[i]; - *env = (i==2) ? '=' : ' '; - while ((*++env = *val++) != '\0') + while ((*s++ = *v++) != '\0') ; + *(s-1) = ' '; + } + if (s != value) + *--s = '\0'; + + e.key = name; + e.data = value; + ep = hsearch(e, ENTER); + free(value); + if (!ep) { + printf("## Error inserting \"%s\" variable, errno=%d\n", + name, errno); + return 1; } - - /* end is marked with double '\0' */ - *++env = '\0'; - - /* Update CRC */ - env_crc_update (); /* * Some variables should be updated when the corresponding - * entry in the enviornment is changed + * entry in the environment is changed */ - if (strcmp(argv[1],"ethaddr") == 0) - return 0; - - if (strcmp(argv[1],"ipaddr") == 0) { + if (strcmp(name,"ipaddr") == 0) { char *s = argv[2]; /* always use only one arg */ char *e; unsigned long addr; @@ -374,70 +319,46 @@ int _do_setenv (int flag, int argc, char *argv[]) } bd->bi_ip_addr = htonl(addr); return 0; - } - if (strcmp(argv[1],"loadaddr") == 0) { + } else if (strcmp(argv[1],"loadaddr") == 0) { load_addr = simple_strtoul(argv[2], NULL, 16); return 0; } #if defined(CONFIG_CMD_NET) - if (strcmp(argv[1],"bootfile") == 0) { + else if (strcmp(argv[1],"bootfile") == 0) { copy_filename (BootFile, argv[2], sizeof(BootFile)); return 0; } #endif - -#ifdef CONFIG_AMIGAONEG3SE - if (strcmp(argv[1], "vga_fg_color") == 0 || - strcmp(argv[1], "vga_bg_color") == 0 ) { - extern void video_set_color(unsigned char attr); - extern unsigned char video_get_attr(void); - - video_set_color(video_get_attr()); - return 0; - } -#endif /* CONFIG_AMIGAONEG3SE */ - return 0; } int setenv (char *varname, char *varvalue) { - char *argv[4] = { "setenv", varname, varvalue, NULL }; + char * const argv[4] = { "setenv", varname, varvalue, NULL }; if ((varvalue == NULL) || (varvalue[0] == '\0')) - return _do_setenv (0, 2, argv); + return _do_env_set(0, 2, argv); else - return _do_setenv (0, 3, argv); + return _do_env_set(0, 3, argv); } -#ifdef CONFIG_HAS_UID -void forceenv (char *varname, char *varvalue) +int do_env_set (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - char *argv[4] = { "forceenv", varname, varvalue, NULL }; - _do_setenv (0xdeaf4add, 3, argv); -} -#endif + if (argc < 2) + return cmd_usage(cmdtp); -int do_setenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } - - return _do_setenv (flag, argc, argv); + return _do_env_set(flag, argc, argv); } -/************************************************************************ +/* * Prompt for environment variable */ - #if defined(CONFIG_CMD_ASKENV) -int do_askenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_env_ask ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { extern char console_buffer[CONFIG_SYS_CBSIZE]; char message[CONFIG_SYS_CBSIZE]; int size = CONFIG_SYS_CBSIZE - 1; - int len; + int i, len, pos; char *local_args[4]; local_args[0] = argv[0]; @@ -445,40 +366,30 @@ int do_askenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) local_args[2] = NULL; local_args[3] = NULL; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } /* Check the syntax */ switch (argc) { case 1: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); - case 2: /* askenv envname */ - sprintf (message, "Please enter '%s':", argv[1]); + case 2: /* env_ask envname */ + sprintf(message, "Please enter '%s':", argv[1]); break; - case 3: /* askenv envname size */ - sprintf (message, "Please enter '%s':", argv[1]); - size = simple_strtoul (argv[2], NULL, 10); + case 3: /* env_ask envname size */ + sprintf(message, "Please enter '%s':", argv[1]); + size = simple_strtoul(argv[2], NULL, 10); break; - default: /* askenv envname message1 ... messagen size */ - { - int i; - int pos = 0; - - for (i = 2; i < argc - 1; i++) { + default: /* env_ask envname message1 ... messagen size */ + for (i=2,pos=0; i < argc - 1; i++) { if (pos) { message[pos++] = ' '; } - strcpy (message+pos, argv[i]); + strcpy(message+pos, argv[i]); pos += strlen(argv[i]); } message[pos] = '\0'; - size = simple_strtoul (argv[argc - 1], NULL, 10); - } + size = simple_strtoul(argv[argc - 1], NULL, 10); break; } @@ -489,7 +400,7 @@ int do_askenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; /* prompt for input */ - len = readline (message); + len = readline(message); if (size < len) console_buffer[size] = '\0'; @@ -501,24 +412,22 @@ int do_askenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } /* Continue calling setenv code */ - return _do_setenv (flag, len, local_args); + return _do_env_set(flag, len, local_args); } #endif -/************************************************************************ +/* * Interactively edit an environment variable */ #if defined(CONFIG_CMD_EDITENV) -int do_editenv(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_env_edit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char buffer[CONFIG_SYS_CBSIZE]; char *init_val; int len; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); /* Set read buffer to initial value or empty sting */ init_val = getenv(argv[1]); @@ -533,35 +442,37 @@ int do_editenv(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } #endif /* CONFIG_CMD_EDITENV */ -/************************************************************************ +/* * Look up variable from environment, * return address of storage for that variable, * or NULL if not found */ - char *getenv (char *name) { - int i, nxt; + if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */ + ENTRY e, *ep; - WATCHDOG_RESET(); + WATCHDOG_RESET(); - for (i=0; env_get_char(i) != '\0'; i=nxt+1) { - int val; + e.key = name; + e.data = NULL; + ep = hsearch (e, FIND); - for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) { - if (nxt >= CONFIG_ENV_SIZE) { - return (NULL); - } - } - if ((val=envmatch((uchar *)name, i)) < 0) - continue; - return ((char *)env_get_addr(val)); + return (ep ? ep->data : NULL); } - return (NULL); + /* restricted capabilities before import */ + + if (getenv_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0) + return (char *)(gd->env_buf); + + return NULL; } -int getenv_r (char *name, char *buf, unsigned len) +/* + * Look up variable from environment for restricted C runtime env. + */ +int getenv_f (char *name, char *buf, unsigned len) { int i, nxt; @@ -575,20 +486,26 @@ int getenv_r (char *name, char *buf, unsigned len) } if ((val=envmatch((uchar *)name, i)) < 0) continue; + /* found; copy out */ - n = 0; - while ((len > n++) && (*buf++ = env_get_char(val++)) != '\0') - ; - if (len == n) - *buf = '\0'; - return (n); + for (n=0; n<len; ++n, ++buf) { + if ((*buf = env_get_char(val++)) == '\0') + return n; + } + + if (n) + *--buf = '\0'; + + printf("env_buf too small [%d]\n", len); + + return n; } return (-1); } #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) -int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_env_save (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { extern char * env_name_spec; @@ -598,7 +515,7 @@ int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } U_BOOT_CMD( - saveenv, 1, 0, do_saveenv, + saveenv, 1, 0, do_env_save, "save environment variables to persistent storage", "" ); @@ -606,7 +523,7 @@ U_BOOT_CMD( #endif -/************************************************************************ +/* * Match a name / name=value pair * * s1 is either a simple 'name', or a 'name=value' pair. @@ -625,12 +542,352 @@ int envmatch (uchar *s1, int i2) return(-1); } +static int do_env_default(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + if ((argc != 2) || (strcmp(argv[1], "-f") != 0)) { + cmd_usage(cmdtp); + return 1; + } + set_default_env("## Resetting to default environment\n"); + return 0; +} + +static int do_env_delete(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + printf("Not implemented yet\n"); + return 0; +} -/**************************************************/ +/* + * env export [-t | -b | -c] addr [size] + * -t: export as text format; if size is given, data will be + * padded with '\0' bytes; if not, one terminating '\0' + * will be added (which is included in the "filesize" + * setting so you can for exmple copy this to flash and + * keep the termination). + * -b: export as binary format (name=value pairs separated by + * '\0', list end marked by double "\0\0") + * -c: export as checksum protected environment format as + * used for example by "saveenv" command + * addr: memory address where environment gets stored + * size: size of output buffer + * + * With "-c" and size is NOT given, then the export command will + * format the data as currently used for the persistent storage, + * i. e. it will use CONFIG_ENV_SECT_SIZE as output block size and + * prepend a valid CRC32 checksum and, in case of resundant + * environment, a "current" redundancy flag. If size is given, this + * value will be used instead of CONFIG_ENV_SECT_SIZE; again, CRC32 + * checksum and redundancy flag will be inserted. + * + * With "-b" and "-t", always only the real data (including a + * terminating '\0' byte) will be written; here the optional size + * argument will be used to make sure not to overflow the user + * provided buffer; the command will abort if the size is not + * sufficient. Any remainign space will be '\0' padded. + * + * On successful return, the variable "filesize" will be set. + * Note that filesize includes the trailing/terminating '\0' byte(s). + * + * Usage szenario: create a text snapshot/backup of the current settings: + * + * => env export -t 100000 + * => era ${backup_addr} +${filesize} + * => cp.b 100000 ${backup_addr} ${filesize} + * + * Re-import this snapshot, deleting all other settings: + * + * => env import -d -t ${backup_addr} + */ +static int do_env_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + char buf[32]; + char *addr, *cmd, *res; + size_t size; + ssize_t len; + env_t *envp; + char sep = '\n'; + int chk = 0; + int fmt = 0; + + cmd = *argv; + + while (--argc > 0 && **++argv == '-') { + char *arg = *argv; + while (*++arg) { + switch (*arg) { + case 'b': /* raw binary format */ + if (fmt++) + goto sep_err; + sep = '\0'; + break; + case 'c': /* external checksum format */ + if (fmt++) + goto sep_err; + sep = '\0'; + chk = 1; + break; + case 't': /* text format */ + if (fmt++) + goto sep_err; + sep = '\n'; + break; + default: + cmd_usage(cmdtp); + return 1; + } + } + } + + if (argc < 1) { + cmd_usage(cmdtp); + return 1; + } + + addr = (char *)simple_strtoul(argv[0], NULL, 16); + + if (argc == 2) { + size = simple_strtoul(argv[1], NULL, 16); + memset(addr, '\0', size); + } else { + size = 0; + } + + if (sep) { /* export as text file */ + len = hexport(sep, &addr, size); + if (len < 0) { + error("Cannot export environment: errno = %d\n", + errno); + return 1; + } + sprintf(buf, "%zX", len); + setenv("filesize", buf); + + return 0; + } + + envp = (env_t *)addr; + + if (chk) /* export as checksum protected block */ + res = (char *)envp->data; + else /* export as raw binary data */ + res = addr; + + len = hexport('\0', &res, ENV_SIZE); + if (len < 0) { + error("Cannot export environment: errno = %d\n", + errno); + return 1; + } + + if (chk) { + envp->crc = crc32(0, envp->data, ENV_SIZE); +#ifdef CONFIG_ENV_ADDR_REDUND + envp->flags = ACTIVE_FLAG; +#endif + } + sprintf(buf, "%zX", len + offsetof(env_t,data)); + setenv("filesize", buf); + + return 0; + +sep_err: + printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n", + cmd); + return 1; +} + +/* + * env import [-d] [-t | -b | -c] addr [size] + * -d: delete existing environment before importing; + * otherwise overwrite / append to existion definitions + * -t: assume text format; either "size" must be given or the + * text data must be '\0' terminated + * -b: assume binary format ('\0' separated, "\0\0" terminated) + * -c: assume checksum protected environment format + * addr: memory address to read from + * size: length of input data; if missing, proper '\0' + * termination is mandatory + */ +static int do_env_import(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + char *cmd, *addr; + char sep = '\n'; + int chk = 0; + int fmt = 0; + int del = 0; + size_t size; + + cmd = *argv; + + while (--argc > 0 && **++argv == '-') { + char *arg = *argv; + while (*++arg) { + switch (*arg) { + case 'b': /* raw binary format */ + if (fmt++) + goto sep_err; + sep = '\0'; + break; + case 'c': /* external checksum format */ + if (fmt++) + goto sep_err; + sep = '\0'; + chk = 1; + break; + case 't': /* text format */ + if (fmt++) + goto sep_err; + sep = '\n'; + break; + case 'd': + del = 1; + break; + default: + cmd_usage(cmdtp); + return 1; + } + } + } + + if (argc < 1) { + cmd_usage(cmdtp); + return 1; + } + + if (!fmt) + printf("## Warning: defaulting to text format\n"); + + addr = (char *)simple_strtoul(argv[0], NULL, 16); + + if (argc == 2) { + size = simple_strtoul(argv[1], NULL, 16); + } else { + char *s = addr; + + size = 0; + + while (size < MAX_ENV_SIZE) { + if ((*s == sep) && (*(s+1) == '\0')) + break; + ++s; + ++size; + } + if (size == MAX_ENV_SIZE) { + printf("## Warning: Input data exceeds %d bytes" + " - truncated\n", MAX_ENV_SIZE); + } + ++size; + printf("## Info: input data size = %zd = 0x%zX\n", size, size); + } + + if (chk) { + uint32_t crc; + env_t *ep = (env_t *)addr; + + size -= offsetof(env_t, data); + memcpy(&crc, &ep->crc, sizeof(crc)); + + if (crc32(0, ep->data, size) != crc) { + puts("## Error: bad CRC, import failed\n"); + return 1; + } + addr = (char *)ep->data; + } + + if (himport(addr, size, sep, del ? 0 : H_NOCLEAR) == 0) { + error("Environment import failed: errno = %d\n", errno); + return 1; + } + gd->flags |= GD_FLG_ENV_READY; + + return 0; + +sep_err: + printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n", + cmd); + return 1; +} + +#if defined(CONFIG_CMD_RUN) +extern int do_run (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +#endif + +/* + * New command line interface: "env" command with subcommands + */ +static cmd_tbl_t cmd_env_sub[] = { +#if defined(CONFIG_CMD_ASKENV) + U_BOOT_CMD_MKENT(ask, CONFIG_SYS_MAXARGS, 1, do_env_ask, "", ""), +#endif + U_BOOT_CMD_MKENT(default, 1, 0, do_env_default, "", ""), + U_BOOT_CMD_MKENT(delete, 2, 0, do_env_delete, "", ""), +#if defined(CONFIG_CMD_EDITENV) + U_BOOT_CMD_MKENT(edit, 2, 0, do_env_edit, "", ""), +#endif + U_BOOT_CMD_MKENT(export, 4, 0, do_env_export, "", ""), + U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", ""), + U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""), +#if defined(CONFIG_CMD_RUN) + U_BOOT_CMD_MKENT(run, CONFIG_SYS_MAXARGS, 1, do_run, "", ""), +#endif +#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) + U_BOOT_CMD_MKENT(save, 1, 0, do_env_save, "", ""), +#endif + U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 0, do_env_set, "", ""), +}; + +#if !defined(CONFIG_RELOC_FIXUP_WORKS) +void env_reloc(void) +{ + fixup_cmdtable(cmd_env_sub, ARRAY_SIZE(cmd_env_sub)); +} +#endif + +static int do_env (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *cp; + + /* drop initial "env" arg */ + argc--; + argv++; + + cp = find_cmd_tbl(argv[0], cmd_env_sub, ARRAY_SIZE(cmd_env_sub)); + + if (cp) + return cp->cmd(cmdtp, flag, argc, argv); + + cmd_usage(cmdtp); + return 1; +} + +U_BOOT_CMD( + env, CONFIG_SYS_MAXARGS, 1, do_env, + "environment handling commands", +#if defined(CONFIG_CMD_ASKENV) + "ask name [message] [size] - ask for environment variable\nenv " +#endif + "default -f - reset default environment\n" +#if defined(CONFIG_CMD_EDITENV) + "env edit name - edit environment variable\n" +#endif + "env export [-t | -b | -c] addr [size] - export environmnt\n" + "env import [-d] [-t | -b | -c] addr [size] - import environmnt\n" + "env print [name ...] - print environment\n" +#if defined(CONFIG_CMD_RUN) + "env run var [...] - run commands in an environment variable\n" +#endif + "env save - save environment\n" + "env set [-f] name [arg ...]\n" +); + +/* + * Old command line interface, kept for compatibility + */ #if defined(CONFIG_CMD_EDITENV) U_BOOT_CMD( - editenv, 2, 0, do_editenv, + editenv, 2, 0, do_env_edit, "edit environment variable", "name\n" " - edit environment variable 'name'" @@ -638,7 +895,7 @@ U_BOOT_CMD( #endif U_BOOT_CMD( - printenv, CONFIG_SYS_MAXARGS, 1, do_printenv, + printenv, CONFIG_SYS_MAXARGS, 1, do_env_print, "print environment variables", "\n - print values of all environment variables\n" "printenv name ...\n" @@ -646,7 +903,7 @@ U_BOOT_CMD( ); U_BOOT_CMD( - setenv, CONFIG_SYS_MAXARGS, 0, do_setenv, + setenv, CONFIG_SYS_MAXARGS, 0, do_env_set, "set environment variables", "name value ...\n" " - set environment variable 'name' to 'value ...'\n" @@ -657,7 +914,7 @@ U_BOOT_CMD( #if defined(CONFIG_CMD_ASKENV) U_BOOT_CMD( - askenv, CONFIG_SYS_MAXARGS, 1, do_askenv, + 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" @@ -672,7 +929,6 @@ U_BOOT_CMD( #endif #if defined(CONFIG_CMD_RUN) -int do_run (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); U_BOOT_CMD( run, CONFIG_SYS_MAXARGS, 1, do_run, "run commands in an environment variable", diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 565257c..83d967b 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -32,7 +32,7 @@ static inline int str2long(char *p, ulong *num) return (*p != '\0' && *endptr == '\0') ? 1 : 0; } -static int arg_off_size(int argc, char *argv[], ulong *off, size_t *size) +static int arg_off_size(int argc, char * const argv[], ulong *off, size_t *size) { if (argc >= 1) { if (!(str2long(argv[0], off))) { @@ -330,154 +330,217 @@ static int onenand_dump(struct mtd_info *mtd, ulong off, int only_oob) return 0; } -int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int do_onenand_info(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - struct onenand_chip *this; - int blocksize; + printf("%s\n", mtd->name); + return 0; +} + +static int do_onenand_bad(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + ulong ofs; + + mtd = &onenand_mtd; + /* Currently only one OneNAND device is supported */ + printf("\nDevice %d bad blocks:\n", 0); + for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) { + if (mtd->block_isbad(mtd, ofs)) + printf(" %08x\n", (u32)ofs); + } + + return 0; +} + +static int do_onenand_read(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + char *s; + int oob = 0; ulong addr, ofs; - size_t len, retlen = 0; + size_t len; int ret = 0; - char *cmd, *s; + size_t retlen = 0; - mtd = &onenand_mtd; - this = mtd->priv; - blocksize = (1 << this->erase_shift); + if (argc < 3) + return cmd_usage(cmdtp); - cmd = argv[1]; + s = strchr(argv[0], '.'); + if ((s != NULL) && (!strcmp(s, ".oob"))) + oob = 1; - switch (argc) { - case 0: - case 1: - goto usage; + addr = (ulong)simple_strtoul(argv[1], NULL, 16); - case 2: - if (strcmp(cmd, "info") == 0) { - printf("%s\n", mtd->name); - return 0; - } + printf("\nOneNAND read: "); + if (arg_off_size(argc - 2, argv + 2, &ofs, &len) != 0) + return 1; - if (strcmp(cmd, "bad") == 0) { - /* Currently only one OneNAND device is supported */ - printf("\nDevice %d bad blocks:\n", 0); - for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) { - if (mtd->block_isbad(mtd, ofs)) - printf(" %08x\n", (u32)ofs); - } + ret = onenand_block_read(ofs, len, &retlen, (u8 *)addr, oob); - return 0; - } + printf(" %d bytes read: %s\n", retlen, ret ? "ERROR" : "OK"); - default: - /* At least 4 args */ + return ret == 0 ? 0 : 1; +} - /* - * Syntax is: - * 0 1 2 3 4 - * onenand erase [force] [off size] - */ - if ((strcmp(cmd, "erase") == 0) || (strcmp(cmd, "test") == 0)) { - int force = argc > 2 && !strcmp("force", argv[2]); - int o = force ? 3 : 2; - int erase; +static int do_onenand_write(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + ulong addr, ofs; + size_t len; + int ret = 0; + size_t retlen = 0; - erase = strcmp(cmd, "erase") == 0; /* 1 = erase, 0 = test */ - printf("\nOneNAND %s: ", erase ? "erase" : "test"); + if (argc < 3) + return cmd_usage(cmdtp); - /* skip first two or three arguments, look for offset and size */ - if (arg_off_size(argc - o, argv + o, &ofs, &len) != 0) - return 1; + addr = (ulong)simple_strtoul(argv[1], NULL, 16); - if (erase) - ret = onenand_block_erase(ofs, len, force); - else - ret = onenand_block_test(ofs, len); + printf("\nOneNAND write: "); + if (arg_off_size(argc - 2, argv + 2, &ofs, &len) != 0) + return 1; - printf("%s\n", ret ? "ERROR" : "OK"); + ret = onenand_block_write(ofs, len, &retlen, (u8 *)addr); - return ret == 0 ? 0 : 1; + printf(" %d bytes written: %s\n", retlen, ret ? "ERROR" : "OK"); + + return ret == 0 ? 0 : 1; +} + +static int do_onenand_erase(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + ulong ofs; + int ret = 0; + size_t len; + int force; + + /* + * Syntax is: + * 0 1 2 3 4 + * onenand erase [force] [off size] + */ + argc--; + argv++; + if (argc) + { + if (!strcmp("force", argv[0])) + { + force = 1; + argc--; + argv++; } + } + printf("\nOneNAND erase: "); - if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { - int read; - int oob = 0; + /* skip first two or three arguments, look for offset and size */ + if (arg_off_size(argc, argv, &ofs, &len) != 0) + return 1; - if (argc < 4) - goto usage; + ret = onenand_block_erase(ofs, len, force); - addr = (ulong)simple_strtoul(argv[2], NULL, 16); + printf("%s\n", ret ? "ERROR" : "OK"); - read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ - printf("\nOneNAND %s: ", read ? "read" : "write"); - if (arg_off_size(argc - 3, argv + 3, &ofs, &len) != 0) - return 1; + return ret == 0 ? 0 : 1; +} - s = strchr(cmd, '.'); - if ((s != NULL) && (!strcmp(s, ".oob"))) - oob = 1; +static int do_onenand_test(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + ulong ofs; + int ret = 0; + size_t len; - if (read) { - ret = onenand_block_read(ofs, len, &retlen, - (u8 *)addr, oob); - } else { - ret = onenand_block_write(ofs, len, &retlen, - (u8 *)addr); - } + /* + * Syntax is: + * 0 1 2 3 4 + * onenand test [force] [off size] + */ - printf(" %d bytes %s: %s\n", retlen, - read ? "read" : "written", ret ? "ERROR" : "OK"); + printf("\nOneNAND test: "); - return ret == 0 ? 0 : 1; - } + /* skip first two or three arguments, look for offset and size */ + if (arg_off_size(argc - 1, argv + 1, &ofs, &len) != 0) + return 1; - if (strcmp(cmd, "markbad") == 0) { - argc -= 2; - argv += 2; - - if (argc <= 0) - goto usage; - - while (argc > 0) { - addr = simple_strtoul(*argv, NULL, 16); - - if (mtd->block_markbad(mtd, addr)) { - printf("block 0x%08lx NOT marked " - "as bad! ERROR %d\n", - addr, ret); - ret = 1; - } else { - printf("block 0x%08lx successfully " - "marked as bad\n", - addr); - } - --argc; - ++argv; - } - return ret; - } + ret = onenand_block_test(ofs, len); - if (strncmp(cmd, "dump", 4) == 0) { - if (argc < 3) - goto usage; + printf("%s\n", ret ? "ERROR" : "OK"); - s = strchr(cmd, '.'); - ofs = (int)simple_strtoul(argv[2], NULL, 16); + return ret == 0 ? 0 : 1; +} - if (s != NULL && strcmp(s, ".oob") == 0) - ret = onenand_dump(mtd, ofs, 1); - else - ret = onenand_dump(mtd, ofs, 0); +static int do_onenand_dump(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + ulong ofs; + int ret = 0; + char *s; - return ret == 0 ? 1 : 0; - } + if (argc < 2) + return cmd_usage(cmdtp); + + s = strchr(argv[0], '.'); + ofs = (int)simple_strtoul(argv[1], NULL, 16); + + if (s != NULL && strcmp(s, ".oob") == 0) + ret = onenand_dump(mtd, ofs, 1); + else + ret = onenand_dump(mtd, ofs, 0); - break; + return ret == 0 ? 1 : 0; +} + +static int do_onenand_markbad(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + int ret = 0; + ulong addr; + + argc -= 2; + argv += 2; + + if (argc <= 0) + return cmd_usage(cmdtp); + + while (argc > 0) { + addr = simple_strtoul(*argv, NULL, 16); + + if (mtd->block_markbad(mtd, addr)) { + printf("block 0x%08lx NOT marked " + "as bad! ERROR %d\n", + addr, ret); + ret = 1; + } else { + printf("block 0x%08lx successfully " + "marked as bad\n", + addr); + } + --argc; + ++argv; } + return ret; +} - return 0; +static cmd_tbl_t cmd_onenand_sub[] = { + U_BOOT_CMD_MKENT(info, 1, 0, do_onenand_info, "", ""), + U_BOOT_CMD_MKENT(bad, 1, 0, do_onenand_bad, "", ""), + U_BOOT_CMD_MKENT(read, 4, 0, do_onenand_read, "", ""), + U_BOOT_CMD_MKENT(write, 4, 0, do_onenand_write, "", ""), + U_BOOT_CMD_MKENT(erase, 3, 0, do_onenand_erase, "", ""), + U_BOOT_CMD_MKENT(test, 3, 0, do_onenand_test, "", ""), + U_BOOT_CMD_MKENT(dump, 2, 0, do_onenand_dump, "", ""), + U_BOOT_CMD_MKENT(markbad, CONFIG_SYS_MAXARGS, 0, do_onenand_markbad, "", ""), +}; + +static int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *c; + + mtd = &onenand_mtd; -usage: - cmd_usage(cmdtp); - return 1; + /* Strip off leading 'onenand' command argument */ + argc--; + argv++; + + c = find_cmd_tbl(argv[0], &cmd_onenand_sub[0], ARRAY_SIZE(cmd_onenand_sub)); + + if (c) + return c->cmd(cmdtp, flag, argc, argv); + else + return cmd_usage(cmdtp); } U_BOOT_CMD( @@ -486,7 +549,7 @@ U_BOOT_CMD( "info - show available OneNAND devices\n" "onenand bad - show bad blocks\n" "onenand read[.oob] addr off size\n" - "onenand write[.oob] addr off size\n" + "onenand write addr off size\n" " read/write 'size' bytes starting at offset 'off'\n" " to/from memory address 'addr', skipping bad blocks.\n" "onenand erase [force] [off size] - erase 'size' bytes from\n" diff --git a/common/cmd_otp.c b/common/cmd_otp.c index 30af5a3..eb93eb2 100644 --- a/common/cmd_otp.c +++ b/common/cmd_otp.c @@ -80,35 +80,35 @@ static void set_otp_timing(bool write) bfrom_OtpCommand(OTP_INIT, write ? timing : timing & ~(-1 << 15)); } -int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + char *cmd; uint32_t ret, base_flags; bool prompt_user, force_read; uint32_t (*otp_func)(uint32_t page, uint32_t flags, uint64_t *page_content); if (argc < 4) { usage: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } prompt_user = false; base_flags = 0; - if (!strcmp(argv[1], "read")) + cmd = argv[1]; + if (!strcmp(cmd, "read")) otp_func = bfrom_OtpRead; - else if (!strcmp(argv[1], "dump")) { + else if (!strcmp(cmd, "dump")) { otp_func = bfrom_OtpRead; force_read = true; - } else if (!strcmp(argv[1], "write")) { + } else if (!strcmp(cmd, "write")) { otp_func = bfrom_OtpWrite; base_flags = OTP_CHECK_FOR_PREV_WRITE; if (!strcmp(argv[2], "--force")) { - argv[2] = argv[1]; argv++; --argc; } else prompt_user = false; - } else if (!strcmp(argv[1], "lock")) { + } else if (!strcmp(cmd, "lock")) { if (argc != 4) goto usage; otp_func = bfrom_OtpWrite; @@ -176,7 +176,7 @@ int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } printf("OTP memory %s: addr 0x%p page 0x%03X count %zu ... ", - argv[1], addr, page, count); + cmd, addr, page, count); set_otp_timing(otp_func == bfrom_OtpWrite); if (otp_func == bfrom_OtpWrite && check_voltage()) { @@ -224,7 +224,8 @@ int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return ret; } -U_BOOT_CMD(otp, 7, 0, do_otp, +U_BOOT_CMD( + otp, 7, 0, do_otp, "One-Time-Programmable sub-system", "read <addr> <page> [count] [half]\n" " - read 'count' half-pages starting at 'page' (offset 'half') to 'addr'\n" diff --git a/common/cmd_pci.c b/common/cmd_pci.c index 8a260df..4bde059 100644 --- a/common/cmd_pci.c +++ b/common/cmd_pci.c @@ -471,7 +471,7 @@ pci_cfg_modify (pci_dev_t bdf, ulong addr, ulong size, ulong value, int incrflag * pci modify[.b, .w, .l] bus.device.function [addr] * pci write[.b, .w, .l] bus.device.function addr value */ -int do_pci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_pci (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr = 0, value = 0, size = 0; pci_dev_t bdf = 0; @@ -534,8 +534,7 @@ int do_pci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; usage: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } /***************************************************/ diff --git a/common/cmd_pcmcia.c b/common/cmd_pcmcia.c index e576b0c..70e5210 100644 --- a/common/cmd_pcmcia.c +++ b/common/cmd_pcmcia.c @@ -66,7 +66,7 @@ extern int pcmcia_on (void); extern int pcmcia_off (void); -int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int rcode = 0; diff --git a/common/cmd_portio.c b/common/cmd_portio.c index f8befee..4f2f499 100644 --- a/common/cmd_portio.c +++ b/common/cmd_portio.c @@ -37,19 +37,18 @@ static uint in_last_addr, in_last_size; static uint out_last_addr, out_last_size, out_last_value; -int do_portio_out (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_portio_out (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { uint addr = out_last_addr; uint size = out_last_size; uint value = out_last_value; - if (argc != 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc != 3) + return cmd_usage(cmdtp); if ((flag & CMD_FLAG_REPEAT) == 0) { - /* New command specified. Check for a size specification. + /* + * New command specified. Check for a size specification. * Defaults to long if no or incorrect specification. */ size = cmd_get_data_size (argv[0], 1); @@ -97,18 +96,17 @@ U_BOOT_CMD( "[.b, .w, .l] port value\n - output to IO port" ); -int do_portio_in (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_portio_in (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { uint addr = in_last_addr; uint size = in_last_size; - if (argc != 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc != 2) + return cmd_usage(cmdtp); if ((flag & CMD_FLAG_REPEAT) == 0) { - /* New command specified. Check for a size specification. + /* + * New command specified. Check for a size specification. * Defaults to long if no or incorrect specification. */ size = cmd_get_data_size (argv[0], 1); diff --git a/common/cmd_reginfo.c b/common/cmd_reginfo.c index 89fd9ec..908876c 100644 --- a/common/cmd_reginfo.c +++ b/common/cmd_reginfo.c @@ -33,9 +33,11 @@ extern void ppc4xx_reginfo(void); #include <mpc5xxx.h> #elif defined (CONFIG_MPC86xx) extern void mpc86xx_reginfo(void); +#elif defined(CONFIG_MPC85xx) +extern void mpc85xx_reginfo(void); #endif -int do_reginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_reginfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #if defined(CONFIG_8xx) volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; @@ -183,6 +185,9 @@ int do_reginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #elif defined(CONFIG_MPC86xx) mpc86xx_reginfo(); +#elif defined(CONFIG_MPC85xx) + mpc85xx_reginfo(); + #elif defined(CONFIG_BLACKFIN) puts("\nSystem Configuration registers\n"); diff --git a/common/cmd_reiser.c b/common/cmd_reiser.c index 8ede782..ced1d40 100644 --- a/common/cmd_reiser.c +++ b/common/cmd_reiser.c @@ -47,7 +47,7 @@ #define PRINTF(fmt,args...) #endif -int do_reiserls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_reiserls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = "/"; int dev=0; @@ -56,10 +56,9 @@ int do_reiserls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) block_dev_desc_t *dev_desc=NULL; int part_length; - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); + dev = (int)simple_strtoul (argv[2], &ep, 16); dev_desc = get_dev(argv[1],dev); @@ -110,7 +109,7 @@ U_BOOT_CMD( /****************************************************************************** * Reiserfs boot command intepreter. Derived from diskboot */ -int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = NULL; char *ep; @@ -150,8 +149,7 @@ int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; default: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } if (!filename) { diff --git a/common/cmd_sata.c b/common/cmd_sata.c index 1693a7e..7efa859 100644 --- a/common/cmd_sata.c +++ b/common/cmd_sata.c @@ -62,7 +62,7 @@ block_dev_desc_t *sata_get_dev(int dev) return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL; } -int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int rc = 0; @@ -77,8 +77,7 @@ int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) switch (argc) { case 0: case 1: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); case 2: if (strncmp(argv[1],"inf", 3) == 0) { int i; @@ -115,8 +114,7 @@ int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } return rc; } - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); case 3: if (strncmp(argv[1], "dev", 3) == 0) { int dev = (int)simple_strtoul(argv[2], NULL, 10); @@ -147,8 +145,7 @@ int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } return rc; } - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); default: /* at least 4 args */ if (strcmp(argv[1], "read") == 0) { @@ -184,8 +181,7 @@ int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) n, (n == cnt) ? "OK" : "ERROR"); return (n == cnt) ? 0 : 1; } else { - cmd_usage(cmdtp); - rc = 1; + return cmd_usage(cmdtp); } return rc; diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index f89492f..6b937f9 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -202,7 +202,7 @@ block_dev_desc_t * scsi_get_dev(int dev) /****************************************************************************** * scsi boot command intepreter. Derived from diskboot */ -int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *boot_device = NULL; char *ep; @@ -229,8 +229,7 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) boot_device = argv[2]; break; default: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } if (!boot_device) { @@ -342,11 +341,12 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /********************************************************************************* * scsi command intepreter */ -int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { switch (argc) { case 0: - case 1: cmd_usage(cmdtp); return 1; + case 1: return cmd_usage(cmdtp); + case 2: if (strncmp(argv[1],"res",3) == 0) { printf("\nReset SCSI\n"); @@ -392,8 +392,7 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf("\nno SCSI devices available\n"); return 1; } - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); case 3: if (strncmp(argv[1],"dev",3) == 0) { int dev = (int)simple_strtoul(argv[2], NULL, 10); @@ -421,8 +420,7 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } return 1; } - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); default: /* at least 4 args */ if (strcmp(argv[1],"read") == 0) { @@ -437,8 +435,7 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } } /* switch */ - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } /**************************************************************************************** diff --git a/common/cmd_setexpr.c b/common/cmd_setexpr.c index f8b5d4d..1ff1232 100644 --- a/common/cmd_setexpr.c +++ b/common/cmd_setexpr.c @@ -28,19 +28,42 @@ #include <config.h> #include <command.h> -int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static ulong get_arg(char *s, int w) +{ + ulong *p; + + /* + * if the parameter starts with a '*' then assume + * it is a pointer to the value we want + */ + + if (s[0] == '*') { + p = (ulong *)simple_strtoul(&s[1], NULL, 16); + switch (w) { + case 1: return((ulong)(*(uchar *)p)); + case 2: return((ulong)(*(ushort *)p)); + case 4: + default: return(*p); + } + } else { + return simple_strtoul(s, NULL, 16); + } +} + +int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong a, b; char buf[16]; + int w; /* Validate arguments */ - if ((argc != 5) || (strlen(argv[3]) != 1)) { - cmd_usage(cmdtp); - return 1; - } + if ((argc != 5) || (strlen(argv[3]) != 1)) + return cmd_usage(cmdtp); + + w = cmd_get_data_size(argv[0], 4); - a = simple_strtoul(argv[2], NULL, 16); - b = simple_strtoul(argv[4], NULL, 16); + a = get_arg(argv[2], w); + b = get_arg(argv[4], w); switch (argv[3][0]) { case '|': sprintf(buf, "%lx", (a | b)); break; @@ -64,7 +87,8 @@ int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD( setexpr, 5, 0, do_setexpr, "set environment variable as the result of eval expression", - "name value1 <op> value2\n" + "[.b, .w, .l] name value1 <op> value2\n" " - set environment variable 'name' to the result of the evaluated\n" - " express specified by <op>. <op> can be &, |, ^, +, -, *, /, %" + " express specified by <op>. <op> can be &, |, ^, +, -, *, /, %\n" + " size argument is only meaningful if value1 and/or value2 are memory addresses" ); diff --git a/common/cmd_sf.c b/common/cmd_sf.c index d69ae6a..6e7be81 100644 --- a/common/cmd_sf.c +++ b/common/cmd_sf.c @@ -19,7 +19,7 @@ static struct spi_flash *flash; -static int do_spi_flash_probe(int argc, char *argv[]) +static int do_spi_flash_probe(int argc, char * const argv[]) { unsigned int bus = 0; unsigned int cs; @@ -75,7 +75,7 @@ usage: return 1; } -static int do_spi_flash_read_write(int argc, char *argv[]) +static int do_spi_flash_read_write(int argc, char * const argv[]) { unsigned long addr; unsigned long offset; @@ -122,7 +122,7 @@ usage: return 1; } -static int do_spi_flash_erase(int argc, char *argv[]) +static int do_spi_flash_erase(int argc, char * const argv[]) { unsigned long offset; unsigned long len; @@ -152,7 +152,7 @@ usage: return 1; } -static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { const char *cmd; @@ -177,8 +177,7 @@ static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return do_spi_flash_erase(argc - 1, argv + 1); usage: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } U_BOOT_CMD( diff --git a/common/cmd_source.c b/common/cmd_source.c index 1424d30..16a627a 100644 --- a/common/cmd_source.c +++ b/common/cmd_source.c @@ -199,7 +199,7 @@ source (ulong addr, const char *fit_uname) /**************************************************/ #if defined(CONFIG_CMD_SOURCE) int -do_source (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_source (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr; int rcode; diff --git a/common/cmd_spi.c b/common/cmd_spi.c index ab7aac7..8c623c9 100644 --- a/common/cmd_spi.c +++ b/common/cmd_spi.c @@ -47,7 +47,9 @@ /* * Values from last command. */ -static unsigned int device; +static unsigned int bus; +static unsigned int cs; +static unsigned int mode; static int bitlen; static uchar dout[MAX_SPI_BYTES]; static uchar din[MAX_SPI_BYTES]; @@ -63,7 +65,7 @@ static uchar din[MAX_SPI_BYTES]; * The command prints out the hexadecimal string received via SPI. */ -int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct spi_slave *slave; char *cp = 0; @@ -78,8 +80,18 @@ int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if ((flag & CMD_FLAG_REPEAT) == 0) { - if (argc >= 2) - device = simple_strtoul(argv[1], NULL, 10); + if (argc >= 2) { + mode = CONFIG_DEFAULT_SPI_MODE; + bus = simple_strtoul(argv[1], &cp, 10); + if (*cp == ':') { + cs = simple_strtoul(cp+1, &cp, 10); + } else { + cs = bus; + bus = CONFIG_DEFAULT_SPI_BUS; + } + if (*cp == '.'); + mode = simple_strtoul(cp+1, NULL, 10); + } if (argc >= 3) bitlen = simple_strtoul(argv[2], NULL, 10); if (argc >= 4) { @@ -91,7 +103,7 @@ int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if(tmp > 15) tmp -= ('a' - 'A'); if(tmp > 15) { - printf("Hex conversion error on %c, giving up.\n", *cp); + printf("Hex conversion error on %c\n", *cp); return 1; } if((j % 2) == 0) @@ -103,24 +115,20 @@ int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } if ((bitlen < 0) || (bitlen > (MAX_SPI_BYTES * 8))) { - printf("Invalid bitlen %d, giving up.\n", bitlen); + printf("Invalid bitlen %d\n", bitlen); return 1; } - /* FIXME: Make these parameters run-time configurable */ - slave = spi_setup_slave(CONFIG_DEFAULT_SPI_BUS, device, 1000000, - CONFIG_DEFAULT_SPI_MODE); + slave = spi_setup_slave(bus, cs, 1000000, mode); if (!slave) { - printf("Invalid device %d, giving up.\n", device); + printf("Invalid device %d:%d\n", bus, cs); return 1; } - debug ("spi chipsel = %08X\n", device); - spi_claim_bus(slave); if(spi_xfer(slave, bitlen, dout, din, SPI_XFER_BEGIN | SPI_XFER_END) != 0) { - printf("Error with the SPI transaction.\n"); + printf("Error during SPI transaction\n"); rcode = 1; } else { for(j = 0; j < ((bitlen + 7) / 8); j++) { @@ -138,9 +146,11 @@ int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD( sspi, 5, 1, do_spi, - "SPI utility commands", - "<device> <bit_len> <dout> - Send <bit_len> bits from <dout> out the SPI\n" - "<device> - Identifies the chip select of the device\n" + "SPI utility command", + "[<bus>:]<cs>[.<mode>] <bit_len> <dout> - Send and receive bits\n" + "<bus> - Identifies the SPI bus\n" + "<cs> - Identifies the chip select\n" + "<mode> - Identifies the SPI mode to use\n" "<bit_len> - Number of bits to send (base 10)\n" "<dout> - Hexadecimal string that gets sent" ); diff --git a/common/cmd_spibootldr.c b/common/cmd_spibootldr.c index d29ed2b..ca76dde 100644 --- a/common/cmd_spibootldr.c +++ b/common/cmd_spibootldr.c @@ -15,7 +15,7 @@ #include <asm/blackfin.h> #include <asm/mach-common/bits/bootrom.h> -int do_spibootldr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_spibootldr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { s32 addr; @@ -30,7 +30,8 @@ int do_spibootldr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return bfrom_SpiBoot(addr, BFLAG_PERIPHERAL | 4, 0, NULL); } -U_BOOT_CMD(spibootldr, 2, 0, do_spibootldr, +U_BOOT_CMD( + spibootldr, 2, 0, do_spibootldr, "boot ldr image from spi", "[offset]\n" " - boot ldr image stored at offset into spi\n"); diff --git a/common/cmd_strings.c b/common/cmd_strings.c index 3a0d8ff..2986324 100644 --- a/common/cmd_strings.c +++ b/common/cmd_strings.c @@ -12,12 +12,10 @@ static char *start_addr, *last_addr; -int do_strings(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_strings(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - if (argc == 1) { - cmd_usage(cmdtp); - return 1; - } + if (argc == 1) + return cmd_usage(cmdtp); if ((flag & CMD_FLAG_REPEAT) == 0) { start_addr = (char *)simple_strtoul(argv[1], NULL, 16); @@ -40,7 +38,8 @@ int do_strings(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -U_BOOT_CMD(strings, 3, 1, do_strings, +U_BOOT_CMD( + strings, 3, 1, do_strings, "display strings", "<addr> [byte count]\n" " - display strings at <addr> for at least [byte count] or first double NUL" diff --git a/common/cmd_terminal.c b/common/cmd_terminal.c index 60ec378..7cc1a6c 100644 --- a/common/cmd_terminal.c +++ b/common/cmd_terminal.c @@ -29,7 +29,7 @@ #include <stdio_dev.h> #include <serial.h> -int do_terminal(cmd_tbl_t * cmd, int flag, int argc, char *argv[]) +int do_terminal(cmd_tbl_t * cmd, int flag, int argc, char * const argv[]) { int last_tilde = 0; struct stdio_dev *dev = NULL; diff --git a/common/cmd_test.c b/common/cmd_test.c index d886f89..fcb5ef2 100644 --- a/common/cmd_test.c +++ b/common/cmd_test.c @@ -24,9 +24,9 @@ #include <common.h> #include <command.h> -int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - char **ap; + char * const *ap; int left, adv, expr, last_expr, neg, last_cmp; /* args? */ @@ -150,7 +150,7 @@ U_BOOT_CMD( "[args..]" ); -int do_false(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_false(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { return 1; } @@ -161,7 +161,7 @@ U_BOOT_CMD( NULL ); -int do_true(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_true(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { return 0; } diff --git a/common/cmd_tsi148.c b/common/cmd_tsi148.c index f2097fd..6dc9dab 100644 --- a/common/cmd_tsi148.c +++ b/common/cmd_tsi148.c @@ -402,7 +402,7 @@ int tsi148_vme_crg_window(unsigned int vmeAddr, int vam) /* * Tundra Tsi148 configuration */ -int do_tsi148(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_tsi148(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr1 = 0, addr2 = 0, size = 0, vam = 0, vdw = 0; char cmd = 'x'; @@ -419,7 +419,7 @@ int do_tsi148(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (argc > 5) vam = simple_strtoul(argv[5], NULL, 16); if (argc > 6) - vdw = simple_strtoul(argv[7], NULL, 16); + vdw = simple_strtoul(argv[6], NULL, 16); switch (cmd) { case 'c': @@ -465,7 +465,7 @@ int do_tsi148(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } U_BOOT_CMD( - tsi148, 8, 1, do_tsi148, + tsi148, 7, 1, do_tsi148, "initialize and configure Turndra Tsi148\n", "init\n" " - initialize tsi148\n" diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c index 54faac1..7692ac7 100644 --- a/common/cmd_ubi.c +++ b/common/cmd_ubi.c @@ -190,7 +190,7 @@ static int ubi_remove_vol(char *volume) { int i, err, reserved_pebs; int found = 0, vol_id = 0; - struct ubi_volume *vol; + struct ubi_volume *vol = NULL; for (i = 0; i < ubi->vtbl_slots; i++) { vol = ubi->volumes[i]; @@ -436,16 +436,14 @@ static int ubi_dev_scan(struct mtd_info *info, char *ubidev, return 0; } -static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { size_t size = 0; ulong addr = 0; int err = 0; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); if (mtdparts_init() != 0) { printf("Error initializing mtdparts!\n"); @@ -471,10 +469,8 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 0; } - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 3) + return cmd_usage(cmdtp); /* todo: get dev number for NAND... */ ubi_dev.nr = 0; @@ -602,7 +598,8 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return -1; } -U_BOOT_CMD(ubi, 6, 1, do_ubi, +U_BOOT_CMD( + ubi, 6, 1, do_ubi, "ubi commands", "part [part] [offset]\n" " - Show or set current partition (with optional VID" diff --git a/common/cmd_ubifs.c b/common/cmd_ubifs.c index ed0e9db..a0ec184 100644 --- a/common/cmd_ubifs.c +++ b/common/cmd_ubifs.c @@ -42,15 +42,14 @@ int ubifs_mount(char *vol_name); int ubifs_ls(char *dir_name); int ubifs_load(char *filename, u32 addr, u32 size); -int do_ubifs_mount(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ubifs_mount(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *vol_name; int ret; - if (argc != 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc != 2) + return cmd_usage(cmdtp); + vol_name = argv[1]; debug("Using volume %s\n", vol_name); @@ -68,7 +67,7 @@ int do_ubifs_mount(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -int do_ubifs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ubifs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = "/"; int ret; @@ -89,7 +88,7 @@ int do_ubifs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return ret; } -int do_ubifs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ubifs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename; char *endp; @@ -102,25 +101,19 @@ int do_ubifs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return -1; } - if (argc < 3) { - cmd_usage(cmdtp); - return -1; - } + if (argc < 3) + return cmd_usage(cmdtp); addr = simple_strtoul(argv[1], &endp, 16); - if (endp == argv[1]) { - cmd_usage(cmdtp); - return 1; - } + if (endp == argv[1]) + return cmd_usage(cmdtp); filename = argv[2]; if (argc == 4) { size = simple_strtoul(argv[3], &endp, 16); - if (endp == argv[3]) { - cmd_usage(cmdtp); - return 1; - } + if (endp == argv[3]) + return cmd_usage(cmdtp); } debug("Loading file '%s' to address 0x%08x (size %d)\n", filename, addr, size); @@ -138,13 +131,15 @@ U_BOOT_CMD( " - mount 'volume-name' volume" ); -U_BOOT_CMD(ubifsls, 2, 0, do_ubifs_ls, +U_BOOT_CMD( + ubifsls, 2, 0, do_ubifs_ls, "list files in a directory", "[directory]\n" " - list files in a 'directory' (default '/')" ); -U_BOOT_CMD(ubifsload, 4, 0, do_ubifs_load, +U_BOOT_CMD( + ubifsload, 4, 0, do_ubifs_load, "load file from an UBIFS filesystem", "<addr> <filename> [bytes]\n" " - load file 'filename' to address 'addr'" diff --git a/common/cmd_universe.c b/common/cmd_universe.c index 0a6d722..a86a574 100644 --- a/common/cmd_universe.c +++ b/common/cmd_universe.c @@ -317,7 +317,7 @@ int universe_vme_slave_window(unsigned int vmeAddr, unsigned int pciAddr, int si /* * Tundra Universe configuration */ -int do_universe(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_universe(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr1 = 0, addr2 = 0, size = 0, vam = 0, pms = 0, vdw = 0; char cmd = 'x'; diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 6b5c582..226ea0d 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -349,7 +349,7 @@ void usb_show_tree(struct usb_device *dev) * usb boot command intepreter. Derived from diskboot */ #ifdef CONFIG_USB_STORAGE -int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *boot_device = NULL; char *ep; @@ -376,8 +376,7 @@ int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) boot_device = argv[2]; break; default: - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } if (!boot_device) { @@ -387,7 +386,7 @@ int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) dev = simple_strtoul(boot_device, &ep, 16); stor_dev = usb_stor_get_dev(dev); - if (stor_dev->type == DEV_TYPE_UNKNOWN) { + if (stor_dev == NULL || stor_dev->type == DEV_TYPE_UNKNOWN) { printf("\n** Device %d not available\n", dev); return 1; } @@ -506,7 +505,7 @@ int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /****************************************************************************** * usb command intepreter */ -int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int i; @@ -516,6 +515,9 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) block_dev_desc_t *stor_dev; #endif + if (argc < 2) + return cmd_usage(cmdtp); + if ((strncmp(argv[1], "reset", 5) == 0) || (strncmp(argv[1], "start", 5) == 0)) { usb_stop(); @@ -595,8 +597,10 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (strncmp(argv[1], "part", 4) == 0) { int devno, ok = 0; if (argc == 2) { - for (devno = 0; devno < USB_MAX_STOR_DEV; ++devno) { + for (devno = 0; ; ++devno) { stor_dev = usb_stor_get_dev(devno); + if (stor_dev == NULL) + break; if (stor_dev->type != DEV_TYPE_UNKNOWN) { ok++; if (devno) @@ -608,7 +612,8 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } else { devno = simple_strtoul(argv[2], NULL, 16); stor_dev = usb_stor_get_dev(devno); - if (stor_dev->type != DEV_TYPE_UNKNOWN) { + if (stor_dev != NULL && + stor_dev->type != DEV_TYPE_UNKNOWN) { ok++; debug("print_part of %x\n", devno); print_part(stor_dev); @@ -668,12 +673,12 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (argc == 3) { int dev = (int)simple_strtoul(argv[2], NULL, 10); printf("\nUSB device %d: ", dev); - if (dev >= USB_MAX_STOR_DEV) { + stor_dev = usb_stor_get_dev(dev); + if (stor_dev == NULL) { printf("unknown device\n"); return 1; } printf("\n Device %d: ", dev); - stor_dev = usb_stor_get_dev(dev); dev_print(stor_dev); if (stor_dev->type == DEV_TYPE_UNKNOWN) return 1; @@ -691,8 +696,7 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } #endif /* CONFIG_USB_STORAGE */ - cmd_usage(cmdtp); - return 1; + return cmd_usage(cmdtp); } #ifdef CONFIG_USB_STORAGE @@ -708,7 +712,7 @@ U_BOOT_CMD( "usb part [dev] - print partition table of one or all USB storage" " devices\n" "usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n" - " to memory address `addr'" + " to memory address `addr'\n" "usb write addr blk# cnt - write `cnt' blocks starting at block `blk#'\n" " from memory address `addr'" ); diff --git a/common/cmd_version.c b/common/cmd_version.c index 7f165c7..7d1b495 100644 --- a/common/cmd_version.c +++ b/common/cmd_version.c @@ -26,7 +26,7 @@ extern char version_string[]; -int do_version(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_version(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { printf("\n%s\n", version_string); diff --git a/common/cmd_vfd.c b/common/cmd_vfd.c index 9c5b038..18c14d1 100644 --- a/common/cmd_vfd.c +++ b/common/cmd_vfd.c @@ -45,14 +45,12 @@ extern int transfer_pic(unsigned char, unsigned char *, int, int); int trab_vfd (ulong bitmap); -int do_vfd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_vfd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong bitmap; - if (argc != 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc != 2) + return cmd_usage(cmdtp); if (argv[1][0] == '/') { /* select bitmap by number */ bitmap = simple_strtoul(argv[1]+1, NULL, 10); diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index 75499b4..dceb975 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -43,7 +43,7 @@ #endif int -do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { ulong addr = load_addr; ulong dest = 0; @@ -262,7 +262,8 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 0; } -U_BOOT_CMD(imxtract, 4, 1, do_imgextract, +U_BOOT_CMD( + imxtract, 4, 1, do_imgextract, "extract a part of a multi-image", "addr part [dest]\n" " - extract <part> from legacy image at <addr> and copy to <dest>" diff --git a/common/cmd_yaffs2.c b/common/cmd_yaffs2.c index d448d04..7c01ea2 100644 --- a/common/cmd_yaffs2.c +++ b/common/cmd_yaffs2.c @@ -24,7 +24,7 @@ extern void cmd_yaffs_mv(const char *oldPath, const char *newPath); extern int yaffs_DumpDevStruct(const char *path); -int do_ymount (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ymount (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *mtpoint = argv[1]; cmd_yaffs_mount(mtpoint); @@ -32,7 +32,7 @@ int do_ymount (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(0); } -int do_yumount (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_yumount (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *mtpoint = argv[1]; cmd_yaffs_umount(mtpoint); @@ -40,7 +40,7 @@ int do_yumount (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(0); } -int do_yls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_yls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *dirname = argv[argc-1]; @@ -49,7 +49,7 @@ int do_yls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(0); } -int do_yrd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_yrd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = argv[1]; printf ("Reading file %s ", filename); @@ -60,7 +60,7 @@ int do_yrd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(0); } -int do_ywr (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ywr (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = argv[1]; ulong value = simple_strtoul(argv[2], NULL, 16); @@ -74,7 +74,7 @@ int do_ywr (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(0); } -int do_yrdm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_yrdm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = argv[1]; ulong addr = simple_strtoul(argv[2], NULL, 16); @@ -84,7 +84,7 @@ int do_yrdm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(0); } -int do_ywrm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ywrm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = argv[1]; ulong addr = simple_strtoul(argv[2], NULL, 16); @@ -95,7 +95,7 @@ int do_ywrm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(0); } -int do_ymkdir (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ymkdir (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *dirname = argv[1]; @@ -104,7 +104,7 @@ int do_ymkdir (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(0); } -int do_yrmdir (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_yrmdir (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *dirname = argv[1]; @@ -113,7 +113,7 @@ int do_yrmdir (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(0); } -int do_yrm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_yrm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *path = argv[1]; @@ -122,7 +122,7 @@ int do_yrm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(0); } -int do_ymv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ymv (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *oldPath = argv[1]; char *newPath = argv[2]; @@ -132,7 +132,7 @@ int do_ymv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(0); } -int do_ydump (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_ydump (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *dirname = argv[1]; if (yaffs_DumpDevStruct(dirname) != 0) diff --git a/common/command.c b/common/command.c index 0c66b7a..d47d719 100644 --- a/common/command.c +++ b/common/command.c @@ -34,7 +34,7 @@ */ int _do_help (cmd_tbl_t *cmd_start, int cmd_items, cmd_tbl_t * cmdtp, int - flag, int argc, char *argv[]) + flag, int argc, char * const argv[]) { int i; int rcode = 0; @@ -153,13 +153,14 @@ int cmd_usage(cmd_tbl_t *cmdtp) puts (cmdtp->help); putc ('\n'); #endif /* CONFIG_SYS_LONGHELP */ - return 0; + return 1; } #ifdef CONFIG_AUTO_COMPLETE -int var_complete(int argc, char *argv[], char last_char, int maxv, char *cmdv[]) +int var_complete(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]) { +#if 0 /* need to reimplement */ static char tmp_buf[512]; int space; @@ -170,12 +171,12 @@ int var_complete(int argc, char *argv[], char last_char, int maxv, char *cmdv[]) if (!space && argc == 2) return env_complete(argv[1], maxv, cmdv, sizeof(tmp_buf), tmp_buf); - +#endif return 0; } static void install_auto_complete_handler(const char *cmd, - int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[])) + int (*complete)(int argc, char * const argv[], char last_char, int maxv, char *cmdv[])) { cmd_tbl_t *cmdtp; @@ -188,6 +189,9 @@ static void install_auto_complete_handler(const char *cmd, void install_auto_complete(void) { +#if defined(CONFIG_CMD_EDITENV) + install_auto_complete_handler("editenv", var_complete); +#endif install_auto_complete_handler("printenv", var_complete); install_auto_complete_handler("setenv", var_complete); #if defined(CONFIG_CMD_RUN) @@ -197,7 +201,7 @@ void install_auto_complete(void) /*************************************************************************************/ -static int complete_cmdv(int argc, char *argv[], char last_char, int maxv, char *cmdv[]) +static int complete_cmdv(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]) { cmd_tbl_t *cmdtp; const char *p; @@ -298,7 +302,7 @@ static int make_argv(char *s, int argvsz, char *argv[]) return argc; } -static void print_argv(const char *banner, const char *leader, const char *sep, int linemax, char *argv[]) +static void print_argv(const char *banner, const char *leader, const char *sep, int linemax, char * const argv[]) { int ll = leader != NULL ? strlen(leader) : 0; int sl = sep != NULL ? strlen(sep) : 0; @@ -325,7 +329,7 @@ static void print_argv(const char *banner, const char *leader, const char *sep, printf("\n"); } -static int find_common_prefix(char *argv[]) +static int find_common_prefix(char * const argv[]) { int i, len; char *anchor, *s, *t; @@ -461,3 +465,40 @@ int cmd_get_data_size(char* arg, int default_size) return default_size; } #endif + +#if !defined(CONFIG_RELOC_FIXUP_WORKS) +DECLARE_GLOBAL_DATA_PTR; + +void fixup_cmdtable(cmd_tbl_t *cmdtp, int size) +{ + int i; + + if (gd->reloc_off == 0) + return; + + for (i = 0; i < size; i++) { + ulong addr; + + addr = (ulong) (cmdtp->cmd) + gd->reloc_off; +#if DEBUG_COMMANDS + printf("Command \"%s\": 0x%08lx => 0x%08lx\n", + cmdtp->name, (ulong) (cmdtp->cmd), addr); +#endif + cmdtp->cmd = + (int (*)(struct cmd_tbl_s *, int, int, char * const []))addr; + addr = (ulong)(cmdtp->name) + gd->reloc_off; + cmdtp->name = (char *)addr; + if (cmdtp->usage) { + addr = (ulong)(cmdtp->usage) + gd->reloc_off; + cmdtp->usage = (char *)addr; + } +#ifdef CONFIG_SYS_LONGHELP + if (cmdtp->help) { + addr = (ulong)(cmdtp->help) + gd->reloc_off; + cmdtp->help = (char *)addr; + } +#endif + cmdtp++; + } +} +#endif diff --git a/common/console.c b/common/console.c index 51c6fb6..7e01886 100644 --- a/common/console.c +++ b/common/console.c @@ -29,10 +29,6 @@ DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_AMIGAONEG3SE -int console_changed = 0; -#endif - #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV /* * if overwrite_console returns 1, the stdin, stderr and stdout @@ -205,7 +201,7 @@ static inline void console_doenv(int file, struct stdio_dev *dev) /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/ -void serial_printf(const char *fmt, ...) +int serial_printf(const char *fmt, ...) { va_list args; uint i; @@ -220,6 +216,7 @@ void serial_printf(const char *fmt, ...) va_end(args); serial_puts(printbuffer); + return i; } int fgetc(int file) @@ -273,7 +270,7 @@ void fputs(int file, const char *s) console_puts(file, s); } -void fprintf(int file, const char *fmt, ...) +int fprintf(int file, const char *fmt, ...) { va_list args; uint i; @@ -289,6 +286,7 @@ void fprintf(int file, const char *fmt, ...) /* Send to desired file */ fputs(file, printbuffer); + return i; } /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/ @@ -367,7 +365,7 @@ void puts(const char *s) } } -void printf(const char *fmt, ...) +int printf(const char *fmt, ...) { va_list args; uint i; @@ -383,9 +381,10 @@ void printf(const char *fmt, ...) /* Print the string */ puts(printbuffer); + return i; } -void vprintf(const char *fmt, va_list args) +int vprintf(const char *fmt, va_list args) { uint i; char printbuffer[CONFIG_SYS_PBSIZE]; @@ -397,6 +396,7 @@ void vprintf(const char *fmt, va_list args) /* Print the string */ puts(printbuffer); + return i; } /* test if ctrl-c was pressed */ diff --git a/common/ddr_spd.c b/common/ddr_spd.c index c058e4f..a7a30de 100644 --- a/common/ddr_spd.c +++ b/common/ddr_spd.c @@ -20,11 +20,15 @@ spd_check(const u8 *buf, u8 spd_rev, u8 spd_cksum) * Check SPD revision supported * Rev 1.2 or less supported by this code */ - if (spd_rev > 0x12) { + if (spd_rev >= 0x20) { printf("SPD revision %02X not supported by this code\n", spd_rev); return 1; } + if (spd_rev > 0x13) { + printf("SPD revision %02X not verified by this code\n", + spd_rev); + } /* * Calculate checksum diff --git a/common/dlmalloc.c b/common/dlmalloc.c index 205fc40..fce7a76 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -222,7 +222,6 @@ - /* Preliminaries */ #ifndef __STD_C @@ -935,10 +934,10 @@ struct mallinfo mALLINFo(); #endif /* ---------- To make a malloc.h, end cutting here ------------ */ -#else /* Moved to malloc.h */ +#endif /* 0 */ /* Moved to malloc.h */ #include <malloc.h> -#if 0 +#ifdef DEBUG #if __STD_C static void malloc_update_mallinfo (void); void malloc_stats (void); @@ -946,9 +945,7 @@ void malloc_stats (void); static void malloc_update_mallinfo (); void malloc_stats(); #endif -#endif /* 0 */ - -#endif /* 0 */ /* Moved to malloc.h */ +#endif /* DEBUG */ DECLARE_GLOBAL_DATA_PTR; @@ -1155,7 +1152,7 @@ struct malloc_chunk INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */ struct malloc_chunk* fd; /* double links -- used only if free. */ struct malloc_chunk* bk; -}; +} __attribute__((__may_alias__)) ; typedef struct malloc_chunk* mchunkptr; @@ -1515,7 +1512,7 @@ void *sbrk(ptrdiff_t increment) ulong new = old + increment; if ((new < mem_malloc_start) || (new > mem_malloc_end)) - return NULL; + return (void *)MORECORE_FAILURE; mem_malloc_brk = new; @@ -1618,9 +1615,9 @@ static struct mallinfo current_mallinfo = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* Tracking mmaps */ -#if 0 +#ifdef DEBUG static unsigned int n_mmaps = 0; -#endif /* 0 */ +#endif /* DEBUG */ static unsigned long mmapped_mem = 0; #if HAVE_MMAP static unsigned int max_n_mmaps = 0; @@ -3101,7 +3098,7 @@ size_t malloc_usable_size(mem) Void_t* mem; /* Utility to update current_mallinfo for malloc_stats and mallinfo() */ -#if 0 +#ifdef DEBUG static void malloc_update_mallinfo() { int i; @@ -3139,7 +3136,7 @@ static void malloc_update_mallinfo() current_mallinfo.keepcost = chunksize(top); } -#endif /* 0 */ +#endif /* DEBUG */ @@ -3158,7 +3155,7 @@ static void malloc_update_mallinfo() */ -#if 0 +#ifdef DEBUG void malloc_stats() { malloc_update_mallinfo(); @@ -3173,19 +3170,19 @@ void malloc_stats() (unsigned int)max_n_mmaps); #endif } -#endif /* 0 */ +#endif /* DEBUG */ /* mallinfo returns a copy of updated current mallinfo. */ -#if 0 +#ifdef DEBUG struct mallinfo mALLINFo() { malloc_update_mallinfo(); return current_mallinfo; } -#endif /* 0 */ +#endif /* DEBUG */ diff --git a/common/env_common.c b/common/env_common.c index 439a4a9..5acda4d 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -1,10 +1,10 @@ /* - * (C) Copyright 2000-2002 + * (C) Copyright 2000-2010 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Andreas Heppel <aheppel@sysgo.de> - + * * See file CREDITS for list of people who contributed to this * project. * @@ -28,22 +28,12 @@ #include <command.h> #include <environment.h> #include <linux/stddef.h> +#include <search.h> +#include <errno.h> #include <malloc.h> DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_AMIGAONEG3SE - extern void enable_nvram(void); - extern void disable_nvram(void); -#endif - -#undef DEBUG_ENV -#ifdef DEBUG_ENV -#define DEBUGF(fmt,args...) printf(fmt ,##args) -#else -#define DEBUGF(fmt,args...) -#endif - extern env_t *env_ptr; extern void env_relocate_spec (void); @@ -139,49 +129,23 @@ uchar default_environment[] = { "\0" }; -void env_crc_update (void) -{ - env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE); -} - static uchar env_get_char_init (int index) { uchar c; /* if crc was bad, use the default environment */ if (gd->env_valid) - { c = env_get_char_spec(index); - } else { + else c = default_environment[index]; - } return (c); } -#ifdef CONFIG_AMIGAONEG3SE uchar env_get_char_memory (int index) { - uchar retval; - enable_nvram(); - if (gd->env_valid) { - retval = ( *((uchar *)(gd->env_addr + index)) ); - } else { - retval = ( default_environment[index] ); - } - disable_nvram(); - return retval; + return *env_get_addr(index); } -#else -uchar env_get_char_memory (int index) -{ - if (gd->env_valid) { - return ( *((uchar *)(gd->env_addr + index)) ); - } else { - return ( default_environment[index] ); - } -} -#endif uchar env_get_char (int index) { @@ -198,78 +162,89 @@ uchar env_get_char (int index) uchar *env_get_addr (int index) { - if (gd->env_valid) { - return ( ((uchar *)(gd->env_addr + index)) ); - } else { - return (&default_environment[index]); - } + if (gd->env_valid) + return (uchar *)(gd->env_addr + index); + else + return &default_environment[index]; } -void set_default_env(void) +void set_default_env(const char *s) { if (sizeof(default_environment) > ENV_SIZE) { - puts ("*** Error - default environment is too large\n\n"); + puts("*** Error - default environment is too large\n\n"); return; } - memset(env_ptr, 0, sizeof(env_t)); - memcpy(env_ptr->data, default_environment, - sizeof(default_environment)); -#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT - env_ptr->flags = 0xFF; -#endif - env_crc_update (); - gd->env_valid = 1; + if (s) { + if (*s == '!') { + printf("*** Warning - %s, " + "using default environment\n\n", + s+1); + } else { + puts(s); + } + } else { + puts("Using default environment\n\n"); + } + + if (himport((char *)default_environment, + sizeof(default_environment), '\0', 0) == 0) { + error("Environment import failed: errno = %d\n", errno); + } + gd->flags |= GD_FLG_ENV_READY; } -void env_relocate (void) +/* + * Check if CRC is valid and (if yes) import the environment. + * Note that "buf" may or may not be aligned. + */ +int env_import(const char *buf, int check) { -#ifndef CONFIG_RELOC_FIXUP_WORKS - DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__, - gd->reloc_off); -#endif + env_t *ep = (env_t *)buf; -#ifdef CONFIG_AMIGAONEG3SE - enable_nvram(); -#endif + if (check) { + uint32_t crc; -#ifdef ENV_IS_EMBEDDED - /* - * The environment buffer is embedded with the text segment, - * just relocate the environment pointer - */ -#ifndef CONFIG_RELOC_FIXUP_WORKS - env_ptr = (env_t *)((ulong)env_ptr + gd->reloc_off); -#endif - DEBUGF ("%s[%d] embedded ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); -#else - /* - * We must allocate a buffer for the environment - */ - env_ptr = (env_t *)malloc (CONFIG_ENV_SIZE); - DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); -#endif + memcpy(&crc, &ep->crc, sizeof(crc)); + + if (crc32(0, ep->data, ENV_SIZE) != crc) { + set_default_env("!bad CRC"); + return 0; + } + } + if (himport((char *)ep->data, ENV_SIZE, '\0', 0)) { + gd->flags |= GD_FLG_ENV_READY; + return 1; + } + + error("Cannot import environment: errno = %d\n", errno); + + set_default_env("!import failed"); + + return 0; +} + +void env_relocate (void) +{ +#if !defined(CONFIG_RELOC_FIXUP_WORKS) + extern void env_reloc(void); + + env_reloc(); +#endif if (gd->env_valid == 0) { -#if defined(CONFIG_GTH) || defined(CONFIG_ENV_IS_NOWHERE) /* Environment not changable */ - puts ("Using default environment\n\n"); +#if defined(CONFIG_ENV_IS_NOWHERE) /* Environment not changable */ + set_default_env(NULL); #else - puts ("*** Warning - bad CRC, using default environment\n\n"); show_boot_progress (-60); + set_default_env("!bad CRC"); #endif - set_default_env(); - } - else { + } else { env_relocate_spec (); } - gd->env_addr = (ulong)&(env_ptr->data); - -#ifdef CONFIG_AMIGAONEG3SE - disable_nvram(); -#endif } -#ifdef CONFIG_AUTO_COMPLETE +#if 0 /* need to reimplement - def CONFIG_AUTO_COMPLETE */ int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf) { int i, nxt, len, vallen, found; diff --git a/common/env_dataflash.c b/common/env_dataflash.c index 27a3bbc..270f2b3 100644 --- a/common/env_dataflash.c +++ b/common/env_dataflash.c @@ -1,4 +1,5 @@ -/* LowLevel function for DataFlash environment support +/* + * LowLevel function for DataFlash environment support * Author : Gilles Gastaldi (Atmel) * * This program is free software; you can redistribute it and/or @@ -15,13 +16,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA - * */ #include <common.h> #include <command.h> #include <environment.h> #include <linux/stddef.h> #include <dataflash.h> +#include <search.h> +#include <errno.h> DECLARE_GLOBAL_DATA_PTR; @@ -29,39 +31,59 @@ env_t *env_ptr = NULL; char * env_name_spec = "dataflash"; -extern int read_dataflash (unsigned long addr, unsigned long size, char -*result); -extern int write_dataflash (unsigned long addr_dest, unsigned long addr_src, - unsigned long size); -extern int AT91F_DataflashInit (void); -extern uchar default_environment[]; +extern int read_dataflash(unsigned long addr, unsigned long size, + char *result); +extern int write_dataflash(unsigned long addr_dest, + unsigned long addr_src, unsigned long size); +extern int AT91F_DataflashInit(void); +extern uchar default_environment[]; -uchar env_get_char_spec (int index) +uchar env_get_char_spec(int index) { uchar c; + read_dataflash(CONFIG_ENV_ADDR + index + offsetof(env_t,data), - 1, (char *)&c); + 1, (char *)&c); return (c); } -void env_relocate_spec (void) +void env_relocate_spec(void) { - read_dataflash(CONFIG_ENV_ADDR, CONFIG_ENV_SIZE, (char *)env_ptr); + char buf[CONFIG_ENV_SIZE]; + + read_dataflash(CONFIG_ENV_ADDR, CONFIG_ENV_SIZE, buf); + + env_import(buf, 1); } +#ifdef CONFIG_ENV_OFFSET_REDUND +#error No support for redundant environment on dataflash yet! +#endif + int saveenv(void) { - /* env must be copied to do not alter env structure in memory*/ - unsigned char temp[CONFIG_ENV_SIZE]; - memcpy(temp, env_ptr, CONFIG_ENV_SIZE); - return write_dataflash(CONFIG_ENV_ADDR, (unsigned long)temp, CONFIG_ENV_SIZE); + env_t env_new; + ssize_t len; + char *res; + + res = (char *)&env_new.data; + len = hexport('\0', &res, ENV_SIZE); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + + return write_dataflash(CONFIG_ENV_ADDR, + (unsigned long)&env_new, + CONFIG_ENV_SIZE); } -/************************************************************************ - * Initialize Environment use +/* + * Initialize environment use * - * We are still running from ROM, so data use is limited + * We are still running from ROM, so data use is limited. * Use a (moderately small) buffer on the stack */ int env_init(void) @@ -69,30 +91,36 @@ int env_init(void) ulong crc, len, new; unsigned off; uchar buf[64]; - if (gd->env_valid == 0){ - AT91F_DataflashInit(); /* prepare for DATAFLASH read/write */ - - /* read old CRC */ - read_dataflash(CONFIG_ENV_ADDR + offsetof(env_t, crc), - sizeof(ulong), (char *)&crc); - new = 0; - len = ENV_SIZE; - off = offsetof(env_t,data); - while (len > 0) { - int n = (len > sizeof(buf)) ? sizeof(buf) : len; - read_dataflash(CONFIG_ENV_ADDR + off, n, (char *)buf); - new = crc32 (new, buf, n); - len -= n; - off += n; - } - if (crc == new) { - gd->env_addr = offsetof(env_t,data); - gd->env_valid = 1; - } else { - gd->env_addr = (ulong)&default_environment[0]; - gd->env_valid = 0; - } + + if (gd->env_valid) + return 0; + + AT91F_DataflashInit(); /* prepare for DATAFLASH read/write */ + + /* read old CRC */ + read_dataflash(CONFIG_ENV_ADDR + offsetof(env_t, crc), + sizeof(ulong), (char *)&crc); + + new = 0; + len = ENV_SIZE; + off = offsetof(env_t,data); + while (len > 0) { + int n = (len > sizeof(buf)) ? sizeof(buf) : len; + + read_dataflash(CONFIG_ENV_ADDR + off, n, (char *)buf); + + new = crc32 (new, buf, n); + len -= n; + off += n; + } + + if (crc == new) { + gd->env_addr = offsetof(env_t,data); + gd->env_valid = 1; + } else { + gd->env_addr = (ulong)&default_environment[0]; + gd->env_valid = 0; } - return (0); + return 0; } diff --git a/common/env_eeprom.c b/common/env_eeprom.c index 4f7f0db..792b44f 100644 --- a/common/env_eeprom.c +++ b/common/env_eeprom.c @@ -1,10 +1,10 @@ /* - * (C) Copyright 2000-2002 + * (C) Copyright 2000-2010 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Andreas Heppel <aheppel@sysgo.de> - + * * See file CREDITS for list of people who contributed to this * project. * @@ -31,21 +31,19 @@ #if defined(CONFIG_I2C_ENV_EEPROM_BUS) #include <i2c.h> #endif - -#ifdef CONFIG_ENV_OFFSET_REDUND -#define ACTIVE_FLAG 1 -#define OBSOLETE_FLAG 0 -#endif +#include <search.h> +#include <errno.h> +#include <linux/compiler.h> /* for BUG_ON */ DECLARE_GLOBAL_DATA_PTR; env_t *env_ptr = NULL; -char * env_name_spec = "EEPROM"; +char *env_name_spec = "EEPROM"; int env_eeprom_bus = -1; -static int eeprom_bus_read (unsigned dev_addr, unsigned offset, uchar *buffer, - unsigned cnt) +static int eeprom_bus_read(unsigned dev_addr, unsigned offset, + uchar *buffer, unsigned cnt) { int rcode; #if defined(CONFIG_I2C_ENV_EEPROM_BUS) @@ -56,9 +54,9 @@ static int eeprom_bus_read (unsigned dev_addr, unsigned offset, uchar *buffer, I2C_MUX_DEVICE *dev = NULL; dev = i2c_mux_ident_muxstring( (uchar *)CONFIG_I2C_ENV_EEPROM_BUS); - if (dev != NULL) { + if (dev != NULL) env_eeprom_bus = dev->busid; - } else + else printf ("error adding env eeprom bus.\n"); } if (old_bus != env_eeprom_bus) { @@ -72,6 +70,7 @@ static int eeprom_bus_read (unsigned dev_addr, unsigned offset, uchar *buffer, #endif rcode = eeprom_read (dev_addr, offset, buffer, cnt); + #if defined(CONFIG_I2C_ENV_EEPROM_BUS) if (old_bus != env_eeprom_bus) i2c_set_bus_num(old_bus); @@ -79,8 +78,8 @@ static int eeprom_bus_read (unsigned dev_addr, unsigned offset, uchar *buffer, return rcode; } -static int eeprom_bus_write (unsigned dev_addr, unsigned offset, uchar *buffer, - unsigned cnt) +static int eeprom_bus_write(unsigned dev_addr, unsigned offset, + uchar *buffer, unsigned cnt) { int rcode; #if defined(CONFIG_I2C_ENV_EEPROM_BUS) @@ -88,7 +87,7 @@ static int eeprom_bus_write (unsigned dev_addr, unsigned offset, uchar *buffer, rcode = i2c_mux_ident_muxstring_f((uchar *)CONFIG_I2C_ENV_EEPROM_BUS); #endif - rcode = eeprom_write (dev_addr, offset, buffer, cnt); + rcode = eeprom_write(dev_addr, offset, buffer, cnt); #if defined(CONFIG_I2C_ENV_EEPROM_BUS) i2c_set_bus_num(old_bus); #endif @@ -100,12 +99,12 @@ uchar env_get_char_spec (int index) uchar c; unsigned int off; off = CONFIG_ENV_OFFSET; + #ifdef CONFIG_ENV_OFFSET_REDUND if (gd->env_valid == 2) off = CONFIG_ENV_OFFSET_REDUND; #endif - - eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR, + eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR, off + index + offsetof(env_t,data), &c, 1); @@ -114,40 +113,60 @@ uchar env_get_char_spec (int index) void env_relocate_spec (void) { + char buf[CONFIG_ENV_SIZE]; unsigned int off = CONFIG_ENV_OFFSET; + #ifdef CONFIG_ENV_OFFSET_REDUND if (gd->env_valid == 2) off = CONFIG_ENV_OFFSET_REDUND; #endif - eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR, + eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR, off, - (uchar*)env_ptr, + (uchar *)buf, CONFIG_ENV_SIZE); + + env_import(buf, 1); } int saveenv(void) { + env_t env_new; + ssize_t len; + char *res; int rc; unsigned int off = CONFIG_ENV_OFFSET; #ifdef CONFIG_ENV_OFFSET_REDUND unsigned int off_red = CONFIG_ENV_OFFSET_REDUND; char flag_obsolete = OBSOLETE_FLAG; +#endif + + BUG_ON(env_ptr != NULL); + + res = (char *)&env_new.data; + len = hexport('\0', &res, ENV_SIZE); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + +#ifdef CONFIG_ENV_OFFSET_REDUND if (gd->env_valid == 1) { off = CONFIG_ENV_OFFSET_REDUND; off_red = CONFIG_ENV_OFFSET; } - env_ptr->flags = ACTIVE_FLAG; + env_new.flags = ACTIVE_FLAG; #endif - rc = eeprom_bus_write (CONFIG_SYS_DEF_EEPROM_ADDR, + rc = eeprom_bus_write(CONFIG_SYS_DEF_EEPROM_ADDR, off, - (uchar *)env_ptr, + (uchar *)&env_new, CONFIG_ENV_SIZE); #ifdef CONFIG_ENV_OFFSET_REDUND if (rc == 0) { - eeprom_bus_write (CONFIG_SYS_DEF_EEPROM_ADDR, + eeprom_bus_write(CONFIG_SYS_DEF_EEPROM_ADDR, off_red + offsetof(env_t,flags), (uchar *)&flag_obsolete, 1); @@ -162,10 +181,10 @@ int saveenv(void) return rc; } -/************************************************************************ +/* * Initialize Environment use * - * We are still running from ROM, so data use is limited + * We are still running from ROM, so data use is limited. * Use a (moderately small) buffer on the stack */ @@ -180,31 +199,31 @@ int env_init(void) unsigned char flags[2]; int i; - eeprom_init (); /* prepare for EEPROM read/write */ + eeprom_init(); /* prepare for EEPROM read/write */ off_env[0] = CONFIG_ENV_OFFSET; off_env[1] = CONFIG_ENV_OFFSET_REDUND; for (i = 0; i < 2; i++) { /* read CRC */ - eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR, + eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR, off_env[i] + offsetof(env_t,crc), (uchar *)&crc[i], sizeof(ulong)); /* read FLAGS */ - eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR, + eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR, off_env[i] + offsetof(env_t,flags), (uchar *)&flags[i], sizeof(uchar)); - crc_tmp= 0; + crc_tmp = 0; len = ENV_SIZE; off = off_env[i] + offsetof(env_t,data); while (len > 0) { int n = (len > sizeof(buf)) ? sizeof(buf) : len; - eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR, off, + eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR, off, buf, n); - crc_tmp = crc32 (crc_tmp, buf, n); + crc_tmp = crc32(crc_tmp, buf, n); len -= n; off += n; } @@ -250,22 +269,23 @@ int env_init(void) unsigned off; uchar buf[64]; - eeprom_init (); /* prepare for EEPROM read/write */ + eeprom_init(); /* prepare for EEPROM read/write */ /* read old CRC */ - eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR, + eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+offsetof(env_t,crc), (uchar *)&crc, sizeof(ulong)); new = 0; len = ENV_SIZE; off = offsetof(env_t,data); + while (len > 0) { int n = (len > sizeof(buf)) ? sizeof(buf) : len; - eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR, + eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET + off, buf, n); - new = crc32 (new, buf, n); + new = crc32(new, buf, n); len -= n; off += n; } diff --git a/common/env_flash.c b/common/env_flash.c index b860c48..1da78b7 100644 --- a/common/env_flash.c +++ b/common/env_flash.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2002 + * (C) Copyright 2000-2010 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> @@ -31,6 +31,8 @@ #include <environment.h> #include <linux/stddef.h> #include <malloc.h> +#include <search.h> +#include <errno.h> DECLARE_GLOBAL_DATA_PTR; @@ -44,12 +46,6 @@ DECLARE_GLOBAL_DATA_PTR; #error CONFIG_ENV_SIZE_REDUND should not be less then CONFIG_ENV_SIZE #endif -#ifdef CONFIG_INFERNO -# ifdef CONFIG_ENV_ADDR_REDUND -#error CONFIG_ENV_ADDR_REDUND is not implemented for CONFIG_INFERNO -# endif -#endif - char * env_name_spec = "Flash"; #ifdef ENV_IS_EMBEDDED @@ -57,39 +53,38 @@ char * env_name_spec = "Flash"; extern uchar environment[]; env_t *env_ptr = (env_t *)(&environment[0]); -#ifdef CMD_SAVEENV -/* static env_t *flash_addr = (env_t *)(&environment[0]);-broken on ARM-wd-*/ static env_t *flash_addr = (env_t *)CONFIG_ENV_ADDR; -#endif #else /* ! ENV_IS_EMBEDDED */ env_t *env_ptr = (env_t *)CONFIG_ENV_ADDR; -#ifdef CMD_SAVEENV static env_t *flash_addr = (env_t *)CONFIG_ENV_ADDR; -#endif #endif /* ENV_IS_EMBEDDED */ +#if defined(CMD_SAVEENV) || defined(CONFIG_ENV_ADDR_REDUND) +/* CONFIG_ENV_ADDR is supposed to be on sector boundary */ +static ulong end_addr = CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1; +#endif + #ifdef CONFIG_ENV_ADDR_REDUND static env_t *flash_addr_new = (env_t *)CONFIG_ENV_ADDR_REDUND; -/* CONFIG_ENV_ADDR is supposed to be on sector boundary */ -static ulong end_addr = CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1; +/* CONFIG_ENV_ADDR_REDUND is supposed to be on sector boundary */ static ulong end_addr_new = CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1; - -#define ACTIVE_FLAG 1 -#define OBSOLETE_FLAG 0 #endif /* CONFIG_ENV_ADDR_REDUND */ extern uchar default_environment[]; -uchar env_get_char_spec (int index) +uchar env_get_char_spec(int index) { - return ( *((uchar *)(gd->env_addr + index)) ); + return (*((uchar *)(gd->env_addr + index))); } +#undef debug +#define debug printf + #ifdef CONFIG_ENV_ADDR_REDUND int env_init(void) @@ -132,91 +127,97 @@ int env_init(void) gd->env_valid = 2; } - return (0); + return 0; } #ifdef CMD_SAVEENV int saveenv(void) { - char *saved_data = NULL; - int rc = 1; - char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG; + env_t env_new; + ssize_t len; + char *saved_data = NULL; + char *res; + int rc = 1; + char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG; #if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE - ulong up_data = 0; + ulong up_data = 0; #endif - debug ("Protect off %08lX ... %08lX\n", + debug("Protect off %08lX ... %08lX\n", (ulong)flash_addr, end_addr); - if (flash_sect_protect (0, (ulong)flash_addr, end_addr)) { - goto Done; + if (flash_sect_protect(0, (ulong)flash_addr, end_addr)) { + goto done; } - debug ("Protect off %08lX ... %08lX\n", + debug("Protect off %08lX ... %08lX\n", (ulong)flash_addr_new, end_addr_new); - if (flash_sect_protect (0, (ulong)flash_addr_new, end_addr_new)) { - goto Done; + if (flash_sect_protect(0, (ulong)flash_addr_new, end_addr_new)) { + goto done; + } + + res = (char *)&env_new.data; + len = hexport('\0', &res, ENV_SIZE); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + goto done; } + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new.flags = new_flag; #if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE up_data = (end_addr_new + 1 - ((long)flash_addr_new + CONFIG_ENV_SIZE)); - debug ("Data to save 0x%x\n", up_data); + debug("Data to save 0x%lX\n", up_data); if (up_data) { if ((saved_data = malloc(up_data)) == NULL) { printf("Unable to save the rest of sector (%ld)\n", up_data); - goto Done; + goto done; } memcpy(saved_data, (void *)((long)flash_addr_new + CONFIG_ENV_SIZE), up_data); - debug ("Data (start 0x%x, len 0x%x) saved at 0x%x\n", - (long)flash_addr_new + CONFIG_ENV_SIZE, - up_data, saved_data); + debug("Data (start 0x%lX, len 0x%lX) saved at 0x%p\n", + (long)flash_addr_new + CONFIG_ENV_SIZE, + up_data, saved_data); } #endif - puts ("Erasing Flash..."); - debug (" %08lX ... %08lX ...", + puts("Erasing Flash..."); + debug(" %08lX ... %08lX ...", (ulong)flash_addr_new, end_addr_new); - if (flash_sect_erase ((ulong)flash_addr_new, end_addr_new)) { - goto Done; + if (flash_sect_erase((ulong)flash_addr_new, end_addr_new)) { + goto done; } - puts ("Writing to Flash... "); - debug (" %08lX ... %08lX ...", + puts("Writing to Flash... "); + debug(" %08lX ... %08lX ...", (ulong)&(flash_addr_new->data), sizeof(env_ptr->data)+(ulong)&(flash_addr_new->data)); - if ((rc = flash_write((char *)env_ptr->data, - (ulong)&(flash_addr_new->data), - sizeof(env_ptr->data))) || - (rc = flash_write((char *)&(env_ptr->crc), - (ulong)&(flash_addr_new->crc), - sizeof(env_ptr->crc))) || + if ((rc = flash_write((char *)&env_new, + (ulong)flash_addr_new, + sizeof(env_new))) || (rc = flash_write(&flag, (ulong)&(flash_addr->flags), - sizeof(flash_addr->flags))) || - (rc = flash_write(&new_flag, - (ulong)&(flash_addr_new->flags), - sizeof(flash_addr_new->flags)))) - { - flash_perror (rc); - goto Done; + sizeof(flash_addr->flags))) ) { + flash_perror(rc); + goto done; } - puts ("done\n"); #if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE if (up_data) { /* restore the rest of sector */ - debug ("Restoring the rest of data to 0x%x len 0x%x\n", - (long)flash_addr_new + CONFIG_ENV_SIZE, up_data); + debug("Restoring the rest of data to 0x%lX len 0x%lX\n", + (long)flash_addr_new + CONFIG_ENV_SIZE, up_data); if (flash_write(saved_data, (long)flash_addr_new + CONFIG_ENV_SIZE, up_data)) { flash_perror(rc); - goto Done; + goto done; } } #endif + puts("done\n"); + { env_t * etmp = flash_addr; ulong ltmp = end_addr; @@ -229,13 +230,12 @@ int saveenv(void) } rc = 0; -Done: - +done: if (saved_data) - free (saved_data); + free(saved_data); /* try to re-protect */ - (void) flash_sect_protect (1, (ulong)flash_addr, end_addr); - (void) flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new); + (void) flash_sect_protect(1, (ulong)flash_addr, end_addr); + (void) flash_sect_protect(1, (ulong)flash_addr_new, end_addr_new); return rc; } @@ -253,89 +253,93 @@ int env_init(void) gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 0; - return (0); + return 0; } #ifdef CMD_SAVEENV int saveenv(void) { - int len, rc; - ulong end_addr; - ulong flash_sect_addr; -#if defined(CONFIG_ENV_SECT_SIZE) && (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) - ulong flash_offset; - uchar env_buffer[CONFIG_ENV_SECT_SIZE]; -#else - uchar *env_buffer = (uchar *)env_ptr; -#endif /* CONFIG_ENV_SECT_SIZE */ - int rcode = 0; - -#if defined(CONFIG_ENV_SECT_SIZE) && (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) - - flash_offset = ((ulong)flash_addr) & (CONFIG_ENV_SECT_SIZE-1); - flash_sect_addr = ((ulong)flash_addr) & ~(CONFIG_ENV_SECT_SIZE-1); - - debug ( "copy old content: " - "sect_addr: %08lX env_addr: %08lX offset: %08lX\n", - flash_sect_addr, (ulong)flash_addr, flash_offset); - - /* copy old contents to temporary buffer */ - memcpy (env_buffer, (void *)flash_sect_addr, CONFIG_ENV_SECT_SIZE); - - /* copy current environment to temporary buffer */ - memcpy ((uchar *)((unsigned long)env_buffer + flash_offset), - env_ptr, - CONFIG_ENV_SIZE); + env_t env_new; + ssize_t len; + int rc = 1; + char *res; + char *saved_data = NULL; +#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE + ulong up_data = 0; - len = CONFIG_ENV_SECT_SIZE; -#else - flash_sect_addr = (ulong)flash_addr; - len = CONFIG_ENV_SIZE; + up_data = (end_addr + 1 - ((long)flash_addr + CONFIG_ENV_SIZE)); + debug("Data to save 0x%lx\n", up_data); + if (up_data) { + if ((saved_data = malloc(up_data)) == NULL) { + printf("Unable to save the rest of sector (%ld)\n", + up_data); + goto done; + } + memcpy(saved_data, + (void *)((long)flash_addr + CONFIG_ENV_SIZE), up_data); + debug("Data (start 0x%lx, len 0x%lx) saved at 0x%lx\n", + (ulong)flash_addr + CONFIG_ENV_SIZE, + up_data, + (ulong)saved_data); + } #endif /* CONFIG_ENV_SECT_SIZE */ -#ifndef CONFIG_INFERNO - end_addr = flash_sect_addr + len - 1; -#else - /* this is the last sector, and the size is hardcoded here */ - /* otherwise we will get stack problems on loading 128 KB environment */ - end_addr = flash_sect_addr + 0x20000 - 1; -#endif + debug("Protect off %08lX ... %08lX\n", + (ulong)flash_addr, end_addr); - debug ("Protect off %08lX ... %08lX\n", - (ulong)flash_sect_addr, end_addr); + if (flash_sect_protect(0, (long)flash_addr, end_addr)) + goto done; - if (flash_sect_protect (0, flash_sect_addr, end_addr)) - return 1; + res = (char *)&env_new.data; + len = hexport('\0', &res, ENV_SIZE); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + goto done; + } + env_new.crc = crc32(0, env_new.data, ENV_SIZE); - puts ("Erasing Flash..."); - if (flash_sect_erase (flash_sect_addr, end_addr)) - return 1; + puts("Erasing Flash..."); + if (flash_sect_erase((long)flash_addr, end_addr)) + goto done; - puts ("Writing to Flash... "); - rc = flash_write((char *)env_buffer, flash_sect_addr, len); + puts("Writing to Flash... "); + rc = flash_write((char *)&env_new, (long)flash_addr, CONFIG_ENV_SIZE); if (rc != 0) { - flash_perror (rc); - rcode = 1; - } else { - puts ("done\n"); + flash_perror(rc); + goto done; } - +#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE + if (up_data) { /* restore the rest of sector */ + debug("Restoring the rest of data to 0x%lx len 0x%lx\n", + (ulong)flash_addr + CONFIG_ENV_SIZE, up_data); + if (flash_write(saved_data, + (long)flash_addr + CONFIG_ENV_SIZE, + up_data)) { + flash_perror(rc); + goto done; + } + } +#endif + puts("done\n"); + rc = 0; +done: + if (saved_data) + free(saved_data); /* try to re-protect */ - (void) flash_sect_protect (1, flash_sect_addr, end_addr); - return rcode; + (void) flash_sect_protect(1, (long)flash_addr, end_addr); + return rc; } #endif /* CMD_SAVEENV */ #endif /* CONFIG_ENV_ADDR_REDUND */ -void env_relocate_spec (void) +void env_relocate_spec(void) { -#if !defined(ENV_IS_EMBEDDED) || defined(CONFIG_ENV_ADDR_REDUND) #ifdef CONFIG_ENV_ADDR_REDUND if (gd->env_addr != (ulong)&(flash_addr->data)) { - env_t * etmp = flash_addr; + env_t *etmp = flash_addr; ulong ltmp = end_addr; flash_addr = flash_addr_new; @@ -351,11 +355,11 @@ void env_relocate_spec (void) char flag = OBSOLETE_FLAG; gd->env_valid = 2; - flash_sect_protect (0, (ulong)flash_addr_new, end_addr_new); + flash_sect_protect(0, (ulong)flash_addr_new, end_addr_new); flash_write(&flag, (ulong)&(flash_addr_new->flags), sizeof(flash_addr_new->flags)); - flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new); + flash_sect_protect(1, (ulong)flash_addr_new, end_addr_new); } if (flash_addr->flags != ACTIVE_FLAG && @@ -363,19 +367,17 @@ void env_relocate_spec (void) char flag = ACTIVE_FLAG; gd->env_valid = 2; - flash_sect_protect (0, (ulong)flash_addr, end_addr); + flash_sect_protect(0, (ulong)flash_addr, end_addr); flash_write(&flag, (ulong)&(flash_addr->flags), sizeof(flash_addr->flags)); - flash_sect_protect (1, (ulong)flash_addr, end_addr); + flash_sect_protect(1, (ulong)flash_addr, end_addr); } if (gd->env_valid == 2) puts ("*** Warning - some problems detected " "reading environment; recovered successfully\n\n"); #endif /* CONFIG_ENV_ADDR_REDUND */ -#ifdef CMD_SAVEENV - memcpy (env_ptr, (void*)flash_addr, CONFIG_ENV_SIZE); -#endif -#endif /* ! ENV_IS_EMBEDDED || CONFIG_ENV_ADDR_REDUND */ + + env_import((char *)flash_addr, 1); } diff --git a/common/env_mgdisk.c b/common/env_mgdisk.c index b9de1ed..a69923b 100644 --- a/common/env_mgdisk.c +++ b/common/env_mgdisk.c @@ -30,7 +30,7 @@ /* references to names in env_common.c */ extern uchar default_environment[]; -char * env_name_spec = "MG_DISK"; +char *env_name_spec = "MG_DISK"; env_t *env_ptr = 0; @@ -38,34 +38,27 @@ DECLARE_GLOBAL_DATA_PTR; uchar env_get_char_spec(int index) { - return (*((uchar *) (gd->env_addr + index))); + return (*((uchar *)(gd->env_addr + index))); } void env_relocate_spec(void) { - unsigned int err; + char buf[CONFIG_ENV_SIZE]; + unsigned int err, rc; err = mg_disk_init(); if (err) { - puts ("*** Warning - mg_disk_init error"); - goto OUT; - } - err = mg_disk_read(CONFIG_ENV_ADDR, (u_char *)env_ptr, CONFIG_ENV_SIZE); - if (err) { - puts ("*** Warning - mg_disk_read error"); - goto OUT; + set_default_env("!mg_disk_init error"); + return; } - if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) { - puts ("*** Warning - CRC error"); - goto OUT; + err = mg_disk_read(CONFIG_ENV_ADDR, buf, CONFIG_ENV_SIZE); + if (err) { + set_default_env("!mg_disk_read error"); + return; } - return; - -OUT: - printf (", using default environment\n\n"); - set_default_env(); + env_import(buf, 1); } int saveenv(void) @@ -76,7 +69,7 @@ int saveenv(void) err = mg_disk_write(CONFIG_ENV_ADDR, (u_char *)env_ptr, CONFIG_ENV_SIZE); if (err) - puts ("*** Warning - mg_disk_write error\n\n"); + puts("*** Warning - mg_disk_write error\n\n"); return err; } @@ -84,7 +77,7 @@ int saveenv(void) int env_init(void) { /* use default */ - gd->env_addr = (ulong) & default_environment[0]; + gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 1; return 0; diff --git a/common/env_mmc.c b/common/env_mmc.c new file mode 100644 index 0000000..3d7fceb --- /dev/null +++ b/common/env_mmc.c @@ -0,0 +1,166 @@ +/* + * (C) Copyright 2008-2010 Freescale Semiconductor, Inc. + * + * 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 + */ + +/* #define DEBUG */ + +#include <common.h> + +#include <command.h> +#include <environment.h> +#include <linux/stddef.h> +#include <malloc.h> +#include <mmc.h> +#include <errno.h> + +/* references to names in env_common.c */ +extern uchar default_environment[]; + +char *env_name_spec = "MMC"; + +#ifdef ENV_IS_EMBEDDED +extern uchar environment[]; +env_t *env_ptr = (env_t *)(&environment[0]); +#else /* ! ENV_IS_EMBEDDED */ +env_t *env_ptr = NULL; +#endif /* ENV_IS_EMBEDDED */ + +/* local functions */ +#if !defined(ENV_IS_EMBEDDED) +static void use_default(void); +#endif + +DECLARE_GLOBAL_DATA_PTR; + +uchar env_get_char_spec(int index) +{ + return *((uchar *)(gd->env_addr + index)); +} + +int env_init(void) +{ + /* use default */ + gd->env_addr = (ulong)&default_environment[0]; + gd->env_valid = 1; + + return 0; +} + +int init_mmc_for_env(struct mmc *mmc) +{ + if (!mmc) { + puts("No MMC card found\n"); + return -1; + } + + if (mmc_init(mmc)) { + puts("MMC init failed\n"); + return -1; + } + + return 0; +} + +#ifdef CONFIG_CMD_SAVEENV + +inline int write_env(struct mmc *mmc, unsigned long size, + unsigned long offset, const void *buffer) +{ + uint blk_start, blk_cnt, n; + + blk_start = ALIGN(offset, mmc->write_bl_len) / mmc->write_bl_len; + blk_cnt = ALIGN(size, mmc->write_bl_len) / mmc->write_bl_len; + + n = mmc->block_dev.block_write(CONFIG_SYS_MMC_ENV_DEV, blk_start, + blk_cnt, (u_char *)buffer); + + return (n == blk_cnt) ? 0 : -1; +} + +int saveenv(void) +{ + env_t env_new; + ssize_t len; + char *res; + struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); + + if (init_mmc_for_env(mmc)) + return 1; + + res = (char *)&env_new.data; + len = hexport('\0', &res, ENV_SIZE); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + printf("Writing to MMC(%d)... ", CONFIG_SYS_MMC_ENV_DEV); + if (write_env(mmc, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, (u_char *)&env_new)) { + puts("failed\n"); + return 1; + } + + puts("done\n"); + return 0; +} +#endif /* CONFIG_CMD_SAVEENV */ + +inline int read_env(struct mmc *mmc, unsigned long size, + unsigned long offset, const void *buffer) +{ + uint blk_start, blk_cnt, n; + + blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len; + blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len; + + n = mmc->block_dev.block_read(CONFIG_SYS_MMC_ENV_DEV, blk_start, + blk_cnt, (uchar *)buffer); + + return (n == blk_cnt) ? 0 : -1; +} + +void env_relocate_spec(void) +{ +#if !defined(ENV_IS_EMBEDDED) + char buf[CONFIG_ENV_SIZE]; + + struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); + + if (init_mmc_for_env(mmc)) { + use_default(); + return; + } + + if (read_env(mmc, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, buf)) { + use_default(); + return; + } + + env_import(buf, 1); +#endif +} + +#if !defined(ENV_IS_EMBEDDED) +static void use_default() +{ + set_default_env(NULL); +} +#endif diff --git a/common/env_nand.c b/common/env_nand.c index 325f112..345d2db 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -1,16 +1,16 @@ /* + * (C) Copyright 2000-2010 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * * (C) Copyright 2008 * Stuart Wood, Lab X Technologies <stuart.wood@labxtechnologies.com> * * (C) Copyright 2004 * Jian Zhang, Texas Instruments, jzhang@ti.com. - - * (C) Copyright 2000-2006 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Andreas Heppel <aheppel@sysgo.de> - + * * See file CREDITS for list of people who contributed to this * project. * @@ -30,7 +30,7 @@ * MA 02111-1307 USA */ -/* #define DEBUG */ +#define DEBUG #include <common.h> #include <command.h> @@ -38,6 +38,8 @@ #include <linux/stddef.h> #include <malloc.h> #include <nand.h> +#include <search.h> +#include <errno.h> #if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_CMD_NAND) #define CMD_SAVEENV @@ -49,10 +51,6 @@ #error CONFIG_ENV_SIZE_REDUND should be the same as CONFIG_ENV_SIZE #endif -#ifdef CONFIG_INFERNO -#error CONFIG_INFERNO not supported yet -#endif - #ifndef CONFIG_ENV_RANGE #define CONFIG_ENV_RANGE CONFIG_ENV_SIZE #endif @@ -60,7 +58,7 @@ /* references to names in env_common.c */ extern uchar default_environment[]; -char * env_name_spec = "NAND"; +char *env_name_spec = "NAND"; #if defined(ENV_IS_EMBEDDED) @@ -72,12 +70,6 @@ env_t *env_ptr = (env_t *)CONFIG_NAND_ENV_DST; env_t *env_ptr = 0; #endif /* ENV_IS_EMBEDDED */ - -/* local functions */ -#if !defined(ENV_IS_EMBEDDED) -static void use_default(void); -#endif - DECLARE_GLOBAL_DATA_PTR; uchar env_get_char_spec (int index) @@ -85,17 +77,17 @@ uchar env_get_char_spec (int index) return ( *((uchar *)(gd->env_addr + index)) ); } - -/* this is called before nand_init() - * so we can't read Nand to validate env data. - * Mark it OK for now. env_relocate() in env_common.c - * will call our relocate function which does the real - * validation. +/* + * This is called before nand_init() so we can't read NAND to + * validate env data. + * + * Mark it OK for now. env_relocate() in env_common.c will call our + * relocate function which does the real validation. * * When using a NAND boot image (like sequoia_nand), the environment - * can be embedded or attached to the U-Boot image in NAND flash. This way - * the SPL loads not only the U-Boot image from NAND but also the - * environment. + * can be embedded or attached to the U-Boot image in NAND flash. + * This way the SPL loads not only the U-Boot image from NAND but + * also the environment. */ int env_init(void) { @@ -192,11 +184,12 @@ int writeenv(size_t offset, u_char *buf) #ifdef CONFIG_ENV_OFFSET_REDUND int saveenv(void) { - int ret = 0; + env_t env_new; + ssize_t len; + char *res; + int ret = 0; nand_erase_options_t nand_erase_options; - env_ptr->flags++; - nand_erase_options.length = CONFIG_ENV_RANGE; nand_erase_options.quiet = 0; nand_erase_options.jffs2 = 0; @@ -204,36 +197,53 @@ int saveenv(void) if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) return 1; + + res = (char *)&env_new.data; + len = hexport('\0', &res, ENV_SIZE); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new.flags = ACTIVE_FLAG; + if(gd->env_valid == 1) { - puts ("Erasing redundant Nand...\n"); + puts("Erasing redundant NAND...\n"); nand_erase_options.offset = CONFIG_ENV_OFFSET_REDUND; if (nand_erase_opts(&nand_info[0], &nand_erase_options)) return 1; - puts ("Writing to redundant Nand... "); - ret = writeenv(CONFIG_ENV_OFFSET_REDUND, (u_char *) env_ptr); + puts("Writing to redundant NAND... "); + ret = writeenv(CONFIG_ENV_OFFSET_REDUND, + (u_char *)&env_new); } else { - puts ("Erasing Nand...\n"); + puts("Erasing NAND...\n"); nand_erase_options.offset = CONFIG_ENV_OFFSET; if (nand_erase_opts(&nand_info[0], &nand_erase_options)) return 1; - puts ("Writing to Nand... "); - ret = writeenv(CONFIG_ENV_OFFSET, (u_char *) env_ptr); + puts("Writing to NAND... "); + ret = writeenv(CONFIG_ENV_OFFSET, + (u_char *)&env_new); } if (ret) { puts("FAILED!\n"); return 1; } - puts ("done\n"); + puts("done\n"); + gd->env_valid = (gd->env_valid == 2 ? 1 : 2); + return ret; } #else /* ! CONFIG_ENV_OFFSET_REDUND */ int saveenv(void) { int ret = 0; + env_t env_new; + ssize_t len; + char *res; nand_erase_options_t nand_erase_options; nand_erase_options.length = CONFIG_ENV_RANGE; @@ -244,23 +254,32 @@ int saveenv(void) if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) return 1; - puts ("Erasing Nand...\n"); + + res = (char *)&env_new.data; + len = hexport('\0', &res, ENV_SIZE); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + + puts("Erasing Nand...\n"); if (nand_erase_opts(&nand_info[0], &nand_erase_options)) return 1; - puts ("Writing to Nand... "); - if (writeenv(CONFIG_ENV_OFFSET, (u_char *) env_ptr)) { + puts("Writing to Nand... "); + if (writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new)) { puts("FAILED!\n"); return 1; } - puts ("done\n"); + puts("done\n"); return ret; } #endif /* CONFIG_ENV_OFFSET_REDUND */ #endif /* CMD_SAVEENV */ -int readenv (size_t offset, u_char * buf) +int readenv(size_t offset, u_char * buf) { size_t end = offset + CONFIG_ENV_RANGE; size_t amount_loaded = 0; @@ -273,6 +292,8 @@ int readenv (size_t offset, u_char * buf) return 1; blocksize = nand_info[0].erasesize; + if (!blocksize) + return 1; len = min(blocksize, CONFIG_ENV_SIZE); while (amount_loaded < CONFIG_ENV_SIZE && offset < end) { @@ -292,48 +313,83 @@ int readenv (size_t offset, u_char * buf) return 0; } +#ifdef CONFIG_ENV_OFFSET_OOB +int get_nand_env_oob(nand_info_t *nand, unsigned long *result) +{ + struct mtd_oob_ops ops; + uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)]; + int ret; + + ops.datbuf = NULL; + ops.mode = MTD_OOB_AUTO; + ops.ooboffs = 0; + ops.ooblen = ENV_OFFSET_SIZE; + ops.oobbuf = (void *) oob_buf; + + ret = nand->read_oob(nand, ENV_OFFSET_SIZE, &ops); + if (ret) { + printf("error reading OOB block 0\n"); + return ret; + } + + if (oob_buf[0] == ENV_OOB_MARKER) { + *result = oob_buf[1] * nand->erasesize; + } else if (oob_buf[0] == ENV_OOB_MARKER_OLD) { + *result = oob_buf[1]; + } else { + printf("No dynamic environment marker in OOB block 0\n"); + return -ENOENT; + } + + return 0; +} +#endif + #ifdef CONFIG_ENV_OFFSET_REDUND -void env_relocate_spec (void) +void env_relocate_spec(void) { #if !defined(ENV_IS_EMBEDDED) int crc1_ok = 0, crc2_ok = 0; - env_t *tmp_env1, *tmp_env2; + env_t *ep, *tmp_env1, *tmp_env2; - tmp_env1 = (env_t *) malloc(CONFIG_ENV_SIZE); - tmp_env2 = (env_t *) malloc(CONFIG_ENV_SIZE); + tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE); + tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE); if ((tmp_env1 == NULL) || (tmp_env2 == NULL)) { puts("Can't allocate buffers for environment\n"); - free (tmp_env1); - free (tmp_env2); - return use_default(); + free(tmp_env1); + free(tmp_env2); + set_default_env("!malloc() failed"); + return; } if (readenv(CONFIG_ENV_OFFSET, (u_char *) tmp_env1)) - puts("No Valid Environment Area Found\n"); + puts("No Valid Environment Area found\n"); + if (readenv(CONFIG_ENV_OFFSET_REDUND, (u_char *) tmp_env2)) - puts("No Valid Reundant Environment Area Found\n"); + puts("No Valid Redundant Environment Area found\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); - if(!crc1_ok && !crc2_ok) { + if (!crc1_ok && !crc2_ok) { free(tmp_env1); free(tmp_env2); - return use_default(); - } else if(crc1_ok && !crc2_ok) + set_default_env("!bad CRC"); + return; + } else if (crc1_ok && !crc2_ok) { gd->env_valid = 1; - else if(!crc1_ok && crc2_ok) + } else if (!crc1_ok && crc2_ok) { gd->env_valid = 2; - else { + } else { /* both ok - check serial */ - if(tmp_env1->flags == 255 && tmp_env2->flags == 0) + if (tmp_env1->flags == 255 && tmp_env2->flags == 0) gd->env_valid = 2; - else if(tmp_env2->flags == 255 && tmp_env1->flags == 0) + else if (tmp_env2->flags == 255 && tmp_env1->flags == 0) gd->env_valid = 1; - else if(tmp_env1->flags > tmp_env2->flags) + else if (tmp_env1->flags > tmp_env2->flags) gd->env_valid = 1; - else if(tmp_env2->flags > tmp_env1->flags) + else if (tmp_env2->flags > tmp_env1->flags) gd->env_valid = 2; else /* flags are equal - almost impossible */ gd->env_valid = 1; @@ -341,40 +397,52 @@ void env_relocate_spec (void) } free(env_ptr); - if(gd->env_valid == 1) { - env_ptr = tmp_env1; - free(tmp_env2); - } else { - env_ptr = tmp_env2; - free(tmp_env1); - } + + if (gd->env_valid == 1) + ep = tmp_env1; + else + ep = tmp_env2; + + env_import((char *)ep, 0); + + free(tmp_env1); + free(tmp_env2); #endif /* ! ENV_IS_EMBEDDED */ } #else /* ! CONFIG_ENV_OFFSET_REDUND */ /* - * The legacy NAND code saved the environment in the first NAND device i.e., - * nand_dev_desc + 0. This is also the behaviour using the new NAND code. + * The legacy NAND code saved the environment in the first NAND + * device i.e., nand_dev_desc + 0. This is also the behaviour using + * the new NAND code. */ void env_relocate_spec (void) { #if !defined(ENV_IS_EMBEDDED) int ret; + char buf[CONFIG_ENV_SIZE]; + +#if defined(CONFIG_ENV_OFFSET_OOB) + ret = get_nand_env_oob(&nand_info[0], &nand_env_oob_offset); + /* + * If unable to read environment offset from NAND OOB then fall through + * to the normal environment reading code below + */ + if (!ret) { + printf("Found Environment offset in OOB..\n"); + } else { + set_default_env("!no env offset in OOB"); + return; + } +#endif - ret = readenv(CONFIG_ENV_OFFSET, (u_char *) env_ptr); - if (ret) - return use_default(); + ret = readenv(CONFIG_ENV_OFFSET, (u_char *)buf); + if (ret) { + set_default_env("!readenv() failed"); + return; + } - if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) - return use_default(); + env_import(buf, 1); #endif /* ! ENV_IS_EMBEDDED */ } #endif /* CONFIG_ENV_OFFSET_REDUND */ - -#if !defined(ENV_IS_EMBEDDED) -static void use_default() -{ - puts ("*** Warning - bad CRC or NAND, using default environment\n\n"); - set_default_env(); -} -#endif diff --git a/common/env_nowhere.c b/common/env_nowhere.c index ccc068b..75ef78d 100644 --- a/common/env_nowhere.c +++ b/common/env_nowhere.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2002 + * (C) Copyright 2000-2010 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> @@ -35,22 +35,21 @@ env_t *env_ptr = NULL; extern uchar default_environment[]; - -void env_relocate_spec (void) +void env_relocate_spec(void) { } -uchar env_get_char_spec (int index) +uchar env_get_char_spec(int index) { return ( *((uchar *)(gd->env_addr + index)) ); } -/************************************************************************ +/* * Initialize Environment use * * We are still running from ROM, so data use is limited */ -int env_init(void) +int env_init(void) { gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 0; diff --git a/common/env_nvram.c b/common/env_nvram.c index 2628fe4..6e90f2b 100644 --- a/common/env_nvram.c +++ b/common/env_nvram.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2002 + * (C) Copyright 2000-2010 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> @@ -44,6 +44,8 @@ #include <command.h> #include <environment.h> #include <linux/stddef.h> +#include <search.h> +#include <errno.h> DECLARE_GLOBAL_DATA_PTR; @@ -59,25 +61,7 @@ char * env_name_spec = "NVRAM"; extern uchar default_environment[]; -#ifdef CONFIG_AMIGAONEG3SE -uchar env_get_char_spec (int index) -{ -#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE - uchar c; - - nvram_read(&c, CONFIG_ENV_ADDR+index, 1); - - return c; -#else - uchar retval; - enable_nvram(); - retval = *((uchar *)(gd->env_addr + index)); - disable_nvram(); - return retval; -#endif -} -#else -uchar env_get_char_spec (int index) +uchar env_get_char_spec(int index) { #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE uchar c; @@ -89,52 +73,57 @@ uchar env_get_char_spec (int index) return *((uchar *)(gd->env_addr + index)); #endif } -#endif -void env_relocate_spec (void) +void env_relocate_spec(void) { + char buf[CONFIG_ENV_SIZE]; + #if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE) - nvram_read(env_ptr, CONFIG_ENV_ADDR, CONFIG_ENV_SIZE); + nvram_read(buf, CONFIG_ENV_ADDR, CONFIG_ENV_SIZE); #else - memcpy (env_ptr, (void*)CONFIG_ENV_ADDR, CONFIG_ENV_SIZE); + memcpy(buf, (void*)CONFIG_ENV_ADDR, CONFIG_ENV_SIZE); #endif + env_import(buf, 1); } -int saveenv (void) +int saveenv(void) { - int rcode = 0; -#ifdef CONFIG_AMIGAONEG3SE - enable_nvram(); -#endif + env_t env_new; + ssize_t len; + char *res; + int rcode = 0; + + res = (char *)&env_new.data; + len = hexport('\0', &res, ENV_SIZE); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE - nvram_write(CONFIG_ENV_ADDR, env_ptr, CONFIG_ENV_SIZE); + nvram_write(CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE); #else - if (memcpy ((char *)CONFIG_ENV_ADDR, env_ptr, CONFIG_ENV_SIZE) == NULL) - rcode = 1 ; -#endif -#ifdef CONFIG_AMIGAONEG3SE - udelay(10000); - disable_nvram(); + if (memcpy((char *)CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE) == NULL) + rcode = 1; #endif return rcode; } -/************************************************************************ +/* * Initialize Environment use * * We are still running from ROM, so data use is limited */ -int env_init (void) +int env_init(void) { -#ifdef CONFIG_AMIGAONEG3SE - enable_nvram(); -#endif #if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE) ulong crc; uchar data[ENV_SIZE]; - nvram_read (&crc, CONFIG_ENV_ADDR, sizeof(ulong)); - nvram_read (data, CONFIG_ENV_ADDR+sizeof(ulong), ENV_SIZE); + + nvram_read(&crc, CONFIG_ENV_ADDR, sizeof(ulong)); + nvram_read(data, CONFIG_ENV_ADDR+sizeof(ulong), ENV_SIZE); if (crc32(0, data, ENV_SIZE) == crc) { gd->env_addr = (ulong)CONFIG_ENV_ADDR + sizeof(long); @@ -147,8 +136,5 @@ int env_init (void) gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 0; } -#ifdef CONFIG_AMIGAONEG3SE - disable_nvram(); -#endif return (0); } diff --git a/common/env_onenand.c b/common/env_onenand.c index cf997bf..02cb535 100644 --- a/common/env_onenand.c +++ b/common/env_onenand.c @@ -1,4 +1,7 @@ /* + * (C) Copyright 2010 DENX Software Engineering + * Wolfgang Denk <wd@denx.de> + * * (C) Copyright 2005-2009 Samsung Electronics * Kyungmin Park <kyungmin.park@samsung.com> * @@ -26,6 +29,8 @@ #include <environment.h> #include <linux/stddef.h> #include <malloc.h> +#include <search.h> +#include <errno.h> #include <linux/mtd/compat.h> #include <linux/mtd/mtd.h> @@ -44,17 +49,13 @@ char *env_name_spec = "OneNAND"; #ifdef ENV_IS_EMBEDDED extern uchar environment[]; -env_t *env_ptr = (env_t *) (&environment[0]); -#else /* ! ENV_IS_EMBEDDED */ -static unsigned char onenand_env[ONENAND_MAX_ENV_SIZE]; -env_t *env_ptr = (env_t *) onenand_env; #endif /* ENV_IS_EMBEDDED */ DECLARE_GLOBAL_DATA_PTR; uchar env_get_char_spec(int index) { - return (*((uchar *) (gd->env_addr + index))); + return (*((uchar *)(gd->env_addr + index))); } void env_relocate_spec(void) @@ -63,48 +64,57 @@ void env_relocate_spec(void) #ifdef CONFIG_ENV_ADDR_FLEX struct onenand_chip *this = &onenand_chip; #endif - loff_t env_addr; - int use_default = 0; + int rc; size_t retlen; +#ifdef ENV_IS_EMBEDDED + char *buf = (char *)&environment[0]; +#else + loff_t env_addr = CONFIG_ENV_ADDR; + char onenand_env[ONENAND_MAX_ENV_SIZE]; + char *buf = (char *)&onenand_env[0]; +#endif /* ENV_IS_EMBEDDED */ - env_addr = CONFIG_ENV_ADDR; -#ifdef CONFIG_ENV_ADDR_FLEX +#ifndef ENV_IS_EMBEDDED +# ifdef CONFIG_ENV_ADDR_FLEX if (FLEXONENAND(this)) env_addr = CONFIG_ENV_ADDR_FLEX; -#endif +# endif /* Check OneNAND exist */ if (mtd->writesize) /* Ignore read fail */ mtd->read(mtd, env_addr, ONENAND_MAX_ENV_SIZE, - &retlen, (u_char *) env_ptr); + &retlen, (u_char *)buf); else mtd->writesize = MAX_ONENAND_PAGESIZE; +#endif /* !ENV_IS_EMBEDDED */ - if (crc32(0, env_ptr->data, ONENAND_ENV_SIZE(mtd)) != env_ptr->crc) - use_default = 1; - - if (use_default) { - memcpy(env_ptr->data, default_environment, - ONENAND_ENV_SIZE(mtd)); - env_ptr->crc = - crc32(0, env_ptr->data, ONENAND_ENV_SIZE(mtd)); - } - - gd->env_addr = (ulong) & env_ptr->data; - gd->env_valid = 1; + rc = env_import(buf, 1); + if (rc) + gd->env_valid = 1; } int saveenv(void) { + env_t env_new; + ssize_t len; + char *res; struct mtd_info *mtd = &onenand_mtd; #ifdef CONFIG_ENV_ADDR_FLEX struct onenand_chip *this = &onenand_chip; #endif - loff_t env_addr = CONFIG_ENV_ADDR; + loff_t env_addr = CONFIG_ENV_ADDR; + size_t retlen; struct erase_info instr = { .callback = NULL, }; - size_t retlen; + + res = (char *)&env_new.data; + len = hexport('\0', &res, ENV_SIZE); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + env_new.crc = crc32(0, env_new.data, ENV_SIZE); instr.len = CONFIG_ENV_SIZE; #ifdef CONFIG_ENV_ADDR_FLEX @@ -122,11 +132,8 @@ int saveenv(void) return 1; } - /* update crc */ - env_ptr->crc = crc32(0, env_ptr->data, ONENAND_ENV_SIZE(mtd)); - if (mtd->write(mtd, env_addr, ONENAND_MAX_ENV_SIZE, &retlen, - (u_char *) env_ptr)) { + (u_char *)&env_new)) { printf("OneNAND: write failed at 0x%llx\n", instr.addr); return 2; } diff --git a/common/env_sf.c b/common/env_sf.c index 6575b6d..fb0c39b 100644 --- a/common/env_sf.c +++ b/common/env_sf.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2002 + * (C) Copyright 2000-2010 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> @@ -29,6 +29,8 @@ #include <environment.h> #include <malloc.h> #include <spi_flash.h> +#include <search.h> +#include <errno.h> #ifndef CONFIG_ENV_SPI_BUS # define CONFIG_ENV_SPI_BUS 0 @@ -43,6 +45,14 @@ # define CONFIG_ENV_SPI_MODE SPI_MODE_3 #endif +#ifdef CONFIG_ENV_OFFSET_REDUND +static ulong env_offset = CONFIG_ENV_OFFSET; +static ulong env_new_offset = CONFIG_ENV_OFFSET_REDUND; + +#define ACTIVE_FLAG 1 +#define OBSOLETE_FLAG 0 +#endif /* CONFIG_ENV_ADDR_REDUND */ + DECLARE_GLOBAL_DATA_PTR; /* references to names in env_common.c */ @@ -58,6 +68,243 @@ uchar env_get_char_spec(int index) return *((uchar *)(gd->env_addr + index)); } +#if defined(CONFIG_ENV_OFFSET_REDUND) +void swap_env(void) +{ + ulong tmp_offset = env_offset; + + env_offset = env_new_offset; + env_new_offset = tmp_offset; +} + +int saveenv(void) +{ + env_t env_new; + ssize_t len; + char *res; + u32 saved_size, saved_offset; + char *saved_buffer = NULL; + u32 sector = 1; + int ret; + char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG; + + if (!env_flash) { + puts("Environment SPI flash not initialized\n"); + return 1; + } + + res = (char *)&env_new.data; + len = hexport('\0', &res, ENV_SIZE); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new.flags = ACTIVE_FLAG; + + /* Is the sector larger than the env (i.e. embedded) */ + if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { + saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; + saved_offset = env_new_offset + CONFIG_ENV_SIZE; + saved_buffer = malloc(saved_size); + if (!saved_buffer) { + ret = 1; + goto done; + } + ret = spi_flash_read(env_flash, saved_offset, + saved_size, saved_buffer); + if (ret) + goto done; + } + + if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { + sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; + if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) + sector++; + } + + puts("Erasing SPI flash..."); + ret = spi_flash_erase(env_flash, env_new_offset, + sector * CONFIG_ENV_SECT_SIZE); + if (ret) + goto done; + + puts("Writing to SPI flash..."); + ret = spi_flash_write(env_flash, + env_new_offset + offsetof(env_t, data), + sizeof(env_new.data), env_new.data); + if (ret) + goto done; + + ret = spi_flash_write(env_flash, + env_new_offset + offsetof(env_t, crc), + sizeof(env_new.crc), &env_new.crc); + if (ret) + goto done; + + ret = spi_flash_write(env_flash, + env_offset + offsetof(env_t, flags), + sizeof(env_new.flags), &flag); + if (ret) + goto done; + + ret = spi_flash_write(env_flash, + env_new_offset + offsetof(env_t, flags), + sizeof(env_new.flags), &new_flag); + if (ret) + goto done; + + if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { + ret = spi_flash_write(env_flash, saved_offset, + saved_size, saved_buffer); + if (ret) + goto done; + } + + swap_env(); + + ret = 0; + puts("done\n"); + + done: + if (saved_buffer) + free(saved_buffer); + return ret; +} + +void env_relocate_spec(void) +{ + int ret; + int crc1_ok = 0, crc2_ok = 0; + env_t *tmp_env1 = NULL; + env_t *tmp_env2 = NULL; + env_t ep; + uchar flag1, flag2; + /* current_env is set only in case both areas are valid! */ + int current_env = 0; + + tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE); + tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE); + + if (!tmp_env1 || !tmp_env2) { + free(tmp_env1); + free(tmp_env2); + set_default_env("!malloc() failed"); + return; + } + + env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, + CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); + if (!env_flash) { + set_default_env("!spi_flash_probe() failed"); + return; + } + + ret = spi_flash_read(env_flash, CONFIG_ENV_OFFSET, + CONFIG_ENV_SIZE, tmp_env1); + if (ret) { + set_default_env("!spi_flash_read() failed"); + goto err_read; + } + + if (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc) + crc1_ok = 1; + flag1 = tmp_env1->flags; + + ret = spi_flash_read(env_flash, CONFIG_ENV_OFFSET_REDUND, + CONFIG_ENV_SIZE, tmp_env2); + if (!ret) { + if (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc) + crc2_ok = 1; + flag2 = tmp_env2->flags; + } + + if (!crc1_ok && !crc2_ok) + goto err_crc; + else if (crc1_ok && !crc2_ok) { + gd->env_valid = 1; + ep = tmp_env1; + } else if (!crc1_ok && crc2_ok) { + gd->env_valid = 1; + ep = tmp_env2; + swap_env(); + } else if (flag1 == ACTIVE_FLAG && flag2 == OBSOLETE_FLAG) { + gd->env_valid = 1; + ep = tmp_env1; + } else if (flag1 == OBSOLETE_FLAG && flag2 == ACTIVE_FLAG) { + gd->env_valid = 1; + ep = tmp_env2; + swap_env(); + } else if (flag1 == flag2) { + gd->env_valid = 2; + ep = tmp_env1; + current_env = 1; + } else if (flag1 == 0xFF) { + gd->env_valid = 2; + ep = tmp_env1; + current_env = 1; + } else { + /* + * this differs from code in env_flash.c, but I think a sane + * default path is desirable. + */ + gd->env_valid = 2; + ep = tmp_env2; + swap_env(); + current_env = 2; + } + + rc = env_import((char *)ep, 0); + if (!rc) { + error("Cannot import environment: errno = %d\n", errno); + goto out; + } + + if (current_env == 1) { + if (flag2 != OBSOLETE_FLAG) { + flag2 = OBSOLETE_FLAG; + spi_flash_write(env_flash, + env_new_offset + offsetof(env_t, flags), + sizeof(env_new.flags), &flag2); + } + if (flag1 != ACTIVE_FLAG) { + flag1 = ACTIVE_FLAG; + spi_flash_write(env_flash, + env_offset + offsetof(env_t, flags), + sizeof(env_new.flags), &flag1); + } + } else if (current_env == 2) { + if (flag1 != OBSOLETE_FLAG) { + flag1 = OBSOLETE_FLAG; + spi_flash_write(env_flash, + env_new_offset + offsetof(env_t, flags), + sizeof(env_new.flags), &flag1); + } + if (flag2 != ACTIVE_FLAG) { + flag2 = ACTIVE_FLAG; + spi_flash_write(env_flash, + env_offset + offsetof(env_t, flags), + sizeof(env_new.flags), &flag2); + } + } + if (gd->env_valid == 2) { + puts("*** Warning - some problems detected " + "reading environment; recovered successfully\n\n"); + } + if (tmp_env1) + free(tmp_env1); + if (tmp_env2) + free(tmp_env2); + return; + +err_read: + spi_flash_free(env_flash); + env_flash = NULL; +out: + free(tmp_env1); + free(tmp_env2); +} +#else int saveenv(void) { u32 saved_size, saved_offset; @@ -117,33 +364,32 @@ int saveenv(void) void env_relocate_spec(void) { + char buf[CONFIG_ENV_SIZE]; int ret; env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); - if (!env_flash) - goto err_probe; - - ret = spi_flash_read(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, env_ptr); - if (ret) - goto err_read; - - if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) - goto err_crc; + if (!env_flash) { + set_default_env("!spi_flash_probe() failed"); + return; + } - gd->env_valid = 1; + ret = spi_flash_read(env_flash, + CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, buf); + if (ret) { + set_default_env("!spi_flash_read() failed"); + goto out; + } - return; + ret = env_import(buf, 1); -err_read: + if (ret) + gd->env_valid = 1; +out: spi_flash_free(env_flash); env_flash = NULL; -err_probe: -err_crc: - puts("*** Warning - bad CRC, using default environment\n\n"); - - set_default_env(); } +#endif int env_init(void) { diff --git a/common/exports.c b/common/exports.c index 60bba75..3dff735 100644 --- a/common/exports.c +++ b/common/exports.c @@ -3,7 +3,7 @@ DECLARE_GLOBAL_DATA_PTR; -static void dummy(void) +__attribute__((unused)) static void dummy(void) { } @@ -34,9 +34,6 @@ unsigned long get_version(void) # define spi_release_bus dummy # define spi_xfer dummy #endif -#ifndef CONFIG_HAS_UID -# define forceenv dummy -#endif void jumptable_init(void) { diff --git a/common/fdt_support.c b/common/fdt_support.c index f89a3ee..5829afd 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -2,6 +2,8 @@ * (C) Copyright 2007 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com * + * Copyright 2010 Freescale Semiconductor, Inc. + * * See file CREDITS for list of people who contributed to this * project. * @@ -360,11 +362,40 @@ void do_fixup_by_compat_u32(void *fdt, const char *compat, do_fixup_by_compat(fdt, compat, prop, &val, 4, create); } -int fdt_fixup_memory(void *blob, u64 start, u64 size) +/* + * Get cells len in bytes + * if #NNNN-cells property is 2 then len is 8 + * otherwise len is 4 + */ +static int get_cells_len(void *blob, char *nr_cells_name) +{ + const u32 *cell; + + cell = fdt_getprop(blob, 0, nr_cells_name, NULL); + if (cell && *cell == 2) + return 8; + + return 4; +} + +/* + * Write a 4 or 8 byte big endian cell + */ +static void write_cell(u8 *addr, u64 val, int size) +{ + int shift = (size - 1) * 8; + while (size-- > 0) { + *addr++ = (val >> shift) & 0xff; + shift -= 8; + } +} + +int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks) { - int err, nodeoffset, len = 0; - u8 tmp[16]; - const u32 *addrcell, *sizecell; + int err, nodeoffset; + int addr_cell_len, size_cell_len, len; + u8 tmp[banks * 8]; + int bank; err = fdt_check_header(blob); if (err < 0) { @@ -389,44 +420,15 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) return err; } - addrcell = fdt_getprop(blob, 0, "#address-cells", NULL); - /* use shifts and mask to ensure endianness */ - if ((addrcell) && (*addrcell == 2)) { - tmp[0] = (start >> 56) & 0xff; - tmp[1] = (start >> 48) & 0xff; - tmp[2] = (start >> 40) & 0xff; - tmp[3] = (start >> 32) & 0xff; - tmp[4] = (start >> 24) & 0xff; - tmp[5] = (start >> 16) & 0xff; - tmp[6] = (start >> 8) & 0xff; - tmp[7] = (start ) & 0xff; - len = 8; - } else { - tmp[0] = (start >> 24) & 0xff; - tmp[1] = (start >> 16) & 0xff; - tmp[2] = (start >> 8) & 0xff; - tmp[3] = (start ) & 0xff; - len = 4; - } - - sizecell = fdt_getprop(blob, 0, "#size-cells", NULL); - /* use shifts and mask to ensure endianness */ - if ((sizecell) && (*sizecell == 2)) { - tmp[0+len] = (size >> 56) & 0xff; - tmp[1+len] = (size >> 48) & 0xff; - tmp[2+len] = (size >> 40) & 0xff; - tmp[3+len] = (size >> 32) & 0xff; - tmp[4+len] = (size >> 24) & 0xff; - tmp[5+len] = (size >> 16) & 0xff; - tmp[6+len] = (size >> 8) & 0xff; - tmp[7+len] = (size ) & 0xff; - len += 8; - } else { - tmp[0+len] = (size >> 24) & 0xff; - tmp[1+len] = (size >> 16) & 0xff; - tmp[2+len] = (size >> 8) & 0xff; - tmp[3+len] = (size ) & 0xff; - len += 4; + addr_cell_len = get_cells_len(blob, "#address-cells"); + size_cell_len = get_cells_len(blob, "#size-cells"); + + for (bank = 0, len = 0; bank < banks; bank++) { + write_cell(tmp + len, start[bank], addr_cell_len); + len += addr_cell_len; + + write_cell(tmp + len, size[bank], size_cell_len); + len += size_cell_len; } err = fdt_setprop(blob, nodeoffset, "reg", tmp, len); @@ -438,6 +440,11 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) return 0; } +int fdt_fixup_memory(void *blob, u64 start, u64 size) +{ + return fdt_fixup_memory_banks(blob, &start, &size, 1); +} + void fdt_fixup_ethernet(void *fdt) { int node, i, j; @@ -474,134 +481,6 @@ void fdt_fixup_ethernet(void *fdt) } } -#ifdef CONFIG_HAS_FSL_DR_USB -void fdt_fixup_dr_usb(void *blob, bd_t *bd) -{ - char *mode; - char *type; - const char *compat = "fsl-usb2-dr"; - const char *prop_mode = "dr_mode"; - const char *prop_type = "phy_type"; - int node_offset; - int err; - - mode = getenv("usb_dr_mode"); - type = getenv("usb_phy_type"); - if (!mode && !type) - return; - - node_offset = fdt_node_offset_by_compatible(blob, 0, compat); - if (node_offset < 0) { - printf("WARNING: could not find compatible node %s: %s.\n", - compat, fdt_strerror(node_offset)); - return; - } - - if (mode) { - err = fdt_setprop(blob, node_offset, prop_mode, mode, - strlen(mode) + 1); - if (err < 0) - printf("WARNING: could not set %s for %s: %s.\n", - prop_mode, compat, fdt_strerror(err)); - } - - if (type) { - err = fdt_setprop(blob, node_offset, prop_type, type, - strlen(type) + 1); - if (err < 0) - printf("WARNING: could not set %s for %s: %s.\n", - prop_type, compat, fdt_strerror(err)); - } -} -#endif /* CONFIG_HAS_FSL_DR_USB */ - -#if defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) -/* - * update crypto node properties to a specified revision of the SEC - * called with sec_rev == 0 if not on an mpc8xxxE processor - */ -void fdt_fixup_crypto_node(void *blob, int sec_rev) -{ - const struct sec_rev_prop { - u32 sec_rev; - u32 num_channels; - u32 channel_fifo_len; - u32 exec_units_mask; - u32 descriptor_types_mask; - } sec_rev_prop_list [] = { - { 0x0200, 4, 24, 0x07e, 0x01010ebf }, /* SEC 2.0 */ - { 0x0201, 4, 24, 0x0fe, 0x012b0ebf }, /* SEC 2.1 */ - { 0x0202, 1, 24, 0x04c, 0x0122003f }, /* SEC 2.2 */ - { 0x0204, 4, 24, 0x07e, 0x012b0ebf }, /* SEC 2.4 */ - { 0x0300, 4, 24, 0x9fe, 0x03ab0ebf }, /* SEC 3.0 */ - { 0x0303, 4, 24, 0x97c, 0x03ab0abf }, /* SEC 3.3 */ - }; - char compat_strlist[ARRAY_SIZE(sec_rev_prop_list) * - sizeof("fsl,secX.Y")]; - int crypto_node, sec_idx, err; - char *p; - u32 val; - - /* locate crypto node based on lowest common compatible */ - crypto_node = fdt_node_offset_by_compatible(blob, -1, "fsl,sec2.0"); - if (crypto_node == -FDT_ERR_NOTFOUND) - return; - - /* delete it if not on an E-processor */ - if (crypto_node > 0 && !sec_rev) { - fdt_del_node(blob, crypto_node); - return; - } - - /* else we got called for possible uprev */ - for (sec_idx = 0; sec_idx < ARRAY_SIZE(sec_rev_prop_list); sec_idx++) - if (sec_rev_prop_list[sec_idx].sec_rev == sec_rev) - break; - - if (sec_idx == ARRAY_SIZE(sec_rev_prop_list)) { - puts("warning: unknown SEC revision number\n"); - return; - } - - val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].num_channels); - err = fdt_setprop(blob, crypto_node, "fsl,num-channels", &val, 4); - if (err < 0) - printf("WARNING: could not set crypto property: %s\n", - fdt_strerror(err)); - - val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].descriptor_types_mask); - err = fdt_setprop(blob, crypto_node, "fsl,descriptor-types-mask", &val, 4); - if (err < 0) - printf("WARNING: could not set crypto property: %s\n", - fdt_strerror(err)); - - val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].exec_units_mask); - err = fdt_setprop(blob, crypto_node, "fsl,exec-units-mask", &val, 4); - if (err < 0) - printf("WARNING: could not set crypto property: %s\n", - fdt_strerror(err)); - - val = cpu_to_fdt32(sec_rev_prop_list[sec_idx].channel_fifo_len); - err = fdt_setprop(blob, crypto_node, "fsl,channel-fifo-len", &val, 4); - if (err < 0) - printf("WARNING: could not set crypto property: %s\n", - fdt_strerror(err)); - - val = 0; - while (sec_idx >= 0) { - p = compat_strlist + val; - val += sprintf(p, "fsl,sec%d.%d", - (sec_rev_prop_list[sec_idx].sec_rev & 0xff00) >> 8, - sec_rev_prop_list[sec_idx].sec_rev & 0x00ff) + 1; - sec_idx--; - } - err = fdt_setprop(blob, crypto_node, "compatible", &compat_strlist, val); - if (err < 0) - printf("WARNING: could not set crypto property: %s\n", - fdt_strerror(err)); -} -#endif /* defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) */ - /* Resize the fdt to its actual size + a bit of padding */ int fdt_resize(void *blob) { @@ -624,11 +503,12 @@ int fdt_resize(void *blob) /* * Calculate the actual size of the fdt - * plus the size needed for two fdt_add_mem_rsv, one - * for the fdt itself and one for a possible initrd + * plus the size needed for 5 fdt_add_mem_rsv, one + * for the fdt itself and 4 for a possible initrd + * ((initrd-start + initrd-end) * 2 (name & value)) */ actualsize = fdt_off_dt_strings(blob) + - fdt_size_dt_strings(blob) + 2*sizeof(struct fdt_reserve_entry); + fdt_size_dt_strings(blob) + 5 * sizeof(struct fdt_reserve_entry); /* Make it so the fdt ends on a page boundary */ actualsize = ALIGN(actualsize + ((uint)blob & 0xfff), 0x1000); @@ -716,36 +596,70 @@ int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose) { #ifdef CONFIG_FDT_FIXUP_NOR_FLASH_SIZE /* + * Provide a weak default function to return the flash bank size. + * There might be multiple non-identical flash chips connected to one + * chip-select, so we need to pass an index as well. + */ +u32 __flash_get_bank_size(int cs, int idx) +{ + extern flash_info_t flash_info[]; + + /* + * As default, a simple 1:1 mapping is provided. Boards with + * a different mapping need to supply a board specific mapping + * routine. + */ + return flash_info[cs].size; +} +u32 flash_get_bank_size(int cs, int idx) + __attribute__((weak, alias("__flash_get_bank_size"))); + +/* * This function can be used to update the size in the "reg" property - * of the NOR FLASH device nodes. This is necessary for boards with + * of all NOR FLASH device nodes. This is necessary for boards with * non-fixed NOR FLASH sizes. */ -int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size) +int fdt_fixup_nor_flash_size(void *blob) { char compat[][16] = { "cfi-flash", "jedec-flash" }; int off; int len; struct fdt_property *prop; - u32 *reg; + u32 *reg, *reg2; int i; for (i = 0; i < 2; i++) { off = fdt_node_offset_by_compatible(blob, -1, compat[i]); while (off != -FDT_ERR_NOTFOUND) { + int idx; + /* - * Found one compatible node, now check if this one - * has the correct CS + * Found one compatible node, so fixup the size + * int its reg properties */ prop = fdt_get_property_w(blob, off, "reg", &len); if (prop) { - reg = (u32 *)&prop->data[0]; - if (reg[0] == cs) { - reg[2] = size; - fdt_setprop(blob, off, "reg", reg, - 3 * sizeof(u32)); - - return 0; + int tuple_size = 3 * sizeof(reg); + + /* + * There might be multiple reg-tuples, + * so loop through them all + */ + reg = reg2 = (u32 *)&prop->data[0]; + for (idx = 0; idx < (len / tuple_size); idx++) { + /* + * Update size in reg property + */ + reg[2] = flash_get_bank_size(reg[0], + idx); + + /* + * Point to next reg tuple + */ + reg += 3; } + + fdt_setprop(blob, off, "reg", reg2, len); } /* Move to next compatible node */ @@ -754,6 +668,558 @@ int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size) } } - return -1; + return 0; +} +#endif + +int fdt_increase_size(void *fdt, int add_len) +{ + int newlen; + + newlen = fdt_totalsize(fdt) + add_len; + + /* Open in place with a new len */ + return fdt_open_into(fdt, fdt, newlen); +} + +#ifdef CONFIG_FDT_FIXUP_PARTITIONS +#include <jffs2/load_kernel.h> +#include <mtd_node.h> + +struct reg_cell { + unsigned int r0; + unsigned int r1; +}; + +int fdt_del_subnodes(const void *blob, int parent_offset) +{ + int off, ndepth; + int ret; + + for (ndepth = 0, off = fdt_next_node(blob, parent_offset, &ndepth); + (off >= 0) && (ndepth > 0); + off = fdt_next_node(blob, off, &ndepth)) { + if (ndepth == 1) { + debug("delete %s: offset: %x\n", + fdt_get_name(blob, off, 0), off); + ret = fdt_del_node((void *)blob, off); + if (ret < 0) { + printf("Can't delete node: %s\n", + fdt_strerror(ret)); + return ret; + } else { + ndepth = 0; + off = parent_offset; + } + } + } + return 0; +} + +int fdt_del_partitions(void *blob, int parent_offset) +{ + const void *prop; + int ndepth = 0; + int off; + int ret; + + off = fdt_next_node(blob, parent_offset, &ndepth); + if (off > 0 && ndepth == 1) { + prop = fdt_getprop(blob, off, "label", NULL); + if (prop == NULL) { + /* + * Could not find label property, nand {}; node? + * Check subnode, delete partitions there if any. + */ + return fdt_del_partitions(blob, off); + } else { + ret = fdt_del_subnodes(blob, parent_offset); + if (ret < 0) { + printf("Can't remove subnodes: %s\n", + fdt_strerror(ret)); + return ret; + } + } + } + return 0; +} + +int fdt_node_set_part_info(void *blob, int parent_offset, + struct mtd_device *dev) +{ + struct list_head *pentry; + struct part_info *part; + struct reg_cell cell; + int off, ndepth = 0; + int part_num, ret; + char buf[64]; + + ret = fdt_del_partitions(blob, parent_offset); + if (ret < 0) + return ret; + + /* + * Check if it is nand {}; subnode, adjust + * the offset in this case + */ + off = fdt_next_node(blob, parent_offset, &ndepth); + if (off > 0 && ndepth == 1) + parent_offset = off; + + part_num = 0; + list_for_each_prev(pentry, &dev->parts) { + int newoff; + + part = list_entry(pentry, struct part_info, link); + + debug("%2d: %-20s0x%08x\t0x%08x\t%d\n", + part_num, part->name, part->size, + part->offset, part->mask_flags); + + sprintf(buf, "partition@%x", part->offset); +add_sub: + ret = fdt_add_subnode(blob, parent_offset, buf); + if (ret == -FDT_ERR_NOSPACE) { + ret = fdt_increase_size(blob, 512); + if (!ret) + goto add_sub; + else + goto err_size; + } else if (ret < 0) { + printf("Can't add partition node: %s\n", + fdt_strerror(ret)); + return ret; + } + newoff = ret; + + /* Check MTD_WRITEABLE_CMD flag */ + if (part->mask_flags & 1) { +add_ro: + ret = fdt_setprop(blob, newoff, "read_only", NULL, 0); + if (ret == -FDT_ERR_NOSPACE) { + ret = fdt_increase_size(blob, 512); + if (!ret) + goto add_ro; + else + goto err_size; + } else if (ret < 0) + goto err_prop; + } + + cell.r0 = cpu_to_fdt32(part->offset); + cell.r1 = cpu_to_fdt32(part->size); +add_reg: + ret = fdt_setprop(blob, newoff, "reg", &cell, sizeof(cell)); + if (ret == -FDT_ERR_NOSPACE) { + ret = fdt_increase_size(blob, 512); + if (!ret) + goto add_reg; + else + goto err_size; + } else if (ret < 0) + goto err_prop; + +add_label: + ret = fdt_setprop_string(blob, newoff, "label", part->name); + if (ret == -FDT_ERR_NOSPACE) { + ret = fdt_increase_size(blob, 512); + if (!ret) + goto add_label; + else + goto err_size; + } else if (ret < 0) + goto err_prop; + + part_num++; + } + return 0; +err_size: + printf("Can't increase blob size: %s\n", fdt_strerror(ret)); + return ret; +err_prop: + printf("Can't add property: %s\n", fdt_strerror(ret)); + return ret; +} + +/* + * Update partitions in nor/nand nodes using info from + * mtdparts environment variable. The nodes to update are + * specified by node_info structure which contains mtd device + * type and compatible string: E. g. the board code in + * ft_board_setup() could use: + * + * struct node_info nodes[] = { + * { "fsl,mpc5121-nfc", MTD_DEV_TYPE_NAND, }, + * { "cfi-flash", MTD_DEV_TYPE_NOR, }, + * }; + * + * fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); + */ +void fdt_fixup_mtdparts(void *blob, void *node_info, int node_info_size) +{ + struct node_info *ni = node_info; + struct mtd_device *dev; + char *parts; + int i, idx; + int noff; + + parts = getenv("mtdparts"); + if (!parts) + return; + + if (mtdparts_init() != 0) + return; + + for (i = 0; i < node_info_size; i++) { + idx = 0; + noff = fdt_node_offset_by_compatible(blob, -1, ni[i].compat); + while (noff != -FDT_ERR_NOTFOUND) { + debug("%s: %s, mtd dev type %d\n", + fdt_get_name(blob, noff, 0), + ni[i].compat, ni[i].type); + dev = device_find(ni[i].type, idx++); + if (dev) { + if (fdt_node_set_part_info(blob, noff, dev)) + return; /* return on error */ + } + + /* Jump to next flash node */ + noff = fdt_node_offset_by_compatible(blob, noff, + ni[i].compat); + } + } +} +#endif + +void fdt_del_node_and_alias(void *blob, const char *alias) +{ + int off = fdt_path_offset(blob, alias); + + if (off < 0) + return; + + fdt_del_node(blob, off); + + off = fdt_path_offset(blob, "/aliases"); + fdt_delprop(blob, off, alias); +} + +/* Helper to read a big number; size is in cells (not bytes) */ +static inline u64 of_read_number(const __be32 *cell, int size) +{ + u64 r = 0; + while (size--) + r = (r << 32) | be32_to_cpu(*(cell++)); + return r; +} + +#define PRu64 "%llx" + +/* Max address size we deal with */ +#define OF_MAX_ADDR_CELLS 4 +#define OF_BAD_ADDR ((u64)-1) +#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ + (ns) > 0) + +/* Debug utility */ +#ifdef DEBUG +static void of_dump_addr(const char *s, const u32 *addr, int na) +{ + printf("%s", s); + while(na--) + printf(" %08x", *(addr++)); + printf("\n"); +} +#else +static void of_dump_addr(const char *s, const u32 *addr, int na) { } +#endif + +/* Callbacks for bus specific translators */ +struct of_bus { + const char *name; + const char *addresses; + void (*count_cells)(void *blob, int parentoffset, + int *addrc, int *sizec); + u64 (*map)(u32 *addr, const u32 *range, + int na, int ns, int pna); + int (*translate)(u32 *addr, u64 offset, int na); +}; + +/* Default translator (generic bus) */ +static void of_bus_default_count_cells(void *blob, int parentoffset, + int *addrc, int *sizec) +{ + const u32 *prop; + + if (addrc) { + prop = fdt_getprop(blob, parentoffset, "#address-cells", NULL); + if (prop) + *addrc = be32_to_cpup(prop); + else + *addrc = 2; + } + + if (sizec) { + prop = fdt_getprop(blob, parentoffset, "#size-cells", NULL); + if (prop) + *sizec = be32_to_cpup(prop); + else + *sizec = 1; + } +} + +static u64 of_bus_default_map(u32 *addr, const u32 *range, + int na, int ns, int pna) +{ + u64 cp, s, da; + + cp = of_read_number(range, na); + s = of_read_number(range + na + pna, ns); + da = of_read_number(addr, na); + + debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n", + cp, s, da); + + if (da < cp || da >= (cp + s)) + return OF_BAD_ADDR; + return da - cp; +} + +static int of_bus_default_translate(u32 *addr, u64 offset, int na) +{ + u64 a = of_read_number(addr, na); + memset(addr, 0, na * 4); + a += offset; + if (na > 1) + addr[na - 2] = a >> 32; + addr[na - 1] = a & 0xffffffffu; + + return 0; +} + +/* Array of bus specific translators */ +static struct of_bus of_busses[] = { + /* Default */ + { + .name = "default", + .addresses = "reg", + .count_cells = of_bus_default_count_cells, + .map = of_bus_default_map, + .translate = of_bus_default_translate, + }, +}; + +static int of_translate_one(void * blob, int parent, struct of_bus *bus, + struct of_bus *pbus, u32 *addr, + int na, int ns, int pna, const char *rprop) +{ + const u32 *ranges; + int rlen; + int rone; + u64 offset = OF_BAD_ADDR; + + /* Normally, an absence of a "ranges" property means we are + * crossing a non-translatable boundary, and thus the addresses + * below the current not cannot be converted to CPU physical ones. + * Unfortunately, while this is very clear in the spec, it's not + * what Apple understood, and they do have things like /uni-n or + * /ht nodes with no "ranges" property and a lot of perfectly + * useable mapped devices below them. Thus we treat the absence of + * "ranges" as equivalent to an empty "ranges" property which means + * a 1:1 translation at that level. It's up to the caller not to try + * to translate addresses that aren't supposed to be translated in + * the first place. --BenH. + */ + ranges = (u32 *)fdt_getprop(blob, parent, rprop, &rlen); + if (ranges == NULL || rlen == 0) { + offset = of_read_number(addr, na); + memset(addr, 0, pna * 4); + debug("OF: no ranges, 1:1 translation\n"); + goto finish; + } + + debug("OF: walking ranges...\n"); + + /* Now walk through the ranges */ + rlen /= 4; + rone = na + pna + ns; + for (; rlen >= rone; rlen -= rone, ranges += rone) { + offset = bus->map(addr, ranges, na, ns, pna); + if (offset != OF_BAD_ADDR) + break; + } + if (offset == OF_BAD_ADDR) { + debug("OF: not found !\n"); + return 1; + } + memcpy(addr, ranges + na, 4 * pna); + + finish: + of_dump_addr("OF: parent translation for:", addr, pna); + debug("OF: with offset: "PRu64"\n", offset); + + /* Translate it into parent bus space */ + return pbus->translate(addr, offset, pna); +} + +/* + * Translate an address from the device-tree into a CPU physical address, + * this walks up the tree and applies the various bus mappings on the + * way. + * + * Note: We consider that crossing any level with #size-cells == 0 to mean + * that translation is impossible (that is we are not dealing with a value + * that can be mapped to a cpu physical address). This is not really specified + * that way, but this is traditionally the way IBM at least do things + */ +u64 __of_translate_address(void *blob, int node_offset, const u32 *in_addr, + const char *rprop) +{ + int parent; + struct of_bus *bus, *pbus; + u32 addr[OF_MAX_ADDR_CELLS]; + int na, ns, pna, pns; + u64 result = OF_BAD_ADDR; + + debug("OF: ** translation for device %s **\n", + fdt_get_name(blob, node_offset, NULL)); + + /* Get parent & match bus type */ + parent = fdt_parent_offset(blob, node_offset); + if (parent < 0) + goto bail; + bus = &of_busses[0]; + + /* Cound address cells & copy address locally */ + bus->count_cells(blob, parent, &na, &ns); + if (!OF_CHECK_COUNTS(na, ns)) { + printf("%s: Bad cell count for %s\n", __FUNCTION__, + fdt_get_name(blob, node_offset, NULL)); + goto bail; + } + memcpy(addr, in_addr, na * 4); + + debug("OF: bus is %s (na=%d, ns=%d) on %s\n", + bus->name, na, ns, fdt_get_name(blob, parent, NULL)); + of_dump_addr("OF: translating address:", addr, na); + + /* Translate */ + for (;;) { + /* Switch to parent bus */ + node_offset = parent; + parent = fdt_parent_offset(blob, node_offset); + + /* If root, we have finished */ + if (parent < 0) { + debug("OF: reached root node\n"); + result = of_read_number(addr, na); + break; + } + + /* Get new parent bus and counts */ + pbus = &of_busses[0]; + pbus->count_cells(blob, parent, &pna, &pns); + if (!OF_CHECK_COUNTS(pna, pns)) { + printf("%s: Bad cell count for %s\n", __FUNCTION__, + fdt_get_name(blob, node_offset, NULL)); + break; + } + + debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n", + pbus->name, pna, pns, fdt_get_name(blob, parent, NULL)); + + /* Apply bus translation */ + if (of_translate_one(blob, node_offset, bus, pbus, + addr, na, ns, pna, rprop)) + break; + + /* Complete the move up one level */ + na = pna; + ns = pns; + bus = pbus; + + of_dump_addr("OF: one level translation:", addr, na); + } + bail: + + return result; +} + +u64 fdt_translate_address(void *blob, int node_offset, const u32 *in_addr) +{ + return __of_translate_address(blob, node_offset, in_addr, "ranges"); +} + +/** + * fdt_node_offset_by_compat_reg: Find a node that matches compatiable and + * who's reg property matches a physical cpu address + * + * @blob: ptr to device tree + * @compat: compatiable string to match + * @compat_off: property name + * + */ +int fdt_node_offset_by_compat_reg(void *blob, const char *compat, + phys_addr_t compat_off) +{ + int len, off = fdt_node_offset_by_compatible(blob, -1, compat); + while (off != -FDT_ERR_NOTFOUND) { + u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", &len); + if (reg) { + if (compat_off == fdt_translate_address(blob, off, reg)) + return off; + } + off = fdt_node_offset_by_compatible(blob, off, compat); + } + + return -FDT_ERR_NOTFOUND; +} + +/** + * fdt_alloc_phandle: Return next free phandle value + * + * @blob: ptr to device tree + */ +int fdt_alloc_phandle(void *blob) +{ + int offset, len, phandle = 0; + const u32 *val; + + for (offset = fdt_next_node(blob, -1, NULL); offset >= 0; + offset = fdt_next_node(blob, offset, NULL)) { + val = fdt_getprop(blob, offset, "linux,phandle", &len); + if (val) + phandle = max(*val, phandle); + } + + return phandle + 1; +} + +#if defined(CONFIG_VIDEO) +int fdt_add_edid(void *blob, const char *compat, unsigned char *edid_buf) +{ + int noff; + int ret; + + noff = fdt_node_offset_by_compatible(blob, -1, compat); + if (noff != -FDT_ERR_NOTFOUND) { + debug("%s: %s\n", fdt_get_name(blob, noff, 0), compat); +add_edid: + ret = fdt_setprop(blob, noff, "edid", edid_buf, 128); + if (ret == -FDT_ERR_NOSPACE) { + ret = fdt_increase_size(blob, 512); + if (!ret) + goto add_edid; + else + goto err_size; + } else if (ret < 0) { + printf("Can't add property: %s\n", fdt_strerror(ret)); + return ret; + } + } + return 0; +err_size: + printf("Can't increase blob size: %s\n", fdt_strerror(ret)); + return ret; } #endif diff --git a/common/flash.c b/common/flash.c index eb4b2f5..781cb9c 100644 --- a/common/flash.c +++ b/common/flash.c @@ -27,6 +27,7 @@ #include <flash.h> #if !defined(CONFIG_SYS_NO_FLASH) +#include <mtd/cfi_flash.h> extern flash_info_t flash_info[]; /* info for FLASH chips */ @@ -43,15 +44,18 @@ extern flash_info_t flash_info[]; /* info for FLASH chips */ void flash_protect (int flag, ulong from, ulong to, flash_info_t *info) { - ulong b_end = info->start[0] + info->size - 1; /* bank end address */ - short s_end = info->sector_count - 1; /* index of last sector */ + ulong b_end; + short s_end; int i; /* Do nothing if input data is bad. */ - if (info->sector_count == 0 || info->size == 0 || to < from) { + if (!info || info->sector_count == 0 || info->size == 0 || to < from) { return; } + s_end = info->sector_count - 1; /* index of last sector */ + b_end = info->start[0] + info->size - 1; /* bank end address */ + debug ("flash_protect %s: from 0x%08lX to 0x%08lX\n", (flag & FLAG_PROTECT_SET) ? "ON" : (flag & FLAG_PROTECT_CLEAR) ? "OFF" : "???", diff --git a/common/hush.c b/common/hush.c index 06c5ff8..4dd9513 100644 --- a/common/hush.c +++ b/common/hush.c @@ -94,7 +94,7 @@ #include <hush.h> #include <command.h> /* find_cmd */ /*cmd_boot.c*/ -extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* do_bootd */ +extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); /* do_bootd */ #endif #ifndef __U_BOOT__ #include <ctype.h> /* isalpha, isdigit */ @@ -1018,13 +1018,13 @@ static void get_user_input(struct in_str *i) fflush(stdout); i->p = the_command; #else - extern char console_buffer[CONFIG_SYS_CBSIZE]; + extern char console_buffer[]; int n; static char the_command[CONFIG_SYS_CBSIZE]; #ifdef CONFIG_BOOT_RETRY_TIME # ifdef CONFIG_RESET_TO_RETRY - extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); # else # error "This currently only works with CONFIG_RESET_TO_RETRY enabled" # endif @@ -1681,7 +1681,7 @@ static int run_pipe_real(struct pipe *pi) } else { int rcode; #if defined(CONFIG_CMD_BOOTD) - extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); /* avoid "bootd" recursion */ if (cmdtp->cmd == do_bootd) { @@ -1694,10 +1694,8 @@ static int run_pipe_real(struct pipe *pi) } #endif /* found - check max args */ - if ((child->argc - i) > cmdtp->maxargs) { - cmd_usage(cmdtp); - return -1; - } + if ((child->argc - i) > cmdtp->maxargs) + return cmd_usage(cmdtp); #endif child->argv+=i; /* XXX horrible hack */ #ifndef __U_BOOT__ @@ -3351,7 +3349,7 @@ static void setup_job_control(void) tcsetpgrp(shell_terminal, shell_pgrp); } -int hush_main(int argc, char **argv) +int hush_main(int argc, char * const *argv) { int opt; FILE *input; @@ -3588,7 +3586,7 @@ static char * make_string(char ** inp) } #ifdef __U_BOOT__ -int do_showvar (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_showvar (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int i, k; int rcode = 0; diff --git a/common/hwconfig.c b/common/hwconfig.c index e5c60ba..1f9f4a0 100644 --- a/common/hwconfig.c +++ b/common/hwconfig.c @@ -11,15 +11,23 @@ * the License, or (at your option) any later version. */ +#ifndef HWCONFIG_TEST #include <config.h> #include <common.h> #include <exports.h> #include <hwconfig.h> #include <linux/types.h> #include <linux/string.h> +#else +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif /* HWCONFIG_TEST */ static const char *hwconfig_parse(const char *opts, size_t maxlen, - const char *opt, char stopch, char eqch, + const char *opt, char *stopchs, char eqch, size_t *arglen) { size_t optlen = strlen(opt); @@ -33,8 +41,9 @@ next: if (end - start > maxlen) return NULL; - if (str && (str == opts || str[-1] == stopch) && - (*end == stopch || *end == eqch || *end == '\0')) { + if (str && (str == opts || strpbrk(str - 1, stopchs) == str - 1) && + (strpbrk(end, stopchs) == end || *end == eqch || + *end == '\0')) { const char *arg_end; if (!arglen) @@ -43,7 +52,7 @@ next: if (*end != eqch) return NULL; - arg_end = strchr(str, stopch); + arg_end = strpbrk(str, stopchs); if (!arg_end) *arglen = min(maxlen, strlen(str)) - optlen - 1; else @@ -66,15 +75,15 @@ static const char *__hwconfig(const char *opt, size_t *arglen) if (env_hwconfig) return hwconfig_parse(env_hwconfig, strlen(env_hwconfig), - opt, ';', ':', arglen); + opt, ";", ':', arglen); if (board_hwconfig) return hwconfig_parse(board_hwconfig, strlen(board_hwconfig), - opt, ';', ':', arglen); + opt, ";", ':', arglen); if (cpu_hwconfig) return hwconfig_parse(cpu_hwconfig, strlen(cpu_hwconfig), - opt, ';', ':', arglen); + opt, ";", ':', arglen); return NULL; } @@ -164,7 +173,7 @@ int hwconfig_sub(const char *opt, const char *subopt) arg = __hwconfig(opt, &arglen); if (!arg) return 0; - return !!hwconfig_parse(arg, arglen, subopt, ',', '=', NULL); + return !!hwconfig_parse(arg, arglen, subopt, ",;", '=', NULL); } /* @@ -185,7 +194,7 @@ const char *hwconfig_subarg(const char *opt, const char *subopt, arg = __hwconfig(opt, &arglen); if (!arg) return NULL; - return hwconfig_parse(arg, arglen, subopt, ',', '=', subarglen); + return hwconfig_parse(arg, arglen, subopt, ",;", '=', subarglen); } /* @@ -208,3 +217,50 @@ int hwconfig_subarg_cmp(const char *opt, const char *subopt, const char *subarg) return !strncmp(argstr, subarg, arglen); } + +#ifdef HWCONFIG_TEST +int main() +{ + const char *ret; + size_t len; + + setenv("hwconfig", "key1:subkey1=value1,subkey2=value2;key2:value3;;;;" + "key3;:,:=;key4", 1); + + ret = hwconfig_arg("key1", &len); + printf("%zd %.*s\n", len, (int)len, ret); + assert(len == 29); + assert(hwconfig_arg_cmp("key1", "subkey1=value1,subkey2=value2")); + assert(!strncmp(ret, "subkey1=value1,subkey2=value2", len)); + + ret = hwconfig_subarg("key1", "subkey1", &len); + printf("%zd %.*s\n", len, (int)len, ret); + assert(len == 6); + assert(hwconfig_subarg_cmp("key1", "subkey1", "value1")); + assert(!strncmp(ret, "value1", len)); + + ret = hwconfig_subarg("key1", "subkey2", &len); + printf("%zd %.*s\n", len, (int)len, ret); + assert(len == 6); + assert(hwconfig_subarg_cmp("key1", "subkey2", "value2")); + assert(!strncmp(ret, "value2", len)); + + ret = hwconfig_arg("key2", &len); + printf("%zd %.*s\n", len, (int)len, ret); + assert(len == 6); + assert(hwconfig_arg_cmp("key2", "value3")); + assert(!strncmp(ret, "value3", len)); + + assert(hwconfig("key3")); + assert(hwconfig_arg("key4", &len) == NULL); + assert(hwconfig_arg("bogus", &len) == NULL); + + unsetenv("hwconfig"); + + assert(hwconfig(NULL) == 0); + assert(hwconfig("") == 0); + assert(hwconfig("key3") == 0); + + return 0; +} +#endif /* HWCONFIG_TEST */ diff --git a/common/image.c b/common/image.c index 9e49713..385464d 100644 --- a/common/image.c +++ b/common/image.c @@ -60,7 +60,7 @@ static int fit_check_ramdisk (const void *fit, int os_noffset, #endif #ifdef CONFIG_CMD_BDI -extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); #endif DECLARE_GLOBAL_DATA_PTR; @@ -84,7 +84,6 @@ static table_entry_t uimage_arch[] = { { IH_ARCH_MICROBLAZE, "microblaze", "MicroBlaze", }, { IH_ARCH_MIPS, "mips", "MIPS", }, { IH_ARCH_MIPS64, "mips64", "MIPS 64 Bit", }, - { IH_ARCH_NIOS, "nios", "NIOS", }, { IH_ARCH_NIOS2, "nios2", "NIOS II", }, { IH_ARCH_PPC, "powerpc", "PowerPC", }, { IH_ARCH_PPC, "ppc", "PowerPC", }, @@ -104,6 +103,7 @@ static table_entry_t uimage_os[] = { { IH_OS_LYNXOS, "lynxos", "LynxOS", }, #endif { IH_OS_NETBSD, "netbsd", "NetBSD", }, + { IH_OS_OSE, "ose", "Enea OSE", }, { IH_OS_RTEMS, "rtems", "RTEMS", }, { IH_OS_U_BOOT, "u-boot", "U-Boot", }, #if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC) @@ -434,22 +434,31 @@ ulong getenv_bootm_low(void) phys_size_t getenv_bootm_size(void) { + phys_size_t tmp; char *s = getenv ("bootm_size"); if (s) { - phys_size_t tmp; tmp = (phys_size_t)simple_strtoull (s, NULL, 16); return tmp; } + s = getenv("bootm_low"); + if (s) + tmp = (phys_size_t)simple_strtoull (s, NULL, 16); + else + tmp = 0; + #if defined(CONFIG_ARM) - return gd->bd->bi_dram[0].size; + return gd->bd->bi_dram[0].size - tmp; #else - return gd->bd->bi_memsize; + return gd->bd->bi_memsize - tmp; #endif } void memmove_wd (void *to, void *from, size_t len, ulong chunksz) { + if (to == from) + return; + #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) while (len > 0) { size_t tail = (len > chunksz) ? chunksz : len; @@ -754,7 +763,7 @@ int genimg_has_config (bootm_headers_t *images) * 1, if ramdisk image is found but corrupted, or invalid * rd_start and rd_end are set to 0 if no ramdisk exists */ -int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, +int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end) { ulong rd_addr, rd_load; @@ -983,7 +992,7 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, return 0; } -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH /** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1072,7 +1081,7 @@ int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, error: return -1; } -#endif /* defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) */ +#endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */ #ifdef CONFIG_OF_LIBFDT static void fdt_error (const char *msg) @@ -1176,6 +1185,7 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) * 0 - success * 1 - failure */ +#if defined(CONFIG_SYS_BOOTMAPSZ) int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, char **of_flat_tree, ulong *of_size) { @@ -1242,7 +1252,7 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, *of_size = of_len; } else { *of_flat_tree = fdt_blob; - of_len = (CONFIG_SYS_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob; + of_len = *of_size + CONFIG_SYS_FDT_PAD; lmb_reserve(lmb, (ulong)fdt_blob, of_len); fdt_set_totalsize(*of_flat_tree, of_len); @@ -1255,6 +1265,7 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, error: return 1; } +#endif /* CONFIG_SYS_BOOTMAPSZ */ /** * boot_get_fdt - main fdt handling routine @@ -1277,7 +1288,7 @@ error: * 1, if fdt image is found but corrupted * of_flat_tree and of_size are set to 0 if no fdt exists */ -int boot_get_fdt (int flag, int argc, char *argv[], bootm_headers_t *images, +int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size) { const image_header_t *fdt_hdr; @@ -1550,7 +1561,7 @@ int boot_get_fdt (int flag, int argc, char *argv[], bootm_headers_t *images, goto error; } - if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { + if (fdt_totalsize(fdt_blob) != fdt_len) { fdt_error ("fdt size != image size"); goto error; } @@ -1564,7 +1575,7 @@ int boot_get_fdt (int flag, int argc, char *argv[], bootm_headers_t *images, } *of_flat_tree = fdt_blob; - *of_size = be32_to_cpu (fdt_totalsize (fdt_blob)); + *of_size = fdt_totalsize(fdt_blob); debug (" of_flat_tree at 0x%08lx size 0x%08lx\n", (ulong)*of_flat_tree, *of_size); @@ -1577,7 +1588,7 @@ error: } #endif /* CONFIG_OF_LIBFDT */ -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#ifdef CONFIG_SYS_BOOT_GET_CMDLINE /** * boot_get_cmdline - allocate and initialize kernel cmdline * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1619,7 +1630,9 @@ int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, return 0; } +#endif /* CONFIG_SYS_BOOT_GET_CMDLINE */ +#ifdef CONFIG_SYS_BOOT_GET_KBD /** * boot_get_kbd - allocate and initialize kernel copy of board info * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1652,7 +1665,7 @@ int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base) return 0; } -#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* CONFIG_SYS_BOOT_GET_KBD */ #endif /* !USE_HOSTCC */ #if defined(CONFIG_FIT) diff --git a/common/kgdb.c b/common/kgdb.c index 0531452..8a621ad 100644 --- a/common/kgdb.c +++ b/common/kgdb.c @@ -1,4 +1,4 @@ -/* taken from arch/ppc/kernel/ppc-stub.c */ +/* taken from arch/powerpc/kernel/ppc-stub.c */ /**************************************************************************** @@ -584,7 +584,7 @@ breakpoint(void) } int -do_kgdb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_kgdb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { printf("Entering KGDB mode via exception handler...\n\n"); kgdb_breakpoint(argc - 1, argv + 1); diff --git a/common/lcd.c b/common/lcd.c index 64fb1c6..d854c21 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -41,7 +41,7 @@ #include <lcd.h> #include <watchdog.h> -#if defined(CONFIG_PXA250) +#if defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS #include <asm/byteorder.h> #endif @@ -78,7 +78,7 @@ static inline void lcd_putc_xy (ushort x, ushort y, uchar c); static int lcd_init (void *lcdbase); -static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); +static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]); static void *lcd_logo (void); static int lcd_getbgcolor (void); @@ -350,7 +350,7 @@ int drv_lcd_init (void) } /*----------------------------------------------------------------------*/ -static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { #if LCD_BPP == LCD_MONOCHROME /* Setting the palette */ @@ -503,7 +503,7 @@ void bitmap_plot (int x, int y) uchar *bmap; uchar *fb; ushort *fb16; -#if defined(CONFIG_PXA250) +#if defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS struct pxafb_info *fbi = &panel_info.pxa; #elif defined(CONFIG_MPC823) volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; @@ -519,7 +519,7 @@ void bitmap_plot (int x, int y) if (NBITS(panel_info.vl_bpix) < 12) { /* Leave room for default color map */ -#if defined(CONFIG_PXA250) +#if defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS cmap = (ushort *)fbi->palette; #elif defined(CONFIG_MPC823) cmap = (ushort *)&(cp->lcd_cmap[BMP_LOGO_OFFSET*sizeof(ushort)]); @@ -615,7 +615,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) unsigned long pwidth = panel_info.vl_col; unsigned colors, bpix, bmp_bpix; unsigned long compression; -#if defined(CONFIG_PXA250) +#if defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS struct pxafb_info *fbi = &panel_info.pxa; #elif defined(CONFIG_MPC823) volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; @@ -656,7 +656,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) #if !defined(CONFIG_MCC200) /* MCC200 LCD doesn't need CMAP, supports 1bpp b&w only */ if (bmp_bpix == 8) { -#if defined(CONFIG_PXA250) +#if defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS cmap = (ushort *)fbi->palette; #elif defined(CONFIG_MPC823) cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]); @@ -745,7 +745,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) WATCHDOG_RESET(); for (j = 0; j < width; j++) { if (bpix != 16) { -#if defined(CONFIG_PXA250) || defined(CONFIG_ATMEL_LCD) +#if defined CONFIG_PXA250 || defined CONFIG_PXA27X || defined CONFIG_CPU_MONAHANS || defined(CONFIG_ATMEL_LCD) *(fb++) = *(bmap++); #elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200) *(fb++) = 255 - *(bmap++); diff --git a/common/main.c b/common/main.c index c860b0b..d97ccd7 100644 --- a/common/main.c +++ b/common/main.c @@ -51,10 +51,10 @@ void inline __show_boot_progress (int val) {} void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress"))); #if defined(CONFIG_BOOT_RETRY_TIME) && defined(CONFIG_RESET_TO_RETRY) -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* for do_reset() prototype */ +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); /* for do_reset() prototype */ #endif -extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); #if defined(CONFIG_UPDATE_TFTP) void update_tftp (void); @@ -68,7 +68,7 @@ static int abortboot(int); #undef DEBUG_PARSER -char console_buffer[CONFIG_SYS_CBSIZE]; /* console I/O buffer */ +char console_buffer[CONFIG_SYS_CBSIZE + 1]; /* console I/O buffer */ static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen); static char erase_seq[] = "\b \b"; /* erase sequence */ @@ -427,14 +427,7 @@ void main_loop (void) } } #endif /* CONFIG_MENUKEY */ -#endif /* CONFIG_BOOTDELAY */ - -#ifdef CONFIG_AMIGAONEG3SE - { - extern void video_banner(void); - video_banner(); - } -#endif +#endif /* CONFIG_BOOTDELAY */ /* * Main Loop for Monitor Command Processing @@ -525,9 +518,6 @@ void reset_cmd_timeout(void) } while (0) #define CTL_CH(c) ((c) - 'a' + 1) - -#define MAX_CMDBUF_SIZE 256 - #define CTL_BACKSPACE ('\b') #define DEL ((char)255) #define DEL7 ((char)127) @@ -538,7 +528,7 @@ void reset_cmd_timeout(void) #define getcmd_cbeep() getcmd_putch('\a') #define HIST_MAX 20 -#define HIST_SIZE MAX_CMDBUF_SIZE +#define HIST_SIZE CONFIG_SYS_CBSIZE static int hist_max = 0; static int hist_add_idx = 0; @@ -546,7 +536,7 @@ static int hist_cur = -1; unsigned hist_num = 0; char* hist_list[HIST_MAX]; -char hist_lines[HIST_MAX][HIST_SIZE]; +char hist_lines[HIST_MAX][HIST_SIZE + 1]; /* Save room for NULL */ #define add_idx_minus_one() ((hist_add_idx == 0) ? hist_max : hist_add_idx-1) @@ -650,12 +640,10 @@ static void cread_print_hist_list(void) #define ERASE_TO_EOL() { \ if (num < eol_num) { \ - int tmp; \ - for (tmp = num; tmp < eol_num; tmp++) \ - getcmd_putch(' '); \ - while (tmp-- > num) \ + printf("%*s", (int)(eol_num - num), ""); \ + do { \ getcmd_putch(CTL_BACKSPACE); \ - eol_num = num; \ + } while (--eol_num > num); \ } \ } @@ -730,6 +718,7 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len) while (!tstc()) { /* while no incoming data */ if (retry_time >= 0 && get_ticks() > endtime) return (-2); /* timed out */ + WATCHDOG_RESET(); } #endif @@ -955,7 +944,7 @@ int readline_into_buffer (const char *const prompt, char * buffer) { char *p = buffer; #ifdef CONFIG_CMDLINE_EDITING - unsigned int len=MAX_CMDBUF_SIZE; + unsigned int len = CONFIG_SYS_CBSIZE; int rc; static int initted = 0; @@ -997,6 +986,7 @@ int readline_into_buffer (const char *const prompt, char * buffer) while (!tstc()) { /* while no incoming data */ if (retry_time >= 0 && get_ticks() > endtime) return (-2); /* timed out */ + WATCHDOG_RESET(); } #endif WATCHDOG_RESET(); /* Trigger watchdog, if needed */ @@ -1005,6 +995,7 @@ int readline_into_buffer (const char *const prompt, char * buffer) while (!tstc()) { extern void show_activity(int arg); show_activity(0); + WATCHDOG_RESET(); } #endif c = getc(); @@ -1418,14 +1409,12 @@ int run_command (const char *cmd, int flag) /****************************************************************************/ #if defined(CONFIG_CMD_RUN) -int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { int i; - if (argc < 2) { - cmd_usage(cmdtp); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); for (i=1; i<argc; ++i) { char *arg; diff --git a/common/miiphyutil.c b/common/miiphyutil.c index 4b186dd..9cf845f 100644 --- a/common/miiphyutil.c +++ b/common/miiphyutil.c @@ -46,21 +46,45 @@ struct mii_dev { struct list_head link; - char *name; - int (*read) (char *devname, unsigned char addr, + const char *name; + int (*read) (const char *devname, unsigned char addr, unsigned char reg, unsigned short *value); - int (*write) (char *devname, unsigned char addr, + int (*write) (const char *devname, unsigned char addr, unsigned char reg, unsigned short value); }; static struct list_head mii_devs; static struct mii_dev *current_mii; +/* + * Lookup the mii_dev struct by the registered device name. + */ +static struct mii_dev *miiphy_get_dev_by_name(const char *devname, int quiet) +{ + struct list_head *entry; + struct mii_dev *dev; + + if (!devname) { + printf("NULL device name!\n"); + return NULL; + } + + list_for_each(entry, &mii_devs) { + dev = list_entry(entry, struct mii_dev, link); + if (strcmp(dev->name, devname) == 0) + return dev; + } + + if (!quiet) + printf("No such device: %s\n", devname); + return NULL; +} + /***************************************************************************** * * Initialize global data. Need to be called before any other miiphy routine. */ -void miiphy_init () +void miiphy_init(void) { INIT_LIST_HEAD (&mii_devs); current_mii = NULL; @@ -70,25 +94,21 @@ void miiphy_init () * * Register read and write MII access routines for the device <name>. */ -void miiphy_register (char *name, - int (*read) (char *devname, unsigned char addr, +void miiphy_register(const char *name, + int (*read) (const char *devname, unsigned char addr, unsigned char reg, unsigned short *value), - int (*write) (char *devname, unsigned char addr, + int (*write) (const char *devname, unsigned char addr, unsigned char reg, unsigned short value)) { - struct list_head *entry; struct mii_dev *new_dev; - struct mii_dev *miidev; unsigned int name_len; + char *new_name; /* check if we have unique name */ - list_for_each (entry, &mii_devs) { - miidev = list_entry (entry, struct mii_dev, link); - if (strcmp (miidev->name, name) == 0) { - printf ("miiphy_register: non unique device name " - "'%s'\n", name); - return; - } + new_dev = miiphy_get_dev_by_name(name, 1); + if (new_dev) { + printf("miiphy_register: non unique device name '%s'\n", name); + return; } /* allocate memory */ @@ -107,9 +127,9 @@ void miiphy_register (char *name, INIT_LIST_HEAD (&new_dev->link); new_dev->read = read; new_dev->write = write; - new_dev->name = (char *)(new_dev + 1); - strncpy (new_dev->name, name, name_len); - new_dev->name[name_len] = '\0'; + new_dev->name = new_name = (char *)(new_dev + 1); + strncpy (new_name, name, name_len); + new_name[name_len] = '\0'; debug ("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n", new_dev->name, new_dev->read, new_dev->write); @@ -121,25 +141,20 @@ void miiphy_register (char *name, current_mii = new_dev; } -int miiphy_set_current_dev (char *devname) +int miiphy_set_current_dev(const char *devname) { - struct list_head *entry; struct mii_dev *dev; - list_for_each (entry, &mii_devs) { - dev = list_entry (entry, struct mii_dev, link); - - if (strcmp (devname, dev->name) == 0) { - current_mii = dev; - return 0; - } + dev = miiphy_get_dev_by_name(devname, 0); + if (dev) { + current_mii = dev; + return 0; } - printf ("No such device: %s\n", devname); return 1; } -char *miiphy_get_current_dev () +const char *miiphy_get_current_dev(void) { if (current_mii) return current_mii->name; @@ -147,6 +162,20 @@ char *miiphy_get_current_dev () return NULL; } +static struct mii_dev *miiphy_get_active_dev(const char *devname) +{ + /* If the current mii is the one we want, return it */ + if (current_mii) + if (strcmp(current_mii->name, devname) == 0) + return current_mii; + + /* Otherwise, set the active one to the one we want */ + if (miiphy_set_current_dev(devname)) + return NULL; + else + return current_mii; +} + /***************************************************************************** * * Read to variable <value> from the PHY attached to device <devname>, @@ -155,33 +184,16 @@ char *miiphy_get_current_dev () * Returns: * 0 on success */ -int miiphy_read (char *devname, unsigned char addr, unsigned char reg, +int miiphy_read(const char *devname, unsigned char addr, unsigned char reg, unsigned short *value) { - struct list_head *entry; struct mii_dev *dev; - int found_dev = 0; - int read_ret = 0; - - if (!devname) { - printf ("NULL device name!\n"); - return 1; - } - - list_for_each (entry, &mii_devs) { - dev = list_entry (entry, struct mii_dev, link); - - if (strcmp (devname, dev->name) == 0) { - found_dev = 1; - read_ret = dev->read (devname, addr, reg, value); - break; - } - } - if (found_dev == 0) - printf ("No such device: %s\n", devname); + dev = miiphy_get_active_dev(devname); + if (dev) + return dev->read(devname, addr, reg, value); - return ((found_dev) ? read_ret : 1); + return 1; } /***************************************************************************** @@ -192,33 +204,16 @@ int miiphy_read (char *devname, unsigned char addr, unsigned char reg, * Returns: * 0 on success */ -int miiphy_write (char *devname, unsigned char addr, unsigned char reg, +int miiphy_write(const char *devname, unsigned char addr, unsigned char reg, unsigned short value) { - struct list_head *entry; struct mii_dev *dev; - int found_dev = 0; - int write_ret = 0; - - if (!devname) { - printf ("NULL device name!\n"); - return 1; - } - - list_for_each (entry, &mii_devs) { - dev = list_entry (entry, struct mii_dev, link); - - if (strcmp (devname, dev->name) == 0) { - found_dev = 1; - write_ret = dev->write (devname, addr, reg, value); - break; - } - } - if (found_dev == 0) - printf ("No such device: %s\n", devname); + dev = miiphy_get_active_dev(devname); + if (dev) + return dev->write(devname, addr, reg, value); - return ((found_dev) ? write_ret : 1); + return 1; } /***************************************************************************** @@ -252,7 +247,7 @@ void miiphy_listdev (void) * Returns: * 0 on success */ -int miiphy_info (char *devname, unsigned char addr, unsigned int *oui, +int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui, unsigned char *model, unsigned char *rev) { unsigned int reg = 0; @@ -290,7 +285,7 @@ int miiphy_info (char *devname, unsigned char addr, unsigned int *oui, * Returns: * 0 on success */ -int miiphy_reset (char *devname, unsigned char addr) +int miiphy_reset(const char *devname, unsigned char addr) { unsigned short reg; int timeout = 500; @@ -332,7 +327,7 @@ int miiphy_reset (char *devname, unsigned char addr) * * Determine the ethernet speed (10/100/1000). Return 10 on error. */ -int miiphy_speed (char *devname, unsigned char addr) +int miiphy_speed(const char *devname, unsigned char addr) { u16 bmcr, anlpar; @@ -386,7 +381,7 @@ miiphy_read_failed: * * Determine full/half duplex. Return half on error. */ -int miiphy_duplex (char *devname, unsigned char addr) +int miiphy_duplex(const char *devname, unsigned char addr) { u16 bmcr, anlpar; @@ -446,7 +441,7 @@ miiphy_read_failed: * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/ * 1000BASE-T, or on error. */ -int miiphy_is_1000base_x (char *devname, unsigned char addr) +int miiphy_is_1000base_x(const char *devname, unsigned char addr) { #if defined(CONFIG_PHY_GIGE) u16 exsr; @@ -467,7 +462,7 @@ int miiphy_is_1000base_x (char *devname, unsigned char addr) * * Determine link status */ -int miiphy_link (char *devname, unsigned char addr) +int miiphy_link(const char *devname, unsigned char addr) { unsigned short reg; diff --git a/common/serial.c b/common/serial.c index 5f9ffd7..c3323ea 100644 --- a/common/serial.c +++ b/common/serial.c @@ -30,7 +30,7 @@ DECLARE_GLOBAL_DATA_PTR; static struct serial_device *serial_devices = NULL; static struct serial_device *serial_current = NULL; -#if !defined(CONFIG_LWMON) && !defined(CONFIG_PXA27X) +#if !defined(CONFIG_LWMON) && !defined(CONFIG_PXA250) && !defined(CONFIG_PXA27X) struct serial_device *__default_serial_console (void) { #if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2) @@ -38,10 +38,10 @@ struct serial_device *__default_serial_console (void) #elif defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \ || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4) return &serial_scc_device; -#elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \ - || defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX) \ - || defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC83xx) \ - || defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) +#elif defined(CONFIG_4xx) \ + || defined(CONFIG_MB86R0x) || defined(CONFIG_MPC5xxx) \ + || defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) \ + || defined(CONFIG_MPC86xx) || defined(CONFIG_SYS_SC520) #if defined(CONFIG_CONS_INDEX) && defined(CONFIG_SYS_NS16550_SERIAL) #if (CONFIG_CONS_INDEX==1) return &eserial1_device; @@ -54,10 +54,16 @@ struct serial_device *__default_serial_console (void) #else #error "Bad CONFIG_CONS_INDEX." #endif -#elif defined(CONFIG_UART1_CONSOLE) - return &serial1_device; #else - return &serial0_device; + return &serial0_device; +#endif +#elif defined(CONFIG_MPC512X) +#if (CONFIG_PSC_CONSOLE == 3) + return &serial3_device; +#elif (CONFIG_PSC_CONSOLE == 6) + return &serial6_device; +#else +#error "Bad CONFIG_PSC_CONSOLE." #endif #elif defined(CONFIG_S3C2410) #if defined(CONFIG_SERIAL1) @@ -69,15 +75,15 @@ struct serial_device *__default_serial_console (void) #else #error "CONFIG_SERIAL? missing." #endif -#elif defined(CONFIG_S5PC1XX) +#elif defined(CONFIG_S5P) #if defined(CONFIG_SERIAL0) - return &s5pc1xx_serial0_device; + return &s5p_serial0_device; #elif defined(CONFIG_SERIAL1) - return &s5pc1xx_serial1_device; + return &s5p_serial1_device; #elif defined(CONFIG_SERIAL2) - return &s5pc1xx_serial2_device; + return &s5p_serial2_device; #elif defined(CONFIG_SERIAL3) - return &s5pc1xx_serial3_device; + return &s5p_serial3_device; #else #error "CONFIG_SERIAL? missing." #endif @@ -118,13 +124,6 @@ void serial_initialize (void) serial_register (&serial_scc_device); #endif -#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \ - || defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX) \ - || defined(CONFIG_MPC5xxx) - serial_register(&serial0_device); - serial_register(&serial1_device); -#endif - #if defined(CONFIG_SYS_NS16550_SERIAL) #if defined(CONFIG_SYS_NS16550_COM1) serial_register(&eserial1_device); @@ -153,11 +152,25 @@ void serial_initialize (void) serial_register(&s3c24xx_serial1_device); serial_register(&s3c24xx_serial2_device); #endif -#if defined(CONFIG_S5PC1XX) - serial_register(&s5pc1xx_serial0_device); - serial_register(&s5pc1xx_serial1_device); - serial_register(&s5pc1xx_serial2_device); - serial_register(&s5pc1xx_serial3_device); +#if defined(CONFIG_S5P) + serial_register(&s5p_serial0_device); + serial_register(&s5p_serial1_device); + serial_register(&s5p_serial2_device); + serial_register(&s5p_serial3_device); +#endif +#if defined(CONFIG_MPC512X) +#if defined(CONFIG_SYS_PSC1) + serial_register(&serial1_device); +#endif +#if defined(CONFIG_SYS_PSC3) + serial_register(&serial3_device); +#endif +#if defined(CONFIG_SYS_PSC4) + serial_register(&serial4_device); +#endif +#if defined(CONFIG_SYS_PSC6) + serial_register(&serial6_device); +#endif #endif serial_assign (default_serial_console ()->name); } @@ -174,6 +187,7 @@ void serial_stdio_init (void) dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; dev.start = s->init; + dev.stop = s->uninit; dev.putc = s->putc; dev.puts = s->puts; dev.getc = s->getc; diff --git a/common/stdio.c b/common/stdio.c index 870ddfd..2501369 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -76,18 +76,10 @@ static void drv_system_init (void) strcpy (dev.name, "serial"); dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; -#ifdef CONFIG_SERIAL_SOFTWARE_FIFO - dev.putc = serial_buffered_putc; - dev.puts = serial_buffered_puts; - dev.getc = serial_buffered_getc; - dev.tstc = serial_buffered_tstc; -#else dev.putc = serial_putc; dev.puts = serial_puts; dev.getc = serial_getc; dev.tstc = serial_tstc; -#endif - stdio_register (&dev); #ifdef CONFIG_SYS_DEVICE_NULLDEV diff --git a/common/usb_storage.c b/common/usb_storage.c index a8642c9..613c4f0 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -175,13 +175,13 @@ void uhci_show_temp_int_td(void); block_dev_desc_t *usb_stor_get_dev(int index) { - return (index < USB_MAX_STOR_DEV) ? &usb_dev_desc[index] : NULL; + return (index < usb_max_devs) ? &usb_dev_desc[index] : NULL; } void usb_show_progress(void) { - printf("."); + debug("."); } /******************************************************************************* @@ -204,6 +204,22 @@ int usb_stor_info(void) return 1; } +static unsigned int usb_get_max_lun(struct us_data *us) +{ + int len; + unsigned char result; + len = usb_control_msg(us->pusb_dev, + usb_rcvctrlpipe(us->pusb_dev, 0), + US_BBB_GET_MAX_LUN, + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, + 0, us->ifnum, + &result, sizeof(result), + USB_CNTL_TIMEOUT * 5); + USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n", + len, (int) result); + return (len > 0) ? result : 0; +} + /******************************************************************************* * scan the usb and reports device info * to the user if mode = 1 @@ -224,10 +240,11 @@ int usb_stor_scan(int mode) for (i = 0; i < USB_MAX_STOR_DEV; i++) { memset(&usb_dev_desc[i], 0, sizeof(block_dev_desc_t)); - usb_dev_desc[i].target = 0xff; usb_dev_desc[i].if_type = IF_TYPE_USB; usb_dev_desc[i].dev = i; usb_dev_desc[i].part_type = PART_TYPE_UNKNOWN; + usb_dev_desc[i].target = 0xff; + usb_dev_desc[i].type = DEV_TYPE_UNKNOWN; usb_dev_desc[i].block_read = usb_stor_read; usb_dev_desc[i].block_write = usb_stor_write; } @@ -240,13 +257,22 @@ int usb_stor_scan(int mode) break; /* no more devices avaiable */ if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) { - /* ok, it is a storage devices - * get info and fill it in + /* OK, it's a storage device. Iterate over its LUNs + * and populate `usb_dev_desc'. */ - if (usb_stor_get_info(dev, &usb_stor[usb_max_devs], - &usb_dev_desc[usb_max_devs])) + int lun, max_lun, start = usb_max_devs; + + max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]); + for (lun = 0; + lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV; + lun++) { + usb_dev_desc[usb_max_devs].lun = lun; + if (usb_stor_get_info(dev, &usb_stor[start], + &usb_dev_desc[usb_max_devs]) == 1) { usb_max_devs++; } + } + } /* if storage device */ if (usb_max_devs == USB_MAX_STOR_DEV) { printf("max USB Storage Device reached: %d stopping\n", @@ -881,6 +907,7 @@ static int usb_inquiry(ccb *srb, struct us_data *ss) do { memset(&srb->cmd[0], 0, 12); srb->cmd[0] = SCSI_INQUIRY; + srb->cmd[1] = srb->lun << 5; srb->cmd[4] = 36; srb->datalen = 36; srb->cmdlen = 12; @@ -888,7 +915,7 @@ static int usb_inquiry(ccb *srb, struct us_data *ss) USB_STOR_PRINTF("inquiry returns %d\n", i); if (i == 0) break; - } while (retry--); + } while (--retry); if (!retry) { printf("error in inquiry\n"); @@ -904,6 +931,7 @@ static int usb_request_sense(ccb *srb, struct us_data *ss) ptr = (char *)srb->pdata; memset(&srb->cmd[0], 0, 12); srb->cmd[0] = SCSI_REQ_SENSE; + srb->cmd[1] = srb->lun << 5; srb->cmd[4] = 18; srb->datalen = 18; srb->pdata = &srb->sense_buf[0]; @@ -923,6 +951,7 @@ static int usb_test_unit_ready(ccb *srb, struct us_data *ss) do { memset(&srb->cmd[0], 0, 12); srb->cmd[0] = SCSI_TST_U_RDY; + srb->cmd[1] = srb->lun << 5; srb->datalen = 0; srb->cmdlen = 12; if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) @@ -942,6 +971,7 @@ static int usb_read_capacity(ccb *srb, struct us_data *ss) do { memset(&srb->cmd[0], 0, 12); srb->cmd[0] = SCSI_RD_CAPAC; + srb->cmd[1] = srb->lun << 5; srb->datalen = 8; srb->cmdlen = 12; if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) @@ -956,6 +986,7 @@ static int usb_read_10(ccb *srb, struct us_data *ss, unsigned long start, { memset(&srb->cmd[0], 0, 12); srb->cmd[0] = SCSI_READ10; + srb->cmd[1] = srb->lun << 5; srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff; srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff; srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff; @@ -972,6 +1003,7 @@ static int usb_write_10(ccb *srb, struct us_data *ss, unsigned long start, { memset(&srb->cmd[0], 0, 12); srb->cmd[0] = SCSI_WRITE10; + srb->cmd[1] = srb->lun << 5; srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff; srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff; srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff; @@ -1080,7 +1112,7 @@ retry_it: usb_disable_asynch(0); /* asynch transfer allowed */ if (blkcnt >= USB_MAX_READ_BLK) - printf("\n"); + debug("\n"); return blkcnt; } @@ -1160,7 +1192,7 @@ retry_it: usb_disable_asynch(0); /* asynch transfer allowed */ if (blkcnt >= USB_MAX_WRITE_BLK) - printf("\n"); + debug("\n"); return blkcnt; } |