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

📄 vectors.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
			mtpr (VINTSR, 0);		} else {			mtpr (VINTSR, VINTSR_DISABLE_VECT_INTF);		}		if ((ls_vintsr & LS_VINTSR_SET) != LS_VINTSR_SET) {			return (FALSE);		} else if ((ls_vintsr & LS_VINTSR_CLR) != 0) {			return (FALSE);		} else if ((ls_mod_rev & 0x80) != 0x80) {			return (FALSE);		} else if ((ls_vctl_csr & LS_VCTL_CSR_CLR) != 0) {			return (FALSE);		} else if ((ls_lsx_ccsr & LS_LSX_CCSR_CLR) != 0) {			return (FALSE);		} else if ((ls_alu_diag_ctrl & LSX_ALU_DIAG_CTRL_CLR) != 0) {			return (FALSE);		} else {			return (TRUE);		}	}}#define	VPC_ERROR	(VPC_ERROR_IMP | VPC_ERROR_IVO | VPC_ERROR_AEX | \			 VPC_ERROR_PMF)#define	VPSR_ERROR	(VPSR_IMP | VPSR_IVO | VPSR_AEX | VPSR_PMF)vp_disabled_fault_handler (mode)int	mode;	/* VP_DIS_USER_MODE or VP_DIS_KERN_MODE */{/* * input:	mode	VP_DIS_USER_MODE or  *			VP_DIS_KERN_MODE * output:	unknown at this time * description:	 */int		new_affinity;	/* new affinity mask of a process becoming a 				 * vector process or of a process which needs  				 * to switch it's affinity for some other 				 * reason.				 */int		save_VPSR;	/* save contents of VPSR for multiple tests				 * of various error bits.				 */struct	cpudata		*pcpu;struct	vpdata		*vpd;struct	vpcontext	*current_vpc;struct	vpcontext	*owning_vpc;    pcpu = CURRENT_CPUDATA;    vpd = pcpu->cpu_vpdata;    current_vpc = pcpu->cpu_proc->p_vpcontext;    if (mode == VP_DIS_KERN_MODE) {	/*	 * process is running in kernel mode.  since kernel code is not 	 * supposed to use the VP for calculating, this is most likely a 	 * fatal error.  there are some exceptions to this:	 * 1. during vector process context switches, kernel mode code 	 *    will move data to/from VP registers.  however, the code 	 *    which does this will set the VPD_IN_KERNEL flag and make sure	 *    that the vector processor is enabled.	 * 2. an implentation dependent error may have occured.  in this 	 *    case it may be possible to switch processors and keep going.	 */	if (vpd->vpd_proc == NULL) {		/* 		 * This process does not "own" the Vector Processor.  Either 		 * this process issued a vector instruction while in kernel 		 * mode, or some hardware error has occured.  In either case, 		 */		panic("DVF in Kernel Mode - no owner of the vector processor");	} else	  if (vpd->vpd_in_kernel !=  VPD_IN_KERNEL) {		/*		 * since this process is running in kernel mode, it should 		 * have set the VPD_IN_KERNEL flag before doing anything that 		 * could have cause this fault.		 */		panic("DVF in Kernel mode - vpd_in_kernel not set");	} else if (mfpr(VPSR) & VPSR_IMP) {		/*		 * There was an implementation dependent error.  There may be 		 * hope.  go see if this is a fatal error (fatal to the VP, 		 * that is).  It is possible that the VP had a problem which 		 * need not be fatal to the process.		 */		/* NOTE:  		 * to date, the only processors (6000-400, 6000-500 and 9000) 		 * which have vectors cannot produce this error.  So, 		 * vp_imp() will panic if it is called.  BUT:  if this 		 * section of code is ever to be executed, it should be 		 * reviewed first.  There are a couple of problems that I 		 * can see:		 *	1. if the VP went bad with state in it, then the 		 *	   user process should be killed, not switched to 		 *	   another processor.		 *	2. if the VP state is saved, then the process can 		 *	   continue, but switch_affinity should not be 		 *	   called.  If the disabled fault is allowed to 		 *	   just exit, then the retry of the instruction 		 *	   will automatically cause it to be moved to 		 *	   another processor		 */		if (vp_imp() == VP_IMP_FATAL) {			/*			 * permanently diable the VP and remove knowledge of			 * it's existance			 */			vp_remove ();			/* update statistics here */			/*			 * set the VPC_ERROR_IMP bit in vpc_error so that when 			 * this instruction is re-tried on another processor, 			 * or if the process dies, it will still know that 			 * there was a IMP failure.			 */			current_vpc->vpc_error |= 				VPC_ERROR_IMP;			/*			 * if there is still a functioning vector processor, 			 * then set process affinity to vpmask.  This way when  			 * the instruction is re-tried it will either get 			 * another disabled fault on another processor.  if 			 * this was the last functioning vector processor in 			 * this system (know this by checking vptotal) then 			 * kill the process.			 */			if (vptotal) {				/*				 * switch_affinity()  (defined in 				 * sys/kern_subr.c) is a routine to assign a 				 * new affinity to a process and to switch the 				 * process to the new cpu.  this routine will 				 * do the swtch().  it uses u.u_procp as the 				 * proc pointer, so at least for debug 				 * purposes i want to check this out. 				 */								if (pcpu->cpu_proc != u.u_procp)					panic ("DVF: pcpu->cpu_proc != u.u_procp");				new_affinity = vpmask & 				    current_vpc->vpc_affinity;				if (new_affinity == 0)					panic ("DVF: vector affinity problem");				else {					switch_affinity (new_affinity);    					pcpu = CURRENT_CPUDATA;    					vpd = pcpu->cpu_vpdata;    					current_vpc = 					    pcpu->cpu_proc->p_vpcontext;				}			} else { /* no more functioning VPs in system */				/* need a u_code or a u_error here */				u.u_code = TERM_VECT_HARD;				psignal (pcpu->cpu_proc, SIGKILL);			}		} else { 			/* 			 * IMP error was not fatal to the VP, so it is fatal 			 * to the process.  Set the VPC_ERROR_IMP bit in			 * vpc_error so that when this process dies, it will 			 * know that there was an IMP failure.			 */			current_vpc->vpc_error |= VPC_ERROR_IMP;			/*			 * send a SIGKILL (kill signal) to the process			 * note:  if there is ever a vector			 *	  implementation which can recover from a IMP			 *	  error, then it might be possible to let the			 *	  process continue.			 */			psignal (pcpu->cpu_proc, SIGKILL);		}	} else		/* 		 * This process is in Kernel mode, the vpd_in_kernel flag is 		 * set and there has not been an IMP error, so some kernel 		 * mode code is accessing VP registers without first making 		 * sure that the VP is enabled, or something went wrong with 		 * load/store/test of a VP register.  The only thing left to 		 * do is ... panic		 *		 * debby - note that the design spec spelled out checking for 		 * AEX and IVO.  since i am panicing at this point, i don't 		 * see the purpose, but i didn't want to forget that i had 		 * made this decision		 */		panic("DVF while in Kernel Mode");    } else { /* in user mode */	/*	 * wait for the VP to go idle, all memory references to	 * complete and all errors to be reported.  This is a hook for	 * future changes to the vector support.  If, in the futrue, we	 * decide to let one process run on the VP while another runs on	 * the SP, then this step becomes necessary.  As long as we force	 * the same process to be running on the SP as is running on the	 * VP this step is uncessary.	 */	while (mfpr(VPSR) & VPSR_BSY) ;	mfpr (VMAC);	mfpr (VMAC);	/*	 * sanity check - debug only	 * make sure cpu_proc and u_procp agree	 */	if (pcpu->cpu_proc != u.u_procp)	    panic ("DVF: CURRENT_CPUDATA->cpu_proc and u.uprocp do not agree");	/*	 * if this process does not have a vpcontext area then it asking to 	 * become a vector process.  go ahead and call vp_allocate() to 	 * allocate the vpcontext area, and to intialize it.  mask out the	 * non-vector present processors from the process affinity.  this will 	 * limit this process to:	 *	1. scalar processors it was already limited to	 *	2. scalar processors which are part of a scalar/vector pair	 * note: do not set affinity to just this processor because there is a	 * possibility that vp_proc will tell us that we cannot have this 	 * processor.	 * if the new process affinity is zero (this will only happen if the	 * process was already limited to a set of processors which were not 	 * part of a scalar/vector pair) then kill the process.	 */	if (current_vpc == NULL) {		if (vp_allocate (pcpu->cpu_proc) == VP_FAILURE) {			return;		}		current_vpc = pcpu->cpu_proc->p_vpcontext;		new_affinity = pcpu->cpu_proc->p_affinity & vpmask;		if (new_affinity == 0) {			panic ("DVF: vector affinity problem");		} else {			pcpu->cpu_proc->p_affinity = new_affinity;		}		current_vpc->vpc_state = VPC_WAIT;	}	/*	 * check for and deal with any errors which may have occured.	 * if the vector processor has no "owner" then	 *	- clear the hardware (if necessary)	 *	- log the error	 * 	- allow the process which caused this disabled vector 	 *	  processor error to continue.	 * if the vector processor has an "owner" then	 *	- charge the owning process  with the error	 *	- determine if the owning process can continue processing 	 *	  (most likely not).	 */	if (vpd->vpd_proc == NULL) {		/*		 * there is no current vector process which "owns" this vector 		 * processor, so clean up any pending errors		 */		if (mfpr(VPSR) & VPSR_IMP) {			/*			 * there has been an implementation dependent error.  			 * call vp_imp() to perform any necessary error 			 * recovery and to determine if the error is fatal to 			 * the vector processor.			 */			/* NOTE:  			 * to date, the only processors (6000-400, 6000-500 			 * and 9000) which have vectors cannot produce this 			 * error.  So, vp_imp() will panic if it is called.			 */			if (vp_imp() == VP_IMP_FATAL) {				/*				 * permanently diable the VP and remove 				 * knowledge of it's existance				 */				vp_remove ();				/* update statistics here */				if (vptotal) {					/* switch_affinity()  (defined in 					 * sys/kern_subr.c) is a routine to 					 * assign a new affinity to a process 					 * and to switch the process to the 					 * new cpu.					 */					/* the new affinity of this process is 					 * the logical and of the processors 					 * which were in the affinity mask 					 * before this process became a vector 					 * process and the cpu mask of those 					 * processors which have a functioning 					 * vector processor.  if this new 					 * affinity is zero, then there are no 					 * processors which are capable of 					 * running this process					 */					new_affinity = vpmask & 					    current_vpc->vpc_affinity;					if (new_affinity == 0) {					    panic 					    ("DVF: vector affinity problem");					} else {						switch_affinity (new_affinity);						pcpu = CURRENT_CPUDATA;						vpd = pcpu->cpu_vpdata;						current_vpc =						    pcpu->cpu_proc->p_vpcontext;					}				} else { /* no more functioning VPs in system */					u.u_code = TERM_VECT_HARD;					psignal (pcpu->cpu_proc, SIGKILL);					return ;				}			} /* the IMP error was not fatal to the VP */			panic ("DVF: uerf: IMP error, u mode, no own\n");		} /* endif - test for VPSR_IMP error */		if (mfpr(VPSR) & VPSR_AEX)			/* vector processor arithmetic exception error */			mprintf ("DVF: uerf: AEX error, u mode, no owner\n");		if (mfpr(VPSR) & VPSR_IVO)			/* vector processor illegal operand error */			panic ("DVF: uerf: IVO error, u mode, no owner\n");	} else { /* some process owns the VP */		owning_vpc = vpd->vpd_proc->p_vpcontext;		/*		 * look for the errors.  if there are any errors then log 		 * them in the vpc_error field of the vpcontext structure and 		 * clear the hardware. 		 */		save_VPSR = mfpr (VPSR);		if (save_VPSR & VPSR_IMP) {			/*			 * there has been an implementation dependent error.  			 * call vp_imp() to handle the error and to determine 			 * if it is fatal to the vector processor.  if it is 			 * fatal to the vector processor, then call 			 * vp_remove() to perminently remove the vector 			 * processor from consideration as an operational 			 * vector processor.			 */			/* NOTE:  			 * to date, the only processors (6000-400, 6000-500 			 * and 9000) which have vectors cannot produce this 			 * error.  So, vp_imp() will panic if it is called.			 */			if (vp_imp() == VP_IMP_FATAL)				vp_remove();			owning_vpc->vpc_error |= VPC_ERROR_IMP;		}		if (save_VPSR & VPSR_AEX) {			/*			 * there has been an arithmetic exception error on the 			 * vector processor.  set the error bit in the 			 * process's vpcontext struct, and make a copy of the 			 * Vector Arithmethic Exception Register (this 			 * register contains the encoded exception condition 			 * summary - see chap 13 of the VAX Architecture 			 * Standard for a breakdown of the contents of this 			 * register.			 */			owning_vpc->vpc_error |= VPC_ERROR_AEX;			owning_vpc->vpc_vaer = mfpr(VAER);		}		if (save_VPSR & VPSR_IVO) {			/*			 * there has been an illegal vector opcode error.  set 			 * the error bit in the process's vpcontext struct.  			 * debby - need to save pc ??  if so where and how ??			 */			owning_vpc->vpc_error |= VPC_ERROR_IVO;		}		if (save_VPSR & VPSR_PMF) {			/*			 * there has been a pending memory fault error.  this 			 * is cause for panic, since I have absolutely no code 			 * in place to handle this			 */			panic("DVF: pending memory fault");		}		/*		 * now that we have save off all the info we need, it there		 * have been any errors, then reset clear the * hardware.  		 * then decide whether the process lives or dies.   		 * if it dies as the result of an arithmetic error, then 		 * send it a nice error packet.		 */		if (save_VPSR & VPSR_ERROR) {			/* 			 * there was some error, so reset the hardware.  			 * this is done by setting the VPSR_BIT.  This 			 * will clear the VPSR (vector processor status 			 * register) and the VAER (vector arithmetic 			 * exception register. This will also clear all 			 * the exceptions in the VP.			 */			mtpr (VPSR, VPSR_RST);			mfpr(VPSR);			if(cpu == VAX_6400) {				/* note:  re-setting the Rigel/Mariah				 * vector processor disables memory				 * mapping; need to re-enable it here.				 */				/* Enable mapping */				mtpr(VIADR, 0x509);				mtpr(VIDLO, 1);

⌨️ 快捷键说明

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