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

📄 fpa3x_dev.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * This function performs write/read test to the MODE register bits 3-0. * The MODE register can be written only via micro-instruction. */mode_test(){	register u_int w;	u_int r;	send_message(0,VERBOSE,tst_reg,"MODE");	for (w = 0; w <= NIBBLE_MAX; w++)	{		if (write_fpa(&fpa->fp_restore_mode3_0,w,ON)) return;		if (read_fpa(&fpa->fp_mode3_0_clear,&r,ON)) return;		r &= MODE_MASK;		if (w != r) send_message(FPERR,ERROR,er_reg,"MODE",w,r);	}}/* * This function tests the WSTATUS register by write to bits 11-8, then * read back and verified.  Bits 11-8 will decode value for bits 15 and 4-0. * For this test, the inexact error bit in IMASK register will be masked. * This test will be done twice, once with inexact error bit mask, once * without.  The WSTATUS register can be written only via micro-instruction. */wstatus_test(){	register u_int w, exp, imask, k;	u_int r;	send_message(0,VERBOSE,tst_reg,"WSTATUS");	for (imask = 0; imask <= 1; imask++)	{		if (write_fpa(&fpa->fp_imask,imask,ON)) return;		for (k = 0; k <= NIBBLE_MAX; k++)		{			w = k << WSTATUS_SHIFT;			if (write_fpa(&fpa->fp_restore_wstatus,w,ON)) return;			if (read_fpa(&fpa->fp_wstatus_clear,&r,ON)) return;			r &= WSTATUS_MASK;			exp = wstatexp[k];			if (!imask && (w == WS_COND)) exp |= WS_ERROR;			if (r != exp) send_message(FPERR,ERROR,er_wstatus,w,exp,r);		}	}}/* * This function tests all registers of current context in register file by * write/read using address pattern. */datareg_test(){	register u_int reg;	u_int ms, ls;	send_message(0,VERBOSE,tst_datareg);	/* Write address pattern to all data registers */	for (reg = 0; reg < FPA_NDATA_REGS; reg++)		if (write_datareg(reg,reg,~reg)) return;	/* Read back to verify all data registers */	for (reg = 0; reg < FPA_NDATA_REGS; reg++)	{		if (read_datareg(reg,&ms,&ls)) return;		if (ms != reg || ls != ~reg)			send_message(FPERR,ERROR,er_datareg,reg,reg,~reg,ms,ls);	}}/* * Function to write to register file in current context. * Function returns 0 if successful, else nonzero. */write_datareg(reg,ms,ls)u_int reg, ms, ls;{	register u_int *addr;	addr = (u_int *)&fpa->fp_data[reg];	if (reg < FPA_NDATA_REGS)	{		if (write_fpa(addr,ms,ON)) return(TRUE);		if (write_fpa(addr+1,ls,ON)) return(TRUE);	}	return(FALSE);}/* * Function to read register file in current context. * Function returns 0 if successful, else nonzero. */read_datareg(reg,ms,ls)u_int reg, *ms, *ls;{	register u_int *addr;	addr = (u_int *)&fpa->fp_data[reg];	if (reg < FPA_NDATA_REGS)	{		if (read_fpa(addr,ms,ON)) return(TRUE);		if (read_fpa(addr+1,ls,ON)) return(TRUE);	}	return(FALSE);}/* * This function tests shadow RAM by write to the register file and read * back from the shadow RAM register. */shadow_test(){	register u_int reg;	u_int ms, ls;	send_message(0,VERBOSE,tst_shadow);	/* Write inverse address pattern to all data registers */	for (reg = 0; reg < FPA_NDATA_REGS; reg++)		if (write_datareg(reg,~reg,reg)) return;	/* Read back to verify Shadow RAM registers */	for (reg = 0; reg < FPA_NSHAD_REGS; reg++)	{		read_shadow(reg,&ms,&ls);		if (ms != ~reg || ls != reg)			send_message(FPERR,ERROR,er_shadow,reg,~reg,reg,ms,ls);	}}/* * Function to read a shadow register in current context. */read_shadow(reg,ms,ls)u_int reg, *ms, *ls;{	register u_int *addr;	addr = (u_int *)&fpa->fp_shad[reg];	if (reg < FPA_NSHAD_REGS)	{		if (read_fpa(addr,ms,ON)) return;		if (read_fpa(addr+1,ls,ON)) return;	}}/* * This function generates error conditions then verifies negative * acknowledegement status from the FPA board. */nack_test(){	register int nack, addr, k;	u_int val;	send_message(0,VERBOSE,tst_nack);	/* non 32-bit access */	addr = (u_int) &fpa->fp_imask;	for (k = 1; k < 4; k++)	{		addr += k;		nack = read_fpa((u_int *)addr,&val,OFF);		check_nack(nack,FPA_NON32_ACCESS);	}	/* write to supervisor space in user mode (hard clear pipe) */	nack = write_fpa(&fpa->fp_hard_clear_pipe,X,OFF);	check_nack(nack,FPA_PROTECTION);	/* write to supervisor space in user mode (state) */	nack = write_fpa(&fpa->fp_state,X,OFF);	check_nack(nack,FPA_PROTECTION);	/* write to Register File while it is disabled */	if (read_fpa(&fpa->fp_state,&val,ON)) return;	if (!(val & FPA_ACCESS_BIT))	{		if (write_fpa(&fpa->fp_load_ptr,X,ON)) return;		nack = write_fpa((u_int *)INS_LOADRF_M,X,OFF);		check_nack(nack,FPA_PROTECTION);	}	/* write to Microstore RAM while it is disabled */	if (read_fpa(&fpa->fp_state,&val,ON)) return;	if (!(val & FPA_LOAD_BIT))	{		if (write_fpa(&fpa->fp_load_ptr,0,ON)) return;		nack = write_fpa(&fpa->fp_ld_ram,X,OFF);		check_nack(nack,FPA_PROTECTION);	}	/* access illegal address */	nack = read_fpa((u_int *)FPA3X_ILLADDR,&val,OFF);	check_nack(nack,FPA_PROTECTION);	/* access illegal diagnostic only address */	nack = read_fpa((u_int *)FPA3X_ILLDIAG,&val,OFF);	check_nack(nack,FPA_PROTECTION);	/* read FPA-3X write-only address */	nack = read_fpa(&fpa->fp_clear_pipe,&val,OFF);	check_nack(nack,FPA_ILLEGAL_ACCESS);	/* write FPA-3X read-only address */	nack = write_fpa(&fpa->fp_pipe_status,X,OFF);	check_nack(nack,FPA_ILLEGAL_ACCESS);	/* illegal access sequence */	if (write_fpa((u_int *)DP_NOP,X,ON)) return;	nack = write_fpa((u_int *)X_LSW,X,OFF);	check_nack(nack,FPA_ILLEGAL_SEQ);	/* access pipe while pipe hung */	if (write_fpa(&fpa->fp_unimplemented,X,ON)) return;	nack = read_fpa((u_int *)&fpa->fp_data[0],&val,OFF);	check_nack(nack,FPA_HUNG_PIPE);	/* access control while pipe hung */	if (write_fpa(&fpa->fp_unimplemented,X,ON)) return;	nack = read_fpa(&fpa->fp_mode3_0_clear,&val,OFF);	check_nack(nack,FPA_HUNG_PIPE);	/* access shadow RAM while pipe hung */	if (write_fpa(&fpa->fp_unimplemented,X,ON)) return;	nack = read_fpa((u_int *)&fpa->fp_shad[0],&val,OFF);	check_nack(nack,FPA_HUNG_PIPE);	/* access illegal control register */	nack = read_fpa((u_int *)FPA3X_ILLCTRL,&val,OFF);	check_nack(nack,FPA_ILLE_CTL_ADDR);}/* * This function verifies that nack occurs and checks the IERR status. * The IERR register will be cleared afterwards, and clear pipe is issued. */check_nack(nack,ierr_exp)register int nack;register int ierr_exp;{	u_int ierr_obs;	if (!nack) send_message(FPERR,ERROR,er_nonack,ierr_exp);	else	{		if (read_fpa(&fpa->fp_ierr,&ierr_obs,ON)) return;		ierr_obs &= IERR_MASK;		if (ierr_obs != ierr_exp)			send_message(FPERR,ERROR,er_nack,ierr_exp,ierr_obs);		if (write_fpa(&fpa->fp_ierr,0,ON)) return;	}	if (write_fpa(&fpa->fp_clear_pipe,X,ON)) return;}/* * Function to issue simple instructions and check pipe status. */simpleins_test(){	register u_int inst, k;	u_int pipestat;	send_message(0,VERBOSE,tst_simpleins);	for (k = 0; inst = simple[k].inst; k++)	{		if (write_fpa((u_int *)inst,X,ON)) return;		if (read_fpa(&fpa->fp_pipe_status,&pipestat,ON)) return;		pipestat &= PIPESTAT_MASK;		if (pipestat != simple[k].stat)			send_message(FPERR,ERROR,er_simpleins,inst,simple[k].stat,pipestat);	}}/* * Function to test the pointers 1 thru 4 using single and double precision * short, extended, and command register instructions. */pointer_test(){	send_message(0,VERBOSE,tst_pointer,"short");	pointer_short();	send_message(0,VERBOSE,tst_pointer,"extended");	pointer_extend();	send_message(0,VERBOSE,tst_pointer,"command register");	pointer_cmdreg();	send_message(0,VERBOSE,tst_pointer,"increment/decrement");	pointer_incdec();}/* * Function to test pointer 2 using single and double precision short * instructions.  This function uses the operation:  reg1 = reg1 + operand. * Where reg1 uses data register 0 thru 15, and holds value 2, and the * operand holds value 6.  Result of reg1 should be 8. */pointer_short(){	register u_int dreg, r1, inst;	u_int ms, ls, ms_exp, ls_exp;	/* single precision short test */	for (r1 = 0; r1 < FPA_NSHORT_REGS; r1++)	{		/* clear all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)			if (write_datareg(dreg,SZERO,SZERO)) return;		/* load register value and execute instruction */		if (write_datareg(r1,STWO,SZERO)) return;		inst = SP_ADD | SP_REG1(r1);		if (write_fpa((u_int *)inst,SSIX,ON)) return;		/* read to check all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)		{			if (read_datareg(dreg,&ms,&ls)) return;			ms_exp = (dreg == r1) ? SEIGHT : SZERO;			ls_exp = SZERO;			if (ms != ms_exp || ls != ls_exp)				send_message(FPERR,ERROR,er_pointer,dreg,ms_exp,ls_exp,ms,ls);		}	}	/* double precision short test */	for (r1 = 0; r1 < FPA_NSHORT_REGS; r1++)	{		/* clear all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)			if (write_datareg(dreg,DZERO_M,DZERO_L)) return;		/* load register value and execute instruction */		if (write_datareg(r1,DTWO_M,DTWO_L)) return;		inst = DP_ADD | DP_REG1(r1);		if (write_fpa((u_int *)inst,DSIX_M,ON)) return;		if (write_fpa((u_int *)DP_LSW,DSIX_L,ON)) return;		/* read to check all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)		{			if (read_datareg(dreg,&ms,&ls)) return;			ms_exp = (dreg == r1) ? DEIGHT_M : DZERO_M;			ls_exp = DZERO_L;			if (ms != ms_exp || ls != ls_exp)				send_message(FPERR,ERROR,er_pointer,dreg,ms_exp,ls_exp,ms,ls);    		}	}}/* * Function to test pointer 1 thru 3 using the extended instructions. * For single precision, it uses the operation:  reg1 = op2 + (reg2 * op1). * Where reg1 uses data register 0 thru 14, and should hold result 9; *	 reg2 uses data register 1 thru 15, and holds value 4; *	 operand1 holds value 2, and operand2 holds value 1. * For double precision, it uses the operation:  reg1 = reg3 + (reg2 * op1). * Where reg1 uses data register 0 thru 13, and should hold result 10; *	 reg2 uses data register 1 thru 14, and holds value 2; *	 reg3 uses data register 2 thru 15, and holds value 4; *	 operand1 holds value 3. */pointer_extend(){	register u_int dreg, r1, r2, r3, inst;	u_int ms, ls, ms_exp, ls_exp;	/* extended single precision test */	for (r1=0, r2=1; r2 < FPA_NSHORT_REGS; r1++, r2++)	{		/* clear all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)			if (write_datareg(dreg,SZERO,SZERO)) return;		/* load register value and execute instruction */		if (write_datareg(r2,SFOUR,SZERO)) return;		inst = XSP_R1_O2aR2xO | X_REG2(r2);		if (write_fpa((u_int *)inst,STWO,ON)) return;		inst = X_LSW | X_REG1(r1);		if (write_fpa((u_int *)inst,SONE,ON)) return;		/* read to check all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)		{			if (read_datareg(dreg,&ms,&ls)) return;			ms_exp = (dreg == r1) ? SNINE : 				 (dreg == r2) ? SFOUR : SZERO;			ls_exp = SZERO;			if (ms != ms_exp || ls != ls_exp)				send_message(FPERR,ERROR,er_pointer,dreg,ms_exp,ls_exp,ms,ls);		}	}	/* extended double precision test */	for (r1=0, r2=1, r3=2; r3 < FPA_NSHORT_REGS; r1++, r2++, r3++)	{		/* clear all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)			if (write_datareg(dreg,DZERO_M,DZERO_L)) return;		/* load register value and execute instruction */		if (write_datareg(r2,DTWO_M,DTWO_L)) return;		if (write_datareg(r3,DFOUR_M,DFOUR_L)) return;		inst = XDP_R1_R3aR2xO | X_REG2(r2);		if (write_fpa((u_int *)inst,DTHREE_M,ON)) return;		inst = X_LSW| X_REG1(r1) | X_REG3(r3); 		if (write_fpa((u_int *)inst,DTHREE_L,ON)) return;		/* read to check all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)		{			if (read_datareg(dreg,&ms,&ls)) return;			ms_exp = (dreg == r1) ? DTEN_M  : 				 (dreg == r2) ? DTWO_M  :				 (dreg == r3) ? DFOUR_M : DZERO_M;			ls_exp = DZERO_L;			if (ms != ms_exp || ls != ls_exp)				send_message(FPERR,ERROR,er_pointer,dreg,ms_exp,ls_exp,ms,ls);		}	}}/* * Function to test pointers 1 thru 4 using command register instructions. * This function uses the operation:  reg1 = reg3 + (reg2 * reg4).  * Where reg1 uses data register 0 thru 28, and should hold result 16;

⌨️ 快捷键说明

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