📄 iceif.c
字号:
return(0);}/************************************************************** int setbp_target(int n,int type,Ulong addr,Ulong addr2,Ulong value) DEF* type: 1=bpc 2=bda 3=itemp 4=sstep 5=nonrt* returns bp number, or -1 on error.*/int setbp_target(n,type,addr,addr2,value)int n,type;Ulong addr,addr2,value;{int i,method,atype,code;Ulong info,x;long mask; /* must be signed */printDiag(1,"setbp_target(%d,%x,%08x,%08x,%08x)\n",n,type,addr,addr2,value); atype = type>>4;type &= 0xf;code = 0;if (type == BPTYPE_NONRT) { printDiag(0,"warning: this breakpoint requires non real-time execution\n"); nonrt = 1; return(0); }if ((n=which_bpt(addr,type)) != -1) { printDiag(1,"setbp_target: %08x duplicate bpt\n",addr); return(0-BP_E_ERR); }if (type == BPTYPE_PC || type == BPTYPE_ITMP || type == BPTYPE_TRACE) { if (is_writeable_target(addr)) method = BRK_METHOD_RAM; else if (is_cacheable(addr) && ilockReq(addr)) method = BRK_METHOD_ROM; else if ((x=hwibReq(addr)) != -1) { method = BRK_METHOD_HW; if (atype&8) mask = addr2; /* 8 = addr2 is a mask */ else if (addr2) { /* compute mask */ for (mask=0x80000000;(addr&mask) == (addr2&mask);mask>>=1) ; mask <<= 1; /* oops! one step too many */ code |= BP_W_MSK; } else mask = 0xffffffff; /* all-enable */#if 0 /* 981214 */ dcs = DCS_TR|DCS_UD|DCS_KD|DCS_DE|DCS_PCE; /* Note: some dbx implementations require a Physical Address */#endif info = (x<<16); } else { printDiag(0,"%08x: can't set bpt\n",addr); return(0-BP_E_ERR); } }else if (type == BPTYPE_DATA) { if ((x=hwdbReq(addr)) == -1) { printDiag(0,"%08x: can't set bpt\n",addr); return(0-BP_E_ERR); } method = BRK_METHOD_HW;#if 0 /* 981214 */ dcs = DCS_TR|DCS_UD|DCS_KD|DCS_DE|DCS_DAE; if (atype&1) dcs |= DCS_DR; /* 1 = read */ if (atype&2) dcs |= DCS_DW; /* 2 = write */#else info = (x<<16); if (atype&1) info |= 2; /* 2 = read */ if (atype&2) info |= 1; /* 1 = write */#endif if (atype&4) return(0-BP_E_VAL); /* 4 is used by the gdb interface to indicate that a value * has been specified. See debug.c. */ if (atype&8) mask = addr2; /* 8 = addr2 is a mask */ else if (addr2) { /* compute mask */ for (mask=0x80000000;(addr&mask) == (addr2&mask);mask>>=1) ; mask <<= 1; /* oops! one step too many */ code |= BP_W_MSK; } else mask = 0xffffffff; /* all-enable */ }if (n == -1) { for (i=0;i<MAX_BPT;i++) if (brkList[i].type == 0) break; if (i >= MAX_BPT) { printDiag(0,"fatal error: out of bpts\n"); return(0-BP_E_ERR); } n = i; }if (n < 0 || n >= MAX_BPT) { printDiag(0,"%d: bad bpt number\n",n); return(0-BP_E_ERR); }brkList[n].type = type;brkList[n].addr = addr;brkList[n].method = method;brkList[n].mask = mask;brkList[n].aux[0] = info;return((code<<16)|n);}/************************************************************** int clrbp_target(int n) DEF* return 0 on error; else 1*/int clrbp_target(n)int n;{printDiag(1,"clrbp_target(%d)\n",n);if (n < 0 || n >= MAX_BPT) { printDiag(0,"%d: bad bpt number\n",n); return(0); }if (brkList[n].type==0) { printDiag(0,"%d: bpt is not set\n",n); return(0); }brkList[n].type = 0;return(1);}/**************************************************************/int which_bpt(Ulong addr,int type){int i;for (i=0;i<MAX_BPT;i++) { if (brkList[i].type==0) continue; if (type && type != brkList[i].type) continue; if (brkList[i].addr == addr) return(i); }return(-1);}/************************************************************** int which_dbpt(int hwbptno) DEF*/int which_dbpt(int hwbptno){int i;for (i=0;i<MAX_BPT;i++) { if (brkList[i].type==0) continue; if (brkList[i].type != BPTYPE_DATA) continue; if (brkList[i].method != BRK_METHOD_HW) continue; if (((int)(brkList[i].aux[0]>>16)) == hwbptno) return(i); }return(-1);}#define RS_(x) (((x) >> 21) & ((1L << 5) - 1))#define SEX16(x) ((long)(x<<16)>>16)#define SIMM16(x) (SEX16(UIMM16(x)))#define UIMM16(x) ((x)&0xffff)#define IS_LDST(n) ((((n)>>26)>=0x20)&&(((n)>>26)<=0x2e))/************************************************************** int is_bpt(addr) DEF*/int is_bpt(addr)Ulong addr;{int i;Ulong instr,ea;for (i=0;i<MAX_BPT;i++) { if (brkList[i].type==0) continue; if (brkList[i].addr == addr) return(brkList[i].type); if (brkList[i].type == BPTYPE_DATA) { instr = read_target(XT_MEM,addr,4); /* read instr */ /* if lw/sw and addr eval == addr return type */ if (!IS_LDST(instr)) continue; ea = read_target(XT_GPR,RS_(instr),4) + SIMM16(instr); if ((ea&brkList[i].mask) == brkList[i].addr) { printDiag(2,"is_bpt: %08x will hwdb\n",addr); return(brkList[i].type); } } }return(0);}/************************************************************** void brkDelete(Ulong type) DEF*/void brkDelete(type)Ulong type;{int i;for (i=0;i<MAX_BPT;i++) { if (type == brkList[i].type) brkList[i].type = 0; }}/************************************************************** int is_writeable_target(Ulong adr) DEF*/int is_writeable_target(adr)Ulong adr;{Uchar x,y;OcmRec *p;if ((p=is_ocm(adr)) && p->readonly) { printDiag(1,"\nocm not writeable(%08x)\n",adr); return(0); }if (!noforcek1) adr |= K1BASE;x = (Uchar)read_target(XT_MEM,adr,1);y = ~x;writeGpr(8,y);writeGpr(9,adr);send_instr(SB(8,0,9));readA0();/* flush_target(DCACHE); */if (read_target(XT_MEM,adr,1) != y) { printDiag(1,"\nnot writeable(%08x)\n",adr); return(0); }printDiag(1,"%08x is writeable\n",adr);/* restore the value */writeGpr(8,x);writeGpr(9,adr);send_instr(SB(8,0,9));readA0();return(1);}/************************************************************** void send_buffer(void) DEF* write_target operations simply write to a buffer. Then* from time to time the buffer gets flushed down to the* target by calling this function.*/void send_buffer(void){int wds;Ulong addr,eadr,v;static send_buffer_active;Uchar *p;if (send_buffer_active) return;if (target_stopped != 2) wakeup();if (ice.buf==0) ice.buf = (Uchar *)malloc(BUFSZ);if (ice.bcnt==0 && ice.rlcnt==0) return;send_buffer_active=1;printDiag(3,"send_buffer()\n");if (is_cacheable(ice.start_addr)) dcache_dirty = 1;printDiag(1,"send_buffer: sadr=%08x bcnt=%d rlcnt=%d\n", ice.start_addr,ice.bcnt,ice.rlcnt);if (ice.rlcnt && ice.rlcnt <= RLTHRESHOLD) /* expand rlcnt in buffer */ for (;ice.rlcnt;ice.rlcnt--) ice.buf[ice.bcnt++] = ice.prev_v;addr = ice.start_addr;eadr = addr+ice.bcnt;p = ice.buf;if (addr == 0xbfff0000 && ice.bcnt == 4) printDiag(1,"[%02x,%02x,%02x,%02x]\n",p[0],p[1],p[2],p[3]);/* send bytes until word aligned address */while (addr&3 && addr < eadr) send_byte(addr++,*p++);/* compute number of complete words */if (addr == eadr) wds = 0;else wds = ((eadr&~3) - addr)/4;printDiag(1,"send_buffer: eadr=%08x wds=%d\n",eadr,wds);if (wds > 3) {#if defined(EJTAG) && !defined(PMCC) if (ejtag_mode) swap32n(p,wds);#endif if (lendian_target) swap32n(p,wds); send_words(addr,(Ulong *)p,wds); addr += wds*4; p += wds*4; }else for (;wds;wds--,addr += 4,p += 4) { v = read_unaligned_long(p);#if defined(EJTAG) && !defined(PMCC) if (ejtag_mode) swap32n((Uchar *)&v,1);#endif if (lendian_target) swap32n((Uchar *)&v,1); send_bhw(addr,v,4); }/* send trailing bytes */while (addr < eadr) send_byte(addr++,*p++);if (ice.rlcnt > RLTHRESHOLD) set_bytes(addr,ice.prev_v,ice.rlcnt);setFlushneeded(ice.start_addr,ice.rlcnt+ice.bcnt);ice.rlcnt = ice.bcnt = 0;send_buffer_active=0;}/************************************************************** void write_target_byte(Ulong addr,Ulong v) DEF* write_target() calls this function to add bytes to the* buffer. send_buffer() is used to actually send the bytes* to the target.*/void write_target_byte(addr,v)Ulong addr,v;{printDiag(5,"write_target_byte(%08x,%02x)\n",addr,v&0xff);if (addr != ice.expected_addr) send_buffer();v &= 0xff;if (v == ice.prev_v && ice.bcnt) { ice.rlcnt++; if (ice.rlcnt >= MAXRL) send_buffer(); }else { if (ice.rlcnt) { if (ice.rlcnt <= RLTHRESHOLD) { /* expand in place */ for (;ice.rlcnt;ice.rlcnt--) ice.buf[ice.bcnt++] = ice.prev_v; if (ice.bcnt >= BUFSZ) send_buffer(); } else send_buffer(); } if (ice.bcnt == 0) ice.start_addr = addr; ice.buf[ice.bcnt++] = ice.prev_v = (Uchar)v; if (ice.bcnt+RLTHRESHOLD >= BUFSZ) send_buffer(); }ice.expected_addr = addr+1;}/************************************************************** void send_byte(Ulong addr,Uchar v) DEF*/void send_byte(Ulong addr,Uchar v){int offs,diff;OcmRec *p;printDiag(5,"send_byte(%08x,%02x)\n",addr,v);if ((p=is_ocm(addr)) && p->func) { run_ocm(p,1,addr,1,v); return; }offs=0;diff = addr-current_r9;if (diff < -32768 || diff > 32767) writeGpr(9,addr);else offs = (addr-current_r9)&0xffff;writeGpr(8,v);send_instr(SB(8,offs,9));readA0();}/************************************************************** void set_bytes(Ulong addr,Uchar v,int n) DEF* Set multiple bytes e.g. fill memory* May also be used during download.*/void set_bytes(Ulong addr,Uchar v,int n){OcmRec *p;int offset;printDiag(4,"set_bytes(%08x,%02x,%d)\n",addr,v,n);#if defined(EJTAG) && !defined(PMCC)if (ejtag_mode) { if (addr&3) { writeGpr(9,addr); writeGpr(2,v); for (offset=0;addr&3;addr++,offset++,n--) { send_instr(SB(2,offset,9)); } readA0(); } if (!EjtagDownload(addr,n/4)) { printDiag(0,"EjtagDownload: failed\n"); return; } if (!EjtagControl(EJTAG_FILL,(v<<24)|(v<<16)|(v<<8)|v,0)) { printDiag(0,"EjtagControl: FILL: failed\n"); return; } addr += n; n &= 3; if (n>0) { writeGpr(9,addr); writeGpr(2,v); for (offset=0;n>0;offset++,n--) { send_instr(SB(2,offset,9)); } readA0(); } return; }#endifif ((p=is_ocm(addr)) && p->func) { for (;n>0;n--) run_ocm(p,1,addr++,1,v); return; }writeGpr(9,addr);writeGpr(8,n);writeGpr(2,v);send_instr(SB(2,0,9));send_instr(SUBIU(8,1));send_instr(BNE(8,0,-3)); /* self=-1 */send_instr(ADDIU(9,9,1));readA0();current_r8 = current_r9 = 0;}/************************************************************** void send_bhw(Ulong addr,Ulong v,int sz) DEF* 980704 Created.** This was created to provide a quick solution for a specific* problem. The problem is that my write buffer discards info* about the size of the write access (bhw). This is not normally a* problem for memory. But can be a big problem for device registers.** The correct solution is to rewrite the buffer so that it remembers* what size data it contains. Writes of a different size would* cause a send_buffer(). But this is complicated to get the RL* encoding right for this scheme. Especially the expand-in-place.** So for now I am handling write hword as a special case. I always* send_buffer(), then I write the hword directly, bypassing the* buffer.*/void send_bhw(addr,v,sz)Ulong addr;Ulong v;int sz;{int offs,diff;OcmRec *p;#ifdef VERBOSE_DOWNLOADprintDiag(1,"send_bhw(%08x,%08x,%d)\n",addr,v,sz);#endifif ((p=is_ocm(addr)) && p->func) { run_ocm(p,1,addr,sz,v); return; }offs=0;diff = addr-current_r9;if (diff < -32768 || diff > 32767) writeGpr(9,addr);else offs = (addr-current_r9)&0xffff;writeGpr(8,v);switch (sz) { case 1 : send_instr(SB(8,offs,9)); break; case 2 : send_instr(SH(8,offs,9)); break; case 4 : send_instr(SW(8,offs,9)); break; }readA0();}#if 0 /* 980704 Replaced by send_bhw *//************************************************************** void send_word(Ulong addr,Ulong v) DEF*/void send_word(addr,v)Ulong addr;Ulong v;{int offs,diff;OcmRec *p;#ifdef VERBOSE_DOWNLOADprintDiag(1,"send_word(%08x,%08x)\n",addr,v);#endifif ((p=is_ocm(addr)) && p->func) { run_ocm(p,1,addr,4,v); return; }offs=0;diff = addr-current_r9;if (diff < -32768 || diff > 32767) writeGpr(9,addr);else offs = (addr-current_r9)&0xffff;writeGpr(8,v);send_instr(SW(8,offs,9));readA0();}#endif/************************************************************** void send_words(Ulong addr,Ulong *vp,int n) DEF* send multiple words i.e. download*/void send_words(addr,vp,n)Ulong addr;Ulong *vp;int n;{int gwp_offs;OcmRec *p;Ulong v;printDiag(1,"send_words(%08x,%08x..,%d)\n",addr,*vp,n);#if defined(EJTAG) && !defined(PMCC)if (ejtag_mode) { printDiag(1,"EjtagDownload(%08x,%d)\n",addr,n); if (!EjtagDownload(addr,n)) { printDiag(0,"EjtagDownload: failed\n"); return; } printDiag(1,"EjtagControl(BLOCK,0,%08x)\n",vp); if (!EjtagControl(EJTAG_BLOCK,0,vp)) { printDiag(0,"EjtagControl: BLOCK: failed\n"); return; }#if 0 printDiag(1,"EjtagControl:WORD"); for (;n>0;n--) { printDiag(1,"%08x ",*vp); if (!EjtagControl(EJTAG_WORD,*vp++,0)) { printDiag(0,"EjtagControl: WORD: failed\n"); return; } } printDiag(1,"\n");#endif return; }#endifif ((p=is_ocm(addr)) && p->func) { for (;n>0;n--,addr += 4) run_ocm(p,1,addr,1,*vp++); return; }getSAP();if (savearea.vers > 1) gwp_offs = ICE_GWP;else gwp_offs = ICE_OLD_GWP;if (savearea.gwp==0) { savearea.gwp = read_target(XT_MEM,(Ulong)(gwp_offs+savearea.sap),4); if (savearea.gwp==0) { printDiag(0,"fatal error: can't get address of get_word\n"); return; } printDiag(1,"gwp %08x\n",savearea.gwp); if (!noforcek1) savearea.gwp |= K1BASE; }send_instr(MOVE(10,31)); /* save RA -- non-leaf */writeGpr(9,addr); /* start address */writeGpr(8,n); /* word count */writeGpr(4,savearea.gwp);/* 4: */send_instr(JALR_R4); /* jal get_word -> v0 */send_instr(SUBIU(8,1)); /* word count-- */send_instr(SW(2,0,9)); /* store the word */send_instr(BNE(8,0,-4)); /* self=-1 */send_instr(ADDIU(9,9,4)); /* next word address */send_instr(MOVE(31,10)); /* restore RA */send_instr(SENDA0); /* execute it */instr_buffer_cnt = 0;PUT_BYTES((Uchar *)vp,n*4); /* send data */if (!readWord(&v)) { /* wait for done */ printDiag(0,"send_words: readWord failed\n"); }current_r8 = current_r9 = 0;}/************************************************************** int is_bptReq(Ulong addr,Ulong v) DEF* Changes a write_target into a setbp or clrbp*/is_bptReq(addr,v)Ulong addr,v;{int n;#if 0 /* old */if (breakcode && (v == breakcode)) setbp_target(-1,BPTYPE_PC,addr,0,0);#else /* 980825 new */#ifdef PMCCif (!(is_xvwmode() || is_gdbmode())) return(0);if ((is_xvwmode() && v == XVWBREAKCODE) || (is_gdbmode() && (v == DBXBREAKCODE || v == GDBBREAKCODE)) ) setbp_target(-1,BPTYPE_PC,addr,0,0);#else /* dll */if (breakcode && (v == breakcode)) setbp_target(-1,BPTYPE_PC,addr,0,0);#endif#endifelse if ((n=which_bpt(addr,0)) != -1) clrbp_target(n);else return(0);printDiag(1,"is_bptReq(%08x,%08x)\n",addr,v);return(1);}#if 0if (xvwmode && v == XVWBREAKCODEgdbmode && v == GDBBREAKCODEif (!(is_xvwmode() || is_gdbmode())) return(0);if ((is_xvwmode() && v == XVWBREAKCODE) || (is_gdbmode() && (v == DBXBREAKCODE || v == GDBBREAKCODE)) ) setbp_target(-1,BPTYPE_PC,addr,0,0);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -