diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile | 1 | ||||
-rw-r--r-- | common/cmd_bdinfo.c | 6 | ||||
-rw-r--r-- | common/cmd_bootm.c | 16 | ||||
-rw-r--r-- | common/cmd_dfu.c | 14 | ||||
-rw-r--r-- | common/cmd_fpgad.c | 84 | ||||
-rw-r--r-- | common/cmd_i2c.c | 2 | ||||
-rw-r--r-- | common/cmd_ini.c | 25 | ||||
-rw-r--r-- | common/cmd_load.c | 24 | ||||
-rw-r--r-- | common/cmd_nand.c | 40 | ||||
-rw-r--r-- | common/cmd_sf.c | 30 | ||||
-rw-r--r-- | common/env_common.c | 2 | ||||
-rw-r--r-- | common/env_nand.c | 116 | ||||
-rw-r--r-- | common/env_sf.c | 2 | ||||
-rw-r--r-- | common/image-fit.c | 11 | ||||
-rw-r--r-- | common/lcd.c | 1 | ||||
-rw-r--r-- | common/spl/spl.c | 5 | ||||
-rw-r--r-- | common/stdio.c | 3 | ||||
-rw-r--r-- | common/usb.c | 87 | ||||
-rw-r--r-- | common/usb_hub.c | 30 | ||||
-rw-r--r-- | common/usb_kbd.c | 15 |
20 files changed, 352 insertions, 162 deletions
diff --git a/common/Makefile b/common/Makefile index 87ba82e..288690b 100644 --- a/common/Makefile +++ b/common/Makefile @@ -92,6 +92,7 @@ COBJS-$(CONFIG_CMD_FLASH) += cmd_flash.o ifdef CONFIG_FPGA COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o endif +COBJS-$(CONFIG_CMD_FPGAD) += cmd_fpgad.o COBJS-$(CONFIG_CMD_FS_GENERIC) += cmd_fs.o COBJS-$(CONFIG_CMD_FUSE) += cmd_fuse.o COBJS-$(CONFIG_CMD_GETTIME) += cmd_gettime.o diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index af884b8..713de14 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -92,7 +92,7 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) print_num("immr_base", bd->bi_immr_base); #endif print_num("bootflags", bd->bi_bootflags); -#if defined(CONFIG_405CR) || defined(CONFIG_405EP) || \ +#if defined(CONFIG_405EP) || \ defined(CONFIG_405GP) || \ defined(CONFIG_440EP) || defined(CONFIG_440EPX) || \ defined(CONFIG_440GR) || defined(CONFIG_440GRX) || \ @@ -106,7 +106,7 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) defined(CONFIG_440SPE) || defined(CONFIG_XILINX_405) print_mhz("pci_busfreq", bd->bi_pci_busfreq); #endif -#else /* ! CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_405, CONFIG_440EP CONFIG_440GR */ +#else /* ! CONFIG_405GP, CONFIG_405EP, CONFIG_XILINX_405, CONFIG_440EP CONFIG_440GR */ #if defined(CONFIG_CPM2) print_mhz("vco", bd->bi_vco); print_mhz("sccfreq", bd->bi_sccfreq); @@ -117,7 +117,7 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) print_mhz("cpmfreq", bd->bi_cpmfreq); #endif print_mhz("busfreq", bd->bi_busfreq); -#endif /* CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_405, CONFIG_440EP CONFIG_440GR */ +#endif /* CONFIG_405GP, CONFIG_405EP, CONFIG_XILINX_405, CONFIG_440EP CONFIG_440GR */ #ifdef CONFIG_ENABLE_36BIT_PHYS #ifdef CONFIG_PHYS_64BIT diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 046e22f..1685c14 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -636,7 +636,7 @@ static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, goto err; else if (ret == BOOTM_ERR_OVERLAP) ret = 0; -#ifdef CONFIG_SILENT_CONSOLE +#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) if (images->os.os == IH_OS_LINUX) fixup_silent_linux(); #endif @@ -1384,9 +1384,19 @@ static void fixup_silent_linux(void) char *buf; const char *env_val; char *cmdline = getenv("bootargs"); + int want_silent; - /* Only fix cmdline when requested */ - if (!(gd->flags & GD_FLG_SILENT)) + /* + * Only fix cmdline when requested. The environment variable can be: + * + * no - we never fixup + * yes - we always fixup + * unset - we rely on the console silent flag + */ + want_silent = getenv_yesno("silent_linux"); + if (want_silent == 0) + return; + else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT)) return; debug("before silent fix-up: %s\n", cmdline); diff --git a/common/cmd_dfu.c b/common/cmd_dfu.c index db066ac..793c422 100644 --- a/common/cmd_dfu.c +++ b/common/cmd_dfu.c @@ -19,8 +19,8 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { const char *str_env; char *s = "dfu"; + int ret, i = 0; char *env_bkp; - int ret; if (argc < 3) return CMD_RET_USAGE; @@ -49,6 +49,15 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) g_dnl_register(s); while (1) { + if (dfu_reset()) + /* + * This extra number of usb_gadget_handle_interrupts() + * calls is necessary to assure correct transmission + * completion with dfu-util + */ + if (++i == 10) + goto exit; + if (ctrlc()) goto exit; @@ -60,6 +69,9 @@ done: dfu_free_entities(); free(env_bkp); + if (dfu_reset()) + run_command("reset", 0); + return CMD_RET_SUCCESS; } diff --git a/common/cmd_fpgad.c b/common/cmd_fpgad.c new file mode 100644 index 0000000..1b25ed8 --- /dev/null +++ b/common/cmd_fpgad.c @@ -0,0 +1,84 @@ +/* + * (C) Copyright 2013 + * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc + * + * based on cmd_mem.c + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> + +#include <gdsys_fpga.h> + +static uint dp_last_fpga; +static uint dp_last_addr; +static uint dp_last_length = 0x40; + +/* + * FPGA Memory Display + * + * Syntax: + * fpgad {fpga} {addr} {len} + */ +#define DISP_LINE_LEN 16 +int do_fpga_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unsigned int k; + unsigned int fpga; + ulong addr, length; + int rc = 0; + u16 linebuf[DISP_LINE_LEN/sizeof(u16)]; + + /* + * We use the last specified parameters, unless new ones are + * entered. + */ + fpga = dp_last_fpga; + addr = dp_last_addr; + length = dp_last_length; + + if (argc < 3) + return CMD_RET_USAGE; + + if ((flag & CMD_FLAG_REPEAT) == 0) { + /* + * FPGA is specified since argc > 2 + */ + fpga = simple_strtoul(argv[1], NULL, 16); + + /* + * Address is specified since argc > 2 + */ + addr = simple_strtoul(argv[2], NULL, 16); + + /* + * If another parameter, it is the length to display. + * Length is the number of objects, not number of bytes. + */ + if (argc > 3) + length = simple_strtoul(argv[3], NULL, 16); + } + + /* Print the lines. */ + for (k = 0; k < DISP_LINE_LEN / sizeof(u16); ++k) + fpga_get_reg(fpga, (u16 *)fpga_ptr[fpga] + k, k * sizeof(u16), + &linebuf[k]); + print_buffer(addr, (void *)linebuf, sizeof(u16), + length, DISP_LINE_LEN / sizeof(u16)); + addr += sizeof(u16)*length; + + dp_last_fpga = fpga; + dp_last_addr = addr; + dp_last_length = length; + return rc; +} + +U_BOOT_CMD( + fpgad, 4, 1, do_fpga_md, + "fpga register display", + "fpga address [# of objects]" +); diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 29f5181..ebce7d4 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -1438,10 +1438,12 @@ int do_i2c_bus_num(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("Current bus is %d\n", i2c_get_bus_num()); else { bus_no = simple_strtoul(argv[1], NULL, 10); +#if defined(CONFIG_SYS_I2C) if (bus_no >= CONFIG_SYS_NUM_I2C_BUSES) { printf("Invalid bus %d\n", bus_no); return -1; } +#endif printf("Setting bus to %d\n", bus_no); ret = i2c_set_bus_num(bus_no); if (ret) diff --git a/common/cmd_ini.c b/common/cmd_ini.c index 74481cb..727fd1c 100644 --- a/common/cmd_ini.c +++ b/common/cmd_ini.c @@ -6,30 +6,7 @@ * Joe Hershberger, National Instruments, joe.hershberger@ni.com * All rights reserved. * - * The "inih" library is distributed under the following license, which is - * derived from and very similar to the 3-clause BSD license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Brush Technology nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY BRUSH TECHNOLOGY ''AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL BRUSH TECHNOLOGY BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * SPDX-License-Identifier: BSD-3-Clause * * Go to the project home page for more info: * http://code.google.com/p/inih/ diff --git a/common/cmd_load.c b/common/cmd_load.c index 0ce9496..f6e522c 100644 --- a/common/cmd_load.c +++ b/common/cmd_load.c @@ -18,7 +18,7 @@ DECLARE_GLOBAL_DATA_PTR; #if defined(CONFIG_CMD_LOADB) -static ulong load_serial_ymodem(ulong offset); +static ulong load_serial_ymodem(ulong offset, int mode); #endif #if defined(CONFIG_CMD_LOADS) @@ -462,7 +462,15 @@ static int do_load_serial_bin(cmd_tbl_t *cmdtp, int flag, int argc, offset, load_baudrate); - addr = load_serial_ymodem(offset); + addr = load_serial_ymodem(offset, xyzModem_ymodem); + + } else if (strcmp(argv[0],"loadx")==0) { + printf("## Ready for binary (xmodem) download " + "to 0x%08lX at %d bps...\n", + offset, + load_baudrate); + + addr = load_serial_ymodem(offset, xyzModem_xmodem); } else { @@ -942,7 +950,7 @@ static int getcxmodem(void) { return (getc()); return -1; } -static ulong load_serial_ymodem(ulong offset) +static ulong load_serial_ymodem(ulong offset, int mode) { int size; int err; @@ -953,7 +961,7 @@ static ulong load_serial_ymodem(ulong offset) ulong addr = 0; size = 0; - info.mode = xyzModem_ymodem; + info.mode = mode; res = xyzModem_stream_open(&info, &err); if (!res) { @@ -1056,6 +1064,14 @@ U_BOOT_CMD( ); U_BOOT_CMD( + loadx, 3, 0, do_load_serial_bin, + "load binary file over serial line (xmodem mode)", + "[ off ] [ baud ]\n" + " - load binary file over serial line" + " with offset 'off' and baudrate 'baud'" +); + +U_BOOT_CMD( loady, 3, 0, do_load_serial_bin, "load binary file over serial line (ymodem mode)", "[ off ] [ baud ]\n" diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 886212a..04ab0f1 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -42,6 +42,7 @@ 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; + int ret = 0; if (repeat) off = last + nand->writesize; @@ -49,11 +50,17 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat) last = off; datbuf = memalign(ARCH_DMA_MINALIGN, nand->writesize); - oobbuf = memalign(ARCH_DMA_MINALIGN, nand->oobsize); - if (!datbuf || !oobbuf) { + if (!datbuf) { puts("No memory for page buffer\n"); return 1; } + + oobbuf = memalign(ARCH_DMA_MINALIGN, nand->oobsize); + if (!oobbuf) { + puts("No memory for page buffer\n"); + ret = 1; + goto free_dat; + } off &= ~(nand->writesize - 1); loff_t addr = (loff_t) off; struct mtd_oob_ops ops; @@ -66,23 +73,25 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat) i = mtd_read_oob(nand, addr, &ops); if (i < 0) { printf("Error (%d) reading page %08lx\n", i, off); - free(datbuf); - free(oobbuf); - return 1; + ret = 1; + goto free_all; } printf("Page %08lx dump:\n", off); - i = nand->writesize >> 4; - p = datbuf; - while (i--) { - if (!only_oob) + if (!only_oob) { + i = nand->writesize >> 4; + p = datbuf; + + while (i--) { printf("\t%02x %02x %02x %02x %02x %02x %02x %02x" " %02x %02x %02x %02x %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); - p += 16; + p += 16; + } } + puts("OOB:\n"); i = nand->oobsize >> 3; p = oobbuf; @@ -91,10 +100,13 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat) p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); p += 8; } - free(datbuf); + +free_all: free(oobbuf); +free_dat: + free(datbuf); - return 0; + return ret; } /* ------------------------------------------------------------------------- */ @@ -604,11 +616,11 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) opts.scrub = 1; else { puts("scrub aborted\n"); - return -1; + return 1; } } else { puts("scrub aborted\n"); - return -1; + return 1; } } ret = nand_erase_opts(nand, &opts); diff --git a/common/cmd_sf.c b/common/cmd_sf.c index 19b0dc9..4af0f0a 100644 --- a/common/cmd_sf.c +++ b/common/cmd_sf.c @@ -151,16 +151,17 @@ static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset, size_t len, const char *buf, char *cmp_buf, size_t *skipped) { debug("offset=%#x, sector_size=%#x, len=%#zx\n", - offset, flash->sector_size, len); + offset, flash->sector_size, len); if (spi_flash_read(flash, offset, len, cmp_buf)) return "read"; if (memcmp(cmp_buf, buf, len) == 0) { debug("Skip region %x size %zx: no change\n", - offset, len); + offset, len); *skipped += len; return NULL; } - if (spi_flash_erase(flash, offset, len)) + /* Erase the entire sector */ + if (spi_flash_erase(flash, offset, flash->sector_size)) return "erase"; if (spi_flash_write(flash, offset, len, buf)) return "write"; @@ -200,7 +201,7 @@ static int spi_flash_update(struct spi_flash *flash, u32 offset, todo = min(end - buf, flash->sector_size); if (get_timer(last_update) > 100) { printf(" \rUpdating, %zu%% %lu B/s", - 100 - (end - buf) / scale, + 100 - (end - buf) / scale, bytes_per_second(buf - start_buf, start_time)); last_update = get_timer(0); @@ -220,9 +221,9 @@ static int spi_flash_update(struct spi_flash *flash, u32 offset, delta = get_timer(start_time); printf("%zu bytes written, %zu bytes skipped", len - skipped, - skipped); + skipped); printf(" in %ld.%lds, speed %ld B/s\n", - delta / 1000, delta % 1000, bytes_per_second(len, start_time)); + delta / 1000, delta % 1000, bytes_per_second(len, start_time)); return 0; } @@ -252,7 +253,7 @@ static int do_spi_flash_read_write(int argc, char * const argv[]) /* Consistency checking */ if (offset + len > flash->size) { printf("ERROR: attempting %s past flash size (%#x)\n", - argv[0], flash->size); + argv[0], flash->size); return 1; } @@ -262,9 +263,9 @@ static int do_spi_flash_read_write(int argc, char * const argv[]) return 1; } - if (strcmp(argv[0], "update") == 0) + if (strcmp(argv[0], "update") == 0) { ret = spi_flash_update(flash, offset, len, buf); - else if (strncmp(argv[0], "read", 4) == 0 || + } else if (strncmp(argv[0], "read", 4) == 0 || strncmp(argv[0], "write", 5) == 0) { int read; @@ -275,7 +276,7 @@ static int do_spi_flash_read_write(int argc, char * const argv[]) ret = spi_flash_write(flash, offset, len, buf); printf("SF: %zu bytes @ %#x %s: %s\n", (size_t)len, (u32)offset, - read ? "Read" : "Written", ret ? "ERROR" : "OK"); + read ? "Read" : "Written", ret ? "ERROR" : "OK"); } unmap_physmem(buf, len); @@ -304,13 +305,13 @@ static int do_spi_flash_erase(int argc, char * const argv[]) /* Consistency checking */ if (offset + len > flash->size) { printf("ERROR: attempting %s past flash size (%#x)\n", - argv[0], flash->size); + argv[0], flash->size); return 1; } ret = spi_flash_erase(flash, offset, len); printf("SF: %zu bytes @ %#x Erased: %s\n", (size_t)len, (u32)offset, - ret ? "ERROR" : "OK"); + ret ? "ERROR" : "OK"); return ret == 0 ? 0 : 1; } @@ -470,7 +471,8 @@ static int do_spi_flash_test(int argc, char * const argv[]) } #endif /* CONFIG_CMD_SF_TEST */ -static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) { const char *cmd; int ret; @@ -526,7 +528,7 @@ U_BOOT_CMD( "SPI flash sub-system", "probe [[bus:]cs] [hz] [mode] - init flash device on given SPI bus\n" " and chip select\n" - "sf read addr offset len - read `len' bytes starting at\n" + "sf read addr offset len - read `len' bytes starting at\n" " `offset' to memory at `addr'\n" "sf write addr offset len - write `len' bytes from memory\n" " at `addr' to flash at `offset'\n" diff --git a/common/env_common.c b/common/env_common.c index f387f9a..1ac3377 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -140,7 +140,6 @@ int set_default_vars(int nvars, char * const vars[]) H_NOCLEAR | H_INTERACTIVE, nvars, vars); } -#ifndef CONFIG_SPL_BUILD /* * Check if CRC is valid and (if yes) import the environment. * Note that "buf" may or may not be aligned. @@ -172,7 +171,6 @@ int env_import(const char *buf, int check) return 0; } -#endif void env_relocate(void) { diff --git a/common/env_nand.c b/common/env_nand.c index 9a6b8a6..7530962 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -152,72 +152,57 @@ int writeenv(size_t offset, u_char *buf) return 0; } -#ifdef CONFIG_ENV_OFFSET_REDUND -static unsigned char env_flags; +struct env_location { + const char *name; + const nand_erase_options_t erase_opts; +}; -int saveenv(void) +static int erase_and_write_env(const struct env_location *location, + u_char *env_new) { - env_t env_new; - ssize_t len; - char *res; - int ret = 0; - nand_erase_options_t nand_erase_options; + int ret = 0; - memset(&nand_erase_options, 0, sizeof(nand_erase_options)); - nand_erase_options.length = CONFIG_ENV_RANGE; - - if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) - return 1; - - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); - env_new.flags = ++env_flags; /* increase the serial */ - - if (gd->env_valid == 1) { - 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_new); - } else { - 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_new); - } - if (ret) { - puts("FAILED!\n"); + printf("Erasing %s...\n", location->name); + if (nand_erase_opts(&nand_info[0], &location->erase_opts)) return 1; - } - - puts("done\n"); - gd->env_valid = gd->env_valid == 2 ? 1 : 2; + printf("Writing to %s... ", location->name); + ret = writeenv(location->erase_opts.offset, env_new); + puts(ret ? "FAILED!\n" : "OK\n"); return ret; } -#else /* ! CONFIG_ENV_OFFSET_REDUND */ + +#ifdef CONFIG_ENV_OFFSET_REDUND +static unsigned char env_flags; +#endif + int saveenv(void) { int ret = 0; ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); ssize_t len; char *res; - nand_erase_options_t nand_erase_options; + int env_idx = 0; + static const struct env_location location[] = { + { + .name = "NAND", + .erase_opts = { + .length = CONFIG_ENV_RANGE, + .offset = CONFIG_ENV_OFFSET, + }, + }, +#ifdef CONFIG_ENV_OFFSET_REDUND + { + .name = "redundant NAND", + .erase_opts = { + .length = CONFIG_ENV_RANGE, + .offset = CONFIG_ENV_OFFSET_REDUND, + }, + }, +#endif + }; - memset(&nand_erase_options, 0, sizeof(nand_erase_options)); - nand_erase_options.length = CONFIG_ENV_RANGE; - nand_erase_options.offset = CONFIG_ENV_OFFSET; if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) return 1; @@ -228,22 +213,29 @@ int saveenv(void) 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; + env_new->crc = crc32(0, env_new->data, ENV_SIZE); +#ifdef CONFIG_ENV_OFFSET_REDUND + env_new->flags = ++env_flags; /* increase the serial */ + env_idx = (gd->env_valid == 1); +#endif - puts("Writing to Nand... "); - if (writeenv(CONFIG_ENV_OFFSET, (u_char *)env_new)) { - puts("FAILED!\n"); - return 1; + ret = erase_and_write_env(&location[env_idx], (u_char *)env_new); +#ifdef CONFIG_ENV_OFFSET_REDUND + if (!ret) { + /* preset other copy for next write */ + gd->env_valid = gd->env_valid == 2 ? 1 : 2; + return ret; } - puts("done\n"); + env_idx = (env_idx + 1) & 1; + ret = erase_and_write_env(&location[env_idx], (u_char *)env_new); + if (!ret) + printf("Warning: primary env write failed," + " redundancy is lost!\n"); +#endif + return ret; } -#endif /* CONFIG_ENV_OFFSET_REDUND */ #endif /* CMD_SAVEENV */ int readenv(size_t offset, u_char *buf) diff --git a/common/env_sf.c b/common/env_sf.c index e3e1897..9f806fb 100644 --- a/common/env_sf.c +++ b/common/env_sf.c @@ -7,7 +7,7 @@ * * (C) Copyright 2008 Atmel Corporation * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> #include <environment.h> diff --git a/common/image-fit.c b/common/image-fit.c index 683c1a5..199b4ed 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -343,6 +343,17 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) else printf("%s\n", desc); + if (IMAGE_ENABLE_TIMESTAMP) { + time_t timestamp; + + ret = fit_get_timestamp(fit, 0, ×tamp); + printf("%s Created: ", p); + if (ret) + printf("unavailable\n"); + else + genimg_print_time(timestamp); + } + fit_image_get_type(fit, image_noffset, &type); printf("%s Type: %s\n", p, genimg_get_type_name(type)); diff --git a/common/lcd.c b/common/lcd.c index 8d5c63c..990650c 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -51,7 +51,6 @@ /* ** FONT DATA */ /************************************************************************/ #include <video_font.h> /* Get font data, width and height */ -#include <video_font_data.h> /************************************************************************/ /* ** LOGO DATA */ diff --git a/common/spl/spl.c b/common/spl/spl.c index d6b0e01..da31457 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -85,8 +85,9 @@ void spl_parse_image_header(const struct image_header *header) } spl_image.os = image_get_os(header); spl_image.name = image_get_name(header); - debug("spl: payload image: %s load addr: 0x%x size: %d\n", - spl_image.name, spl_image.load_addr, spl_image.size); + debug("spl: payload image: %.*s load addr: 0x%x size: %d\n", + sizeof(spl_image.name), spl_image.name, + spl_image.load_addr, spl_image.size); } else { /* Signature not found - assume u-boot.bin */ debug("mkimage signature not found - ih_magic = %x\n", diff --git a/common/stdio.c b/common/stdio.c index 721e9a1..844f98c 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -196,9 +196,6 @@ int stdio_init (void) /* Initialize the list */ INIT_LIST_HEAD(&(devs.list)); -#ifdef CONFIG_ARM_DCC - drv_arm_dcc_init (); -#endif #ifdef CONFIG_SYS_I2C i2c_init_all(); #else diff --git a/common/usb.c b/common/usb.c index f740e5e..c97f522 100644 --- a/common/usb.c +++ b/common/usb.c @@ -323,6 +323,7 @@ static int usb_set_maxpacket(struct usb_device *dev) /******************************************************************************* * Parse the config, located in buffer, and fills the dev->config structure. * Note that all little/big endian swapping are done automatically. + * (wTotalLength has already been swapped and sanitized when it was read.) */ static int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno) @@ -343,24 +344,43 @@ static int usb_parse_config(struct usb_device *dev, head->bDescriptorType); return -1; } - memcpy(&dev->config, buffer, buffer[0]); - le16_to_cpus(&(dev->config.desc.wTotalLength)); + if (head->bLength != USB_DT_CONFIG_SIZE) { + printf("ERROR: Invalid USB CFG length (%d)\n", head->bLength); + return -1; + } + memcpy(&dev->config, head, USB_DT_CONFIG_SIZE); dev->config.no_of_if = 0; index = dev->config.desc.bLength; /* Ok the first entry must be a configuration entry, * now process the others */ head = (struct usb_descriptor_header *) &buffer[index]; - while (index + 1 < dev->config.desc.wTotalLength) { + while (index + 1 < dev->config.desc.wTotalLength && head->bLength) { switch (head->bDescriptorType) { case USB_DT_INTERFACE: + if (head->bLength != USB_DT_INTERFACE_SIZE) { + printf("ERROR: Invalid USB IF length (%d)\n", + head->bLength); + break; + } + if (index + USB_DT_INTERFACE_SIZE > + dev->config.desc.wTotalLength) { + puts("USB IF descriptor overflowed buffer!\n"); + break; + } if (((struct usb_interface_descriptor *) \ - &buffer[index])->bInterfaceNumber != curr_if_num) { + head)->bInterfaceNumber != curr_if_num) { /* this is a new interface, copy new desc */ ifno = dev->config.no_of_if; + if (ifno >= USB_MAXINTERFACES) { + puts("Too many USB interfaces!\n"); + /* try to go on with what we have */ + return 1; + } if_desc = &dev->config.if_desc[ifno]; dev->config.no_of_if++; - memcpy(if_desc, &buffer[index], buffer[index]); + memcpy(if_desc, head, + USB_DT_INTERFACE_SIZE); if_desc->no_of_ep = 0; if_desc->num_altsetting = 1; curr_if_num = @@ -374,12 +394,31 @@ static int usb_parse_config(struct usb_device *dev, } break; case USB_DT_ENDPOINT: + if (head->bLength != USB_DT_ENDPOINT_SIZE) { + printf("ERROR: Invalid USB EP length (%d)\n", + head->bLength); + break; + } + if (index + USB_DT_ENDPOINT_SIZE > + dev->config.desc.wTotalLength) { + puts("USB EP descriptor overflowed buffer!\n"); + break; + } + if (ifno < 0) { + puts("Endpoint descriptor out of order!\n"); + break; + } epno = dev->config.if_desc[ifno].no_of_ep; if_desc = &dev->config.if_desc[ifno]; + if (epno > USB_MAXENDPOINTS) { + printf("Interface %d has too many endpoints!\n", + if_desc->desc.bInterfaceNumber); + return 1; + } /* found an endpoint */ if_desc->no_of_ep++; - memcpy(&if_desc->ep_desc[epno], - &buffer[index], buffer[index]); + memcpy(&if_desc->ep_desc[epno], head, + USB_DT_ENDPOINT_SIZE); ep_wMaxPacketSize = get_unaligned(&dev->config.\ if_desc[ifno].\ ep_desc[epno].\ @@ -392,9 +431,23 @@ static int usb_parse_config(struct usb_device *dev, debug("if %d, ep %d\n", ifno, epno); break; case USB_DT_SS_ENDPOINT_COMP: + if (head->bLength != USB_DT_SS_EP_COMP_SIZE) { + printf("ERROR: Invalid USB EPC length (%d)\n", + head->bLength); + break; + } + if (index + USB_DT_SS_EP_COMP_SIZE > + dev->config.desc.wTotalLength) { + puts("USB EPC descriptor overflowed buffer!\n"); + break; + } + if (ifno < 0 || epno < 0) { + puts("EPC descriptor out of order!\n"); + break; + } if_desc = &dev->config.if_desc[ifno]; - memcpy(&if_desc->ss_ep_comp_desc[epno], - &buffer[index], buffer[index]); + memcpy(&if_desc->ss_ep_comp_desc[epno], head, + USB_DT_SS_EP_COMP_SIZE); break; default: if (head->bLength == 0) @@ -473,7 +526,7 @@ int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer, int cfgno) { int result; - unsigned int tmp; + unsigned int length; struct usb_config_descriptor *config; config = (struct usb_config_descriptor *)&buffer[0]; @@ -487,16 +540,18 @@ int usb_get_configuration_no(struct usb_device *dev, "(expected %i, got %i)\n", 9, result); return -1; } - tmp = le16_to_cpu(config->wTotalLength); + length = le16_to_cpu(config->wTotalLength); - if (tmp > USB_BUFSIZ) { - printf("usb_get_configuration_no: failed to get " \ - "descriptor - too long: %d\n", tmp); + if (length > USB_BUFSIZ) { + printf("%s: failed to get descriptor - too long: %d\n", + __func__, length); return -1; } - result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, tmp); - debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result, tmp); + result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, length); + debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result, length); + config->wTotalLength = length; /* validated, with CPU byte order */ + return result; } diff --git a/common/usb_hub.c b/common/usb_hub.c index 754d436..ffac0e7 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -44,6 +44,10 @@ static struct usb_hub_device hub_dev[USB_MAX_HUB]; static int usb_hub_index; +__weak void usb_hub_reset_devices(int port) +{ + return; +} static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size) { @@ -110,7 +114,7 @@ static void usb_hub_power_on(struct usb_hub_device *hub) ret = usb_get_port_status(dev, i + 1, portsts); if (ret < 0) { debug("port %d: get_port_status failed\n", i + 1); - return; + continue; } /* @@ -125,7 +129,7 @@ static void usb_hub_power_on(struct usb_hub_device *hub) portstatus = le16_to_cpu(portsts->wPortStatus); if (portstatus & (USB_PORT_STAT_POWER << 1)) { debug("port %d: Port power change failed\n", i + 1); - return; + continue; } } @@ -302,7 +306,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port) static int usb_hub_configure(struct usb_device *dev) { - int i; + int i, length; ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ); unsigned char *bitmap; short hubCharacteristics; @@ -323,20 +327,14 @@ static int usb_hub_configure(struct usb_device *dev) } descriptor = (struct usb_hub_descriptor *)buffer; - /* silence compiler warning if USB_BUFSIZ is > 256 [= sizeof(char)] */ - i = descriptor->bLength; - if (i > USB_BUFSIZ) { - debug("usb_hub_configure: failed to get hub " \ - "descriptor - too long: %d\n", descriptor->bLength); - return -1; - } + length = min(descriptor->bLength, sizeof(struct usb_hub_descriptor)); - if (usb_get_hub_descriptor(dev, buffer, descriptor->bLength) < 0) { + if (usb_get_hub_descriptor(dev, buffer, length) < 0) { debug("usb_hub_configure: failed to get hub " \ "descriptor 2nd giving up %lX\n", dev->status); return -1; } - memcpy((unsigned char *)&hub->desc, buffer, descriptor->bLength); + memcpy((unsigned char *)&hub->desc, buffer, length); /* adjust 16bit values */ put_unaligned(le16_to_cpu(get_unaligned( &descriptor->wHubCharacteristics)), @@ -426,6 +424,14 @@ static int usb_hub_configure(struct usb_device *dev) "" : "no "); usb_hub_power_on(hub); + /* + * Reset any devices that may be in a bad state when applying + * the power. This is a __weak function. Resetting of the devices + * should occur in the board file of the device. + */ + for (i = 0; i < dev->maxchild; i++) + usb_hub_reset_devices(i + 1); + for (i = 0; i < dev->maxchild; i++) { ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); unsigned short portstatus, portchange; diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 2ca3767..1ad67ca 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -104,6 +104,11 @@ struct usb_kbd_pdata { uint8_t flags; }; +extern int __maybe_unused net_busy_flag; + +/* The period of time between two calls of usb_kbd_testc(). */ +static unsigned long __maybe_unused kbd_testc_tms; + /* Generic keyboard event polling. */ void usb_kbd_generic_poll(void) { @@ -349,6 +354,16 @@ static int usb_kbd_testc(void) struct usb_device *usb_kbd_dev; struct usb_kbd_pdata *data; +#ifdef CONFIG_CMD_NET + /* + * If net_busy_flag is 1, NET transfer is running, + * then we check key-pressed every second (first check may be + * less than 1 second) to improve TFTP booting performance. + */ + if (net_busy_flag && (get_timer(kbd_testc_tms) < CONFIG_SYS_HZ)) + return 0; + kbd_testc_tms = get_timer(0); +#endif dev = stdio_get_by_name(DEVNAME); usb_kbd_dev = (struct usb_device *)dev->priv; data = usb_kbd_dev->privptr; |