⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iceif.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
📖 第 1 页 / 共 3 页
字号:
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 + -