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

📄 iceif.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************  void write_target(int type,Ulong addr,Ulong v,int sz) DEF*/void write_target(int type,Ulong addr,Ulong v,int sz){int reg;printDiag(1,"write_target(%s,%08x,%08x,%d)\n", xtcodes[type],addr,v,sz);reg = addr;switch (type) {	case XT_PC :	   switch (reg) {		case 0 :		   getSAP();		   if (savearea.vers > 1)		   write_target(XT_MEM,(Ulong)(ICE_EPC+savearea.sap),v,4);		   else		   write_target(XT_MEM,(Ulong)(ICE_OLD_EPC+savearea.sap),v,4);		   break;		case 1 :			writeGpr(8,v);			send_instr(OP_MTHI|(8<<21));			break;		case 2 :			writeGpr(8,v);			send_instr(OP_MTLO|(8<<21));			break;		}		break;  /* 990319 */	case XT_MEM :		if (!savearea.sap) getSAP(); /* 980818 */		/* Be sure that sap info is known before starting to		 * fill the buffer. Otherwise download can fail.		 */#if 0  	/* 981222 This screws up 4011 downloads. The 3 bytes at the beginning	of each block gets corrupted. I can't see why I thought I needed it. */		if (is_cacheable(addr) && has_wb_dcache && dcache_dirty)			flush_target(DCACHE);#endif		switch (sz) {			case 1 : write_target_byte(addr,v); break;			case 2 : /* 980704 This is a hack */				send_buffer();				send_bhw(addr,v,2);				break;			case 4 : 				if (is_bptReq(addr,v)) break;				if (lendian_target) swap32n((Uchar *)&v,1);				write_target_byte(addr,v>>24);				write_target_byte(addr+1,v>>16);				write_target_byte(addr+2,v>>8);				write_target_byte(addr+3,v);				break;			}		break;	case XT_GPR : 		writeUgpr(reg,v);		break;	case XT_CP0 : 		writeGpr(8,v);		send_instr(MTC0(8,reg));		v = readA0();		break;	case XT_CP1 :		writeGpr(8,v);		send_instr(OP_MTC1|(8<<16)|(reg<<11));		v = readA0();		break;	case XT_CP1C :		writeGpr(8,v);		send_instr(OP_CTC1|(8<<16)|(reg<<11));		v = readA0();		break;	case XT_DBX :		writeGpr(8,v);		send_instr(MTD(8,reg));		v = readA0();		break;	case XT_CP2 :	case XT_CP2C :	case XT_CP3 : 	case XT_CP3C : 	default : printDiag(0,"%08x: write_target: bad type\n",type);	}}/**************************************************************  int writeGpr(int reg,Ulong v) DEF*/int writeGpr(reg,v)int reg;Ulong v;{long n;int t,cnt;printDiag(2,"writeGpr(%d,%08x)\n",reg,v);if (reg == 8) current_r8 = v;else if (reg == 9) current_r9 = v;t = cnt = 0;n = (long)v;send_buffer();if (n >= -32768 && n <= 32767) {	send_instr(OP_ADDIU|(reg<<16)|(0<<21)|v&0xffff);	cnt++;	}else {	if (v&0xffff0000) {		send_instr(OP_LUI|(reg<<16)|(v>>16));		t = reg;		cnt++;		}	if (v&0xffff) {		send_instr(OP_ORI|(reg<<16)|(t<<21)|(v&0xffff));		cnt++;		}	}return(cnt);}/**************************************************************  Ulong read_target(int type,Ulong addr,int sz) DEF*/Ulong read_target(int type,Ulong addr,int sz){int reg,offs,diff;Ulong v;OcmRec *p;printDiag(1,"read_target(%s,%08x,%d) ",xtcodes[type],addr,sz);send_buffer();reg = addr;switch (type) {	case XT_PC :		switch (reg) {		   case 0 : /* PC */			getSAP();			if (savearea.vers > 1)			return read_target(XT_MEM,(Ulong)(ICE_EPC+savearea.sap),4);			else			return read_target(XT_MEM,(Ulong)(ICE_OLD_EPC+savearea.sap),4);		   case 1 : /* HI */			send_instr(OP_MFHI|(4<<11));			return readA0();		   case 2 : /* LO */			send_instr(OP_MFLO|(4<<11));			return readA0();		   }	case XT_MEM :		if ((p=is_ocm(addr)) && p->func) {			return run_ocm(p,0,addr,sz,v);			}		if (sz == 4 && addr&3) { /* 970401 half-word aligned */			addr &= ~1; /* clear LS bit */			v = read_target(XT_MEM,addr,2)<<16;			v |= read_target(XT_MEM,addr+2,2);			return(v);			}		offs=0;		diff = addr-current_r9;		if (diff < -32768 || diff > 32767) writeGpr(9,addr);		else offs = (addr-current_r9)&0xffff;		switch (sz) {			case 1 : send_instr(OP_LBU|(4<<16)|(9<<21)|offs); break;			case 2 : send_instr(OP_LHU|(4<<16)|(9<<21)|offs); break;			case 4 : send_instr(LW(4,offs,9)); break;			}		return readA0();	case XT_GPR :		return readUgpr(reg);	case XT_CP0 : 		send_instr(MFC0(4,reg));		return readA0();	case XT_CP1 :		send_instr(OP_MFC1|(4<<16)|(reg<<11));		return readA0();	case XT_CP1C :		send_instr(OP_CFC1|(4<<16)|(reg<<11));		return readA0();	case XT_DBX :		send_instr(MFD(4,reg));		return readA0();		break;	case XT_CP2 :	case XT_CP2C :	case XT_CP3 : 	case XT_CP3C : 	default : printDiag(0,"%08x: read_target: bad type\n",type);	}return(0);}/**************************************************************  Ulong readUgpr(int reg);*	Read user's GP register*/Ulong readUgpr(int reg){Ulong msk,v;int i,n;printDiag(1,"readUgpr(%d)\n",reg);getSAP();send_buffer();if (savearea.vers == 1) {	switch (reg) {	    case 2 : /* v0 */		v = read_target(XT_MEM,(Ulong)(ICE_V0+savearea.sap),4);		break;	    case 4 : /* a0 */		v = read_target(XT_MEM,(Ulong)(ICE_A0+savearea.sap),4);		break;	    case 5 : /* a1 */		v = read_target(XT_MEM,(Ulong)(ICE_A1+savearea.sap),4);		break;	    case 8 : /* t0 */		v = read_target(XT_MEM,(Ulong)(ICE_T0+savearea.sap),4);		break;	    case 9 : /* t1 */		v = read_target(XT_MEM,(Ulong)(ICE_T1+savearea.sap),4);		break;	    case 10 : /* t2 */		v = read_target(XT_MEM,(Ulong)(ICE_T2+savearea.sap),4);		break;	    case 16: /* s0 */		v = read_target(XT_MEM,(Ulong)(ICE_S0+savearea.sap),4);		break;	    case 31: /* ra */		v = read_target(XT_MEM,(Ulong)(ICE_RA+savearea.sap),4);		break;	    case 32 :		send_instr(OP_MFHI|(4<<11));		v = readA0();		break;	    case 33 :		send_instr(OP_MFLO|(4<<11));		v = readA0();		break;	    default :		if (reg == 30 && no_gpr30) return(0);		send_instr(OP_OR|(4<<11)|(0<<16)|(reg<<21));		v = readA0();		}	return(v);	}if (reg == 30 && no_gpr30) return(0);else if (reg == 32) {	send_instr(OP_MFHI|(4<<11));	v = readA0();	}else if (reg == 33) {	send_instr(OP_MFLO|(4<<11));	v = readA0();	}else if (savearea.map&(1<<reg)) { /* reg is in save area */	msk = 1;	for (i=n=0;i<reg;i++) {		if (savearea.map&msk) n++;		msk <<= 1;		}	printDiag(1,"readUgpr hsize=%d n=%d\n",savearea.hsize,n); 	v = read_target(XT_MEM,(Ulong)(savearea.hsize+n+savearea.sap),4);	}else { /* reg not in save area */	send_instr(OP_OR|(4<<11)|(0<<16)|(reg<<21));	v = readA0();	}return(v);}/**************************************************************  void writeUgpr(int reg,Ulong v);*	Write user's GP register*/void writeUgpr(int reg,Ulong v){Ulong msk;int i,n;printDiag(1,"writeUgpr(%d,%08x)\n",reg,v);getSAP();send_buffer();if (savearea.vers == 1) {	switch (reg) {	    case 2 : /* v0 */		write_target(XT_MEM,(Ulong)(ICE_V0+savearea.sap),v,4);		break;	    case 4 : /* a0 */		write_target(XT_MEM,(Ulong)(ICE_A0+savearea.sap),v,4);		break;	    case 5 : /* a1 */		write_target(XT_MEM,(Ulong)(ICE_A1+savearea.sap),v,4);		break;	    case 8 : /* t0 */		write_target(XT_MEM,(Ulong)(ICE_T0+savearea.sap),v,4);		break;	    case 9 : /* t1 */		write_target(XT_MEM,(Ulong)(ICE_T1+savearea.sap),v,4);		break;	    case 10 : /* t2 */		write_target(XT_MEM,(Ulong)(ICE_T2+savearea.sap),v,4);		break;	    case 16: /* s0 */		write_target(XT_MEM,(Ulong)(ICE_S0+savearea.sap),v,4);		break;	    case 31: /* ra */		write_target(XT_MEM,(Ulong)(ICE_RA+savearea.sap),v,4);		break;	    case 32 :		writeGpr(8,v);		send_instr(OP_MTHI|(8<<21));		break;	    case 33 :		writeGpr(8,v);		send_instr(OP_MTLO|(8<<21));		break;	    default :		if (reg == 30 && no_gpr30) break;		writeGpr(reg,v);		}	readA0();	return;	}if (reg == 30 && no_gpr30) return;else if (reg == 32) {	writeGpr(8,v);	send_instr(OP_MTHI|(8<<21));	readA0();	}else if (reg == 33) {	writeGpr(8,v);	send_instr(OP_MTLO|(8<<21));	readA0();	}else if (savearea.map&(1<<reg)) { /* reg is in save area */	msk = 1;	for (i=n=0;i<reg;i++) {		if (savearea.map&msk) n++;		msk <<= 1;		}	write_target(XT_MEM,(Ulong)(savearea.hsize+n+savearea.sap),v,4);	}else { /* reg not in save area */	writeGpr(reg,v);	readA0();	}}/**************************************************************  void freeOcmRec(OcmRec *p)*	add the OcmRec to freeOcmChain*	I do this because the IMON interface in crt3.s doesn't*	  support free();*/void freeOcmRec(OcmRec *p){p->next = freeOcmChain;freeOcmChain = p;}/**************************************************************  OcmRec *mallocOcmRec(void)*	Try to get an OcmRec from freeOcmChain. else use malloc.*/OcmRec *mallocOcmRec(void){OcmRec *p;if (freeOcmChain) {	p = freeOcmChain;	freeOcmChain = p->next;	return(p);	}return (OcmRec *)malloc(sizeof(OcmRec));}/**************************************************************  OcmRec *addOcmRec(Ulong addr,Ulong size,Ulong *func,int funclen);*	arg0 = start address of Ocm region*	arg1 = size (in bytes) of Ocm region*	arg2 = optional address of access function. else 0.*	arg3 = optional length (in words) of access function. else 0.*/OcmRec *addOcmRec(Ulong addr,Ulong size,Ulong *func,int funclen){OcmRec *p;printDiag(1,"addOcmRec(%08x,%08x,%08x,%d)\n",addr,size,func,funclen);p = mallocOcmRec();if (!p) {        printDiag(0,"addOcmRec: malloc failure. Out of memory.\n");        return(0);        }p->addr = addr;p->size = size;p->func = func;p->funclen = funclen;p->regmap_ok = 0;p->readonly = 0;p->map = 0;p->next = ocmChain;ocmChain = p;return(p);}/**************************************************************  int deleteOcmRec(Ulong addr)*/int deleteOcmRec(Ulong addr){OcmRec *p;printDiag(2,"deleteOcmRec(%08x)\n",addr);p = ocmChain;if (!p) return(0);if (p->addr == addr) { /* 1st item in chain */	ocmChain = p->next;	freeOcmRec(p);	return(1);	}for (p=ocmChain;p->next;p=p->next) {	if (p->next->addr == addr) {		p->next = p->next->next;		freeOcmRec(p->next);		return(1);		}	}return(0);}/**************************************************************  OcmRec *is_ocm(Ulong addr) DEF*       return addr of OcmRec if addr falls within an ocm region.*/OcmRec *is_ocm(addr)Ulong addr;{OcmRec *p;for (p=ocmChain;p;p=p->next) {        if (addr >= p->addr && addr < p->addr+p->size) {		printDiag(2,"%08x=ocm\n",addr);		return(p);		}        }return(0);}/**************************************************************  Ulong run_ocm(OcmRec *ocm,int mode,Ulong addr,int sz,Ulong value);*	Run the designated ocm routine.*	mode: 0=read 1=write*/Ulong run_ocm(OcmRec *ocm,int mode,Ulong addr,int sz,Ulong value){int i;Ulong need,r;Ulong saved[32];printDiag(1,"run_ocm(x,%s,%08x,%d,%08x)\n",(mode)?"write":"read",addr,sz,value);/* Can't do this if there's no function */if (ocm->func == 0 || ocm->funclen == 0) {	printDiag(1,"run_ocm: ERROR: func=%08x funclen=%d\n",		ocm->func,ocm->funclen);	return(0);	}#if 0if (savearea.vers == 1) {	printDiag(1,"ocm %08x needs new format savearea.\n",addr);	return(0);	}#endif/* return if this is a write and ocm region is readonly */if (mode == 1 && ocm->readonly) {	printDiag(1,"run_ocm: ERROR: write to ro ocm\n");	return(0);	}/* must know regmap and ibs of kernel */if (savearea.map == 0) savearea.map = kernel_map;if (savearea.ibs == 0) savearea.ibs = kernel_ibs;if (savearea.map == 0 || savearea.ibs == 0) {	printDiag(1,"run_ocm: ERROR: map=%08x ibs=%d\n",		savearea.map,savearea.ibs);	return(0);	}if (ocm->funclen > ((int)savearea.ibs)) {	printDiag(1,"ocm %08x func too large for ibuf.\n",addr);	return(0);	}if (!ocm->regmap_ok) {	send_buffer();	if (ocm->map == 0) {		writeGpr(4,2); /* regmap function */		for (i=0;i<ocm->funclen;i++) send_instr(ocm->func[i]);		ocm->map = readA0();		}	printDiag(1,"ocm %08x samap %08x ocmmap %08x.\n",				addr,savearea.map,ocm->map);	/* savearea.map is what the kernel saves */	/* ocm.map is what the ocm routine needs */	need = (~(savearea.map&ocm->map)) & ocm->map;	/* need are those extra registers that must be saved */	if (need) {#if 0	if ((savearea.map&regmap) != regmap) {		/* incompatible regmaps */		printDiag(1,"ocm %08x bad regmap %08x %08x.\n",				addr,savearea.map,regmap);		return(0);#endif		printDiag(1,"ocm %08x need %08x\n",addr,need);		send_buffer();		for (i=0;i<32;i++) {			if (need&(1<<i)) {				send_instr(OP_OR|(4<<11)|(0<<16)|(i<<21));				saved[i] = readA0();				printDiag(1,"ocm %08x save $%d %08x\n",					addr,i,saved[i]);				}			}		}	if (!need) ocm->regmap_ok = 1;	/* regmap_ok indicates that no extra saves are necessary */	}send_buffer();writeGpr(4,mode);writeGpr(5,addr);writeGpr(6,sz);writeGpr(7,value);for (i=0;i<ocm->funclen;i++) send_instr(ocm->func[i]);r = readA0();/* restore extra regs */if (need) {	for (i=0;i<32;i++) if (need&(1<<i)) {		printDiag(1,"ocm %08x restore $%d %08x\n",			addr,i,saved[i]);		writeGpr(i,saved[i]);		}	readA0();	}return(r);}/**************************************************************  Ulong domt1(Ulong sadr,Ulong eadr)*	Do Memory test part1*/Ulong domt1(Ulong sadr,Ulong eadr){/* domt1: The gpr[10]s in this func were 26 (k0) *//* domt1: The gpr[11]s in this func were 27 (k1) */send_buffer();/* part1: walking ones */writeGpr(4,sadr);writeGpr(9,eadr);/* 1: */writeGpr(10,1);/* 2: */send_instr(SW(10,0,4));send_instr(LW(11,0,4));send_instr(0);send_instr(BNE(10,11,6)); /* 1f */send_instr(0);send_instr(SLLV(10,1));send_instr(BNE(10,0,-7)); /* 2b */send_instr(0);send_instr(ADDIU(4,4,4));send_instr(BNE(4,9,-11)); /* 1b *//* 1: */return readA0();}/**************************************************************  int domt2(Ulong sadr,Ulong eadr)*	Do Memory test part2* 	part2: write address to each word*/void domt2(Ulong sadr,Ulong eadr){send_buffer();writeGpr(4,sadr);writeGpr(9,eadr);/* 1: */send_instr(SW(4,0,4));send_instr(ADDIU(4,4,4));send_instr(BNE(4,9,-3)); /* 1b */readA0();}/**************************************************************  Ulong domt3(Ulong sadr,Ulong eadr)*	Do Memory test part3* 	part3: check each word contains address*/Ulong domt3(Ulong sadr,Ulong eadr){/* domt3: The gpr[10]s in this func were 26 (k0) */send_buffer();writeGpr(4,sadr);writeGpr(9,eadr);/* 1: */send_instr(LW(10,0,4));send_instr(0);send_instr(BNE(10,4,3)); /* 1f */send_instr(0);send_instr(ADDIU(4,4,4));send_instr(BNE(4,9,-6)); /* 1b *//* 1: */return readA0();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -