#include <command.h>
#include <console.h>
#include <cpu_func.h>
+#include <efi_loader.h>
#include <env.h>
+#include <exports.h>
+#ifdef CONFIG_MTD_NOR_FLASH
#include <flash.h>
+#endif
#include <image.h>
-#include <s_record.h>
+#include <lmb.h>
+#include <mapmem.h>
#include <net.h>
-#include <exports.h>
+#include <s_record.h>
#include <serial.h>
#include <xyzModem.h>
#include <asm/cache.h>
+#include <asm/global_data.h>
#include <linux/delay.h>
DECLARE_GLOBAL_DATA_PTR;
offset = simple_strtol(argv[1], NULL, 16);
}
if (argc == 3) {
- load_baudrate = (int)simple_strtoul(argv[2], NULL, 10);
+ load_baudrate = (int)dectoul(argv[2], NULL);
/* default to current baudrate */
if (load_baudrate == 0)
printf("## Switch baudrate to %d bps and press ENTER ...\n",
load_baudrate);
udelay(50000);
+ flush();
gd->baudrate = load_baudrate;
serial_setbrg();
udelay(50000);
printf("## Switch baudrate to %d bps and press ESC ...\n",
current_baudrate);
udelay(50000);
+ flush();
gd->baudrate = current_baudrate;
serial_setbrg();
udelay(50000);
static ulong load_serial(long offset)
{
+ struct lmb lmb;
char record[SREC_MAXRECLEN + 1]; /* buffer for one S-Record */
char binbuf[SREC_MAXBINLEN]; /* buffer for binary data */
int binlen; /* no. of data bytes in S-Rec. */
ulong start_addr = ~0;
ulong end_addr = 0;
int line_count = 0;
+ long ret;
+
+ lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
while (read_record(record, SREC_MAXRECLEN + 1) >= 0) {
type = srec_decode(record, &binlen, &addr, binbuf);
} else
#endif
{
+ ret = lmb_reserve(&lmb, store_addr, binlen);
+ if (ret) {
+ printf("\nCannot overwrite reserved area (%08lx..%08lx)\n",
+ store_addr, store_addr + binlen);
+ return ret;
+ }
memcpy((char *)(store_addr), binbuf, binlen);
+ lmb_free(&lmb, store_addr, binlen);
}
if ((store_addr) < start_addr)
start_addr = store_addr;
#endif
if (argc >= 2) {
- offset = simple_strtoul(argv[1], NULL, 16);
+ offset = hextoul(argv[1], NULL);
}
#ifdef CONFIG_SYS_LOADS_BAUD_CHANGE
if (argc >= 3) {
- size = simple_strtoul(argv[2], NULL, 16);
+ size = hextoul(argv[2], NULL);
}
if (argc == 4) {
- save_baudrate = (int)simple_strtoul(argv[3], NULL, 10);
+ save_baudrate = (int)dectoul(argv[3], NULL);
/* default to current baudrate */
if (save_baudrate == 0)
}
#else /* ! CONFIG_SYS_LOADS_BAUD_CHANGE */
if (argc == 3) {
- size = simple_strtoul(argv[2], NULL, 16);
+ size = hextoul(argv[2], NULL);
}
#endif /* CONFIG_SYS_LOADS_BAUD_CHANGE */
printf("## Switch baudrate to %d bps and press ESC ...\n",
(int)current_baudrate);
udelay(50000);
+ flush();
gd->baudrate = current_baudrate;
serial_setbrg();
udelay(50000);
/* pre-set offset from $loadaddr */
s = env_get("loadaddr");
if (s)
- offset = simple_strtoul(s, NULL, 16);
+ offset = hextoul(s, NULL);
load_baudrate = current_baudrate = gd->baudrate;
if (argc >= 2) {
- offset = simple_strtoul(argv[1], NULL, 16);
+ offset = hextoul(argv[1], NULL);
}
if (argc == 3) {
- load_baudrate = (int)simple_strtoul(argv[2], NULL, 10);
+ load_baudrate = (int)dectoul(argv[2], NULL);
/* default to current baudrate */
if (load_baudrate == 0)
printf("## Switch baudrate to %d bps and press ENTER ...\n",
load_baudrate);
udelay(50000);
+ flush();
gd->baudrate = load_baudrate;
serial_setbrg();
udelay(50000);
addr = load_serial_ymodem(offset, xyzModem_ymodem);
+ if (addr == ~0) {
+ image_load_addr = 0;
+ printf("## Binary (ymodem) download aborted\n");
+ rcode = 1;
+ } else {
+ printf("## Start Addr = 0x%08lX\n", addr);
+ image_load_addr = addr;
+ }
} else if (strcmp(argv[0],"loadx")==0) {
printf("## Ready for binary (xmodem) download "
"to 0x%08lX at %d bps...\n",
addr = load_serial_ymodem(offset, xyzModem_xmodem);
+ if (addr == ~0) {
+ image_load_addr = 0;
+ printf("## Binary (xmodem) download aborted\n");
+ rcode = 1;
+ } else {
+ printf("## Start Addr = 0x%08lX\n", addr);
+ image_load_addr = addr;
+ }
} else {
printf("## Ready for binary (kermit) download "
printf("## Switch baudrate to %d bps and press ESC ...\n",
current_baudrate);
udelay(50000);
+ flush();
gd->baudrate = current_baudrate;
serial_setbrg();
udelay(50000);
udelay(1000);
}
+ if (size == 0)
+ return ~0; /* Download aborted */
+
flush_cache(offset, size);
printf("## Total Size = 0x%08x = %d Bytes\n", size, size);
res = xyzModem_stream_open(&info, &err);
if (!res) {
+ err = 0;
while ((res =
xyzModem_stream_read(ymodemBuf, 1024, &err)) > 0) {
store_addr = addr + offset;
rc = flash_write((char *) ymodemBuf,
store_addr, res);
if (rc != 0) {
+ xyzModem_stream_terminate(true, &getcxmodem);
+ xyzModem_stream_close(&err);
+ printf("\n");
flash_perror(rc);
return (~0);
}
}
}
+ if (err) {
+ xyzModem_stream_terminate((err == xyzModem_cancel) ? false : true, &getcxmodem);
+ xyzModem_stream_close(&err);
+ printf("\n%s\n", xyzModem_error(err));
+ return (~0); /* Download aborted */
+ }
+
+ if (IS_ENABLED(CONFIG_CMD_BOOTEFI))
+ efi_set_bootdev("Uart", "", "",
+ map_sysmem(offset, 0), size);
+
} else {
- printf("%s\n", xyzModem_error(err));
+ printf("\n%s\n", xyzModem_error(err));
+ return (~0); /* Download aborted */
}
- xyzModem_stream_close(&err);
xyzModem_stream_terminate(false, &getcxmodem);
+ xyzModem_stream_close(&err);
flush_cache(offset, ALIGN(size, ARCH_DMA_MINALIGN));
#endif
+#if defined(CONFIG_CMD_LOADM)
+static int do_load_memory_bin(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ ulong addr, dest, size;
+ void *src, *dst;
+
+ if (argc != 4)
+ return CMD_RET_USAGE;
+
+ addr = simple_strtoul(argv[1], NULL, 16);
+
+ dest = simple_strtoul(argv[2], NULL, 16);
+
+ size = simple_strtoul(argv[3], NULL, 16);
+
+ if (!size) {
+ printf("loadm: can not load zero bytes\n");
+ return 1;
+ }
+
+ src = map_sysmem(addr, size);
+ dst = map_sysmem(dest, size);
+
+ memcpy(dst, src, size);
+
+ unmap_sysmem(src);
+ unmap_sysmem(dst);
+
+ if (IS_ENABLED(CONFIG_CMD_BOOTEFI))
+ efi_set_bootdev("Mem", "", "", map_sysmem(dest, 0), size);
+
+ printf("loaded bin to memory: size: %lu\n", size);
+
+ return 0;
+}
+#endif
+
/* -------------------------------------------------------------------- */
#if defined(CONFIG_CMD_LOADS)
);
#endif /* CONFIG_CMD_LOADB */
+
+#if defined(CONFIG_CMD_LOADM)
+U_BOOT_CMD(
+ loadm, 4, 0, do_load_memory_bin,
+ "load binary blob from source address to destination address",
+ "[src_addr] [dst_addr] [size]\n"
+ " - load a binary blob from one memory location to other"
+ " from src_addr to dst_addr by size bytes"
+);
+#endif /* CONFIG_CMD_LOADM */