summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2020-08-05 16:05:33 -0400
committerTom Rini <[email protected]>2020-08-05 16:05:33 -0400
commit635dfee2cb522f5072530ca63fd4ab02890b90a2 (patch)
tree8abedb1958a51367a9a08922eea3d33cfb6035f4 /cmd
parentf1c0b7cd4be2081ae3711cec2c4cc2910a5817e1 (diff)
parent7b27e0fe13d8d44da6cd357a69668a726b852502 (diff)
Merge branch '2020-08-05-misc-fixes'
- A large number of assorted fixes and minor improvements
Diffstat (limited to 'cmd')
-rw-r--r--cmd/Kconfig8
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/bdinfo.c14
-rw-r--r--cmd/bootz.c2
-rw-r--r--cmd/clone.c126
5 files changed, 147 insertions, 4 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig
index d7136b0e790..e11176451b1 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1148,6 +1148,14 @@ config CMD_MMC_SWRITE
endif
+config CMD_CLONE
+ bool "clone"
+ depends on BLK
+ help
+ Enable storage cloning over block devices, useful for
+ initial flashing by external block device without network
+ or usb support.
+
config CMD_MTD
bool "mtd"
depends on MTD
diff --git a/cmd/Makefile b/cmd/Makefile
index 6e0086ba07f..70750375d12 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -98,6 +98,7 @@ obj-$(CONFIG_CMD_MMC) += mmc.o
obj-$(CONFIG_MP) += mp.o
obj-$(CONFIG_CMD_MTD) += mtd.o
obj-$(CONFIG_CMD_MTDPARTS) += mtdparts.o
+obj-$(CONFIG_CMD_CLONE) += clone.o
ifneq ($(CONFIG_CMD_NAND)$(CONFIG_CMD_SF),)
obj-y += legacy-mtd-utils.o
endif
diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c
index 8b2c105e777..9485c404740 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -9,6 +9,7 @@
#include <common.h>
#include <command.h>
#include <env.h>
+#include <lmb.h>
#include <net.h>
#include <vsprintf.h>
#include <asm/cache.h>
@@ -33,9 +34,10 @@ static void print_eth(int idx)
printf("%-12s= %s\n", name, val);
}
-static void print_lnum(const char *name, unsigned long long value)
+static void print_phys_addr(const char *name, phys_addr_t value)
{
- printf("%-12s= 0x%.8llX\n", name, value);
+ printf("%-12s= 0x%.*llx\n", name, 2 * (int)sizeof(ulong),
+ (unsigned long long)value);
}
void bdinfo_print_mhz(const char *name, unsigned long hz)
@@ -74,7 +76,7 @@ int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
bdinfo_print_num("boot_params", (ulong)bd->bi_boot_params);
print_bi_dram(bd);
bdinfo_print_num("memstart", (ulong)bd->bi_memstart);
- print_lnum("memsize", (u64)bd->bi_memsize);
+ print_phys_addr("memsize", bd->bi_memsize);
bdinfo_print_num("flashstart", (ulong)bd->bi_flashstart);
bdinfo_print_num("flashsize", (ulong)bd->bi_flashsize);
bdinfo_print_num("flashoffset", (ulong)bd->bi_flashoffset);
@@ -96,6 +98,12 @@ int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
bdinfo_print_num("multi_dtb_fit", (ulong)gd->multi_dtb_fit);
#endif
+ if (gd->fdt_blob) {
+ struct lmb lmb;
+
+ lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
+ lmb_dump_all_force(&lmb);
+ }
arch_print_bdinfo();
diff --git a/cmd/bootz.c b/cmd/bootz.c
index 1c8b0cf89f9..7556cd2752a 100644
--- a/cmd/bootz.c
+++ b/cmd/bootz.c
@@ -54,7 +54,7 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc,
* Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
* have a header that provide this informaiton.
*/
- if (bootm_find_images(flag, argc, argv, zi_start, zi_end - zi_start))
+ if (bootm_find_images(flag, argc, argv, images->ep, zi_end - zi_start))
return 1;
return 0;
diff --git a/cmd/clone.c b/cmd/clone.c
new file mode 100644
index 00000000000..97747f8f080
--- /dev/null
+++ b/cmd/clone.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 John Chau <[email protected]>
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <part.h>
+#include <blk.h>
+#include <vsprintf.h>
+
+#define BUFSIZE (1 * 1024 * 1024)
+static int do_clone(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
+{
+ int srcdev, destdev;
+ struct blk_desc *srcdesc, *destdesc;
+ int srcbz, destbz, ret;
+ char *unit, *buf;
+ unsigned long wrcnt, rdcnt, requested, srcblk, destblk;
+ unsigned long timer;
+ const unsigned long buffersize = 1024 * 1024;
+
+ if (argc < 6)
+ return CMD_RET_USAGE;
+
+ srcdev = blk_get_device_by_str(argv[1], argv[2], &srcdesc);
+ destdev = blk_get_device_by_str(argv[3], argv[4], &destdesc);
+ if (srcdev < 0) {
+ printf("Unable to open source device\n");
+ return 1;
+ } else if (destdev < 0) {
+ printf("Unable to open destination device\n");
+ return 1;
+ }
+ requested = simple_strtoul(argv[5], &unit, 10);
+ srcbz = srcdesc->blksz;
+ destbz = destdesc->blksz;
+
+ if ((srcbz * (buffersize / srcbz) != buffersize) &&
+ (destbz * (buffersize / destbz) != buffersize)) {
+ printf("failed: cannot match device block sizes\n");
+ return 1;
+ }
+ if (requested == 0) {
+ unsigned long a = srcdesc->lba * srcdesc->blksz;
+ unsigned long b = destdesc->lba * destdesc->blksz;
+
+ if (a > b)
+ requested = a;
+ else
+ requested = b;
+ } else {
+ switch (unit[0]) {
+ case 'g':
+ case 'G':
+ requested *= 1024;
+ case 'm':
+ case 'M':
+ requested *= 1024;
+ case 'k':
+ case 'K':
+ requested *= 1024;
+ break;
+ }
+ }
+ printf("Copying %ld bytes from %s:%s to %s:%s\n",
+ requested, argv[1], argv[2], argv[3], argv[4]);
+ wrcnt = 0;
+ rdcnt = 0;
+ buf = (char *)malloc(BUFSIZE);
+ srcblk = 0;
+ destblk = 0;
+ timer = get_timer(0);
+ while (wrcnt < requested) {
+ unsigned long toread = BUFSIZE / srcbz;
+ unsigned long towrite = BUFSIZE / destbz;
+ unsigned long offset = 0;
+
+read:
+ ret = blk_dread(srcdesc, srcblk, toread, buf + offset);
+ if (ret < 0) {
+ printf("Src read error @blk %ld\n", srcblk);
+ goto exit;
+ }
+ rdcnt += ret * srcbz;
+ srcblk += ret;
+ if (ret < toread) {
+ toread -= ret;
+ offset += ret * srcbz;
+ goto read;
+ }
+ offset = 0;
+write:
+ ret = blk_dwrite(destdesc, destblk, towrite, buf + offset);
+ if (ret < 0) {
+ printf("Dest write error @blk %ld\n", srcblk);
+ goto exit;
+ }
+ wrcnt += ret * destbz;
+ destblk += ret;
+ if (ret < towrite) {
+ towrite -= ret;
+ offset += ret * destbz;
+ goto write;
+ }
+ }
+
+exit:
+ timer = get_timer(timer);
+ timer = 1000 * timer / CONFIG_SYS_HZ;
+ printf("%ld read\n", rdcnt);
+ printf("%ld written\n", wrcnt);
+ printf("%ldms, %ldkB/s\n", timer, wrcnt / timer);
+ free(buf);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ clone, 6, 1, do_clone,
+ "simple storage cloning",
+ "<src interface> <src dev> <dest interface> <dest dev> <size[K/M/G]>\n"
+ "clone storage from 'src dev' on 'src interface' to 'dest dev' on 'dest interface' with maximum 'size' bytes (or 0 for clone to end)"
+);