📄 load.c
字号:
/************************************************************* * File: imon/load.c * Purpose: file load command for imon * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970303 Deleted unused static globals * 970303 Moved def of blksz and blkinx here. * 970305 Added -f flag to load from flash * 970305 Deleted -t from _opts. It isn't implemented anyway. * 970305 delete all line termination characters. * 970514 Add null to eol deletion list - needed for Ethernet * 970901 Removed lastdownloadsz. See getNextSloadAdr(). * 970902 Prob w "goto drvrInit" in "load -f". Created callDriver(). * 970920 Added error msg if "load -f" w/o reset. * 980107 Added ifdef for GHS jal indirect bug * 980113 Added (char *) casts for av[] * 980206 Move cache flush to start of 'callDriver'. * 980405 Added -m option. * 980602 Added len check for driver loads. */#include <termio.h>#include <imon.h>Optdesc load_opts[] = { {"[-vbeasi][-baud][offset][-c cmdstr]","load memory from hostport"}, {"-c cmdstr","send cmdstr to host"}, {"-s","don't clear symbols"}, {"-b","don't clear breakpoints"}, {"-e","don't clear exception handlers"}, {"-a","don't add offset to symbols"}, {"-d","load Target Description Driver"},/* {"-t","load at top of memory"}, 970305 */ {"-f","load driver from flash"}, {"-i","ignore checksum errors"},#ifdef ETHERNET {"-B","binary transfer mode"}, {"-v","verbose mode"},#endif {"-<num>","set baud rate"}, {"-m","don't load memory - symbols only"}, {0}};char *dlerrs[] = {0,"bad char","bad length","bad type", "bad chksum", "out of symbol space"};#ifdef CROSSVIEW#ifdef NOPROTO#define _(x) ()#else#define _(x) x#endif#define REC_END 2#define REC_DATA 3#define REC_ERROR 4typedef unsigned long ADDR;#endifUlong start_address;Ulong nextaddr;Ulong wordbuf;Ulong tbase;int chksum;int tot;int blksz;int blkinx;#define ether_bcopy() (* ether_bcopy_ptr)()Func *ether_bcopy_ptr;/************************************************************** load(ac,av)*/load(ac,av)int ac;Uchar *av[];{struct termio tbuf;char *hostport,*cmdstr,*p;int fd,dlecho,dlproto,dltype,count,n;int len,err,i,j,s,flags;Ulong offset;Uchar recbuf[MAXREC],*baudrate;int errs[6],line;int fflag;baudrate = 0;offset = 0;count = 0;cmdstr = 0;flags = 0;for (i=0;i<6;i++) errs[i] = 0;hostport = getMonEnv("hostport");vflag = fflag = 0;for (i=1;i<ac;i++) { if (av[i][0] == '-') { for (j=1;av[i][j];j++) { if (av[i][j] == 's') flags |= DL_SFLAG; else if (av[i][j] == 'b') flags |= DL_bFLAG; else if (av[i][j] == 'B') flags |= DL_BFLAG; else if (av[i][j] == 'e') flags |= DL_EFLAG; else if (av[i][j] == 'a') flags |= DL_AFLAG; else if (av[i][j] == 'd') flags |= DL_DFLAG; else if (av[i][j] == 'v') vflag = 1; else if (av[i][j] == 'f') fflag=1; /* 970305 */#if 0 /* 970305 */ else if (av[i][j] == 't') { flags |= DL_TFLAG; write_target(XT_GPR,7,0); }#endif else if (av[i][j] == 'i') flags |= DL_IFLAG; else if (av[i][j] == 'c') { i++; if (i >= ac) { printf("bad arg count\n"); return(1); } cmdstr = (char *)av[i]; /* 980113 */ break; } else if (isdigit(av[i][j])) { baudrate = &av[i][j]; break; } else printf("%c: unrecognized option\n",av[i][j]); } } else { if (av[i][0] == 't') hostport = (char *)av[i]; /* 980113 */ else if (count == 0) { if (!get_rsa(&offset,av[i])) return(1); count++; } else printf("%s: unrecognized argument\n",av[i]); } }if (regChain && fflag) { /* 970920 */ printf("ERROR: reset controller before reloading driver.\n"); return; }if (!(flags&DL_SFLAG)) clrsyms();if (!(flags&DL_bFLAG)) clrbpt(-1);if (!(flags&DL_EFLAG)) clrhndlrs();if (fflag) { /* load from flash */ int val,len; Ulong src,dst; src = nvInfo.dvrsa; dst = DRIVER_BASE; /* len always stored in BE format */ len = load_byte(src++); len = (len<<8)|load_byte(src++); len = (len<<8)|load_byte(src++); len = (len<<8)|load_byte(src++); if (len == -1 || len > 0x20000) { /* 980602 */ printf("driver not found.\n"); return; } printf("loading %d bytes to %08x\n",len,dst); for (i=0;i<len;i++) { val = load_byte(src++); store_byte(dst++,val); } callDriver(); return; }#ifdef CROSSVIEWif (strequ(av[0],"lo")) hostport = "tty0";#endiffd = open(hostport,0,0);if (fd == -1) { printf("can't open %s\n",hostport); return; }dltype = -1; /* dltype is set by 1st char of 1st record */printf("Downloading from %s, ^C to abort\n",hostport);ioctl(fd,TCGETA,&tbuf);tbuf.c_iflag &= ~IXOFF;ioctl(fd,TCSETAF,&tbuf);if (baudrate) { if ((n=getbaudrate(fd,baudrate)) == 0) { printf("%s: unsupported baud rate\n",baudrate); return; } tbuf.c_cflag &= ~CBAUD; tbuf.c_cflag |= n; ioctl(fd,TCSETAF,&tbuf); }dlecho = matchenv("dlecho");if (dlecho == OFF || dlecho == LFEED) { tbuf.c_lflag &= ~ECHO; ioctl(fd,TCSETAF,&tbuf); }dlproto = matchenv("dlproto");if (cmdstr) { write(fd,cmdstr,strlen(cmdstr)); write(fd,"\r",1); }#ifdef ETHERNETif (flags&DL_BFLAG) { ether_bcopy(); return; /* never exits via this return. Uses ^C's longjmp */ }#endifchksum = 0;err = tot = 0;#ifdef CROSSVIEWif (strequ(av[0],"lo")) { dltype = 2; tbuf.c_iflag &= ~(ISTRIP|ICRNL); tbuf.c_cc[2] = 0xff; /* turn off bs processing */ ioctl(fd,TCSETAF,&tbuf); dlink_init_admin(); }#endifline = 0;for (;;) {#ifdef CROSSVIEW if (dltype == 2) { s = getBinRec(fd,recbuf,&nextaddr, &len); /* ** the last record in the download sequence ** contains the start address */ start_address = nextaddr; if (s == REC_DATA) memwrite(recbuf,len); if (s == REC_ERROR) { /* dlink_terminate( fd ); */ s = -3; } } else {#endif blksz = read(fd,recbuf,MAXREC-1); line++;#if 0 /* original */ if (blksz) blksz--; /* remove line termination char */#else /* 970305 delete all line termination characters */ while (blksz && (recbuf[blksz-1] == '\n' || recbuf[blksz-1] == 0 || recbuf[blksz-1] == '\r' || recbuf[blksz-1] == 003)) blksz--;#endif recbuf[blksz] = 0; /* null terminate the line */ if (dlproto == XONXOFF) writec(fd,CNTRL('s')); if (strempty(recbuf)) { if (dlproto == XONXOFF) writec(fd,CNTRL('q')); else if (dlproto == ETXACK) writec(fd,CNTRL('f')); if (dlecho == LFEED) writec(fd,'\n'); continue; /* skip blank lines */ }#ifdef CROSSVIEW }#endif blkinx = 0; if (dltype == -1) { if (recbuf[0] == '/') dltype = 1; else if (recbuf[0] == 'S') dltype = 0; else { printf("bad record type\n"); dltype = ETXACK; err++; break; } } if (dltype == 1) s = fload(recbuf,offset,&len,&flags); else if (dltype == 0) s = sload(recbuf,offset,&len,&flags); /* return: -1..-N = err, 0 = end, 1 = ok */ if (s < 0) { printf("error %d on line %d\n",s,line); err++; errs[0-s]++; } else tot += len;#ifdef CROSSVIEW if ( dltype == 2 ) { if ( s == REC_END ) break; } else#endif { if (s == 0) break; if (s < 0 && dlproto == ETXACK) break; } if (dltype != 2) { if (dlproto == XONXOFF) writec(fd,CNTRL('q')); else if (dlproto == ETXACK) writec(fd,CNTRL('f')); } if (dlecho == LFEED) writec(fd,'\n'); }if ( dltype != 2 ) { if (dlproto == XONXOFF) writec(fd,CNTRL('q')); else if (dlproto == ETXACK) { if (err > 0) writec(fd,CNTRL('u')); else writec(fd,CNTRL('f')); } }if (dlecho == LFEED) writec(fd,'\n');if (fd > STDERR) close(fd);flush_target(ICACHE);if (err) { printf("\n%d errors\n",err); for (i=1;i<6;i++) if (errs[i]) printf(" %3d %s\n",errs[i],dlerrs[i]); }else { if ( dltype == 2 ) printf("!540!pc=%08x\n", start_address ); else { if (!(flags&DL_DFLAG)) printf("Entry address is %08x\n",getPc()); printf("\ntotal = 0x%x bytes\n",tot); } }writec(fd,CNTRL('q'));if (!err && flags&DL_DFLAG) callDriver();}/************************************************************** callDriver()*/callDriver(){DriverTbl *d;Func *f;flush_cache(DCACHE);flush_cache(ICACHE);d = (DriverTbl *)DRIVER_BASE;if (d->version != DVRIF_VERS) { printf("%d: unexpected driver interface version. Need %d\n", d->version,DVRIF_VERS); if (d->version > 10000) { printf("It looks like it might have the wrong endianness\n"); } return; }cpuType = *d->cputype;printf("%s has been loaded.\n",d->name);addGpRegs();#ifdef GHSf = (Func *)DRIVER_BASE;(* f)(); /* call the driver */#else(* ((Func *)DRIVER_BASE))(); /* call the driver */#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -