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

📄 trap.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic char *sccsid = "@(#)trap.c	4.9    ULTRIX  3/6/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1988 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.	* *									* ************************************************************************//* ------------------------------------------------------------------ *//* | Copyright Unpublished, MIPS Computer Systems, Inc.  All Rights | *//* | Reserved.  This software contains proprietary and confidential | *//* | information of MIPS and its suppliers.  Use, disclosure or     | *//* | reproduction is prohibited without the prior express written   | *//* | consent of MIPS.                                               | *//* ------------------------------------------------------------------ *//************************************************************************ * *	Modification History: trap.c * * 06-Mar-91 -- jaw *	optimize 3min spl changes. * * 20-Feb-91 -- jaw *	allow for secondary cpus to run softnet code. * * 19-Dec-90 -- jaw *  	fix up affinity on syscall exit...  takes care of any longjmps *	that might not have restored the affinity... * * 10-Aug-90 -- sekhar *	cleaned up softnet interrupt handler by removing duplication  *	of code. also changed softnet to call log_errinfo on a write *	timeout. * * 05-Jul-90 -- sekhar *	modified softnet interrupt handler for write buffer timeouts  *	on memory mapped accessed devices. * * 30-Apr-90 	Randall Brown *	Renamed intr() to kn01_intr() and whatspl() to kn01_whatspl().  This *	allows other systems to have different routines to handle the same *	thing.  These routines are now called through the cpu switch. * * 16-Apr-90 -- jaw *	performance fixes for single cpu. * * 29-Mar-90 -- gmm/jaw *	Call psignal() in softnet() if the process needs a signal. Result *	of changing splhigh() and spl6() to be same as splclock(). * * 14-Feb-90 -- gmm *	replace pcpu with CURRENT_CPUDATA in trap() where the process could *	context switched and come back on a different processor. * * 30-Dec-89 -- bp *	Replaced useage of atintr_level with CPU specific in an interrupt *	service routine evaluation. * * 14-Nov-89 -- sekhar * 	Fixes to turn profiling off when scale set to 1. * * 13-Nov-89 -- afd *	Don't panic if we return from cpu specific bus error handler * * 19-Oct-89 -- jmartin *	Add TLBMISS_STUCK code to panic if retrying a page fault endlessly. * * 13-Oct-89 gmm *	smp changes. Access nofault, nofault_cause etc through cpudata. *	Changes for per processor tlbpids. Handle affinity correctly for *	system calls. * * 04-Oct-89 jaw *	release all locks held when "longjmp" out of a syscall occurs.  This *	is a tempory fix until code in "soclose" is fixed to handle  *	interrupted system calls. * * 09-Jun-89 -- scott *	added audit support * * 09-Jun-89 -- gmm *	Update cpudata structure for number of interrupts. * * 02-May-89 -- jaw, jmartin *	fix forkutl to work on mips. * * 07-Apr-89 -- afd *	Moved all pmax specific code out to kn01.c. *	System specific routines now called thru the cpu switch. *	Cleaned out some old unused code. * * 10-Feb-89 -- Randall Brown *	Added the global variable 'atintr_level' that get incremented on *	every entrance to intr().  This is used by printf() during config *	to determine if we are at interrupt level. * * 19-Jan-89 -- Kong *	Made routines more generic so that they work for multiple *	machines. * * 29-Dec-88 -- Randall Brown *	In the 'pmaxconsprint' routine, changed the state of the variable  *	printstate so that printf (and cprintf) will use the prom *	putchar. (only if console is graphic device) * * 15-Dec-1988  afd *	Clear MEMERR bit in memintr() routine. *	Also fix address calculation in trap() & memintr(); *	  when we compare a physical address to physmem the physical *	  address must be converted to pages (btop(pa)). * * 18-Nov-1988  afd (for rr) *	Added system call trace hooks. * * 17-Nov-1988  depp *	Added addition memory page protection to tlbmiss(), and tlbmod(). * * 09-Nov-1988  jaa *	allow process to turn on/off unaligned access messages * * 09-Aug-1988  afd *	Added error logging support for PMAX: *	  - Added error log routines: pmaxlogesrpkt(), pmaxlogmempkt(), *	    pmaxconsprint(), chk_cpe(). *	  - Added fault isolation for memory parity error (don't call buserror) *	  - Call the error log routines from trap() and memintr(). *	  - Changed fixade() routine to give back failure status. *	  - Added whatspl() routine to give the current IPL level. * *************************************************************************/#define CNT_TLBMISS_HACK 0#include "../machine/cpu.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/kernel.h"#include "../h/proc.h"#include "../h/conf.h"#include "../h/vm.h"#include "../h/buf.h"#include "../h/syslog.h"#include "../h/ptrace.h"#include "../h/cpudata.h"#include "../h/systrace.h"#include "../h/errlog.h"#include "../h/cmap.h"#include "../net/net/netisr.h"#include "../../machine/common/cpuconf.h"#include "../machine/reg.h"#include "../machine/pte.h"#include "../machine/inst.h"#include "../machine/fpu.h"/* * Exception handling dispatch table.  */extern VEC_syscall(), VEC_cpfault(), VEC_trap(), VEC_int(), VEC_tlbmod();extern VEC_tlbmiss(), VEC_breakpoint(), VEC_addrerr(), VEC_ibe(), VEC_dbe();extern VEC_unexp();int  (*causevec[16])() = {	/*  0: EXC_INT */		VEC_int,	/*  1: EXC_MOD */		VEC_tlbmod,	/*  2: EXC_RMISS */		VEC_tlbmiss,	/*  3: EXC_WMISS */		VEC_tlbmiss,	/*  4: EXC_RADE */		VEC_addrerr,	/*  5: EXC_WADE */		VEC_addrerr,	/*  6: EXC_IBE */		VEC_ibe,	/*  7: EXC_DBE */		VEC_dbe,	/*  8: EXC_SYSCALL */	 	VEC_syscall,	/*  9: EXC_BREAK */		VEC_breakpoint,	/* 10: EXC_II */		VEC_trap,	/* 11: EXC_CPU */		VEC_cpfault,	/* 12: EXC_OV */		VEC_trap,	/* 13: undefined */		VEC_unexp,	/* 14: undefined */		VEC_unexp,	/* 15: undefined */		VEC_unexp};/* * Interrupt dispatch table */extern softclock(), softnet(), biointr(), netintr(), ttyintr(); extern hardclock(), fpuintr(), memintr();extern struct cpusw *cpup;	 /* Pointer to cpusw entry for this machine*/extern int mmap_debug;int  (*c0vec_tbl[8])();int	c0vec_tblsize = {sizeof(c0vec_tbl)};	/* Size in bytes */biointr(){	/* this should be enhanced to determine which SII interrupted and	   dispatch accordingly. */	sii_intr(0);}netintr(){	/* this should be enhanced to determine which LANCE interrupted and	   dispatch accordingly. */	lnintr(0);}/* * nofault dispatch table */extern baerror(), cerror(), adderr(), uerror(), uaerror(), softfp_adderr();extern reviderror(), cstrerror(), softfp_insterr(), fixade_error();extern rdnf_error();int  (*nofault_pc[NF_NENTRIES])() = {	/* unused */		0,	/* NF_BADADDR */	baerror,	/* NF_COPYIO */		cerror,	/* NF_ADDUPC */		adderr,	/* NF_FSUMEM */		uerror,	/* NF_USERACC */	uaerror,	/* NF_SOFTFP */		softfp_adderr,	/* NF_REVID */		reviderror,	/* NF_COPYSTR */	cstrerror,	/* NF_SOFTFPI */	softfp_insterr,	/* NF_FIXADE */		fixade_error,	/* NF_INTR */		rdnf_error};/* * Used for decoding break instructions.  There is an old standing bug in the * assembler which encoded the break code right justified to bit 16 not to * bit 6 (that's why the BRK_SHIFT is 16 not 6 as would be obvious). */#define BRK_MASK	0xfc00003f#define BRK_SHIFT	16#define BRK_SUBCODE(x)	(((x) & ~BRK_MASK) >> BRK_SHIFT)/* * This must be declared as an int array to keep the assembler from * making it gp relative. */extern int sstepbp[];extern struct	sysent	sysent[];int	nsysent;/*  *	The following two pointer are used in the exception handler as *	a pointer to the data that needs to be saved on the exception frame *	in the system specific entries.  If a particular processor does not *	need to use these they must be set to values that can be read *	and written. *//* * rpbfix: put in comment */u_int sr_usermask = (SR_IMASK0|SR_IEP|SR_KUP);	/* disable IEc, enable IEp, prev umode *//* * TODO: Get parameters in agreement with locore.s */#define USERFAULT 1extern int runrun;extern int k_puac;/* * Called from locore.s (VEC_trap) to handle exception conditions */trap(ep, code, sr, cause)	register u_int *ep;		/* exception frame ptr */	register u_int code;		/* trap code (trap type) */	u_int sr, cause;		/* status and cause regs */{	register struct proc *p;	register int i, vaddr;	struct timeval syst;	struct pte *pte;	int nofault_save;	u_int inst;	int signo;	struct cpudata *pcpu;	pcpu = CURRENT_CPUDATA;	syst = u.u_ru.ru_stime;	p = u.u_procp;	signo = 0;	if (USERMODE(sr)) {		code |= USERFAULT;	}	XPRINTF(XPR_TRAP, "trap %R cause %R\n", code, exccode_desc,	    cause, cause_desc);	XPRINTF(XPR_TRAP, "trap sr %r\n", sr, sr_desc, 0, 0);	nofault_save = pcpu->cpu_nofault;	pcpu->cpu_nofault = 0;	switch(code) {	case SEXC_PAGEIN:	case SEXC_PAGEIN|USERFAULT:		/* pagein. */		i = u.u_error;	/* ??? the VAX does this ??? */		vaddr = ep[EF_BADVADDR];		pagein(vaddr, 0);		u.u_error = i;		pte = vtopte(p, btop(vaddr));		tlbdropin(p->p_tlbpid, vaddr, *(int *)pte);		if (code == SEXC_PAGEIN)			goto done;		break;	case EXC_RMISS|USERFAULT:	/* from softfp nofault code */	case EXC_WMISS|USERFAULT:	/* from softfp nofault code */		code = SEXC_SEGV|USERFAULT;		/* fall through */	case SEXC_SEGV|USERFAULT:		XPRINTF(XPR_TRAP, "trap USER SEGV badva 0x%x",		    ep[EF_BADVADDR], 0, 0, 0);		if (grow(ep[EF_BADVADDR]))			break;		XPRINTF(XPR_TRAP, "trap SEGV grow failed", 0, 0, 0, 0);		u.u_code = code & ~USERFAULT;		XPRINTF(XPR_SM,"SIGSEGV: faulting addr 0x%x",ep[EF_BADVADDR],					0,0,0);		signo = SIGSEGV;		break;	case SEXC_RESCHED|USERFAULT:		astoff();		if ((u.u_oweupc&SOWEUPC) && (u.u_prof.pr_scale > 1)) {			addupc(ep[EF_EPC], &u.u_prof, 1);			u.u_oweupc &= ~SOWEUPC;		}		break;	case EXC_II|USERFAULT:	case SEXC_CPU|USERFAULT:		u.u_code = code & ~USERFAULT;		signo = SIGILL;		break;	case EXC_OV|USERFAULT:		u.u_code = code & ~USERFAULT;		signo = SIGFPE;		break;	case EXC_DBE|USERFAULT:		/*		 * interpret instruction to calculate faulting address		 */		ep[EF_BADVADDR] = ldst_addr(ep);		/* fall through */	case EXC_IBE|USERFAULT:		u.u_code = code & ~USERFAULT;		/*		 * Call processor specific routine to handle trap error.		 * "signo" is passed as a return parameter: it gets set to		 *     SIGBUS if we want to terminate the user process.		 * If the system needs to panic, it does so in the processor		 *     specific routine.		 */ 		if ((*(cpup->machcheck))(ep, code, sr, cause, &signo) < 0)			panic("no trap error routine configured");		break;	case EXC_RADE|USERFAULT:	case EXC_WADE|USERFAULT:		if(u.u_procp->p_mips_flag & SFIXADE) {			if((i = fixade(ep, cause)) == 0) {				/* success */				if( k_puac && p->p_puac) {  					mprintf("Fixed up unaligned data access for pid %d (%s) at pc 0x%x\n",					p->p_pid, u.u_comm, ep[EF_EPC]);					uprintf("Fixed up unaligned data access for pid %d (%s) at pc 0x%x\n",					p->p_pid, u.u_comm, ep[EF_EPC]);				}				break;			} 			uprintf("pid %d (%s) was killed on %s access, at pc 0x%x \n",			p->p_pid, u.u_comm,			(i == 1 ? "a kernel" : "an unaligned"), ep[EF_EPC]);		}		u.u_code = code & ~USERFAULT;		signo = SIGBUS;		break;	case EXC_BREAK|USERFAULT:		signo = SIGTRAP;		vaddr = ep[EF_EPC];		if (ep[EF_CAUSE] & CAUSE_BD)			vaddr += 4;		inst = fuiword((caddr_t)vaddr);		u.u_trapcause = (inst == *sstepbp) ? CAUSESINGLE : CAUSEBREAK;		u.u_code = BRK_SUBCODE(inst);		break;	case SEXC_SEGV:		if (nofault_save && grow(ep[EF_BADVADDR]))			goto done;		goto chk_nofault;	case EXC_DBE:		/*		 * interpret instruction to calculate faulting address		 */		ep[EF_BADVADDR] = ldst_addr(ep);		/* fall through */	case EXC_CPU:	case EXC_IBE:	case EXC_RADE:	case EXC_WADE:chk_nofault:		/* nofault handler */		if (nofault_save) {			extern (*nofault_pc[])();			CURRENT_CPUDATA->cpu_nofault_cause = cause;			CURRENT_CPUDATA->cpu_nofault_badvaddr = ep[EF_BADVADDR];			i = nofault_save;			nofault_save = 0;			if (i < 1 || i >= NF_NENTRIES)				panic("bad nofault");			ep[EF_EPC] = (u_int)nofault_pc[i];			goto done;		}		/* fall through to default */	default:		/*		 * Kernel mode errors.		 * They all panic, its just a matter of what we log		 *     and what panic message we issue.		 * Call processor specific routine to log and panic.		 * If we return to here then continue (this will happen		 *     when doing a memory dump and we get a cpu read ECC		 *     error on the dump).		 */ 		if ((*(cpup->machcheck))(ep, code, sr, cause, &signo) < 0)			panic("no trap error routine configured");		break;	}	CURRENT_CPUDATA->cpu_trap++;	if (signo) {		XPRINTF(XPR_TRAP, "trap sending signal %N", signo,		    sig_values, 0, 0);		psignal(p, signo);		if (u.u_pcb.pcb_bd_ra) {			ep[EF_EPC] = u.u_pcb.pcb_bd_epc;			ep[EF_CAUSE] = u.u_pcb.pcb_bd_cause;			u.u_pcb.pcb_bd_ra = 0;		}	}	if (p->p_cursig || ISSIG(p,0))		psig();	p->p_pri = p->p_usrpri;	if (CURRENT_CPUDATA->cpu_runrun) {		/*		 * Since we are u.u_procp, clock will normally just change		 * our priority without moving us from one queue to another		 * (since the running process is not on a queue.)		 * If that happened after we setrq ourselves but before we		 * swtch()'ed, we might not be on the queue indicated by		 * our priority.		 */		pcpu = CURRENT_CPUDATA;		pcpu->cpu_proc->p_hlock = pcpu->cpu_hlock;		pcpu->cpu_hlock=0;		(void) splclock();		smp_lock(&lk_rq,LK_RETRY);		setrq(p);		u.u_ru.ru_nivcsw++;		swtch();		pcpu = CURRENT_CPUDATA;		pcpu->cpu_hlock = pcpu->cpu_proc->p_hlock;		pcpu->cpu_proc->p_hlock = 0;	}	/*	 * if single stepping this process, install breakpoints before	 * returning to user mode.  Do this here rather than in procxmt	 * so single stepping will work when signals are delivered.	 */	if (u.u_pcb.pcb_sstep && USERMODE(sr))		install_bp();	if (u.u_prof.pr_scale > 1) {		int ticks = times_to_ticks(&u.u_ru.ru_stime,&syst);		if (ticks)			addupc(ep[EF_EPC], &u.u_prof, ticks);	}done:	CURRENT_CPUDATA->cpu_nofault = nofault_save;}static char *p_on = "\033[5i";static char *p_off = "\033[4i";turnon_printer(){	cprintf("%s",p_on);}

⌨️ 快捷键说明

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