xref: /csrg-svn/sys/hp300/hp300/trap.c (revision 50753)
141475Smckusick /*
241475Smckusick  * Copyright (c) 1988 University of Utah.
341475Smckusick  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
441475Smckusick  * All rights reserved.
541475Smckusick  *
641475Smckusick  * This code is derived from software contributed to Berkeley by
741475Smckusick  * the Systems Programming Group of the University of Utah Computer
841475Smckusick  * Science Department.
941475Smckusick  *
1041475Smckusick  * %sccs.include.redist.c%
1141475Smckusick  *
1249317Shibler  * from: Utah $Hdr: trap.c 1.32 91/04/06$
1341475Smckusick  *
14*50753Skarels  *	@(#)trap.c	7.14.1.3 (Berkeley) 08/02/91
1541475Smckusick  */
1641475Smckusick 
1748465Skarels #include "param.h"
1848465Skarels #include "systm.h"
1948465Skarels #include "proc.h"
2048465Skarels #include "seg.h"
2148465Skarels #include "acct.h"
2248465Skarels #include "kernel.h"
2348465Skarels #include "signalvar.h"
2448465Skarels #include "resourcevar.h"
2548465Skarels #include "syslog.h"
2648465Skarels #include "user.h"
2748465Skarels #ifdef KTRACE
2848465Skarels #include "ktrace.h"
2948465Skarels #endif
3048465Skarels 
3149125Skarels #include "../include/psl.h"
3248465Skarels #include "../include/trap.h"
3345788Sbostic #include "../include/cpu.h"
3445788Sbostic #include "../include/reg.h"
3545788Sbostic #include "../include/mtpr.h"
3641475Smckusick 
3748465Skarels #include "vm/vm.h"
3845788Sbostic #include "vm/pmap.h"
3948465Skarels #include "vmmeter.h"
4045751Smckusick 
4141475Smckusick #ifdef HPUXCOMPAT
4241475Smckusick #include "../hpux/hpux.h"
4341475Smckusick #endif
4441475Smckusick 
4541475Smckusick struct	sysent	sysent[];
4641475Smckusick int	nsysent;
4741475Smckusick 
4841475Smckusick char	*trap_type[] = {
4941475Smckusick 	"Bus error",
5041475Smckusick 	"Address error",
5141475Smckusick 	"Illegal instruction",
5241475Smckusick 	"Zero divide",
5341475Smckusick 	"CHK instruction",
5441475Smckusick 	"TRAPV instruction",
5541475Smckusick 	"Privilege violation",
5641475Smckusick 	"Trace trap",
5741475Smckusick 	"MMU fault",
5841475Smckusick 	"SSIR trap",
5941475Smckusick 	"Format error",
6041475Smckusick 	"68881 exception",
6141475Smckusick 	"Coprocessor violation",
6241475Smckusick 	"Async system trap"
6341475Smckusick };
6441475Smckusick #define	TRAP_TYPES	(sizeof trap_type / sizeof trap_type[0])
6541475Smckusick 
6649317Shibler /*
6749317Shibler  * Size of various exception stack frames (minus the standard 8 bytes)
6849317Shibler  */
6949317Shibler short	exframesize[] = {
7049317Shibler 	FMT0SIZE,	/* type 0 - normal (68020/030/040) */
7149317Shibler 	FMT1SIZE,	/* type 1 - throwaway (68020/030/040) */
7249317Shibler 	FMT2SIZE,	/* type 2 - normal 6-word (68020/030/040) */
7349317Shibler 	-1,		/* type 3 - FP post-instruction (68040) */
7449317Shibler 	-1, -1, -1,	/* type 4-6 - undefined */
7549317Shibler 	-1,		/* type 7 - access error (68040) */
7649317Shibler 	58,		/* type 8 - bus fault (68010) */
7749317Shibler 	FMT9SIZE,	/* type 9 - coprocessor mid-instruction (68020/030) */
7849317Shibler 	FMTASIZE,	/* type A - short bus fault (68020/030) */
7949317Shibler 	FMTBSIZE,	/* type B - long bus fault (68020/030) */
8049317Shibler 	-1, -1, -1, -1	/* type C-F - undefined */
8149317Shibler };
8249317Shibler 
8341475Smckusick #ifdef DEBUG
8441475Smckusick int mmudebug = 0;
8541475Smckusick #endif
8641475Smckusick 
8741475Smckusick /*
8849531Skarels  * Trap is called from locore to handle most types of processor traps,
8949531Skarels  * including events such as simulated software interrupts/AST's.
9049531Skarels  * System calls are broken out for efficiency.
9141475Smckusick  */
9241475Smckusick /*ARGSUSED*/
9341475Smckusick trap(type, code, v, frame)
9441475Smckusick 	int type;
9541475Smckusick 	unsigned code;
9641475Smckusick 	register unsigned v;
9741475Smckusick 	struct frame frame;
9841475Smckusick {
9941475Smckusick 	register int i;
10041475Smckusick 	unsigned ucode = 0;
10148465Skarels 	register struct proc *p = curproc;
10241475Smckusick 	struct timeval syst;
10341475Smckusick 	unsigned ncode;
104*50753Skarels 	int s;
10541475Smckusick 
10641475Smckusick 	cnt.v_trap++;
10748465Skarels 	syst = p->p_stime;
10841475Smckusick 	if (USERMODE(frame.f_sr)) {
10949531Skarels 		type |= T_USER;
11048465Skarels 		p->p_regs = frame.f_regs;
11141475Smckusick 	}
11241475Smckusick 	switch (type) {
11341475Smckusick 
11441475Smckusick 	default:
11541475Smckusick dopanic:
11641475Smckusick 		printf("trap type %d, code = %x, v = %x\n", type, code, v);
11741475Smckusick 		regdump(frame.f_regs, 128);
11849531Skarels 		type &= ~T_USER;
11941475Smckusick 		if ((unsigned)type < TRAP_TYPES)
12041475Smckusick 			panic(trap_type[type]);
12141475Smckusick 		panic("trap");
12241475Smckusick 
12341475Smckusick 	case T_BUSERR:		/* kernel bus error */
12449125Skarels 		if (!p->p_addr->u_pcb.pcb_onfault)
12541475Smckusick 			goto dopanic;
12641475Smckusick 		/*
12741475Smckusick 		 * If we have arranged to catch this fault in any of the
12841475Smckusick 		 * copy to/from user space routines, set PC to return to
12941475Smckusick 		 * indicated location and set flag informing buserror code
13041475Smckusick 		 * that it may need to clean up stack frame.
13141475Smckusick 		 */
13241475Smckusick copyfault:
13349317Shibler 		frame.f_stackadj = exframesize[frame.f_format];
13449317Shibler 		frame.f_format = frame.f_vector = 0;
13549125Skarels 		frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault;
13641475Smckusick 		return;
13741475Smckusick 
13849531Skarels 	case T_BUSERR|T_USER:	/* bus error */
13949531Skarels 	case T_ADDRERR|T_USER:	/* address error */
14041475Smckusick 		i = SIGBUS;
14141475Smckusick 		break;
14241475Smckusick 
14341475Smckusick #ifdef FPCOPROC
14441475Smckusick 	case T_COPERR:		/* kernel coprocessor violation */
14541475Smckusick #endif
14641475Smckusick 	case T_FMTERR:		/* kernel format error */
14741475Smckusick 	/*
14841475Smckusick 	 * The user has most likely trashed the RTE or FP state info
14941475Smckusick 	 * in the stack frame of a signal handler.
15041475Smckusick 	 */
15149531Skarels 		type |= T_USER;
15248465Skarels 		printf("pid %d: kernel %s exception\n", p->p_pid,
15341475Smckusick 		       type==T_COPERR ? "coprocessor" : "format");
15448465Skarels 		p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL;
15541475Smckusick 		i = sigmask(SIGILL);
15641475Smckusick 		p->p_sigignore &= ~i;
15741475Smckusick 		p->p_sigcatch &= ~i;
15841475Smckusick 		p->p_sigmask &= ~i;
15942370Skarels 		i = SIGILL;
16041475Smckusick 		ucode = frame.f_format;	/* XXX was ILL_RESAD_FAULT */
16142370Skarels 		break;
16241475Smckusick 
16341475Smckusick #ifdef FPCOPROC
16449531Skarels 	case T_COPERR|T_USER:	/* user coprocessor violation */
16541475Smckusick 	/* What is a proper response here? */
16641475Smckusick 		ucode = 0;
16741475Smckusick 		i = SIGFPE;
16841475Smckusick 		break;
16941475Smckusick 
17049531Skarels 	case T_FPERR|T_USER:	/* 68881 exceptions */
17141475Smckusick 	/*
17241475Smckusick 	 * We pass along the 68881 status register which locore stashed
17341475Smckusick 	 * in code for us.  Note that there is a possibility that the
17441475Smckusick 	 * bit pattern of this register will conflict with one of the
17541475Smckusick 	 * FPE_* codes defined in signal.h.  Fortunately for us, the
17641475Smckusick 	 * only such codes we use are all in the range 1-7 and the low
17741475Smckusick 	 * 3 bits of the status register are defined as 0 so there is
17841475Smckusick 	 * no clash.
17941475Smckusick 	 */
18041475Smckusick 		ucode = code;
18141475Smckusick 		i = SIGFPE;
18241475Smckusick 		break;
18341475Smckusick #endif
18441475Smckusick 
18549531Skarels 	case T_ILLINST|T_USER:	/* illegal instruction fault */
18641475Smckusick #ifdef HPUXCOMPAT
18748465Skarels 		if (p->p_flag & SHPUX) {
18841475Smckusick 			ucode = HPUX_ILL_ILLINST_TRAP;
18941475Smckusick 			i = SIGILL;
19041475Smckusick 			break;
19141475Smckusick 		}
19241475Smckusick 		/* fall through */
19341475Smckusick #endif
19449531Skarels 	case T_PRIVINST|T_USER:	/* privileged instruction fault */
19541475Smckusick #ifdef HPUXCOMPAT
19648465Skarels 		if (p->p_flag & SHPUX)
19741475Smckusick 			ucode = HPUX_ILL_PRIV_TRAP;
19841475Smckusick 		else
19941475Smckusick #endif
20041475Smckusick 		ucode = frame.f_format;	/* XXX was ILL_PRIVIN_FAULT */
20141475Smckusick 		i = SIGILL;
20241475Smckusick 		break;
20341475Smckusick 
20449531Skarels 	case T_ZERODIV|T_USER:	/* Divide by zero */
20541475Smckusick #ifdef HPUXCOMPAT
20648465Skarels 		if (p->p_flag & SHPUX)
20741475Smckusick 			ucode = HPUX_FPE_INTDIV_TRAP;
20841475Smckusick 		else
20941475Smckusick #endif
21041475Smckusick 		ucode = frame.f_format;	/* XXX was FPE_INTDIV_TRAP */
21141475Smckusick 		i = SIGFPE;
21241475Smckusick 		break;
21341475Smckusick 
21449531Skarels 	case T_CHKINST|T_USER:	/* CHK instruction trap */
21541475Smckusick #ifdef HPUXCOMPAT
21648465Skarels 		if (p->p_flag & SHPUX) {
21741475Smckusick 			/* handled differently under hp-ux */
21841475Smckusick 			i = SIGILL;
21941475Smckusick 			ucode = HPUX_ILL_CHK_TRAP;
22041475Smckusick 			break;
22141475Smckusick 		}
22241475Smckusick #endif
22341475Smckusick 		ucode = frame.f_format;	/* XXX was FPE_SUBRNG_TRAP */
22441475Smckusick 		i = SIGFPE;
22541475Smckusick 		break;
22641475Smckusick 
22749531Skarels 	case T_TRAPVINST|T_USER:	/* TRAPV instruction trap */
22841475Smckusick #ifdef HPUXCOMPAT
22948465Skarels 		if (p->p_flag & SHPUX) {
23041475Smckusick 			/* handled differently under hp-ux */
23141475Smckusick 			i = SIGILL;
23241475Smckusick 			ucode = HPUX_ILL_TRAPV_TRAP;
23341475Smckusick 			break;
23441475Smckusick 		}
23541475Smckusick #endif
23641475Smckusick 		ucode = frame.f_format;	/* XXX was FPE_INTOVF_TRAP */
23741475Smckusick 		i = SIGFPE;
23841475Smckusick 		break;
23941475Smckusick 
24041475Smckusick 	/*
24141475Smckusick 	 * XXX: Trace traps are a nightmare.
24241475Smckusick 	 *
24341475Smckusick 	 *	HP-UX uses trap #1 for breakpoints,
24441475Smckusick 	 *	HPBSD uses trap #2,
24541475Smckusick 	 *	SUN 3.x uses trap #15,
24648465Skarels 	 *	KGDB uses trap #15 (for kernel breakpoints; handled elsewhere).
24741475Smckusick 	 *
24841475Smckusick 	 * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
24941475Smckusick 	 * SUN 3.x traps get passed through as T_TRAP15 and are not really
25048465Skarels 	 * supported yet.
25141475Smckusick 	 */
25241475Smckusick 	case T_TRACE:		/* kernel trace trap */
25348465Skarels 	case T_TRAP15:		/* SUN trace trap */
25441475Smckusick 		frame.f_sr &= ~PSL_T;
25541475Smckusick 		i = SIGTRAP;
25641475Smckusick 		break;
25741475Smckusick 
25849531Skarels 	case T_TRACE|T_USER:	/* user trace trap */
25949531Skarels 	case T_TRAP15|T_USER:	/* SUN user trace trap */
26041475Smckusick 		frame.f_sr &= ~PSL_T;
26141475Smckusick 		i = SIGTRAP;
26241475Smckusick 		break;
26341475Smckusick 
26443413Shibler 	case T_ASTFLT:		/* system async trap, cannot happen */
26541475Smckusick 		goto dopanic;
26641475Smckusick 
26749531Skarels 	case T_ASTFLT|T_USER:	/* user async trap */
26849125Skarels 		astpending = 0;
26941475Smckusick 		/*
27041475Smckusick 		 * We check for software interrupts first.  This is because
27141475Smckusick 		 * they are at a higher level than ASTs, and on a VAX would
27241475Smckusick 		 * interrupt the AST.  We assume that if we are processing
27341475Smckusick 		 * an AST that we must be at IPL0 so we don't bother to
27441475Smckusick 		 * check.  Note that we ensure that we are at least at SIR
27541475Smckusick 		 * IPL while processing the SIR.
27641475Smckusick 		 */
27741475Smckusick 		spl1();
27841475Smckusick 		/* fall into... */
27941475Smckusick 
28041475Smckusick 	case T_SSIR:		/* software interrupt */
28149531Skarels 	case T_SSIR|T_USER:
28241475Smckusick 		if (ssir & SIR_NET) {
28341475Smckusick 			siroff(SIR_NET);
28441475Smckusick 			cnt.v_soft++;
28541475Smckusick 			netintr();
28641475Smckusick 		}
28741475Smckusick 		if (ssir & SIR_CLOCK) {
28841475Smckusick 			siroff(SIR_CLOCK);
28941475Smckusick 			cnt.v_soft++;
29041475Smckusick 			softclock((caddr_t)frame.f_pc, (int)frame.f_sr);
29141475Smckusick 		}
29241475Smckusick 		/*
29341475Smckusick 		 * If this was not an AST trap, we are all done.
29441475Smckusick 		 */
295*50753Skarels 		if (type != (T_ASTFLT|T_USER)) {
29641475Smckusick 			cnt.v_trap--;
29741475Smckusick 			return;
29841475Smckusick 		}
29941475Smckusick 		spl0();
30041475Smckusick #ifndef PROFTIMER
30148465Skarels 		if ((p->p_flag&SOWEUPC) && p->p_stats->p_prof.pr_scale) {
30248465Skarels 			addupc(frame.f_pc, &p->p_stats->p_prof, 1);
30348465Skarels 			p->p_flag &= ~SOWEUPC;
30441475Smckusick 		}
30541475Smckusick #endif
30641475Smckusick 		goto out;
30741475Smckusick 
30841475Smckusick 	case T_MMUFLT:		/* kernel mode page fault */
30941475Smckusick 		/* fall into ... */
31041475Smckusick 
31149531Skarels 	case T_MMUFLT|T_USER:	/* page fault */
31245751Smckusick 	    {
31345751Smckusick 		register vm_offset_t va;
31448465Skarels 		register struct vmspace *vm = p->p_vmspace;
31545751Smckusick 		register vm_map_t map;
31645751Smckusick 		int rv;
31745751Smckusick 		vm_prot_t ftype;
31845751Smckusick 		extern vm_map_t kernel_map;
31945751Smckusick 
32041475Smckusick 		/*
32145751Smckusick 		 * It is only a kernel address space fault iff:
32249531Skarels 		 * 	1. (type & T_USER) == 0  and
32345751Smckusick 		 * 	2. pcb_onfault not set or
32445751Smckusick 		 *	3. pcb_onfault set but supervisor space data fault
32545751Smckusick 		 * The last can occur during an exec() copyin where the
32645751Smckusick 		 * argument space is lazy-allocated.
32741475Smckusick 		 */
32845751Smckusick 		if (type == T_MMUFLT &&
32949125Skarels 		    (!p->p_addr->u_pcb.pcb_onfault ||
33045751Smckusick 		     (code & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD)))
33145751Smckusick 			map = kernel_map;
33245751Smckusick 		else
33348465Skarels 			map = &vm->vm_map;
33445751Smckusick 		if ((code & (SSW_DF|SSW_RW)) == SSW_DF)	/* what about RMW? */
33545751Smckusick 			ftype = VM_PROT_READ | VM_PROT_WRITE;
33645751Smckusick 		else
33745751Smckusick 			ftype = VM_PROT_READ;
33845751Smckusick 		va = trunc_page((vm_offset_t)v);
33941475Smckusick #ifdef DEBUG
34045751Smckusick 		if (map == kernel_map && va == 0) {
34145751Smckusick 			printf("trap: bad kernel access at %x\n", v);
34241475Smckusick 			goto dopanic;
34341475Smckusick 		}
34441475Smckusick #endif
34549317Shibler 		rv = vm_fault(map, va, ftype, FALSE);
34641475Smckusick 		/*
34749317Shibler 		 * If this was a stack access we keep track of the maximum
34849317Shibler 		 * accessed stack size.  Also, if vm_fault gets a protection
34949317Shibler 		 * failure it is due to accessing the stack region outside
35049317Shibler 		 * the current limit and we need to reflect that as an access
35149317Shibler 		 * error.
35241475Smckusick 		 */
35348465Skarels 		if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) {
35449317Shibler 			if (rv == KERN_SUCCESS) {
35549317Shibler 				unsigned nss;
35649317Shibler 
35749317Shibler 				nss = clrnd(btoc(USRSTACK-(unsigned)va));
35849317Shibler 				if (nss > vm->vm_ssize)
35949317Shibler 					vm->vm_ssize = nss;
36049317Shibler 			} else if (rv == KERN_PROTECTION_FAILURE)
36149317Shibler 				rv = KERN_INVALID_ADDRESS;
36241475Smckusick 		}
36345751Smckusick 		if (rv == KERN_SUCCESS) {
36441475Smckusick 			if (type == T_MMUFLT)
36541475Smckusick 				return;
36641475Smckusick 			goto out;
36741475Smckusick 		}
36845751Smckusick 		if (type == T_MMUFLT) {
36949125Skarels 			if (p->p_addr->u_pcb.pcb_onfault)
37045751Smckusick 				goto copyfault;
37145751Smckusick 			printf("vm_fault(%x, %x, %x, 0) -> %x\n",
37245751Smckusick 			       map, va, ftype, rv);
37345751Smckusick 			printf("  type %x, code [mmu,,ssw]: %x\n",
37445751Smckusick 			       type, code);
37545751Smckusick 			goto dopanic;
37645751Smckusick 		}
37748465Skarels 		ucode = v;
37845751Smckusick 		i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV;
37945751Smckusick 		break;
38045751Smckusick 	    }
38141475Smckusick 	}
38248465Skarels 	trapsignal(p, i, ucode);
38349531Skarels 	if ((type & T_USER) == 0)
38441475Smckusick 		return;
38541475Smckusick out:
38648465Skarels 	while (i = CURSIG(p))
38742370Skarels 		psig(i);
38841475Smckusick 	p->p_pri = p->p_usrpri;
38948465Skarels 	if (want_resched) {
39041475Smckusick 		/*
39148465Skarels 		 * Since we are curproc, clock will normally just change
39241475Smckusick 		 * our priority without moving us from one queue to another
39341475Smckusick 		 * (since the running process is not on a queue.)
39441475Smckusick 		 * If that happened after we setrq ourselves but before we
39541475Smckusick 		 * swtch()'ed, we might not be on the queue indicated by
39641475Smckusick 		 * our priority.
39741475Smckusick 		 */
398*50753Skarels 		s = splclock();
39941475Smckusick 		setrq(p);
40048465Skarels 		p->p_stats->p_ru.ru_nivcsw++;
40141475Smckusick 		swtch();
402*50753Skarels 		splx(s);
40348465Skarels 		while (i = CURSIG(p))
40442370Skarels 			psig(i);
40541475Smckusick 	}
40648465Skarels 	if (p->p_stats->p_prof.pr_scale) {
40741475Smckusick 		int ticks;
40848465Skarels 		struct timeval *tv = &p->p_stime;
40941475Smckusick 
41041475Smckusick 		ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
41141475Smckusick 			(tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
41241475Smckusick 		if (ticks) {
41341475Smckusick #ifdef PROFTIMER
41441475Smckusick 			extern int profscale;
41548465Skarels 			addupc(frame.f_pc, &p->p_stats->p_prof,
41648465Skarels 			    ticks * profscale);
41741475Smckusick #else
41848465Skarels 			addupc(frame.f_pc, &p->p_stats->p_prof, ticks);
41941475Smckusick #endif
42041475Smckusick 		}
42141475Smckusick 	}
42241475Smckusick 	curpri = p->p_pri;
42341475Smckusick }
42441475Smckusick 
42541475Smckusick /*
42649531Skarels  * Proces a system call.
42741475Smckusick  */
42841475Smckusick syscall(code, frame)
42941475Smckusick 	volatile int code;
43041475Smckusick 	struct frame frame;
43141475Smckusick {
43241475Smckusick 	register caddr_t params;
43341475Smckusick 	register int i;
43441475Smckusick 	register struct sysent *callp;
43548465Skarels 	register struct proc *p = curproc;
436*50753Skarels 	int error, opc, numsys, s;
43744018Skarels 	struct args {
43844018Skarels 		int i[8];
43944018Skarels 	} args;
44044018Skarels 	int rval[2];
44141475Smckusick 	struct timeval syst;
44241475Smckusick 	struct sysent *systab;
44341475Smckusick #ifdef HPUXCOMPAT
44441475Smckusick 	extern struct sysent hpuxsysent[];
44541475Smckusick 	extern int hpuxnsysent, notimp();
44641475Smckusick #endif
44741475Smckusick 
44841475Smckusick 	cnt.v_syscall++;
44948465Skarels 	syst = p->p_stime;
45041475Smckusick 	if (!USERMODE(frame.f_sr))
45141475Smckusick 		panic("syscall");
45248465Skarels 	p->p_regs = frame.f_regs;
45341475Smckusick 	opc = frame.f_pc - 2;
45441475Smckusick 	systab = sysent;
45541475Smckusick 	numsys = nsysent;
45641475Smckusick #ifdef HPUXCOMPAT
45742370Skarels 	if (p->p_flag & SHPUX) {
45841475Smckusick 		systab = hpuxsysent;
45941475Smckusick 		numsys = hpuxnsysent;
46041475Smckusick 	}
46141475Smckusick #endif
46249531Skarels 	params = (caddr_t)frame.f_regs[SP] + sizeof(int);
46342370Skarels 	if (code == 0) {			/* indir */
46442370Skarels 		code = fuword(params);
46549531Skarels 		params += sizeof(int);
46642370Skarels 	}
46742370Skarels 	if (code >= numsys)
46842370Skarels 		callp = &systab[0];		/* indir (illegal) */
46942370Skarels 	else
47042370Skarels 		callp = &systab[code];
47141475Smckusick 	if ((i = callp->sy_narg * sizeof (int)) &&
47244018Skarels 	    (error = copyin(params, (caddr_t)&args, (u_int)i))) {
47341475Smckusick #ifdef HPUXCOMPAT
47441475Smckusick 		if (p->p_flag & SHPUX)
47542370Skarels 			error = bsdtohpuxerrno(error);
47641475Smckusick #endif
47749362Skarels 		frame.f_regs[D0] = error;
47841475Smckusick 		frame.f_sr |= PSL_C;	/* carry bit */
47941475Smckusick #ifdef KTRACE
48043641Skarels 		if (KTRPOINT(p, KTR_SYSCALL))
48144018Skarels 			ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
48241475Smckusick #endif
48341475Smckusick 		goto done;
48441475Smckusick 	}
48541475Smckusick #ifdef KTRACE
48643641Skarels 	if (KTRPOINT(p, KTR_SYSCALL))
48744018Skarels 		ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
48841475Smckusick #endif
48943641Skarels 	rval[0] = 0;
49043641Skarels 	rval[1] = frame.f_regs[D1];
49141475Smckusick #ifdef HPUXCOMPAT
49242370Skarels 	/* debug kludge */
49342370Skarels 	if (callp->sy_call == notimp)
49448465Skarels 		error = notimp(p, args.i, rval, code, callp->sy_narg);
49542370Skarels 	else
49641475Smckusick #endif
49748465Skarels 	error = (*callp->sy_call)(p, &args, rval);
49849817Smckusick #ifdef DIAGNOSTIC
49949817Smckusick 	if (curproc->p_spare[0])
50049817Smckusick 		panic("syscall: M_NAMEI");
50149817Smckusick 	if (curproc->p_spare[1])
50249817Smckusick 		panic("syscall: STARTSAVE");
50349911Smckusick 	if (curproc->p_spare[2])
50449911Smckusick 		panic("syscall: LOCK COUNT");
50549817Smckusick #endif
50642370Skarels 	if (error == ERESTART)
50742370Skarels 		frame.f_pc = opc;
50842370Skarels 	else if (error != EJUSTRETURN) {
50942370Skarels 		if (error) {
51041475Smckusick #ifdef HPUXCOMPAT
51142370Skarels 			if (p->p_flag & SHPUX)
51242370Skarels 				error = bsdtohpuxerrno(error);
51341475Smckusick #endif
51449362Skarels 			frame.f_regs[D0] = error;
51542370Skarels 			frame.f_sr |= PSL_C;	/* carry bit */
51641475Smckusick 		} else {
51743641Skarels 			frame.f_regs[D0] = rval[0];
51843641Skarels 			frame.f_regs[D1] = rval[1];
51941475Smckusick 			frame.f_sr &= ~PSL_C;
52041475Smckusick 		}
52142370Skarels 	}
52242370Skarels 	/* else if (error == EJUSTRETURN) */
52341475Smckusick 		/* nothing to do */
52442370Skarels 
52541475Smckusick done:
52641475Smckusick 	/*
52742370Skarels 	 * Reinitialize proc pointer `p' as it may be different
52842370Skarels 	 * if this is a child returning from fork syscall.
52942370Skarels 	 */
53048465Skarels 	p = curproc;
53149317Shibler 	while (i = CURSIG(p))
53249317Shibler 		psig(i);
53341475Smckusick 	p->p_pri = p->p_usrpri;
53448465Skarels 	if (want_resched) {
53541475Smckusick 		/*
53648465Skarels 		 * Since we are curproc, clock will normally just change
53741475Smckusick 		 * our priority without moving us from one queue to another
53841475Smckusick 		 * (since the running process is not on a queue.)
53941475Smckusick 		 * If that happened after we setrq ourselves but before we
54041475Smckusick 		 * swtch()'ed, we might not be on the queue indicated by
54141475Smckusick 		 * our priority.
54241475Smckusick 		 */
543*50753Skarels 		s = splclock();
54441475Smckusick 		setrq(p);
54548465Skarels 		p->p_stats->p_ru.ru_nivcsw++;
54641475Smckusick 		swtch();
547*50753Skarels 		splx(s);
54849317Shibler 		while (i = CURSIG(p))
54949317Shibler 			psig(i);
55041475Smckusick 	}
55148465Skarels 	if (p->p_stats->p_prof.pr_scale) {
55241475Smckusick 		int ticks;
55348465Skarels 		struct timeval *tv = &p->p_stime;
55441475Smckusick 
55541475Smckusick 		ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
55641475Smckusick 			(tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
55741475Smckusick 		if (ticks) {
55841475Smckusick #ifdef PROFTIMER
55941475Smckusick 			extern int profscale;
56048465Skarels 			addupc(frame.f_pc, &p->p_stats->p_prof,
56148465Skarels 			    ticks * profscale);
56241475Smckusick #else
56348465Skarels 			addupc(frame.f_pc, &p->p_stats->p_prof, ticks);
56441475Smckusick #endif
56541475Smckusick 		}
56641475Smckusick 	}
56741475Smckusick 	curpri = p->p_pri;
56841475Smckusick #ifdef KTRACE
56943641Skarels 	if (KTRPOINT(p, KTR_SYSRET))
57043641Skarels 		ktrsysret(p->p_tracep, code, error, rval[0]);
57141475Smckusick #endif
57241475Smckusick }
573