summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Makefile1
-rw-r--r--common/cmd_bdinfo.c6
-rw-r--r--common/cmd_bootm.c16
-rw-r--r--common/cmd_dfu.c14
-rw-r--r--common/cmd_fpgad.c84
-rw-r--r--common/cmd_i2c.c2
-rw-r--r--common/cmd_ini.c25
-rw-r--r--common/cmd_load.c24
-rw-r--r--common/cmd_nand.c40
-rw-r--r--common/cmd_sf.c30
-rw-r--r--common/env_common.c2
-rw-r--r--common/env_nand.c116
-rw-r--r--common/env_sf.c2
-rw-r--r--common/image-fit.c11
-rw-r--r--common/lcd.c1
-rw-r--r--common/spl/spl.c5
-rw-r--r--common/stdio.c3
-rw-r--r--common/usb.c87
-rw-r--r--common/usb_hub.c30
-rw-r--r--common/usb_kbd.c15
20 files changed, 352 insertions, 162 deletions
diff --git a/common/Makefile b/common/Makefile
index 87ba82e204..288690bca5 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 af884b8a6a..713de1464c 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 046e22ff48..1685c14a52 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 db066acc36..793c422123 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 0000000000..1b25ed8747
--- /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 29f5181baf..ebce7d4c3c 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 74481cbf6f..727fd1c664 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 0ce949683e..f6e522cbb3 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 886212aa07..04ab0f19be 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 19b0dc9f43..4af0f0af26 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 f387f9ab91..1ac337730c 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 9a6b8a6fb2..75309621b0 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 e3e1897ccb..9f806fb090 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 683c1a511d..199b4ed16a 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, &timestamp);
+ 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 8d5c63c29e..990650c7ef 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 d6b0e01075..da31457d5f 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 721e9a1444..844f98c184 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 f740e5ec21..c97f522bed 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 754d436ad4..ffac0e743c 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 2ca3767ecf..1ad67caf13 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;
OpenPOWER on IntegriCloud