/************************************************************* * File: imon/main.c * Purpose: main module for imon (ICEmonitor) * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970217 Moved stuff from cmdtable.c into this module. Deleted * cmdtable.c. * 970227 Added setbp checks to setTrcbp. * 970303 trace_mode removed (and other dup globals) * 970304 Added chm command * 970305 Added erase to chm * 970305 Removed 'call' command * 970319 Commented out the debug cmds dhm and chm. * 970728 Cygnus required Uchar in load_byte for load -f * 970901 Changed sdtf to use getNextSloadAdr(). Needed for gaps. * 970911 Fixed bug w sstep self branches. Added parens. * 970919 Changed getNextSloadAdr to getHighLoadAdr for BSO fix. * 980107 Added ifdef for GHS jal indirect bug * 980602 Don't print nvmsg if nvram not present. * 980616 Switched from devinit to hostInit(8). */ #include #include #ifdef MIPSEB char endian[] = "EB"; #else char endian[] = "EL"; #endif int vflag; int cp1ok; Ulong topClientMem; int pmlst,clilst; /* list of files opened by: PMON & client */ extern int *curlst; /* list of files opened by: current context */ unsigned long initial_sr; unsigned long _filebase; /* struct termio ttsave; 970303 */ Ulong hostType; Func *c_exception_ptr, *asm_exception_ptr; int trace_count; int trace_verbose; int trace_invalid; int trace_over; int trace_bflag; int trace_cflag; int mode_64bit; extern char *regs_sw[]; int bitstate, getjtag_cnt, putjtag_cnt; int sdump(),transp(),stty(),load(); int debug(),flush_cmd(),dhm(),chm(),sdtf(); extern Optdesc load_opts[]; extern Optdesc stty_opts[]; extern Optdesc call_opts[]; extern Optdesc tr_opts[]; extern Optdesc sdump_opts[]; extern Optdesc debug_opts[]; extern Optdesc flush_opts[]; extern Optdesc dhm_opts[]; extern Optdesc chm_opts[]; extern Optdesc sdtf_opts[]; CmdRec cmdlist[] = { {"flush",flush_opts,flush_cmd}, {"stty",stty_opts,stty}, {"tr",tr_opts,transp}, {"load",load_opts,load}, {"dump",sdump_opts,sdump}, /* 970305 {"call",call_opts,call}, */ {"sdtf",sdtf_opts,sdtf}, #if 0 /* 970319 these are useful for debugging */ {"dhm",dhm_opts,dhm}, {"chm",chm_opts,chm}, #endif {0}}; #ifndef PROMPT #define PROMPT "IMON> " #endif #ifndef DLECHO #define DLECHO "off" #endif #ifndef DLPROTO #define DLPROTO "none" #endif #ifndef HOSTPORT #define HOSTPORT "tty0" #endif #ifndef ETHERHWADDR #define ETHERHWADDR "aa:bb:cc:00:00:00" #endif #ifndef ETHERIPADDR #define ETHERIPADDR "71.0.0.211" #endif int do_diagsw(); EnvRec envlist[] = { {"dlecho",DLECHO,"off on lfeed"}, {"dlproto",DLPROTO,"none XonXoff EtxAck"}, {"hostport",HOSTPORT}, {"prompt",PROMPT}, #ifdef ETHERNET {"etheraddr",ETHERHWADDR}, {"ipaddr",ETHERIPADDR}, #endif {"heaptop"}, {"diag","0","N[:dev]",do_diagsw}, {0}}; /************************************************************* * imoninit(adr) * Called from mips.s after caches have been flushed * Executed from cacheable space * o Identifies CPU type (inits cp2 if necessary) * o Sets initial SR value * o Inits devices, command history mechanism, and environment vars * o Checks for NVRAM present * o Prints banner * o Inits breakpoint variables * Returns control to mips.s */ imoninit(adr) char *adr; { int i,c,n,nlcnt,memsize; char ch,buf[80],nvmsg[40]; Ulong saved_sr; hostType = getHostType(); initial_sr = mfc0(C0_SR); /* for imon. Clear the first 32 words of the driver */ bzero(DRIVER_BASE,32*4); #if 1 /* 980616 */ hostInit(8); #else devinit(); #endif #ifdef AUTOCONSOLE /* * A (so far) unsuccessful attempt to scan all devices to * assign the console device. */ for (;;) { nlcnt = 0; write(1,"B",1); ioctl(0,FIONREAD,&n); if (n) { for (i=0;i<1000000;i++) { ioctl(0,FIONREAD,&n); for (;n>0;n--) { read(0,&ch,1); if (ch == '\n') nlcnt++; } if (nlcnt >= 2) break; } } if (nlcnt >= 2) break; rotateCfgTbl(); devinit(); } #endif moninit(); for (i=0;cmdlist[i].name;i++) addCmdRec(&cmdlist[i]); for (i=0;envlist[i].name;i++) addEnvRec(&envlist[i]); sprintf(buf,"set heaptop %08x",CLIENTPC); do_cmd(buf); sprintf(buf,"set prompt \"%s\"",PROMPT); do_cmd(buf); hostInit(6); /* add other devices */ #ifdef NVRAM hostInit(4); if (nvCheck(nvmsg)) do_shrc(); #endif printf("\n"); printf("IMON version %s [%s",vers,endian); sprintf(full_vers_info,"imon:%s mon:%s lib:%s tools:%s inc:%s cc:%s", vers,monvers,libvers,toolvers,incvers,tools); #ifdef FPEM cp1ok = 1; printf(",FP"); #endif printf("], LSI LOGIC Corp. %s\n",date); printf("This is free software, and comes with ABSOLUTELY NO WARRANTY.\n"); printf("You are welcome to redistribute it without restriction.\n"); *prnbuf = 0; #ifdef NVRAM /* the global nvmsg was set by nvCheck earlier */ if (*nvmsg) printfb("NVRAM: %s.",nvmsg); #endif #if defined(CROSSVIEW) && defined(GDB_SUPPORT) printfb("Debugger support: CROSSVIEW, DBX."); #else #if defined(CROSSVIEW) printfb("Debugger support: CROSSVIEW."); #else #if defined(GDB_SUPPORT) printfb("Debugger support: DBX."); #endif #endif #endif printfb("Visit www.carmel.com for updates."); printfb("Type 'h' for on-line help."); printfb("\n"); printf("\n\n"); clrbpt(-1); #ifdef FPEM #ifndef NEWFP c1dat = (struct c1state *)malloc(_fpstatesz()); _fpinit(c1dat); #endif #endif } /************************************************************* * swlst(lst) */ swlst(lst) int lst; { switch (lst) { case 1 : curlst = &pmlst; break; case 2 : curlst = &clilst; break; } } /************************************************************* * pmexception(epc,cause) * An exception has been generated within PMON */ pmexception(epc,cause) unsigned long epc,cause; { printf("\nIMON Exception Epc=%08x Cause=%08x (%s) Badva=%08x\n", epc,cause, getexcname(cause&CAUSE_EXCMASK),mfc0(C0_BADVA)); monmain(); } /************************************************************* * exception() * An exception has been generated within the client * control is passed here from _exception in mips.s */ exception() { stop(0); } /************************************************************* * disp_Gprs(n) */ disp_Gprs(n) int n; { int i; if (n==1) { printf(" "); for (i=0;i<8;i++) printf(" %~8s",regs_sw[i]); printf("\n"); } printf(" $0-"); for(i = 0; i < 8; i++) printf(" %08x", getGpr(i)); if (n==1) { printf("\n "); for (i=8;i<16;i++) printf(" %~8s",regs_sw[i]); } printf("\n $8-"); for(i = 8; i < 16; i++) printf(" %08x", getGpr(i)); if (n==1) { printf("\n "); for (i=16;i<24;i++) printf(" %~8s",regs_sw[i]); } printf("\n$16-"); for(i = 16; i < 24; i++) printf(" %08x", getGpr(i)); if (n==1) { printf("\n "); for (i=24;i<32;i++) printf(" %~8s",regs_sw[i]); } printf("\n$24-"); for(i = 24; i < 32; i++) printf(" %08x", getGpr(i)); printf("\n"); } /************************************************************* * onesCount(x) * return the number of ones set */ onesCount(x) Ulong x; { int n,i; for (i=n=0;i<32;i++) { if (x&1) n++; x >>= 1; } return(n); } /************************************************************* * load_byte(addr) */ load_byte(addr) Uchar *addr; { return *addr; } /************************************************************* * store_byte(addr,v) */ store_byte(addr,v) char *addr; int v; { *addr = v; } /************************************************************* * stubs */ niceExit() { /* should never be called */ } getCpuType() { printf("tdd not loaded\n"); } disableints() {} /************************************************************* * flush_target(n) * calls the driver */ flush_target(n) int n; { if (!regChain) return; _flush_target(n); } /************************************************************* * setbp_target(n,type,addr,addr2,value) * calls the driver */ setbp_target(n,type,addr,addr2,value) int n,type; Ulong addr,addr2,value; { if (!regChain) return; _setbp_target(n,type,addr,addr2,value); } /************************************************************* * clrbp_target(n) * calls the driver */ clrbp_target(n) int n; { if (!regChain) return; _clrbp_target(n); } clienttos() {return 0xa007ffe8;} /************************************************************* * Bool setTrcbp(Ulong adr,Bool stepover) * creates the breakpoints required to perform one step * returns 1 on success, 0 on failure. */ setTrcbp(adr,stepover) Ulong adr; int stepover; { Ulong target,inst; int sz,dsz; inst = read_target32(adr); sz = instr_size(adr,inst); if (is_branch(adr,inst)) { target = actual_branch_target_address(adr,inst); if (target == adr) target = adr+((sz==2)?2:8); /* skip self branches */ /* handle the fall-thru case for conditional branches */ if (is_jal(adr,inst) && stepover) { dsz = instr_size(adr+4,read_target32(adr+4)); if (setbp_target(-1,BPTYPE_TRACE,adr+4+dsz,0,0) < 0) return(0); } #if 0 /* this was for calls to PMON entry-points */ else if (is_jr(adr,inst) && !is_writeable_target(target)) { setbp_target(-1,BPTYPE_TRACE,getGpr(31),0,0); } #endif else if (setbp_target(-1,BPTYPE_TRACE,target,0,0) < 0) return(0); } else if (setbp_target(-1,BPTYPE_TRACE,adr+sz,0,0) < 0) return(0); /* trace */ return(1); } /************************************************************* */ Optdesc flush_opts[] = { {"","flush target caches"}, {"-i","flush Icache only"}, {"-d","flush Dcache only"}, {0}}; flush_cmd(ac,av) int ac; char *av[]; { if (!regChain) { printf("Target Description Driver not loaded\n"); return; } if (ac == 1) { flush_target(ICACHEI); flush_target(DCACHEI); } else if (strequ(av[1],"-i")) flush_target(ICACHEI); else if (strequ(av[1],"-d")) flush_target(DCACHEI); } /************************************************************* */ Optdesc dhm_opts[] = { {"[adr]","display host memory"}, {0}}; dhm(ac,av) int ac; char *av[]; { int i; static Ulong *adr; if (ac > 1) sscanf(av[1],"%x",&adr); printf("%08x ",adr); for (i=0;i<32;i++) { if (i && (i%4)==0) printf("\n%08x ",adr); printf("%08x ",*adr++); } printf("\n"); } /************************************************************* */ Optdesc chm_opts[] = { {"[-f] from to size","copy host memory [to flash]"}, {0}}; chm(ac,av) int ac; char *av[]; { int i,len,val,fflag,n; Ulong src,dst; fflag = n = 0; for (i=1;i>24)&0xff); (* nvInfo.driver)(NV_WRITE,dst++,(len>>16)&0xff); (* nvInfo.driver)(NV_WRITE,dst++,(len>>8)&0xff); (* nvInfo.driver)(NV_WRITE,dst++,(len>>0)&0xff); for (i=0;i