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

📄 trap.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
turnoff_printer(){	cprintf("%s",p_off);}static int dumpstack_once = 0;dumpstack(ep)unsigned *ep;{	register int i;	if (dumpstack_once)		return;	dumpstack_once++;	while((unsigned)ep < (unsigned)(KERNELSTACK-4*4)) {		printf("0x%x\t0x%x\t0x%x\t0x%x\t0x%x\n",			ep,*ep,*(ep+1),*(ep+2),*(ep+3));		ep += 4;		DELAY(300000);	}	/* print the last few stack addresses (no more than 4 left) */	if((unsigned)ep < (unsigned)(KERNELSTACK-4)) {		printf("0x%x\t0x%x",ep,*ep);prloop:		ep++;		if((unsigned)ep < (unsigned)(KERNELSTACK-4)) {			printf("\t0x%x",*ep);			goto prloop;		}		printf("\n");	}}/* * install_bp -- install breakpoints to implement single stepping */staticinstall_bp(){	unsigned inst;	unsigned target_pc;	if (u.u_pcb.pcb_ssi.ssi_cnt)		panic("install_bp2");	/*	 * If user can't access where his pc points, we give up.	 * He'll be getting a SIGSEGV shortly anyway!	 */	if (!useracc(USER_REG(EF_EPC), sizeof(int), B_READ))		return;	inst = fuiword(USER_REG(EF_EPC));	if (is_branch(inst)) {		target_pc = branch_target(inst, USER_REG(EF_EPC));		/*		 * Can't single step self-branches, so just wait		 * until they fall through		 */		if (target_pc != USER_REG(EF_EPC))			set_bp(target_pc);		set_bp(USER_REG(EF_EPC)+8);	} else		set_bp(USER_REG(EF_EPC)+4);	/*	 * only install breakpoints once!	 */	u.u_pcb.pcb_sstep = 0;}staticset_bp(addr)unsigned *addr;{	register struct ssi_bp *ssibp;	ssibp = &u.u_pcb.pcb_ssi.ssi_bp[u.u_pcb.pcb_ssi.ssi_cnt];	ssibp->bp_addr = addr;	/*	 * Assume that if the fuiword fails, the write_utext will also	 */	ssibp->bp_inst = fuiword(addr);	if (write_utext(addr, *sstepbp))		u.u_pcb.pcb_ssi.ssi_cnt++;}/* * remove_bp -- remove single step breakpoints from current process */remove_bp(){	register struct ssi_bp *ssibp;	while (u.u_pcb.pcb_ssi.ssi_cnt > 0) {		u.u_pcb.pcb_ssi.ssi_cnt--;		ssibp = &u.u_pcb.pcb_ssi.ssi_bp[u.u_pcb.pcb_ssi.ssi_cnt];		if (!write_utext(ssibp->bp_addr, ssibp->bp_inst)) {			uprintf("couldn't remove breakpoint\n");			continue;		}	}}staticis_branch(inst){	union mips_instruction i;	i.word = inst;	switch (i.j_format.opcode) {	case spec_op:		switch (i.r_format.func) {		case jr_op:		case jalr_op:			return(1);		}		return(0);	case bcond_op:	case j_op:	case jal_op:	case beq_op:	case bne_op:	case blez_op:	case bgtz_op:		return(1);	case cop0_op:	case cop1_op:	case cop2_op:	case cop3_op:		switch (i.r_format.rs) {		case bc_op:			return(1);		}		return(0);	}	return(0);}#define	REGVAL(x)	((x)?USER_REG((x)+EF_AT-1):0)staticbranch_target(inst, pc){	union mips_instruction i;	i.word = inst;	switch (i.j_format.opcode) {	case spec_op:		switch (i.r_format.func) {		case jr_op:		case jalr_op:			return(REGVAL(i.r_format.rs));		}		break;	case j_op:	case jal_op:		return( ((pc+4)&~((1<<28)-1)) | (i.j_format.target<<2) );	case bcond_op:	case beq_op:	case bne_op:	case blez_op:	case bgtz_op:		return(pc+4+(i.i_format.simmediate<<2));	case cop0_op:	case cop1_op:	case cop2_op:	case cop3_op:		switch (i.r_format.rs) {		case bc_op:			return(pc+4+(i.i_format.simmediate<<2));		}		break;	}	panic("branch_target");}ldst_addr(ep)register u_int *ep;{	register u_int *pc;	union mips_instruction i;	int base;	pc = (u_int *)ep[EF_EPC];	if (ep[EF_CAUSE] & CAUSE_BD)		pc++;	i.word = *pc;	/* theoretically can't fault */	if (i.i_format.opcode < lb_op) {		panic("DBE not on load or store");	}	base = (i.i_format.rs == 0) ? 0 : ep[EF_AT + i.i_format.rs - 1];	return (base + i.i_format.simmediate);}	trap_nofault(ep, code, sr, cause)register u_int *ep;register u_int code;u_int sr, cause;{	register int i;	struct cpudata *pcpu;	pcpu = CURRENT_CPUDATA;	switch(code) {	case EXC_DBE:		/* nofault handler */		if (pcpu->cpu_nofault) {			extern (*nofault_pc[])();			i = pcpu->cpu_nofault;			pcpu->cpu_nofault = 0;			if (i < 1 || i >= NF_NENTRIES)				panic("bad nofault");			ep[EF_EPC] = (u_int)nofault_pc[i];			return;		}		/* fall through to default */	default:		splhigh();		panic("trap_nofault");	}}dumpregs(ep)unsigned *ep;{	extern struct reg_desc cause_desc[], sr_desc[];	/*	 * Dump out other items of interest	 */	printf("Faulting PC: 0x%x\n", ep[EF_EPC]);	printf("Cause register: %R\n", ep[EF_CAUSE], cause_desc);	printf("Status register: %R\n", ep[EF_SR], sr_desc);	printf("Bad Vaddress: 0x%x\n", ep[EF_BADVADDR]);	printf("Stack Pointer: 0x%x\n", ep[EF_SP]);}#ifdef TLBMISS_STUCK	/* must be power of 2 */#define VADDR_RING_SIZE (1<<3)u_int vaddr_ring[VADDR_RING_SIZE];int vaddr_ring_index = 0;#endif TLBMISS_STUCKtlbmiss(ep, code, vaddr, cause)u_int *ep;u_int code, vaddr, cause;{	register u_int vpn, uvpn;	register struct pte *pte;	register u_int kvpn;	register struct tlbinfo *ti;	struct pte tpte;	struct proc *p;	extern unsigned Syssize;#if CNT_TLBMISS_HACK==1	u.u_ru.ru_oublock++;#endif CNT_TLBMISS_HACK	/*	 * Workaround for 3.0/4.0 chip bug.  If badvaddr has been trashed	 * by chip, epc is correct vaddr	 */	if (vaddr == E_VEC)		vaddr = ep[EF_EPC];	vpn = btop(vaddr);	p = u.u_procp;	pte = (struct pte *)0;	if (IS_KUSEG(vaddr)) {		pte = vtopte(p, vpn);#ifdef TLBMISS_STUCK		{		   int i;		   vaddr_ring[vaddr_ring_index++ & (VADDR_RING_SIZE-1)] = vaddr;		   for (i=0; i < VADDR_RING_SIZE-1; i++)		       if (vaddr_ring[i] != vaddr_ring[i+1])			   break;		   if (i == VADDR_RING_SIZE-1) {		       printf("vaddr==%8x\tproc_slot==%d\tpte==%8x\tpte/%8x\n",			      vaddr, p - &proc[0], pte, *(int *)pte);		       panic("tlbmiss: stuck on same vaddr");		   }	        }#endif TLBMISS_STUCK	} else if (IS_KPTESEG(vaddr)) {		extern char utlbmiss[], eutlbmiss[];		int is_utlbmiss = ep[EF_EPC] >= UT_VEC			&& ep[EF_EPC] < UT_VEC + (eutlbmiss - utlbmiss);		if (!is_utlbmiss && !IS_Forkmap(vaddr)) {			printf("epc= 0x%x, vaddr= 0x%x\n", ep[EF_EPC], vaddr);			panic("kpteseg miss outside utlbmiss");		}		uvpn = (struct pte *)vaddr - (struct pte *)KPTEBASE;		if (uvpn >= btop(KUSIZE))			panic("kpteseg");		/*		 * set-up the EPC and SR so that return to place that		 * caused the original utlbmiss		 */		if (is_utlbmiss) {			ep[EF_EPC] = ep[EF_K1];			ep[EF_SR] &= ~(SR_KUP|SR_IEP);			ep[EF_SR] |= (ep[EF_SR] & (SR_KUO|SR_IEO)) >> 2;		}		pte = vtopte(p, uvpn);		if (!pte) {			/*			 * User referenced a bad page that caused a two			 * level miss.  Drop in an invalid pte for the			 * user and retry the reference so that BADVADDR			 * can be fully determined for the signal handler.			 */			vaddr = (u_int)ptob(uvpn);			tlbdropin(p->p_tlbpid, vaddr, 0);			return(0);		}		/*		 * Map kpte window		 */		kvpn = btop((unsigned)pte - K2BASE);		tpte = Sysmap[kvpn];		if (!tpte.pg_v)			panic("tlbmiss page table not valid");		tpte.pg_g = 0;#if NOMEMCACHE==1		tpte.pg_n = 1;#endif		ti = p->p_tlbinfo;		if (p->p_tlbindx < NPAGEMAP) {			ti += p->p_tlbindx;			ti->lo.tl_word = *(unsigned *)&tpte;			ti->hi.th_word = (unsigned)vaddr & TLBHI_VPNMASK;			tlbwired(p->p_tlbindx+UPAGES, p->p_tlbpid, vaddr, tpte);			p->p_tlbindx++;		} else {			tlbdropin(p->p_tlbpid, vaddr, tpte);		}		if (!is_utlbmiss)			return(0);		vaddr = (u_int)ptob(uvpn);		ep[EF_BADVADDR] = vaddr;	} else if (IS_KSEG2(vaddr)) {		vpn -= btop(K2BASE);		if (vpn < Syssize) {			pte = &Sysmap[vpn];			if (!pte->pg_v) {				printf("vaddr= 0x%x, pte= 0x%x\n", vaddr, *pte);				printf("epc = 0x%x\n", ep[EF_EPC]);				panic("tlbmiss on invalid kernel page");			}#if NOMEMCACHE==1			pte->pg_n = 1;#endif		}	}	if (pte) {		XPRINTF(XPR_TLB, "tlbmiss pte va: 0x%x  pte: %r\n", vaddr,		    *(int *)pte, pte_desc, 0);		if (!pte->pg_v) {			/* if "no access"  */			if (pte->pg_prot < PROT_URKR)				return(SEXC_SEGV);			return(SEXC_PAGEIN);		}		if (pte->pg_g) {			tlbdropin(0, vaddr, *(int *)pte);		} else if ((p->p_tlbpid != -1) || (CURRENT_CPUDATA->cpu_tps[p->p_tlbpid].tps_procpid == p->p_pid)) {			tlbdropin(p->p_tlbpid, vaddr, *(int *)pte);		} else {			panic("tlbmiss no tlbpid assigned");		}		return(0);	}	XPRINTF(XPR_TLB, "tlbmiss segv va 0x%x\n", vaddr, 0, 0, 0);	return(SEXC_SEGV);}/* * Changes for ULTRIX include: *  1. if a shared memory segment, then account for some users having *     read only and some users having read/write */tlbmod(ep, code, vaddr, cause)u_int *ep;{	register unsigned vpn;	register struct pte *pte;	register struct proc *p;	register int shm_page = 0;	int smindex;	vpn = btop(vaddr);	p = u.u_procp;	pte = vtopte(p, vpn);	if (!pte)		panic("tlbmod on invalid pte");	XPRINTF(XPR_TLB, "tlbmod vaddr 0x%x pte %r\n", vaddr, *(int *)pte,	    pte_desc, 0);	if (pte->pg_prot != PROT_UW) {		if (isasmsv(p, vpn, &smindex) &&   /* SHMEM */		    (p->p_sm[smindex].sm_pflag) == PROT_UW) {			shm_page++;			goto good;		}		return(SEXC_SEGV);	}good:	if (shm_page) {		pte->pg_swapm = 1;		tlbdropin(p->p_tlbpid, vaddr, (*(int *)pte | PG_M));	} else {		pte->pg_m = 1;		tlbdropin(p->p_tlbpid, vaddr, *(int *)pte);	}			return(0);}softnet(){	extern int netisr;	register struct isrent {		int value;		int (*function)();	} *pisr;	extern struct isrent netisr_tab[];		int s, signo;	acksoftnet();	/* see if any "extreme" priority signals posted by the 	   fpu code */	if (CURRENT_CPUDATA->cpu_fpe_event) {		s = splfpu();	/* sync with fpu */		/* send the signals...lowest numbered (highest		   priority) first */		while(CURRENT_CPUDATA->cpu_fpe_sendsig) {			signo=ffs(CURRENT_CPUDATA->cpu_fpe_sendsig);			/* note signo is 1-32 */			CURRENT_CPUDATA->cpu_fpe_sendsig &= ~(1<<(signo-1));			splx(s);			psignal(CURRENT_CPUDATA->cpu_fpe_event,signo);			s = splfpu();		}		CURRENT_CPUDATA->cpu_fpe_event = 0; /* no more */		splx(s);	}	pisr = netisr_tab;	while(pisr->value != -1) {		s = splimp();		if ((netisr & (1<<pisr->value)) &&		    clear_bit_atomic(pisr->value, &netisr)) {			splx(s);			(*pisr->function)();		} else			splx(s);		pisr++;	}	if (CURRENT_CPUDATA->cpu_wto_event) {		if (mmap_debug || 		   (sm_killp(CURRENT_CPUDATA->cpu_wto_pfn) == -1)){			/*			 *	log the information into error log buffer, 			 *	print the error info on the console and then crash.			 */		        (*(cpup->log_errinfo))(CURRENT_CPUDATA->cpu_log_errinfo);		        (*(cpup->print_consinfo))(CURRENT_CPUDATA->cpu_consinfo);			CURRENT_CPUDATA->cpu_wto_event = 0;                        panic("CPU write timeout");		}		else 			CURRENT_CPUDATA->cpu_wto_event = 0;	}}int traceopens = 0;syscall(ep, code, sr, cause)register u_int *ep;u_int code;{	register int regparams, nargs;	register struct sysent *callp;	register struct proc *p;	register int *params;	struct timeval syst;	extern char *syscallnames[];	struct cpudata *pcpu;	syst = u.u_ru.ru_stime;	u.u_error = 0;	if (!USERMODE(sr))		panic("syscall");	ep[EF_EPC] += 4;		/* normal return executes next inst */	regparams = EF_A0;	if (code >= nsysent) {		callp = &sysent[0];	/* indir (illegal) */		ep[EF_EPC] -= 4;	/* just leave pc at the syscall inst */	}	else {		callp = &sysent[code];		if (callp == sysent) {			/*			 * indirect system call (syscall), first param is			 * sys call number			 */			code = ep[EF_A0];			regparams++;			if (code >= nsysent)				callp = &sysent[0];			else				callp = &sysent[code];		}	}	u.u_eosys = NORMALRETURN;	params = (int *)u.u_arg;	for (nargs = callp->sy_narg; nargs && regparams <= EF_A3; nargs--)		*params++ = ep[regparams++];	if (nargs) {

⌨️ 快捷键说明

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