- printf ("## Application terminated, rc = 0x%lx\n", rc);
- return rcode;
-}
-
-#if (CONFIG_COMMANDS & CFG_CMD_LOADS)
-int do_load_serial (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
- ulong offset = 0;
- ulong addr;
- int i;
- char *env_echo;
- int rcode = 0;
-#ifdef CFG_LOADS_BAUD_CHANGE
- DECLARE_GLOBAL_DATA_PTR;
- int load_baudrate, current_baudrate;
-
- load_baudrate = current_baudrate = gd->baudrate;
-#endif
-
- if (((env_echo = getenv("loads_echo")) != NULL) && (*env_echo == '1')) {
- do_echo = 1;
- } else {
- do_echo = 0;
- }
-
-#ifdef CFG_LOADS_BAUD_CHANGE
- if (argc >= 2) {
- offset = simple_strtoul(argv[1], NULL, 16);
- }
- if (argc == 3) {
- load_baudrate = (int)simple_strtoul(argv[2], NULL, 10);
-
- /* default to current baudrate */
- if (load_baudrate == 0)
- load_baudrate = current_baudrate;
- }
-#else /* ! CFG_LOADS_BAUD_CHANGE */
- if (argc == 2) {
- offset = simple_strtoul(argv[1], NULL, 16);
- }
-#endif /* CFG_LOADS_BAUD_CHANGE */
-
-#ifdef CFG_LOADS_BAUD_CHANGE
- if (load_baudrate != current_baudrate) {
- printf ("## Switch baudrate to %d bps and press ENTER ...\n",
- load_baudrate);
- udelay(50000);
- gd->baudrate = load_baudrate;
- serial_setbrg ();
- udelay(50000);
- for (;;) {
- if (getc() == '\r')
- break;
- }
- }
-#endif /* CFG_LOADS_BAUD_CHANGE */
- printf ("## Ready for S-Record download ...\n");
-
- addr = load_serial (offset);
-
- /*
- * Gather any trailing characters (for instance, the ^D which
- * is sent by 'cu' after sending a file), and give the
- * box some time (100 * 1 ms)
- */
- for (i=0; i<100; ++i) {
- if (serial_tstc()) {
- (void) serial_getc();
- }
- udelay(1000);
- }
-
- if (addr == ~0) {
- printf ("## S-Record download aborted\n");
- rcode = 1;
- } else {
- printf ("## Start Addr = 0x%08lx\n", addr);
- load_addr = addr;
- }
-
-#ifdef CFG_LOADS_BAUD_CHANGE
- if (load_baudrate != current_baudrate) {
- printf ("## Switch baudrate to %d bps and press ESC ...\n",
- current_baudrate);
- udelay (50000);
- gd->baudrate = current_baudrate;
- serial_setbrg ();
- udelay (50000);
- for (;;) {
- if (getc() == 0x1B) /* ESC */
- break;
- }
- }
-#endif
- return rcode;
-}
-
-static ulong
-load_serial (ulong offset)
-{
- 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. */
- int type; /* return code for record type */
- ulong addr; /* load address from S-Record */
- ulong size; /* number of bytes transferred */
- char buf[32];
- ulong store_addr;
- ulong start_addr = ~0;
- ulong end_addr = 0;
- int line_count = 0;
-
- while (read_record(record, SREC_MAXRECLEN + 1) >= 0) {
- type = srec_decode (record, &binlen, &addr, binbuf);
-
- if (type < 0) {
- return (~0); /* Invalid S-Record */
- }
-
- switch (type) {
- case SREC_DATA2:
- case SREC_DATA3:
- case SREC_DATA4:
- store_addr = addr + offset;
- if (addr2info(store_addr)) {
- int rc;
-
- rc = flash_write((uchar *)binbuf,store_addr,binlen);
- if (rc != 0) {
- flash_perror (rc);
- return (~0);
- }
- } else {
- memcpy ((char *)(store_addr), binbuf, binlen);
- }
- if ((store_addr) < start_addr)
- start_addr = store_addr;
- if ((store_addr + binlen - 1) > end_addr)
- end_addr = store_addr + binlen - 1;
- break;
- case SREC_END2:
- case SREC_END3:
- case SREC_END4:
- udelay (10000);
- size = end_addr - start_addr + 1;
- printf ("\n"
- "## First Load Addr = 0x%08lX\n"
- "## Last Load Addr = 0x%08lX\n"
- "## Total Size = 0x%08lX = %ld Bytes\n",
- start_addr, end_addr, size, size
- );
- flush_cache (addr, size);
- sprintf(buf, "%lX", size);
- setenv("filesize", buf);
- return (addr);
- case SREC_START:
- break;
- default:
- break;
- }
- if (!do_echo) { /* print a '.' every 100 lines */
- if ((++line_count % 100) == 0)
- putc ('.');
- }
- }
-
- return (~0); /* Download aborted */
-}
-
-static int
-read_record (char *buf, ulong len)
-{
- char *p;
- char c;
-
- --len; /* always leave room for terminating '\0' byte */
-
- for (p=buf; p < buf+len; ++p) {
- c = serial_getc(); /* read character */
- if (do_echo)
- serial_putc (c); /* ... and echo it */
-
- switch (c) {
- case '\r':
- case '\n':
- *p = '\0';
- return (p - buf);
- case '\0':
- case 0x03: /* ^C - Control C */
- return (-1);
- default:
- *p = c;
- }
-
- /* Check for the console hangup (if any different from serial) */
-
- if (syscall_tbl[SYSCALL_GETC] != serial_getc) {
- if (ctrlc()) {
- return (-1);
- }
- }
- }
-
- /* line too long - truncate */
- *p = '\0';
- return (p - buf);
-}
-
-#if (CONFIG_COMMANDS & CFG_CMD_SAVES)
-
-int do_save_serial (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
- ulong offset = 0;
- ulong size = 0;
-#ifdef CFG_LOADS_BAUD_CHANGE
- DECLARE_GLOBAL_DATA_PTR;
- int save_baudrate, current_baudrate;
-
- save_baudrate = current_baudrate = gd->baudrate;
-#endif
-
- if (argc >= 2) {
- offset = simple_strtoul(argv[1], NULL, 16);
- }
-#ifdef CFG_LOADS_BAUD_CHANGE
- if (argc >= 3) {
- size = simple_strtoul(argv[2], NULL, 16);
- }
- if (argc == 4) {
- save_baudrate = (int)simple_strtoul(argv[3], NULL, 10);
-
- /* default to current baudrate */
- if (save_baudrate == 0)
- save_baudrate = current_baudrate;
- }
-#else /* ! CFG_LOADS_BAUD_CHANGE */
- if (argc == 3) {
- size = simple_strtoul(argv[2], NULL, 16);
- }
-#endif /* CFG_LOADS_BAUD_CHANGE */
-
-#ifdef CFG_LOADS_BAUD_CHANGE
- if (save_baudrate != current_baudrate) {
- printf ("## Switch baudrate to %d bps and press ENTER ...\n",
- save_baudrate);
- udelay(50000);
- gd->baudrate = save_baudrate;
- serial_setbrg ();
- udelay(50000);
- for (;;) {
- if (getc() == '\r')
- break;
- }
- }
-#endif /* CFG_LOADS_BAUD_CHANGE */
- printf ("## Ready for S-Record upload, press ENTER to proceed ...\n");
- for (;;) {
- if (getc() == '\r')
- break;
- }
- if(save_serial (offset, size)) {
- printf ("## S-Record upload aborted\n");
- } else {
- printf ("## S-Record upload complete\n");
- }
-#ifdef CFG_LOADS_BAUD_CHANGE
- if (save_baudrate != current_baudrate) {
- printf ("## Switch baudrate to %d bps and press ESC ...\n",
- (int)current_baudrate);
- udelay (50000);
- gd->baudrate = current_baudrate;
- serial_setbrg ();
- udelay (50000);
- for (;;) {
- if (getc() == 0x1B) /* ESC */
- break;
- }
- }
-#endif
- return 0;
-}
-
-#define SREC3_START "S0030000FC\n"
-#define SREC3_FORMAT "S3%02X%08lX%s%02X\n"
-#define SREC3_END "S70500000000FA\n"
-#define SREC_BYTES_PER_RECORD 16
-
-static int save_serial (ulong address, ulong count)
-{
- int i, c, reclen, checksum, length;
- char *hex = "0123456789ABCDEF";
- char record[2*SREC_BYTES_PER_RECORD+16]; /* buffer for one S-Record */
- char data[2*SREC_BYTES_PER_RECORD+1]; /* buffer for hex data */
-
- reclen = 0;
- checksum = 0;
-
- if(write_record(SREC3_START)) /* write the header */
- return (-1);
- do {
- if(count) { /* collect hex data in the buffer */
- c = *(volatile uchar*)(address + reclen); /* get one byte */
- checksum += c; /* accumulate checksum */
- data[2*reclen] = hex[(c>>4)&0x0f];
- data[2*reclen+1] = hex[c & 0x0f];
- data[2*reclen+2] = '\0';
- ++reclen;
- --count;
- }
- if(reclen == SREC_BYTES_PER_RECORD || count == 0) {
- /* enough data collected for one record: dump it */
- if(reclen) { /* build & write a data record: */
- /* address + data + checksum */
- length = 4 + reclen + 1;
-
- /* accumulate length bytes into checksum */
- for(i = 0; i < 2; i++)
- checksum += (length >> (8*i)) & 0xff;
-
- /* accumulate address bytes into checksum: */
- for(i = 0; i < 4; i++)
- checksum += (address >> (8*i)) & 0xff;
-
- /* make proper checksum byte: */
- checksum = ~checksum & 0xff;
-
- /* output one record: */
- sprintf(record, SREC3_FORMAT, length, address, data, checksum);
- if(write_record(record))
- return (-1);
- }
- address += reclen; /* increment address */
- checksum = 0;
- reclen = 0;
- }
- }
- while(count);
- if(write_record(SREC3_END)) /* write the final record */
- return (-1);
- return(0);
-}
-
-static int
-write_record (char *buf)
-{
- char c;
-
- while((c = *buf++))
- serial_putc(c);
-
- /* Check for the console hangup (if any different from serial) */
-
- if (ctrlc()) {
- return (-1);
- }
- return (0);
-}
-# endif /* CFG_CMD_SAVES */
-
-#endif /* CFG_CMD_LOADS */
-
-
-#if (CONFIG_COMMANDS & CFG_CMD_LOADB) /* loadb command (load binary) included */
-
-#define XON_CHAR 17
-#define XOFF_CHAR 19
-#define START_CHAR 0x01
-#define END_CHAR 0x0D
-#define SPACE 0x20
-#define K_ESCAPE 0x23
-#define SEND_TYPE 'S'
-#define DATA_TYPE 'D'
-#define ACK_TYPE 'Y'
-#define NACK_TYPE 'N'
-#define BREAK_TYPE 'B'
-#define tochar(x) ((char) (((x) + SPACE) & 0xff))
-#define untochar(x) ((int) (((x) - SPACE) & 0xff))
-
-extern int os_data_count;
-extern int os_data_header[8];
-
-static void set_kerm_bin_mode(unsigned long *);
-static int k_recv(void);
-static ulong load_serial_bin (ulong offset);
-
-
-char his_eol; /* character he needs at end of packet */
-int his_pad_count; /* number of pad chars he needs */
-char his_pad_char; /* pad chars he needs */
-char his_quote; /* quote chars he'll use */
-
-int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
- DECLARE_GLOBAL_DATA_PTR;
-
- ulong offset = 0;
- ulong addr;
- int i;
- int load_baudrate, current_baudrate;
- int rcode = 0;
-
- load_baudrate = current_baudrate = gd->baudrate;
-
- if (argc >= 2) {
- offset = simple_strtoul(argv[1], NULL, 16);
- }
- if (argc == 3) {
- load_baudrate = (int)simple_strtoul(argv[2], NULL, 10);
-
- /* default to current baudrate */
- if (load_baudrate == 0)
- load_baudrate = current_baudrate;
- }
-
- if (load_baudrate != current_baudrate) {
- printf ("## Switch baudrate to %d bps and press ENTER ...\n",
- load_baudrate);
- udelay(50000);
- gd->baudrate = load_baudrate;
- serial_setbrg ();
- udelay(50000);
- for (;;) {
- if (getc() == '\r')
- break;
- }
- }
- printf ("## Ready for binary (kermit) download ...\n");
-
- addr = load_serial_bin (offset);
-
- /*
- * Gather any trailing characters (for instance, the ^D which
- * is sent by 'cu' after sending a file), and give the
- * box some time (100 * 1 ms)
- */
- for (i=0; i<100; ++i) {
- if (serial_tstc()) {
- (void) serial_getc();
- }
- udelay(1000);
- }
-
- if (addr == ~0) {
- load_addr = 0;
- printf ("## Binary (kermit) download aborted\n");
- rcode = 1;
- } else {
- printf ("## Start Addr = 0x%08lx\n", addr);
- load_addr = addr;
- }
-
- if (load_baudrate != current_baudrate) {
- printf ("## Switch baudrate to %d bps and press ESC ...\n",
- current_baudrate);
- udelay (50000);
- gd->baudrate = current_baudrate;
- serial_setbrg ();
- udelay (50000);
- for (;;) {
- if (getc() == 0x1B) /* ESC */
- break;
- }
- }
-
-#ifdef CONFIG_AUTOSCRIPT
- if (load_addr) {
- char *s;
-
- if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
- printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
- rcode = autoscript (load_addr);
- }
- }
-#endif