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

📄 vectors.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
				/* Initialize cache controller: Enable memory 				 * transactions, enable cache, enable error 				 * reporting, clear errors, and flush cache.				 */				mtpr(VIADR, 0x520);				mtpr(VIDLO, 0x138e00);				/* Initialize vector controller status 				 * register enable hard and soft error 				 * reporting.				 */				mtpr(VIADR, 0x489);				mtpr(VIDLO, 0xc0000);				/* read VMAC ??? */				/* do SYNC ??? */			}			if (owning_vpc->vpc_error & VPC_ERROR_IMP) {			    u.u_code = TERM_VECT_HARD;			    psignal (vpd->vpd_proc, SIGKILL);			}			if (owning_vpc->vpc_error & VPC_ERROR_IVO) {			    u.u_code = ILL_VECOP_FAULT;			    uprintf			      ("illegal vector opcode on vector capable cpu\n");			    psignal (vpd->vpd_proc, SIGILL);			    return ;			}			if (owning_vpc->vpc_error & VPC_ERROR_AEX) {			    if (vpd->vpd_proc  != u.u_procp)			        panic ("DVF: not loading VAER into u_code");			    else			        u.u_code = owning_vpc->vpc_vaer;			    psignal (vpd->vpd_proc, SIGFPE);			}			/*			 * if the current proc and the owning proc are the 			 * same, then return.  this will give control back 			 * to trap().  trap() will see the signal and kill 			 * the process.  since the process is killed, the 			 * instruction which caused the disabled fault will 			 * not be re-issued (debby - is this true ???)			 */			if ((owning_vpc->vpc_error & VPC_ERROR) && 			    (pcpu->cpu_proc == vpd->vpd_proc)) {				return ;			}		}	} /* end else VP has an owner */	/* end error processing */	if ( u.u_procp == vpd->vpd_proc ) {		/* the current process already owns the vector processor */		/* Refresh the memory management registers */		/*		 * This is necessary for Rigel, and so it must be		 * necessary for Mariah.  Not necessary for Aquarius.		 */		if(cpu == VAX_6400) {			mtpr (P0BR, mfpr (P0BR));			mtpr (P0LR, mfpr (P0LR));			mtpr (P1BR, mfpr (P1BR));			mtpr (P1LR, mfpr (P1LR));			mtpr (SBR, mfpr (SBR));			mtpr (SLR, mfpr (SLR));		}		/*		 * since there is an "owner" for the VP, it cannot be VPC_WAIT 		 * nor VPC_SAVED.  it must be VPC_LOAD or VPC_LIMBO.  if it is 		 * VPC_LOAD then the translation buffer is already o.k.  if 		 * it is VPC_LIMBO, then the translation buffer needs to be 		 * invalidated		 */		if (owning_vpc->vpc_state == VPC_LIMBO) {			/* flush the vector translation buffer */			/*			 * This is necessary for Rigel, and so it must be			 * necessary for Mariah.  Not necessary for Aquarius.			 */			if(cpu == VAX_6400)  mtpr (VTBIA, 0);			owning_vpc->vpc_state = VPC_LOAD;		}		/* update statistics */		/* cheap context switches per process */		owning_vpc->vpc_cheap ++ ;		/* cheap context switches per cpu */		vpd->vpd_ccsw ++ ;		/* requesting process given "ownership" of vector processor */		vpd->vpd_success ++ ;		/* 		 * enable the vector processor (that is, after all, why I'm		 * here		 */		mtpr (VPSR, (mfpr(VPSR) | VPSR_VEN));		mfpr(VPSR);		vpd->vpd_state &= ~ VPD_DISABLED;		vpd->vpd_state |= VPD_ENABLED;		return ;	}	/*	 * current process does not own the vector processor.  if this is the 	 * only vector processor in the system, then take it.  if there is 	 * more than one, then call vp_proc() to ask permission to take it.	 */	if ((vptotal == 1) || (vp_proc(pcpu->cpu_proc) == PROC_MAY_HAVE_VP)) {		/*		 * go ahead and take the vector processor.  		 * since we might have to call vp_contextsave() or 		 * vp_contextrest() which will be executing stuff in kernel 		 * mode, enable the vector processor now.		 */		mtpr (VPSR, (mfpr (VPSR) | VPSR_VEN) );		mfpr(VPSR);		vpd->vpd_state &= ~ VPD_DISABLED;		vpd->vpd_state |= VPD_ENABLED;		/*		 * look to see if there is a context in the vector processor.		 * if there is, then the vector processor is "owned" by 		 * someone else, and that vector process needs to be saved 		 * before this vector process can "steal" the vector 		 * processor.		 */		if (vpd->vpd_proc != NULL) {			if (vp_contextsave (vpd->vpd_proc) == VP_FAILURE) {				/*				 * vp_contextsave() will only fail if it				 * gets a vector IMP error.  When this				 * happen the system panics, to the				 * following signal will never be				 * reached.  However... Some future				 * vector implementation may allow a				 * recovery from an IMP error.  If that				 * ever happens then the following				 * psignal should be reconsidered.				 */				psignal (vpd->vpd_proc, SIGKILL);				return ;			}			/*			 * vp_contextsave() succeeded so restore the saved 			 * affinity and update the vpc_state.  update vpfree			 * and update the state of the saved process			 * note:  if the saved affinity does not include a 			 *	  cpu with a vector unit, then don't touch 			 *	  the process affinity.  The only time 			 *	  this could occur is if the following 			 *	  happens:			 *	  - there is no vector processor on the 			 *	    boot cpu			 *	  - the vector process, while in a state 			 *	    of VPC_LIMBO issues an instruction 			 *	    which causes the kernel to move the 			 *	    process to the boot cpu.  While there, 			 *	    the process needs to wait for some 			 *	    reason and is taken off of the run queue.  			 *	  - another vector process takes this 			 *	    vector cpu, forcing a vp_contextsave() 			 *	    on this process.  Since vpc_affinity 			 *	    is kept up to date by switch_affinity, 			 *	    the saved affinity would not include a 			 *	    cpu with a vector processor.			 *	  - note:  the routine which calls 			 *	    switch_affinity is responsible for 			 *	    keeping a copy of the old affinity.  			 *	    Therefore, before the user level 			 *	    process can execute another vector 			 *	    instruction, an affinity which includes 			 *	    a vector processor will be in place.			 */			new_affinity = 			    owning_vpc->vpc_affinity & vpmask;			if (new_affinity != 0) {				vpd->vpd_proc->p_affinity = new_affinity;			}			owning_vpc->vpc_state = VPC_SAVED;			vpd->vpd_proc = NULL;			set_bit_atomic (pcpu->cpu_num, &vpfree);		}		/*		 * make the current process the owner of the vector processor.		 * update the vpfree mask.  load this process's vector context 		 * into the vector processor.		 */		vpd->vpd_proc = pcpu->cpu_proc;		owning_vpc = vpd->vpd_proc->p_vpcontext;		if (vp_contextrest (pcpu->cpu_proc) == VP_FAILURE) {			/*			 * vp_contextrest() will only fail if it gets a			 * vector IMP error.  When this happen the system			 * panics, to the following signal will never be			 * reached.  However... Some future vector			 * implementation may allow a recovery from an			 * IMP error.  If that ever happens then the			 * following psignal should be reconsidered.			 */			psignal (pcpu->cpu_proc, SIGKILL);			return ;		} else {			owning_vpc->vpc_state =			    VPC_LOAD;		}		clear_bit_atomic (pcpu->cpu_num, &vpfree);					/* limit this process's affinity to this cpu */		pcpu->cpu_proc->p_affinity = pcpu->cpu_mask;		/*		 * refresh the memory management registers, this is done by 		 * writing to these regs on the scalar, this will cause the 		 * vector copy to be updated.  and invalidate the translation 		 * buffer		 */		/*		 * This is necessary for Rigel, and so it must be		 * necessary for Mariah.  Not necessary for Aquarius?		 */		if(cpu == VAX_6400) {			mtpr (P0BR, mfpr (P0BR));			mtpr (P0LR, mfpr (P0LR));			mtpr (P1BR, mfpr (P1BR));			mtpr (P1LR, mfpr (P1LR));			mtpr (SBR, mfpr (SBR));			mtpr (SLR, mfpr (SLR));			mtpr (VTBIA, 0);		}		/* update statistics */		/* expensive context switches per process */		owning_vpc->vpc_expen ++ ;		/* expensive context switches per cpu */		vpd->vpd_ecsw += 1 ;		/* requesting process given "ownership" of vector processor */		vpd->vpd_success ++ ;		/* clear the vpd_in_kernel flag */		vpd->vpd_in_kernel = ~VPD_IN_KERNEL;		return ;	} else { /* vp_proc() returned PROC_MAY_NOT_HAVE_VP */		/* update statistics */		/* no. times process refused "ownership" (count per process) */		current_vpc->vpc_refuse ++ ;		/* requesting process refued "ownership" of vector processor		 * (count per cpu)		 */		vpd->vpd_failed ++ ;		/*		 * eliminate this processor from the process's affinity mask.  		 * this will prevent this process from being immediately 		 * scheduled on this processor again.  note: don't need to 		 * check for an affinity of zero here because that possibility 		 * would have been eliminated by vp_proc().		 * (need switch_affinity ???)		 */		pcpu->cpu_proc->p_affinity &= ~(pcpu->cpu_mask);		return ;	}    } /* endif - kernel or user mode */}vp_reset (cpu_number)int	cpu_number;{int	i;/* * input:	cpu_number *		the cpu number of the cpu whose vector processor is being *		reset. *		note: this cannot be obtained from CURRENT_CPUDATA because  *		      when a non-boot processor is being started,  *		      CURRENT_CPUDATA refers to the boot cpu, but this  *		      routine is resetting one of the non-boot cpus. * description:	reset the vector processor from the scalar side and from the  *		vector side.  leave the vector processor disabled, but make  *		sure that memory management is enabled. * issues:	 */	if(cpu == VAX_6400) {	/* Rigel/Mariah only */		/*		 * first, reset from the scalar side.  This is done by setting		 * the reset bit in the Vector INTerface Status Register.  This		 * bit must be set for 100 scalar cycles.  Then it may be		 * cleared.  It must be cleared for 100 cycles before accessing		 * the vector processor.		 */		mtpr (VINTSR, VINTSR_VECTOR_MODULE_RESET);		for (i=0; i<100; i++) ;		mtpr (VINTSR, 0);		for (i=0; i<100; i++) ;	}	/* 	 * wait for the VP to go idle, and all memory references to complete 	 * and all errors to be reported.  this is probably unnessary since	 * it follows a reset, but it's unlikely that it will hurt.  also,	 * the spec says that a VPSR_RST while VPSR_BSY is set will have 	 * undefined results, so ...	 */	while (mfpr(VPSR) & VPSR_BSY) ;	mfpr (VMAC);	mfpr (VMAC);	/* 	 * now reset the vector side.  setting the VPSR_RST bit will	 * clear the VPSR (vector processor status register), the VAER 	 * (vector arithmetic exception register and the VCTL_CSR.	 * Leave the VP disabled.	 */	mtpr (VPSR, VPSR_RST);	mfpr(VPSR);	if (cpu==VAX_6400) {		/*		 * Enable mapping by writting a 1 to VIR_LSX_TBCSR (TB control		 * register)		 */		mtpr(VIADR, 0x509);		mtpr(VIDLO, 1);		/* Initialize cache controller: Enable memory transactions,		 * enable cache, enable error reporting, clear errors,		 * and flush cache.		 * this is donw by writing a 0x138e00 to VIR_LSX_CCSR (Cache 		 * control register)		 */		mtpr(VIADR, 0x520);		mtpr(VIDLO, 0x138e00);		/* Initialize vector controller status register; enable		 * hard and soft error reporting.		 * This is done by writing a 0xc0000 to VIR_VCTL_CSR (Vector		 * controller Status)		 */		mtpr(VIADR, 0x489);		mtpr(VIDLO, 0xc0000);		/*		 * refresh the memory management registers, this is done by		 * writing to these regs on the scalar, this will cause the		 * vector copy to be updated.  and invalidate the translation		 * buffer		 */		mtpr (P0BR, mfpr (P0BR));		mtpr (P0LR, mfpr (P0LR));		mtpr (P1BR, mfpr (P1BR));		mtpr (P1LR, mfpr (P1LR));		mtpr (SBR, mfpr (SBR));		mtpr (SLR, mfpr (SLR));		mtpr (VTBIA, 0);	} 	CURRENT_CPUDATA->cpu_vpdata->vpd_state = VPD_ALIVE | VPD_DISABLED;}vp_imp (){/* * input:	unknown at this time * output:	VP_IMP_FATAL or VP_IMP_NOT_FATAL * description:	handle implementation specific vector hardware errors.  do *		whatever the specific implementation has recommended and *		clear VPSR<IMP>. */	panic ("vp_imp(): now what??");			return (VP_IMP_FATAL);}vp_idle(){/* * description:  Idle the vector processor (if any) associated with the * current scalar processor. */	if(vpmask & (1 << CURRENT_CPUDATA->cpu_num)) {		while(mfpr(VPSR) & VPSR_BSY) ;		mfpr(VMAC);		mfpr(VMAC);	}}#endif VECTORS

⌨️ 快捷键说明

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