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

📄 ri.c

📁 国产CPU-龙芯(loongson)BIOS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//extern onintr(int a,int *b);//#include "mips/cpu.h"#include <prid.h>#include <stdio.h>	#include <sys/sys/signal.h>#ifdef R3081#include "r3081.h"#endif#ifdef R3041#include "r3041.h"#endif#include "ri.h"#ifdef	GODSONEV1int global_div_num=0;#endifextern int do_ri (struct pt_regs *xcp);int __compute_return_epc(struct pt_regs *regs);static unsigned long mips_get_word_l(struct pt_regs *xcp, void *va, int *perr){		*perr = 0;		return(*(unsigned long *)va);}static int mips_put_word_l(struct pt_regs *xcp, void *va, unsigned long val){		*(unsigned long *)va = val;		return 0;}static int emu_lwl(struct pt_regs * regs,mips_instruction ir,vaddr_t_l emulpc){ 	int err = 0;	/*the "ir" is the instruction causing the exception*/	/*get the real address,perhaps the address is not word aligned*/	void *va = REG_TO_VA_l (regs->regs[MIPSInst_RS(ir)])+ MIPSInst_SIMM(ir);		unsigned long addr = 0;	unsigned long emul_pc = (unsigned long)emulpc;		unsigned long little_three_bits;	unsigned long value,value_tmp;//	printf("emu_lwl\r\n");	/*compute the correct position in the RT*/	/*note !!!!: we have supposed the CPU is little_Endianness and status regiester's RE bit =0 */	/*little Endianness*/	little_three_bits = (unsigned long)va&(0x7);	value_tmp = regs->regs[MIPSInst_RT(ir)];	switch(little_three_bits) {		case 0:		case 4:		 /*must check lwl valid*/		 addr = (unsigned long) va;		 check_axs(emul_pc,addr,4);		 value = mips_get_word_l(regs,va,&err);		 if(err){			 return SIGBUS;		 }		 value<<=24;		 value_tmp &= 0xffffff;	         regs->regs[MIPSInst_RT(ir)] =value_tmp|value;			break;					case 1:		case 5:		addr = (unsigned long)va -1;		check_axs(emul_pc,addr,4);		value = mips_get_word_l(regs,(void *)((unsigned long) va-1),&err);		if(err){			return SIGBUS;		}		value<<=16;		value_tmp&=0xffff;		regs->regs[MIPSInst_RT(ir)] =value_tmp|value;			break;		case 2:		case 6:		addr = (unsigned long)va - 2;		check_axs(emul_pc,addr,4);		value = mips_get_word_l(regs,(void *)((unsigned long)va-2),&err);		if(err){			return SIGBUS;		}		value<<=8;		value_tmp &= 0xff;		regs->regs[MIPSInst_RT(ir)] =value_tmp|value;			break;					case 3:		case 7:		addr = (unsigned long)va - 3;		check_axs(emul_pc,addr,4);		value = mips_get_word_l(regs,(void *)((unsigned long)va-3),&err);		if(err){			return SIGBUS;		};		regs->regs[MIPSInst_RT(ir)] = value;			break;	} /*swith ended*/	return 0;}static int emu_lwr(struct pt_regs *regs,mips_instruction ir,vaddr_t_l emulpc){ 	int err = 0;	/*the "ir" is the instruction causing the exception*/	/*get the real address,perhaps the address is not word aligned*/	void *va = REG_TO_VA_l (regs->regs[MIPSInst_RS(ir)])		+ MIPSInst_SIMM(ir);	unsigned long addr;	unsigned long emul_pc = (unsigned long)emulpc;	unsigned long little_three_bits;	unsigned long value,value_tmp;//	printf("emu_lwr\r\n");	/*compute the correct position in the RT*/	/*note !!!!: we have supposed the CPU is little_Endianness and status regiester's RE bit =0 */	little_three_bits = (unsigned long)va&(0x7);	value_tmp = regs->regs[MIPSInst_RT(ir)];	switch(little_three_bits) {		case 0:		case 4:		 /*must check lwl valid*/		addr = (unsigned long)va ;		check_axs(emul_pc,addr,4);		 value = mips_get_word_l(regs,va,&err);		 if(err){			 return SIGBUS;		 }	         regs->regs[MIPSInst_RT(ir)] =value;			break;					case 1:		case 5:		addr = (unsigned long)va -1;		check_axs(emul_pc,addr,4);		value = mips_get_word_l(regs,(void *)((unsigned long)va-1),&err);		if(err){			return SIGBUS;		}		value>>=8;		value_tmp&=0xff000000;		regs->regs[MIPSInst_RT(ir)] =value_tmp|value;			break;		case 2:		case 6:		addr = (unsigned long)va-2;		check_axs(emul_pc,addr,4);		value = mips_get_word_l(regs,(void *)((unsigned long)va-2),&err);		if(err){			return SIGBUS;		}		value>>=16;		value_tmp &= 0xffff0000;		regs->regs[MIPSInst_RT(ir)] =value_tmp|value;			break;					case 3:		case 7:		addr = (unsigned long)va -3;		check_axs(emul_pc,addr,4);		value = mips_get_word_l(regs,(void *)((unsigned long)va-3),&err);		if(err){			return SIGBUS;		};		value>>=24;		value_tmp &= 0xffffff00;		regs->regs[MIPSInst_RT(ir)] = value_tmp|value;			break;	} /*swith ended*/	return 0;}static int emu_swl(struct pt_regs *regs,mips_instruction ir, vaddr_t_l emulpc){	int err = 0;	/*the "ir" is the instruction causing the exception*/	/*get the real address,perhaps the address is not word aligned*/	void *va = REG_TO_VA_l (regs->regs[MIPSInst_RS(ir)])		+ MIPSInst_SIMM(ir);	unsigned long addr;	unsigned long emul_pc = (unsigned long)emulpc;	unsigned long little_three_bits;	unsigned long value,value_tmp;//	printf("emu_swl\r\n");	/*compute the correct position in the RT*/	/*note !!!!: we have supposed the CPU is little_Endianness and status re	* giester's RE bit =0 */	little_three_bits = (unsigned long)va&(0x7);	value_tmp = regs->regs[MIPSInst_RT(ir)];	switch(little_three_bits) {		case 0:		case 4:			addr = (unsigned long)va;			check_axs(emul_pc,addr,4);			value_tmp >>= 24;			value = mips_get_word_l(regs,va,&err);			if(err){				return SIGBUS;			}			value &=0xffffff00;			value |= value_tmp;			if(mips_put_word_l(regs,va,value)){				return SIGBUS;			}			break;		case 1:		case 5:			addr = (unsigned long)va -1;			check_axs(emul_pc,addr,4);			value_tmp >>= 16;			value = mips_get_word_l(regs,(void *)((unsigned long)va-1),&err);			if(err){				return SIGBUS;			}			value &=0xffff0000;			value |= value_tmp;			if(mips_put_word_l(regs,(void *)((unsigned long)va-1),value)){				return SIGBUS;			}			break;		case 2:		case 6:			addr = (unsigned long)va - 2;			check_axs(emul_pc,addr,4);			value_tmp >>= 8;			value = mips_get_word_l(regs,(void *)((unsigned long)va-2),&err);			if(err){				return SIGBUS;			}			value &=0xff000000;			value |= value_tmp;			if(mips_put_word_l(regs,(void *)((unsigned long)va-2),value)){				return SIGBUS;			}			break;		case 3:		case 7:			addr = (unsigned long)va - 3;			check_axs(emul_pc,addr,4);			value = value_tmp;									if(mips_put_word_l(regs,(void *)((unsigned long)va-3),value)){				return SIGBUS;			}			break;	}	return 0;}static int emu_swr(struct pt_regs *regs,mips_instruction ir, vaddr_t_l emulpc){	int err = 0;	/*the "ir" is the instruction causing the exception*/	/*get the real address,perhaps the address is not word aligned*/	void *va = REG_TO_VA_l (regs->regs[MIPSInst_RS(ir)])		+ MIPSInst_SIMM(ir);	unsigned long addr;	unsigned long emul_pc = (unsigned long)emulpc;		unsigned long little_three_bits;	unsigned long value,value_tmp;	//	printf("emu_swr\r\n");	/*compute the correct position in the RT*/	/*note !!!!: we have supposed the CPU is little_Endianness and status re	* giester's RE bit =0 */	little_three_bits = (unsigned long)va&(0x7);	value_tmp = regs->regs[MIPSInst_RT(ir)];	switch(little_three_bits) {		case 0:		case 4:			addr = (unsigned long) va;			check_axs(emul_pc,addr,4);			value = value_tmp;			if(mips_put_word_l(regs,va,value)){				return SIGBUS;			}			break;		case 1:		case 5:			addr = (unsigned long)va -1;			check_axs(emul_pc,addr,4);			value_tmp <<= 8;			value = mips_get_word_l(regs,(void *)((unsigned long)va-1),&err);			if(err){				return SIGBUS;			}			value &=0xff;			value |= value_tmp;			if(mips_put_word_l(regs,(void *)((unsigned long)va-1),value)){				return SIGBUS;			}			break;		case 2:		case 6:			addr = (unsigned long)va - 2;			check_axs(emul_pc,addr,4);			value_tmp <<= 16;			value = mips_get_word_l(regs,(void *)((unsigned long)va-2),&err);			if(err){				return SIGBUS;			}			value &=0xffff;			value |= value_tmp;			if(mips_put_word_l(regs,(void *)((unsigned long)va-2),value)){				return SIGBUS;			}			break;		case 3:		case 7:			addr = (unsigned long)va -3;			check_axs(emul_pc,addr,4);			value_tmp <<= 24;			value = mips_get_word_l(regs,(void *)((unsigned long)va-3),&err);			if(err){				return SIGBUS;			}			value &= 0xffffff;			value |= value_tmp;						if(mips_put_word_l(regs,(void *)((unsigned long)va-3),value)){				return SIGBUS;			}			break;	}	return 0;}static int emu_div(struct pt_regs *regs,mips_instruction ir){	int x,y;	int flag = 0;	int quotient = 0,remainder = 0;	unsigned int absx,absy,absquotient = 0,absremainder = 0,bm = 1;	/*the "ir" is the instruction causing the exception*/	x = regs->regs[MIPSInst_RS(ir)];	y = regs->regs[MIPSInst_RT(ir)];	#ifdef __test_ri__	//printf("now in function:emu_div().\r\n");#endif	if( y == 0 ) {/*overflow*/		return SIGABRT;	}	/*x and y 符号是否不同*/	flag = (x&0x80000000)^(y&0x80000000);		/*get the abs(x)*/	if(x<0){		absx = (unsigned int)-x;	}else {		absx = (unsigned int)x;	}		/*get the abs(y)*/	if(y<0){		absy = (unsigned int) -y;	}else {		absy = (unsigned int)y;	}		/*caculate the absx/absy*/			if(absx<absy) {/*don't need to calculate*/		absquotient = 0;		absremainder = absx;		goto end;	}       	while(!(absy&0x80000000))

⌨️ 快捷键说明

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