X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=cmd%2Fload.c;h=e44ae0d56b750c4311ff006fbcf8cd864ac77edc;hb=46b5c8ed017958fc387ab86c71ae6c90abb6793c;hp=63a94145430a8e465cff44b411e565fd8b21ccb0;hpb=b0b13f4114d30b6756e0f6f3b5819d78de22541e;p=platform%2Fkernel%2Fu-boot.git diff --git a/cmd/load.c b/cmd/load.c index 63a9414..e44ae0d 100644 --- a/cmd/load.c +++ b/cmd/load.c @@ -11,15 +11,21 @@ #include #include #include +#include #include +#include +#ifdef CONFIG_MTD_NOR_FLASH #include +#endif #include -#include +#include +#include #include -#include +#include #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -67,7 +73,7 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc, 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) @@ -81,7 +87,7 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc, serial_setbrg(); udelay(50000); for (;;) { - if (getc() == '\r') + if (getchar() == '\r') break; } } @@ -102,7 +108,7 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc, */ for (i=0; i<100; ++i) { if (tstc()) { - (void) getc(); + getchar(); } udelay(1000); } @@ -124,7 +130,7 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc, serial_setbrg(); udelay(50000); for (;;) { - if (getc() == 0x1B) /* ESC */ + if (getchar() == 0x1B) /* ESC */ break; } } @@ -134,6 +140,7 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc, 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. */ @@ -144,6 +151,9 @@ static ulong load_serial(long offset) 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); @@ -169,7 +179,14 @@ static ulong load_serial(long offset) } 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; @@ -212,7 +229,7 @@ static int read_record(char *buf, ulong len) --len; /* always leave room for terminating '\0' byte */ for (p=buf; p < buf+len; ++p) { - c = getc(); /* read character */ + c = getchar(); /* read character */ if (do_echo) putc(c); /* ... and echo it */ @@ -228,12 +245,11 @@ static int read_record(char *buf, ulong len) *p = c; } - /* Check for the console hangup (if any different from serial) */ - if (gd->jt->getc != getc) { - if (ctrlc()) { - return (-1); + /* Check for the console hangup (if any different from serial) */ + if (gd->jt->getc != getchar) { + if (ctrlc()) + return (-1); } - } } /* line too long - truncate */ @@ -255,14 +271,14 @@ int do_save_serial(struct cmd_tbl *cmdtp, int flag, int argc, #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) @@ -276,19 +292,19 @@ int do_save_serial(struct cmd_tbl *cmdtp, int flag, int argc, serial_setbrg(); udelay(50000); for (;;) { - if (getc() == '\r') + if (getchar() == '\r') break; } } #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("## Ready for S-Record upload, press ENTER to proceed ...\n"); for (;;) { - if (getc() == '\r') + if (getchar() == '\r') break; } if (save_serial(offset, size)) { @@ -305,7 +321,7 @@ int do_save_serial(struct cmd_tbl *cmdtp, int flag, int argc, serial_setbrg(); udelay(50000); for (;;) { - if (getc() == 0x1B) /* ESC */ + if (getchar() == 0x1B) /* ESC */ break; } } @@ -436,15 +452,15 @@ static int do_load_serial_bin(struct cmd_tbl *cmdtp, int flag, int argc, /* 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) @@ -459,7 +475,7 @@ static int do_load_serial_bin(struct cmd_tbl *cmdtp, int flag, int argc, serial_setbrg(); udelay(50000); for (;;) { - if (getc() == '\r') + if (getchar() == '\r') break; } } @@ -472,6 +488,14 @@ static int do_load_serial_bin(struct cmd_tbl *cmdtp, int flag, int argc, 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", @@ -480,6 +504,14 @@ static int do_load_serial_bin(struct cmd_tbl *cmdtp, int flag, int argc, 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 " @@ -505,7 +537,7 @@ static int do_load_serial_bin(struct cmd_tbl *cmdtp, int flag, int argc, serial_setbrg(); udelay(50000); for (;;) { - if (getc() == 0x1B) /* ESC */ + if (getchar() == 0x1B) /* ESC */ break; } } @@ -528,11 +560,14 @@ static ulong load_serial_bin(ulong offset) */ for (i=0; i<100; ++i) { if (tstc()) { - (void) getc(); + getchar(); } udelay(1000); } + if (size == 0) + return ~0; /* Download aborted */ + flush_cache(offset, size); printf("## Total Size = 0x%08x = %d Bytes\n", size, size); @@ -831,7 +866,7 @@ static int k_recv(void) /* get a packet */ /* wait for the starting character or ^C */ for (;;) { - switch (getc ()) { + switch (getchar()) { case START_CHAR: /* start packet */ goto START; case ETX_CHAR: /* ^C waiting for packet */ @@ -843,13 +878,13 @@ static int k_recv(void) START: /* get length of packet */ sum = 0; - new_char = getc(); + new_char = getchar(); if ((new_char & 0xE0) == 0) goto packet_error; sum += new_char & 0xff; length = untochar(new_char); /* get sequence number */ - new_char = getc(); + new_char = getchar(); if ((new_char & 0xE0) == 0) goto packet_error; sum += new_char & 0xff; @@ -876,7 +911,7 @@ START: /* END NEW CODE */ /* get packet type */ - new_char = getc(); + new_char = getchar(); if ((new_char & 0xE0) == 0) goto packet_error; sum += new_char & 0xff; @@ -886,19 +921,19 @@ START: if (length == -2) { /* (length byte was 0, decremented twice) */ /* get the two length bytes */ - new_char = getc(); + new_char = getchar(); if ((new_char & 0xE0) == 0) goto packet_error; sum += new_char & 0xff; len_hi = untochar(new_char); - new_char = getc(); + new_char = getchar(); if ((new_char & 0xE0) == 0) goto packet_error; sum += new_char & 0xff; len_lo = untochar(new_char); length = len_hi * 95 + len_lo; /* check header checksum */ - new_char = getc(); + new_char = getchar(); if ((new_char & 0xE0) == 0) goto packet_error; if (new_char != tochar((sum + ((sum >> 6) & 0x03)) & 0x3f)) @@ -908,7 +943,7 @@ START: } /* bring in rest of packet */ while (length > 1) { - new_char = getc(); + new_char = getchar(); if ((new_char & 0xE0) == 0) goto packet_error; sum += new_char & 0xff; @@ -925,13 +960,13 @@ START: } } /* get and validate checksum character */ - new_char = getc(); + new_char = getchar(); if ((new_char & 0xE0) == 0) goto packet_error; if (new_char != tochar((sum + ((sum >> 6) & 0x03)) & 0x3f)) goto packet_error; /* get END_CHAR */ - new_char = getc(); + new_char = getchar(); if (new_char != END_CHAR) { packet_error: /* restore state machines */ @@ -955,7 +990,7 @@ START: static int getcxmodem(void) { if (tstc()) - return (getc()); + return (getchar()); return -1; } static ulong load_serial_ymodem(ulong offset, int mode) @@ -973,6 +1008,7 @@ static ulong load_serial_ymodem(ulong offset, int mode) res = xyzModem_stream_open(&info, &err); if (!res) { + err = 0; while ((res = xyzModem_stream_read(ymodemBuf, 1024, &err)) > 0) { store_addr = addr + offset; @@ -985,6 +1021,9 @@ static ulong load_serial_ymodem(ulong offset, int mode) 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); } @@ -996,12 +1035,24 @@ static ulong load_serial_ymodem(ulong offset, int mode) } } + 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)); @@ -1014,6 +1065,44 @@ static ulong load_serial_ymodem(ulong offset, int mode) #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) @@ -1066,25 +1155,35 @@ U_BOOT_CMD( U_BOOT_CMD( loadb, 3, 0, do_load_serial_bin, "load binary file over serial line (kermit mode)", - "[ off ] [ baud ]\n" + "[ addr [ baud ] ]\n" " - load binary file over serial line" - " with offset 'off' and baudrate 'baud'" + " at address 'addr' with baudrate 'baud'" ); U_BOOT_CMD( loadx, 3, 0, do_load_serial_bin, "load binary file over serial line (xmodem mode)", - "[ off ] [ baud ]\n" + "[ addr [ baud ] ]\n" " - load binary file over serial line" - " with offset 'off' and baudrate 'baud'" + " at address 'addr' with baudrate 'baud'" ); U_BOOT_CMD( loady, 3, 0, do_load_serial_bin, "load binary file over serial line (ymodem mode)", - "[ off ] [ baud ]\n" + "[ addr [ baud ] ]\n" " - load binary file over serial line" - " with offset 'off' and baudrate 'baud'" + " at address 'addr' with baudrate 'baud'" ); #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 */