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

📄 vectors.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef lintstatic char *sccsid = "@(#)vectors.c	4.6	ULTRIX	4/12/91";#endif lint/************************************************************************ *									* *		  Copyright (c) 1983,1986,1988,1990 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any	other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived	from  software	received  from	the	* *   University    of	California,   Berkeley,   and	from   Bell	* *   Laboratories.  Use, duplication, or disclosure is	subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or	reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* ------------------------------------------------------------------------ * Modification History: /sys/machine/vax/vectors.c * * 11-Apr-91	dlh * 	decreased number of times pointers were calculated * 	 * 	added smp locks around uses of vpmask, vpfree & vptotal * 	 * 	disabled fault handler:   * 		- new affinity after vp_contextsave - now considers pre-vector  * 		  affinity. * 		- also will not allow new affinity to become zero.  this could  * 		  have happened if the boot cpu does not have a vp and the  * 		  process has been forced to the boot cpu. * 	 * 	vp_reset: * 		set's state of CURRENT cpu, not input cpu. * 	 * 	vp_contextlimbo: * 		- if a CPU is being stopped, then it's VP context needs to be * 		  saved, and it's affinity needs to be changed.   * 		- Also, do not let the affinity go to zero.  This would happen  * 		  if the secondary CPUs are being stopped and the boot * 		  CPU does not have an attached vector processor.  In * 		  this case the vector process would 'hang' until a * 		  secondary CPU with a VP is re-started. * * 12/20/90 - dlh *	added parameter to vp_reset() * * 12/18/90 -- paradis * 	Added vp_idle() routine. * * 10/10/90 -- paradis *	Added VAX 9000 support (this consisted primarily of identifying *	those sections peculiar to Rigel/Mariah and making them *	conditional on "if(cpu == VAX_6400)" * * 9/4/90 -- dlh *    original * * * ------------------------------------------------------------------------ */#include "../h/types.h"#include "../h/param.h"#include "../machine/vectors.h"#include "../h/cpudata.h"#include "../h/time.h"#include "../machine/mtpr.h"#include "../h/proc.h"#include "../h/kmalloc.h"#include "../../machine/common/cpuconf.h"#include "../h/user.h"#include "../h/acct.h"#include "../h/signal.h"#ifdef VAX6400#include "../machine/ka6400.h"#endif VAX6400int	max_vec_procs;#ifdef VECTORSvp_allocate (p)struct proc *p;{/* * input:	pointer to proc structure of process which wants to  * 		allocate a vpcontext area * output:	VP_FAILURE or VP_SUCCESS * description:	Convert a regular process to a vector process by allocating a * 		vector context (vpcontext) area for that process.  Initialize *		the vpcontext area. * side effect:	set AVP flag in the accounting flag of the u area * errors:	There is a maximum number of vector processes which are  *		allowed.  If this maximum is exceeded then vp_allocate will  *		fail. * note:	KM_ALLOC will sleep if there is not enough memory available  *		for the allocation.  Therefore it is guaranteed that the  *		allocation will succeed. */struct	vpcontext	*vpc;	if (++num_vec_procs > max_vec_procs) {		--num_vec_procs;		u.u_code = TERM_VECT_TOOMANY;		u.u_error = EAGAIN;		uprintf ("too many vector processes\n");		psignal (CURRENT_CPUDATA->cpu_proc, SIGTERM);		return (VP_FAILURE);	}	KM_ALLOC ( p->p_vpcontext, struct vpcontext *,	    sizeof(struct vpcontext), KM_VECTOR, KM_CLEAR | KM_CONTIG);	vpc = p->p_vpcontext;	u.u_acflag |= AVP;	vpc->vpc_state = VPC_WAIT;		/* waiting for a vector processor to be allocated for this 		 * process; i.e.: this process is a vector process, but it 		 * does not have it's vector context stored in any vector 		 * processor.		 */	vpc->vpc_affinity = p->p_affinity;		/* save the current affinity of the process.  This will allow 		 * for returning to the saved affinity if this process ever 		 * decides it is no longer a vector processes		 */	/* no need to initialize the vpc_refuse, vpc_cheap or the 	 * vpc_expen fields since the memory was zeroed by KM_ALLOC() 	 */	KM_ALLOC (vpc->vpc_vregs, char *, 	    VPREGSIZE, KM_VECTOR, KM_CLEAR | KM_CONTIG);	return (VP_SUCCESS);}vp_proc (p)struct proc *p;{/* * input:	pointer to proc structure of process which is requesting the *		attached vector processor * output:	PROC_MAY_HAVE_VP or PROC_MAY_NOT_HAVE_VP (defined in vectors.h) * description:	decide if the process can be given the attached vector *		processor. * errors:	 * assumption:	before calling vp_proc() the caller should test to see if *		there is only one VP in the system.  This may be done by  *		using the VP_PROC macro defined in vectors.h * issues:	what if vptotal == 1 && vpd_state == VPD_DEAD ??  this *		routine will never be called. */struct	cpudata	*pcpu;struct	vpdata	*vpd;	pcpu = CURRENT_CPUDATA ;	vpd = pcpu->cpu_vpdata ;	if (vpd->vpd_state == VPD_DEAD)		return (PROC_MAY_NOT_HAVE_VP);	else if (vpd->vpd_proc == NULL)		return (PROC_MAY_HAVE_VP);     /*	else if # of times this process has been refused is too great */     /*		return (PROC_MAY_HAVE_VP);                            */	else if (pcpu->cpu_mask == p->p_affinity)		return (PROC_MAY_HAVE_VP);	else if (vpfree)		return (PROC_MAY_NOT_HAVE_VP);	else		return (PROC_MAY_HAVE_VP);}vp_remove (){/* * input:	none * description:	permanently disable and remove the attached vector processor  *		by clearing the Vector Present bit in the Access Control and  *		Status register.  Also remove software reference to this  *		processor. * note:	the variable cpu is declared in cpu.h, but I have not yet *		tracked down where it is initialized. */struct	cpudata	*pcpu;struct	vpdata	*vpd;	pcpu = CURRENT_CPUDATA ;	if (cpu==VAX_6400) {		mtpr(ACCS,mfpr(ACCS) & ~1);	} else {		printf ("vp_remove(): cpu %d\n", cpu);	}		/*	 * update the system wide masks and count	 */	clear_bit_atomic (pcpu->cpu_num, &vpmask);	clear_bit_atomic (pcpu->cpu_num, &vpfree);	adawi ((-1), &vptotal);	/*	 * update the vpdata struct withing the cpudata struct to reflect 	 * the fact that the attached vp is out of commission.	 */	vpd = pcpu->cpu_vpdata ;	vpd->vpd_proc = NULL;	vpd->vpd_state &= ~(VPD_ALIVE | VPD_ENABLED);	vpd->vpd_state |= VPD_DEAD;}vp_contextsave (p)struct	proc	*p;{/* * input:	proc struct pointer * output:	VP_FAILURE or VP_SUCCESS * description:	copy the vector process context area from the vector  *		processor to the vpcontext area pointed to by the proc  *		struct. * assumptions:	process is running on the SP-VP pair whose VP contains the *		vpcontext * note:	caller is responsible for: *			updating the p_affinity *			updating the vpc_state *			updating the vpd_proc *		this routine leaves the vector processor enabled. */struct	cpudata		*pcpu;struct	vpcontext	*vpc;struct	vpdata		*vpd;	pcpu = CURRENT_CPUDATA;	vpd = pcpu->cpu_vpdata;	vpc = p->p_vpcontext;			/*	 * when ever vector instructions will be executed while the	 * process is kernel mode, the VPD_IN_KERNEL flag must be set.	 */	vpd->vpd_in_kernel = VPD_IN_KERNEL;	/*	 * enable the vector processor.  this will prevent a vector	 * disabled fault	*/	mtpr (VPSR, (mfpr(VPSR) | VPSR_VEN));	mfpr(VPSR);	/*	 * wait for the VP to be idle	 */	while (mfpr(VPSR) & VPSR_BSY) ;	/*	 * wait for completion of vector memory access, and all	 * errors to be reproted.	 */	mfpr (VMAC);	mfpr (VMAC);	if (vpc->vpc_error & VPC_ERROR_PMF) {		/*		 * According to the Chap 13 of the VAX Arch spec (the		 * chapter on vector processors), this fault will only		 * happen in a system which implements the "asyncronous		 * method of memeory management", which I don't think we		 * have. (Can you tell I'm not sure of myself!)  Also,		 * after talking to the ULTRIX vm experts, I don't think		 * this will happen as long as I continue to guarentee		 * that a vector process will never run on a vector		 * processor / scalar processor pair where the scalar		 * process is running some other process.  Until I find		 * out different, or get to that stage of debug, this if		 * clause will just write to the error logger.		 *		 * If I ever do add in code to fill this if clause it will 		 * save the hardware state by:		 *	1. load the VSAR (Vector State Address Register) with 		 *	   a pointer to the hardware area.  this must be in 		 *	   memory which is guarentee'd not to cause an 		 *	   exception (see section 13.2.3, Internal Processor 		 *	   Registers , of vax arch spec)		 *	2. Set the VSS (Vector State Store) bit of the VPSR 		 *	   (Vector Status Register).  This will cause the 		 *	   state to be save.		 */		panic ("vp_contextsave(): got a VPC_ERROR_PMF, now what ?!");	} else if (vpc->vpc_error & VPC_ERROR_IMP) {		panic ("vp_contextsave(): got a VPC_ERROR_IMP, now what ?!");	} else {		/*		 * save the vector control registers: VCR, VLR and all 		 * 64-bits of VMR		 */		vpc->vpc_vcr = mfvcr();		vpc->vpc_vlr = mfvlr();		vpc->vpc_vmrlo = mfvmrlo();		vpc->vpc_vmrhi = mfvmrhi();		/*		 * save the vector registers (load the length register and 		 * issue the Store Vector Register Data into Memory 		 * instruction)		 * (debby: does this need to be a macro or maybe a routine?)		 */		mtvlr (64);		vstq (vpc->vpc_vregs);		/* wait for the store to complete */		while (mfpr(VPSR) & VPSR_BSY) ;		mfpr (VMAC);		mfpr (VMAC);			}	vpd->vpd_in_kernel = ~ VPD_IN_KERNEL;	if (vpc->vpc_error & VPC_ERROR_IMP)		return (VP_FAILURE);	else		return (VP_SUCCESS);}vp_contextrest (p)struct	proc	*p;{/* * input:	proc struct pointer * output:	VP_FAILURE or VP_SUCCESS * description:	copy the vector process context area from the vpcontext  *		area pointed to by the proc struct to the vector processor  * note:	caller is responsible for updating the vpc_state and vpd_proc */struct	vpdata		*vpd;struct	vpcontext	*vpc;	vpd = CURRENT_CPUDATA->cpu_vpdata;	vpc = p->p_vpcontext;	vpd->vpd_in_kernel = VPD_IN_KERNEL;	if (vpc->vpc_error & VPC_ERROR_IMP) {		panic ("vp_contextrest(): got a VPC_ERROR_IMP, now what ?!");	} else {		/*		 * restore the vector registers (load the length register and 		 * issue the Load Memory Data into Vector Register 		 * instruction)		 * (debby: does this need to be a macro or maybe a routine?)		 */		mtvlr (64);		vldq (vpc->vpc_vregs);				/*		 * restore the vector control registers: VCR, VLR and all 		 * 64-bits of VMR		 */		mtvcr(vpc->vpc_vcr);		mtvlr(vpc->vpc_vlr);		mtvmrlo(vpc->vpc_vmrlo);		mtvmrhi(vpc->vpc_vmrhi);		/* 		 * wait for the vector instruction(s), the memory references 		 * to complete and all errors to be reported		 */		while (mfpr(VPSR) & VPSR_BSY) ;		mfpr (VMAC);		mfpr (VMAC);		if (vpc->vpc_error & VPC_ERROR_PMF) {			/*			 * According to the Chap 13 of the VAX Arch spec (the 			 * chapter on vector processors), this fault will only 			 * happen in a system which implements the 			 * "asyncronous method of memeory management", which 			 * is on neither Rigel nor Aquarius, but will be 			 * on Mariah, so I'll worry about this one 			 * latter! Also, after talking to the ULTRIX vm 			 * experts, I don't think this will happen as long as 			 * I continue to guarentee that a vector process will 			 * never run on a vector processor / scalar processor 			 * pair where the scalar process is running some other 			 * process.  Until I find out different, or get to 			 * that stage of debug, this if clause will just write 			 * to the error logger.			 *			 * If I ever do add in code to fill this if clause it 			 * will restore the hardware state by:			 *	1. load the VSAR (Vector State Address 			 *	   Register) with a pointer to the hardware 			 *	   area.  this must be in memory which is 			 *	   guarentee'd not to cause an exception (see 			 *	   section 13.2.3, Internal Processor 			 *	   Registers , of vax arch spec)			 *	2. Set the RLD (vector ReLoaD) bit of the VPSR 			 *	   (Vector Status Register).  This will cause 			 *	   the state to be restored.			 *	3. Clear the soft copy of vpcontext area			 *	   Pending Memory Fault (PMF) bit

⌨️ 快捷键说明

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