xref: /csrg-svn/sys/hp300/hp300/trap.c (revision 56508)
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  *
1253933Shibler  * from: Utah $Hdr: trap.c 1.35 91/12/26$
1341475Smckusick  *
14*56508Sbostic  *	@(#)trap.c	7.25 (Berkeley) 10/11/92
1541475Smckusick  */
1641475Smckusick 
17*56508Sbostic #include <sys/param.h>
18*56508Sbostic #include <sys/systm.h>
19*56508Sbostic #include <sys/proc.h>
20*56508Sbostic #include <sys/acct.h>
21*56508Sbostic #include <sys/kernel.h>
22*56508Sbostic #include <sys/signalvar.h>
23*56508Sbostic #include <sys/resourcevar.h>
24*56508Sbostic #include <sys/syscall.h>
25*56508Sbostic #include <sys/syslog.h>
26*56508Sbostic #include <sys/user.h>
2748465Skarels #ifdef KTRACE
28*56508Sbostic #include <sys/ktrace.h>
2948465Skarels #endif
3048465Skarels 
31*56508Sbostic #include <machine/psl.h>
32*56508Sbostic #include <machine/trap.h>
33*56508Sbostic #include <machine/cpu.h>
34*56508Sbostic #include <machine/reg.h>
35*56508Sbostic #include <machine/mtpr.h>
3641475Smckusick 
37*56508Sbostic #include <vm/vm.h>
38*56508Sbostic #include <vm/pmap.h>
3945751Smckusick 
4041475Smckusick #ifdef HPUXCOMPAT
41*56508Sbostic #include <hp/hpux/hpux.h>
4241475Smckusick #endif
4341475Smckusick 
4441475Smckusick struct	sysent	sysent[];
4541475Smckusick int	nsysent;
4641475Smckusick 
4741475Smckusick char	*trap_type[] = {
4841475Smckusick 	"Bus error",
4941475Smckusick 	"Address error",
5041475Smckusick 	"Illegal instruction",
5141475Smckusick 	"Zero divide",
5241475Smckusick 	"CHK instruction",
5341475Smckusick 	"TRAPV instruction",
5441475Smckusick 	"Privilege violation",
5541475Smckusick 	"Trace trap",
5641475Smckusick 	"MMU fault",
5741475Smckusick 	"SSIR trap",
5841475Smckusick 	"Format error",
5941475Smckusick 	"68881 exception",
6041475Smckusick 	"Coprocessor violation",
6141475Smckusick 	"Async system trap"
6241475Smckusick };
6341475Smckusick #define	TRAP_TYPES	(sizeof trap_type / sizeof trap_type[0])
6441475Smckusick 
6549317Shibler /*
6649317Shibler  * Size of various exception stack frames (minus the standard 8 bytes)
6749317Shibler  */
6849317Shibler short	exframesize[] = {
6949317Shibler 	FMT0SIZE,	/* type 0 - normal (68020/030/040) */
7049317Shibler 	FMT1SIZE,	/* type 1 - throwaway (68020/030/040) */
7149317Shibler 	FMT2SIZE,	/* type 2 - normal 6-word (68020/030/040) */
7253933Shibler 	FMT3SIZE,	/* type 3 - FP post-instruction (68040) */
7349317Shibler 	-1, -1, -1,	/* type 4-6 - undefined */
7453933Shibler 	FMT7SIZE,	/* type 7 - access error (68040) */
7549317Shibler 	58,		/* type 8 - bus fault (68010) */
7649317Shibler 	FMT9SIZE,	/* type 9 - coprocessor mid-instruction (68020/030) */
7749317Shibler 	FMTASIZE,	/* type A - short bus fault (68020/030) */
7849317Shibler 	FMTBSIZE,	/* type B - long bus fault (68020/030) */
7949317Shibler 	-1, -1, -1, -1	/* type C-F - undefined */
8049317Shibler };
8149317Shibler 
8254801Storek #ifdef HP380
8353933Shibler #define KDFAULT(c)	(mmutype == MMU_68040 ? \
8453933Shibler 			    ((c) & SSW4_TMMASK) == SSW4_TMKD : \
8553933Shibler 			    ((c) & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD))
8653933Shibler #define WRFAULT(c) 	(mmutype == MMU_68040 ? \
8753933Shibler 			    ((c) & SSW4_RW) == 0 : \
8853933Shibler 			    ((c) & (SSW_DF|SSW_RW)) == SSW_DF)
8953933Shibler #else
9053933Shibler #define KDFAULT(c)	(((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
9153933Shibler #define WRFAULT(c)	(((c) & (SSW_DF|SSW_RW)) == SSW_DF)
9253933Shibler #endif
9353933Shibler 
9441475Smckusick #ifdef DEBUG
9541475Smckusick int mmudebug = 0;
9653933Shibler int mmupid = -1;
9753933Shibler #define MDB_FOLLOW	1
9853933Shibler #define MDB_WBFOLLOW	2
9953933Shibler #define MDB_WBFAILED	4
10053933Shibler #define MDB_ISPID(p)	(p) == mmupid
10141475Smckusick #endif
10241475Smckusick 
10341475Smckusick /*
10454801Storek  * trap and syscall both need the following work done before returning
10554801Storek  * to user mode.
10654801Storek  */
10754801Storek static inline void
10854801Storek userret(p, fp, oticks, faultaddr, fromtrap)
10954801Storek 	register struct proc *p;
11054801Storek 	register struct frame *fp;
11154801Storek 	u_quad_t oticks;
11254801Storek 	u_int faultaddr;
11354801Storek 	int fromtrap;
11454801Storek {
11554801Storek 	int sig, s;
11654801Storek #ifdef HP380
11754801Storek 	int beenhere = 0;
11854801Storek 
11954801Storek again:
12054801Storek #endif
12154801Storek 	/* take pending signals */
12254801Storek 	while ((sig = CURSIG(p)) != 0)
12354801Storek 		psig(sig);
12454801Storek 	p->p_pri = p->p_usrpri;
12554801Storek 	if (want_resched) {
12654801Storek 		/*
12754801Storek 		 * Since we are curproc, clock will normally just change
12854801Storek 		 * our priority without moving us from one queue to another
12954801Storek 		 * (since the running process is not on a queue.)
13054801Storek 		 * If that happened after we setrq ourselves but before we
13154801Storek 		 * swtch()'ed, we might not be on the queue indicated by
13254801Storek 		 * our priority.
13354801Storek 		 */
13454801Storek 		s = splstatclock();
13554801Storek 		setrq(p);
13654801Storek 		p->p_stats->p_ru.ru_nivcsw++;
13754801Storek 		swtch();
13854801Storek 		splx(s);
13954801Storek 		while ((sig = CURSIG(p)) != 0)
14054801Storek 			psig(sig);
14154801Storek 	}
14254801Storek 
14354801Storek 	/*
14454801Storek 	 * If profiling, charge system time to the trapped pc.
14554801Storek 	 */
14656318Shibler 	if (p->p_flag & SPROFIL) {
14756318Shibler 		extern int psratio;
14856318Shibler 
14956318Shibler 		addupc_task(p, fp->f_pc,
15056318Shibler 			    (int)(p->p_sticks - oticks) * psratio);
15156318Shibler 	}
15254801Storek #ifdef HP380
15354801Storek 	/*
15454801Storek 	 * Deal with user mode writebacks (from trap, or from sigreturn).
15554801Storek 	 * If any writeback fails, go back and attempt signal delivery.
15654801Storek 	 * unless we have already been here and attempted the writeback
15754801Storek 	 * (e.g. bad address with user ignoring SIGSEGV).  In that case
15854801Storek 	 * we just return to the user without sucessfully completing
15954801Storek 	 * the writebacks.  Maybe we should just drop the sucker?
16054801Storek 	 */
16154801Storek 	if (mmutype == MMU_68040 && fp->f_format == FMT7) {
16254801Storek 		if (beenhere) {
16354801Storek #ifdef DEBUG
16454801Storek 			if (mmudebug & MDB_WBFAILED)
16554801Storek 				printf(fromtrap ?
16654801Storek 		"pid %d(%s): writeback aborted, pc=%x, fa=%x\n" :
16754801Storek 		"pid %d(%s): writeback aborted in sigreturn, pc=%x\n",
16854801Storek 				    p->p_pid, p->p_comm, fp->f_pc, faultaddr);
16954801Storek #endif
17054801Storek 		} else if (sig = writeback(fp, fromtrap)) {
17154801Storek 			beenhere = 1;
17254801Storek 			oticks = p->p_sticks;
17354801Storek 			trapsignal(p, sig, faultaddr);
17454801Storek 			goto again;
17554801Storek 		}
17654801Storek 	}
17754801Storek #endif
17854801Storek 	curpri = p->p_pri;
17954801Storek }
18054801Storek 
18154801Storek /*
18249531Skarels  * Trap is called from locore to handle most types of processor traps,
18349531Skarels  * including events such as simulated software interrupts/AST's.
18449531Skarels  * System calls are broken out for efficiency.
18541475Smckusick  */
18641475Smckusick /*ARGSUSED*/
18741475Smckusick trap(type, code, v, frame)
18841475Smckusick 	int type;
18941475Smckusick 	unsigned code;
19041475Smckusick 	register unsigned v;
19141475Smckusick 	struct frame frame;
19241475Smckusick {
19341475Smckusick 	register int i;
19454801Storek 	unsigned ucode;
19554801Storek 	register struct proc *p;
19654801Storek 	u_quad_t sticks;
19741475Smckusick 	unsigned ncode;
19854574Storek 	extern char fswintr[];
19941475Smckusick 
20041475Smckusick 	cnt.v_trap++;
20154801Storek 	p = curproc;
20254801Storek 	ucode = 0;
20341475Smckusick 	if (USERMODE(frame.f_sr)) {
20449531Skarels 		type |= T_USER;
20554801Storek 		sticks = p->p_sticks;
20652380Smckusick 		p->p_md.md_regs = frame.f_regs;
20741475Smckusick 	}
20841475Smckusick 	switch (type) {
20941475Smckusick 
21041475Smckusick 	default:
21141475Smckusick dopanic:
21241475Smckusick 		printf("trap type %d, code = %x, v = %x\n", type, code, v);
21341475Smckusick 		regdump(frame.f_regs, 128);
21449531Skarels 		type &= ~T_USER;
21541475Smckusick 		if ((unsigned)type < TRAP_TYPES)
21641475Smckusick 			panic(trap_type[type]);
21741475Smckusick 		panic("trap");
21841475Smckusick 
21941475Smckusick 	case T_BUSERR:		/* kernel bus error */
22049125Skarels 		if (!p->p_addr->u_pcb.pcb_onfault)
22141475Smckusick 			goto dopanic;
22241475Smckusick 		/*
22341475Smckusick 		 * If we have arranged to catch this fault in any of the
22441475Smckusick 		 * copy to/from user space routines, set PC to return to
22541475Smckusick 		 * indicated location and set flag informing buserror code
22641475Smckusick 		 * that it may need to clean up stack frame.
22741475Smckusick 		 */
22841475Smckusick copyfault:
22949317Shibler 		frame.f_stackadj = exframesize[frame.f_format];
23049317Shibler 		frame.f_format = frame.f_vector = 0;
23149125Skarels 		frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault;
23241475Smckusick 		return;
23341475Smckusick 
23449531Skarels 	case T_BUSERR|T_USER:	/* bus error */
23549531Skarels 	case T_ADDRERR|T_USER:	/* address error */
23653933Shibler 		ucode = v;
23741475Smckusick 		i = SIGBUS;
23841475Smckusick 		break;
23941475Smckusick 
24041475Smckusick #ifdef FPCOPROC
24141475Smckusick 	case T_COPERR:		/* kernel coprocessor violation */
24241475Smckusick #endif
24353933Shibler 	case T_FMTERR|T_USER:	/* do all RTE errors come in as T_USER? */
24453933Shibler 	case T_FMTERR:		/* ...just in case... */
24541475Smckusick 	/*
24641475Smckusick 	 * The user has most likely trashed the RTE or FP state info
24741475Smckusick 	 * in the stack frame of a signal handler.
24841475Smckusick 	 */
24949531Skarels 		type |= T_USER;
25048465Skarels 		printf("pid %d: kernel %s exception\n", p->p_pid,
25141475Smckusick 		       type==T_COPERR ? "coprocessor" : "format");
25248465Skarels 		p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL;
25341475Smckusick 		i = sigmask(SIGILL);
25441475Smckusick 		p->p_sigignore &= ~i;
25541475Smckusick 		p->p_sigcatch &= ~i;
25641475Smckusick 		p->p_sigmask &= ~i;
25742370Skarels 		i = SIGILL;
25841475Smckusick 		ucode = frame.f_format;	/* XXX was ILL_RESAD_FAULT */
25942370Skarels 		break;
26041475Smckusick 
26141475Smckusick #ifdef FPCOPROC
26249531Skarels 	case T_COPERR|T_USER:	/* user coprocessor violation */
26341475Smckusick 	/* What is a proper response here? */
26441475Smckusick 		ucode = 0;
26541475Smckusick 		i = SIGFPE;
26641475Smckusick 		break;
26741475Smckusick 
26849531Skarels 	case T_FPERR|T_USER:	/* 68881 exceptions */
26941475Smckusick 	/*
27041475Smckusick 	 * We pass along the 68881 status register which locore stashed
27141475Smckusick 	 * in code for us.  Note that there is a possibility that the
27241475Smckusick 	 * bit pattern of this register will conflict with one of the
27341475Smckusick 	 * FPE_* codes defined in signal.h.  Fortunately for us, the
27441475Smckusick 	 * only such codes we use are all in the range 1-7 and the low
27541475Smckusick 	 * 3 bits of the status register are defined as 0 so there is
27641475Smckusick 	 * no clash.
27741475Smckusick 	 */
27841475Smckusick 		ucode = code;
27941475Smckusick 		i = SIGFPE;
28041475Smckusick 		break;
28141475Smckusick #endif
28241475Smckusick 
28354801Storek #ifdef HP380
28453933Shibler 	case T_FPEMULI|T_USER:	/* unimplemented FP instuction */
28553933Shibler 	case T_FPEMULD|T_USER:	/* unimplemented FP data type */
28653933Shibler 		/* XXX need to FSAVE */
28753933Shibler 		printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n",
28853933Shibler 		       p->p_pid, p->p_comm,
28953933Shibler 		       frame.f_format == 2 ? "instruction" : "data type",
29053933Shibler 		       frame.f_pc, frame.f_fmt2.f_iaddr);
29153933Shibler 		/* XXX need to FRESTORE */
29253933Shibler 		i = SIGFPE;
29353933Shibler 		break;
29453933Shibler #endif
29553933Shibler 
29649531Skarels 	case T_ILLINST|T_USER:	/* illegal instruction fault */
29741475Smckusick #ifdef HPUXCOMPAT
29848465Skarels 		if (p->p_flag & SHPUX) {
29941475Smckusick 			ucode = HPUX_ILL_ILLINST_TRAP;
30041475Smckusick 			i = SIGILL;
30141475Smckusick 			break;
30241475Smckusick 		}
30341475Smckusick 		/* fall through */
30441475Smckusick #endif
30549531Skarels 	case T_PRIVINST|T_USER:	/* privileged instruction fault */
30641475Smckusick #ifdef HPUXCOMPAT
30748465Skarels 		if (p->p_flag & SHPUX)
30841475Smckusick 			ucode = HPUX_ILL_PRIV_TRAP;
30941475Smckusick 		else
31041475Smckusick #endif
31141475Smckusick 		ucode = frame.f_format;	/* XXX was ILL_PRIVIN_FAULT */
31241475Smckusick 		i = SIGILL;
31341475Smckusick 		break;
31441475Smckusick 
31549531Skarels 	case T_ZERODIV|T_USER:	/* Divide by zero */
31641475Smckusick #ifdef HPUXCOMPAT
31748465Skarels 		if (p->p_flag & SHPUX)
31841475Smckusick 			ucode = HPUX_FPE_INTDIV_TRAP;
31941475Smckusick 		else
32041475Smckusick #endif
32141475Smckusick 		ucode = frame.f_format;	/* XXX was FPE_INTDIV_TRAP */
32241475Smckusick 		i = SIGFPE;
32341475Smckusick 		break;
32441475Smckusick 
32549531Skarels 	case T_CHKINST|T_USER:	/* CHK instruction trap */
32641475Smckusick #ifdef HPUXCOMPAT
32748465Skarels 		if (p->p_flag & SHPUX) {
32841475Smckusick 			/* handled differently under hp-ux */
32941475Smckusick 			i = SIGILL;
33041475Smckusick 			ucode = HPUX_ILL_CHK_TRAP;
33141475Smckusick 			break;
33241475Smckusick 		}
33341475Smckusick #endif
33441475Smckusick 		ucode = frame.f_format;	/* XXX was FPE_SUBRNG_TRAP */
33541475Smckusick 		i = SIGFPE;
33641475Smckusick 		break;
33741475Smckusick 
33849531Skarels 	case T_TRAPVINST|T_USER:	/* TRAPV instruction trap */
33941475Smckusick #ifdef HPUXCOMPAT
34048465Skarels 		if (p->p_flag & SHPUX) {
34141475Smckusick 			/* handled differently under hp-ux */
34241475Smckusick 			i = SIGILL;
34341475Smckusick 			ucode = HPUX_ILL_TRAPV_TRAP;
34441475Smckusick 			break;
34541475Smckusick 		}
34641475Smckusick #endif
34741475Smckusick 		ucode = frame.f_format;	/* XXX was FPE_INTOVF_TRAP */
34841475Smckusick 		i = SIGFPE;
34941475Smckusick 		break;
35041475Smckusick 
35141475Smckusick 	/*
35241475Smckusick 	 * XXX: Trace traps are a nightmare.
35341475Smckusick 	 *
35441475Smckusick 	 *	HP-UX uses trap #1 for breakpoints,
35541475Smckusick 	 *	HPBSD uses trap #2,
35641475Smckusick 	 *	SUN 3.x uses trap #15,
35748465Skarels 	 *	KGDB uses trap #15 (for kernel breakpoints; handled elsewhere).
35841475Smckusick 	 *
35941475Smckusick 	 * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
36041475Smckusick 	 * SUN 3.x traps get passed through as T_TRAP15 and are not really
36148465Skarels 	 * supported yet.
36241475Smckusick 	 */
36341475Smckusick 	case T_TRACE:		/* kernel trace trap */
36448465Skarels 	case T_TRAP15:		/* SUN trace trap */
36541475Smckusick 		frame.f_sr &= ~PSL_T;
36641475Smckusick 		i = SIGTRAP;
36741475Smckusick 		break;
36841475Smckusick 
36949531Skarels 	case T_TRACE|T_USER:	/* user trace trap */
37049531Skarels 	case T_TRAP15|T_USER:	/* SUN user trace trap */
37141475Smckusick 		frame.f_sr &= ~PSL_T;
37241475Smckusick 		i = SIGTRAP;
37341475Smckusick 		break;
37441475Smckusick 
37543413Shibler 	case T_ASTFLT:		/* system async trap, cannot happen */
37641475Smckusick 		goto dopanic;
37741475Smckusick 
37849531Skarels 	case T_ASTFLT|T_USER:	/* user async trap */
37949125Skarels 		astpending = 0;
38041475Smckusick 		/*
38141475Smckusick 		 * We check for software interrupts first.  This is because
38241475Smckusick 		 * they are at a higher level than ASTs, and on a VAX would
38341475Smckusick 		 * interrupt the AST.  We assume that if we are processing
38441475Smckusick 		 * an AST that we must be at IPL0 so we don't bother to
38541475Smckusick 		 * check.  Note that we ensure that we are at least at SIR
38641475Smckusick 		 * IPL while processing the SIR.
38741475Smckusick 		 */
38841475Smckusick 		spl1();
38941475Smckusick 		/* fall into... */
39041475Smckusick 
39141475Smckusick 	case T_SSIR:		/* software interrupt */
39249531Skarels 	case T_SSIR|T_USER:
39341475Smckusick 		if (ssir & SIR_NET) {
39441475Smckusick 			siroff(SIR_NET);
39541475Smckusick 			cnt.v_soft++;
39641475Smckusick 			netintr();
39741475Smckusick 		}
39841475Smckusick 		if (ssir & SIR_CLOCK) {
39941475Smckusick 			siroff(SIR_CLOCK);
40041475Smckusick 			cnt.v_soft++;
40154801Storek 			softclock();
40241475Smckusick 		}
40341475Smckusick 		/*
40441475Smckusick 		 * If this was not an AST trap, we are all done.
40541475Smckusick 		 */
40650753Skarels 		if (type != (T_ASTFLT|T_USER)) {
40741475Smckusick 			cnt.v_trap--;
40841475Smckusick 			return;
40941475Smckusick 		}
41041475Smckusick 		spl0();
41154801Storek 		if (p->p_flag & SOWEUPC) {
41248465Skarels 			p->p_flag &= ~SOWEUPC;
41354801Storek 			ADDUPROF(p);
41441475Smckusick 		}
41541475Smckusick 		goto out;
41641475Smckusick 
41741475Smckusick 	case T_MMUFLT:		/* kernel mode page fault */
41854574Storek 		/*
41954574Storek 		 * If we were doing profiling ticks or other user mode
42054574Storek 		 * stuff from interrupt code, Just Say No.
42154574Storek 		 */
42254574Storek 		if (p->p_addr->u_pcb.pcb_onfault == fswintr)
42354574Storek 			goto copyfault;
42441475Smckusick 		/* fall into ... */
42541475Smckusick 
42649531Skarels 	case T_MMUFLT|T_USER:	/* page fault */
42745751Smckusick 	    {
42845751Smckusick 		register vm_offset_t va;
42948465Skarels 		register struct vmspace *vm = p->p_vmspace;
43045751Smckusick 		register vm_map_t map;
43145751Smckusick 		int rv;
43245751Smckusick 		vm_prot_t ftype;
43345751Smckusick 		extern vm_map_t kernel_map;
43445751Smckusick 
43553933Shibler #ifdef DEBUG
43653933Shibler 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
43753933Shibler 		printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n",
43853933Shibler 		       p->p_pid, code, v, frame.f_pc, frame.f_sr);
43953933Shibler #endif
44041475Smckusick 		/*
44145751Smckusick 		 * It is only a kernel address space fault iff:
44249531Skarels 		 * 	1. (type & T_USER) == 0  and
44345751Smckusick 		 * 	2. pcb_onfault not set or
44445751Smckusick 		 *	3. pcb_onfault set but supervisor space data fault
44545751Smckusick 		 * The last can occur during an exec() copyin where the
44645751Smckusick 		 * argument space is lazy-allocated.
44741475Smckusick 		 */
44845751Smckusick 		if (type == T_MMUFLT &&
44953933Shibler 		    (!p->p_addr->u_pcb.pcb_onfault || KDFAULT(code)))
45045751Smckusick 			map = kernel_map;
45145751Smckusick 		else
45248465Skarels 			map = &vm->vm_map;
45353933Shibler 		if (WRFAULT(code))
45445751Smckusick 			ftype = VM_PROT_READ | VM_PROT_WRITE;
45545751Smckusick 		else
45645751Smckusick 			ftype = VM_PROT_READ;
45745751Smckusick 		va = trunc_page((vm_offset_t)v);
45841475Smckusick #ifdef DEBUG
45945751Smckusick 		if (map == kernel_map && va == 0) {
46045751Smckusick 			printf("trap: bad kernel access at %x\n", v);
46141475Smckusick 			goto dopanic;
46241475Smckusick 		}
46341475Smckusick #endif
46449317Shibler 		rv = vm_fault(map, va, ftype, FALSE);
46553933Shibler #ifdef DEBUG
46653933Shibler 		if (rv && MDB_ISPID(p->p_pid))
46753933Shibler 			printf("vm_fault(%x, %x, %x, 0) -> %x\n",
46853933Shibler 			       map, va, ftype, rv);
46953933Shibler #endif
47041475Smckusick 		/*
47149317Shibler 		 * If this was a stack access we keep track of the maximum
47249317Shibler 		 * accessed stack size.  Also, if vm_fault gets a protection
47349317Shibler 		 * failure it is due to accessing the stack region outside
47449317Shibler 		 * the current limit and we need to reflect that as an access
47549317Shibler 		 * error.
47641475Smckusick 		 */
47748465Skarels 		if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) {
47849317Shibler 			if (rv == KERN_SUCCESS) {
47949317Shibler 				unsigned nss;
48049317Shibler 
48149317Shibler 				nss = clrnd(btoc(USRSTACK-(unsigned)va));
48249317Shibler 				if (nss > vm->vm_ssize)
48349317Shibler 					vm->vm_ssize = nss;
48449317Shibler 			} else if (rv == KERN_PROTECTION_FAILURE)
48549317Shibler 				rv = KERN_INVALID_ADDRESS;
48641475Smckusick 		}
48745751Smckusick 		if (rv == KERN_SUCCESS) {
48853933Shibler 			if (type == T_MMUFLT) {
48954801Storek #ifdef HP380
49053933Shibler 				if (mmutype == MMU_68040)
49153933Shibler 					(void) writeback(&frame, 1);
49253933Shibler #endif
49341475Smckusick 				return;
49453933Shibler 			}
49541475Smckusick 			goto out;
49641475Smckusick 		}
49745751Smckusick 		if (type == T_MMUFLT) {
49849125Skarels 			if (p->p_addr->u_pcb.pcb_onfault)
49945751Smckusick 				goto copyfault;
50045751Smckusick 			printf("vm_fault(%x, %x, %x, 0) -> %x\n",
50145751Smckusick 			       map, va, ftype, rv);
50245751Smckusick 			printf("  type %x, code [mmu,,ssw]: %x\n",
50345751Smckusick 			       type, code);
50445751Smckusick 			goto dopanic;
50545751Smckusick 		}
50648465Skarels 		ucode = v;
50745751Smckusick 		i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV;
50845751Smckusick 		break;
50945751Smckusick 	    }
51041475Smckusick 	}
51148465Skarels 	trapsignal(p, i, ucode);
51249531Skarels 	if ((type & T_USER) == 0)
51341475Smckusick 		return;
51441475Smckusick out:
51554801Storek 	userret(p, &frame, sticks, v, 1);
51641475Smckusick }
51741475Smckusick 
51854801Storek #ifdef HP380
51953933Shibler #ifdef DEBUG
52053933Shibler struct writebackstats {
52153933Shibler 	int calls;
52253933Shibler 	int cpushes;
52353933Shibler 	int move16s;
52453933Shibler 	int wb1s, wb2s, wb3s;
52553933Shibler 	int wbsize[4];
52653933Shibler } wbstats;
52753933Shibler 
52853933Shibler char *f7sz[] = { "longword", "byte", "word", "line" };
52953933Shibler char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" };
53053933Shibler char *f7tm[] = { "d-push", "u-data", "u-code", "M-data",
53153933Shibler 		 "M-code", "k-data", "k-code", "RES" };
53253933Shibler char wberrstr[] =
53353933Shibler     "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n";
53453933Shibler #endif
53553933Shibler 
53653933Shibler writeback(fp, docachepush)
53753933Shibler 	struct frame *fp;
53853933Shibler 	int docachepush;
53953933Shibler {
54053933Shibler 	register struct fmt7 *f = &fp->f_fmt7;
54153933Shibler 	register struct proc *p = curproc;
54253933Shibler 	int err = 0;
54353933Shibler 	u_int fa;
54453933Shibler 	caddr_t oonfault = p->p_addr->u_pcb.pcb_onfault;
54553933Shibler 
54653933Shibler #ifdef DEBUG
54753933Shibler 	if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) {
54853933Shibler 		printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa);
54953933Shibler 		dumpssw(f->f_ssw);
55053933Shibler 	}
55153933Shibler 	wbstats.calls++;
55253933Shibler #endif
55353933Shibler 	/*
55453933Shibler 	 * Deal with special cases first.
55553933Shibler 	 */
55653933Shibler 	if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) {
55753933Shibler 		/*
55853933Shibler 		 * Dcache push fault.
55953933Shibler 		 * Line-align the address and write out the push data to
56053933Shibler 		 * the indicated physical address.
56153933Shibler 		 */
56253933Shibler #ifdef DEBUG
56353933Shibler 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) {
56453933Shibler 			printf(" pushing %s to PA %x, data %x",
56553933Shibler 			       f7sz[(f->f_ssw & SSW4_SZMASK) >> 5],
56653933Shibler 			       f->f_fa, f->f_pd0);
56753933Shibler 			if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN)
56853933Shibler 				printf("/%x/%x/%x",
56953933Shibler 				       f->f_pd1, f->f_pd2, f->f_pd3);
57053933Shibler 			printf("\n");
57153933Shibler 		}
57253933Shibler 		if (f->f_wb1s & SSW4_WBSV)
57353933Shibler 			panic("writeback: cache push with WB1S valid");
57453933Shibler 		wbstats.cpushes++;
57553933Shibler #endif
57653933Shibler 		/*
57753933Shibler 		 * XXX there are security problems if we attempt to do a
57853933Shibler 		 * cache push after a signal handler has been called.
57953933Shibler 		 */
58053933Shibler 		if (docachepush) {
58153933Shibler 			pmap_enter(kernel_pmap, (vm_offset_t)vmmap,
58253933Shibler 				   trunc_page(f->f_fa), VM_PROT_WRITE, TRUE);
58353933Shibler 			fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF];
58453933Shibler 			bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16);
58553933Shibler 			DCFL(pmap_extract(kernel_pmap, (vm_offset_t)fa));
58653933Shibler 			pmap_remove(kernel_pmap, (vm_offset_t)vmmap,
58753933Shibler 				    (vm_offset_t)&vmmap[NBPG]);
58853933Shibler 		} else
58953933Shibler 			printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n",
59053933Shibler 			       p->p_pid, p->p_comm, p->p_ucred->cr_uid);
59153933Shibler 	} else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) {
59253933Shibler 		/*
59353933Shibler 		 * MOVE16 fault.
59453933Shibler 		 * Line-align the address and write out the push data to
59553933Shibler 		 * the indicated virtual address.
59653933Shibler 		 */
59753933Shibler #ifdef DEBUG
59853933Shibler 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
59953933Shibler 			printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n",
60053933Shibler 			       f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1,
60153933Shibler 			       f->f_pd2, f->f_pd3);
60253933Shibler 		if (f->f_wb1s & SSW4_WBSV)
60353933Shibler 			panic("writeback: MOVE16 with WB1S valid");
60453933Shibler 		wbstats.move16s++;
60553933Shibler #endif
60653933Shibler 		if (KDFAULT(f->f_wb1s))
60753933Shibler 			bcopy((caddr_t)&f->f_pd0, (caddr_t)(f->f_fa & ~0xF), 16);
60853933Shibler 		else
60953933Shibler 			err = suline((caddr_t)(f->f_fa & ~0xF), (caddr_t)&f->f_pd0);
61053933Shibler 		if (err) {
61153933Shibler 			fa = f->f_fa & ~0xF;
61253933Shibler #ifdef DEBUG
61353933Shibler 			if (mmudebug & MDB_WBFAILED)
61453933Shibler 				printf(wberrstr, p->p_pid, p->p_comm,
61553933Shibler 				       "MOVE16", fp->f_pc, f->f_fa,
61653933Shibler 				       f->f_fa & ~0xF, f->f_pd0);
61753933Shibler #endif
61853933Shibler 		}
61953933Shibler 	} else if (f->f_wb1s & SSW4_WBSV) {
62053933Shibler 		/*
62153933Shibler 		 * Writeback #1.
62253933Shibler 		 * Position the "memory-aligned" data and write it out.
62353933Shibler 		 */
62453933Shibler 		register u_int wb1d = f->f_wb1d;
62553933Shibler 		register int off;
62653933Shibler 
62753933Shibler #ifdef DEBUG
62853933Shibler 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
62953933Shibler 			dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d);
63053933Shibler 		wbstats.wb1s++;
63153933Shibler 		wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++;
63253933Shibler #endif
63353933Shibler 		off = (f->f_wb1a & 3) * 8;
63453933Shibler 		switch (f->f_wb1s & SSW4_SZMASK) {
63553933Shibler 		case SSW4_SZLW:
63653933Shibler 			if (off)
63753933Shibler 				wb1d = (wb1d >> (32 - off)) | (wb1d << off);
63853933Shibler 			if (KDFAULT(f->f_wb1s))
63953933Shibler 				*(long *)f->f_wb1a = wb1d;
64053933Shibler 			else
64153933Shibler 				err = suword((caddr_t)f->f_wb1a, wb1d);
64253933Shibler 			break;
64353933Shibler 		case SSW4_SZB:
64453933Shibler 			off = 24 - off;
64553933Shibler 			if (off)
64653933Shibler 				wb1d >>= off;
64753933Shibler 			if (KDFAULT(f->f_wb1s))
64853933Shibler 				*(char *)f->f_wb1a = wb1d;
64953933Shibler 			else
65053933Shibler 				err = subyte((caddr_t)f->f_wb1a, wb1d);
65153933Shibler 			break;
65253933Shibler 		case SSW4_SZW:
65353933Shibler 			off = (off + 16) % 32;
65453933Shibler 			if (off)
65553933Shibler 				wb1d = (wb1d >> (32 - off)) | (wb1d << off);
65653933Shibler 			if (KDFAULT(f->f_wb1s))
65753933Shibler 				*(short *)f->f_wb1a = wb1d;
65853933Shibler 			else
65953933Shibler 				err = susword((caddr_t)f->f_wb1a, wb1d);
66053933Shibler 			break;
66153933Shibler 		}
66253933Shibler 		if (err) {
66353933Shibler 			fa = f->f_wb1a;
66453933Shibler #ifdef DEBUG
66553933Shibler 			if (mmudebug & MDB_WBFAILED)
66653933Shibler 				printf(wberrstr, p->p_pid, p->p_comm,
66753933Shibler 				       "#1", fp->f_pc, f->f_fa,
66853933Shibler 				       f->f_wb1a, f->f_wb1d);
66953933Shibler #endif
67053933Shibler 		}
67153933Shibler 	}
67253933Shibler 	/*
67353933Shibler 	 * Deal with the "normal" writebacks.
67453933Shibler 	 *
67553933Shibler 	 * XXX writeback2 is known to reflect a LINE size writeback after
67653933Shibler 	 * a MOVE16 was already dealt with above.  Ignore it.
67753933Shibler 	 */
67853933Shibler 	if (err == 0 && (f->f_wb2s & SSW4_WBSV) &&
67953933Shibler 	    (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) {
68053933Shibler #ifdef DEBUG
68153933Shibler 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
68253933Shibler 			dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d);
68353933Shibler 		wbstats.wb2s++;
68453933Shibler 		wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++;
68553933Shibler #endif
68653933Shibler 		switch (f->f_wb2s & SSW4_SZMASK) {
68753933Shibler 		case SSW4_SZLW:
68853933Shibler 			if (KDFAULT(f->f_wb2s))
68953933Shibler 				*(long *)f->f_wb2a = f->f_wb2d;
69053933Shibler 			else
69153933Shibler 				err = suword((caddr_t)f->f_wb2a, f->f_wb2d);
69253933Shibler 			break;
69353933Shibler 		case SSW4_SZB:
69453933Shibler 			if (KDFAULT(f->f_wb2s))
69553933Shibler 				*(char *)f->f_wb2a = f->f_wb2d;
69653933Shibler 			else
69753933Shibler 				err = subyte((caddr_t)f->f_wb2a, f->f_wb2d);
69853933Shibler 			break;
69953933Shibler 		case SSW4_SZW:
70053933Shibler 			if (KDFAULT(f->f_wb2s))
70153933Shibler 				*(short *)f->f_wb2a = f->f_wb2d;
70253933Shibler 			else
70353933Shibler 				err = susword((caddr_t)f->f_wb2a, f->f_wb2d);
70453933Shibler 			break;
70553933Shibler 		}
70653933Shibler 		if (err) {
70753933Shibler 			fa = f->f_wb2a;
70853933Shibler #ifdef DEBUG
70953933Shibler 			if (mmudebug & MDB_WBFAILED) {
71053933Shibler 				printf(wberrstr, p->p_pid, p->p_comm,
71153933Shibler 				       "#2", fp->f_pc, f->f_fa,
71253933Shibler 				       f->f_wb2a, f->f_wb2d);
71353933Shibler 				dumpssw(f->f_ssw);
71453933Shibler 				dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d);
71553933Shibler 			}
71653933Shibler #endif
71753933Shibler 		}
71853933Shibler 	}
71953933Shibler 	if (err == 0 && (f->f_wb3s & SSW4_WBSV)) {
72053933Shibler #ifdef DEBUG
72153933Shibler 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
72253933Shibler 			dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d);
72353933Shibler 		wbstats.wb3s++;
72453933Shibler 		wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++;
72553933Shibler #endif
72653933Shibler 		switch (f->f_wb3s & SSW4_SZMASK) {
72753933Shibler 		case SSW4_SZLW:
72853933Shibler 			if (KDFAULT(f->f_wb3s))
72953933Shibler 				*(long *)f->f_wb3a = f->f_wb3d;
73053933Shibler 			else
73153933Shibler 				err = suword((caddr_t)f->f_wb3a, f->f_wb3d);
73253933Shibler 			break;
73353933Shibler 		case SSW4_SZB:
73453933Shibler 			if (KDFAULT(f->f_wb3s))
73553933Shibler 				*(char *)f->f_wb3a = f->f_wb3d;
73653933Shibler 			else
73753933Shibler 				err = subyte((caddr_t)f->f_wb3a, f->f_wb3d);
73853933Shibler 			break;
73953933Shibler 		case SSW4_SZW:
74053933Shibler 			if (KDFAULT(f->f_wb3s))
74153933Shibler 				*(short *)f->f_wb3a = f->f_wb3d;
74253933Shibler 			else
74353933Shibler 				err = susword((caddr_t)f->f_wb3a, f->f_wb3d);
74453933Shibler 			break;
74553933Shibler #ifdef DEBUG
74653933Shibler 		case SSW4_SZLN:
74753933Shibler 			panic("writeback: wb3s indicates LINE write");
74853933Shibler #endif
74953933Shibler 		}
75053933Shibler 		if (err) {
75153933Shibler 			fa = f->f_wb3a;
75253933Shibler #ifdef DEBUG
75353933Shibler 			if (mmudebug & MDB_WBFAILED)
75453933Shibler 				printf(wberrstr, p->p_pid, p->p_comm,
75553933Shibler 				       "#3", fp->f_pc, f->f_fa,
75653933Shibler 				       f->f_wb3a, f->f_wb3d);
75753933Shibler #endif
75853933Shibler 		}
75953933Shibler 	}
76053933Shibler 	p->p_addr->u_pcb.pcb_onfault = oonfault;
76153933Shibler 	/*
76253933Shibler 	 * Determine the cause of the failure if any translating to
76353933Shibler 	 * a signal.  If the corresponding VA is valid and RO it is
76453933Shibler 	 * a protection fault (SIGBUS) otherwise consider it an
76553933Shibler 	 * illegal reference (SIGSEGV).
76653933Shibler 	 */
76753933Shibler 	if (err) {
76853933Shibler 		if (vm_map_check_protection(&p->p_vmspace->vm_map,
76953933Shibler 					    trunc_page(fa), round_page(fa),
77053933Shibler 					    VM_PROT_READ) &&
77153933Shibler 		    !vm_map_check_protection(&p->p_vmspace->vm_map,
77253933Shibler 					     trunc_page(fa), round_page(fa),
77353933Shibler 					     VM_PROT_WRITE))
77453933Shibler 			err = SIGBUS;
77553933Shibler 		else
77653933Shibler 			err = SIGSEGV;
77753933Shibler 	}
77853933Shibler 	return(err);
77953933Shibler }
78053933Shibler 
78153933Shibler #ifdef DEBUG
78253933Shibler dumpssw(ssw)
78353933Shibler 	register u_short ssw;
78453933Shibler {
78553933Shibler 	printf(" SSW: %x: ", ssw);
78653933Shibler 	if (ssw & SSW4_CP)
78753933Shibler 		printf("CP,");
78853933Shibler 	if (ssw & SSW4_CU)
78953933Shibler 		printf("CU,");
79053933Shibler 	if (ssw & SSW4_CT)
79153933Shibler 		printf("CT,");
79253933Shibler 	if (ssw & SSW4_CM)
79353933Shibler 		printf("CM,");
79453933Shibler 	if (ssw & SSW4_MA)
79553933Shibler 		printf("MA,");
79653933Shibler 	if (ssw & SSW4_ATC)
79753933Shibler 		printf("ATC,");
79853933Shibler 	if (ssw & SSW4_LK)
79953933Shibler 		printf("LK,");
80053933Shibler 	if (ssw & SSW4_RW)
80153933Shibler 		printf("RW,");
80253933Shibler 	printf(" SZ=%s, TT=%s, TM=%s\n",
80353933Shibler 	       f7sz[(ssw & SSW4_SZMASK) >> 5],
80453933Shibler 	       f7tt[(ssw & SSW4_TTMASK) >> 3],
80553933Shibler 	       f7tm[ssw & SSW4_TMMASK]);
80653933Shibler }
80753933Shibler 
80853933Shibler dumpwb(num, s, a, d)
80953933Shibler 	int num;
81053933Shibler 	u_short s;
81153933Shibler 	u_int a, d;
81253933Shibler {
81353933Shibler 	register struct proc *p = curproc;
81453933Shibler 	vm_offset_t pa;
81553933Shibler 
81653933Shibler 	printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n",
81753933Shibler 	       num, a, d, f7sz[(s & SSW4_SZMASK) >> 5],
81853933Shibler 	       f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]);
81953933Shibler 	printf("               PA ");
82053933Shibler 	pa = pmap_extract(&p->p_vmspace->vm_pmap, (vm_offset_t)a);
82153933Shibler 	if (pa == 0)
82253933Shibler 		printf("<invalid address>");
82353933Shibler 	else
82453933Shibler 		printf("%x, current value %x", pa, fuword((caddr_t)a));
82553933Shibler 	printf("\n");
82653933Shibler }
82753933Shibler 
82853933Shibler #ifdef HPFPLIB
82953933Shibler fppanic(frame)
83053933Shibler 	struct fppanicframe {
83153933Shibler 		int	fpsaveframe;
83253933Shibler 		int	regs[16];
83353933Shibler 		int	fpregs[8*3];
83453933Shibler 		int	fpcregs[3];
83553933Shibler 		int	hole[5];
83653933Shibler 		int	oa6;
83753933Shibler 		short	sr;
83853933Shibler 		int	pc;
83953933Shibler 		short	vector;
84053933Shibler 	} frame;
84153933Shibler {
84253933Shibler 	printf("FP exception: pid %d(%s): no busy frame, ft=%x pc=%x vec=%x\n",
84353933Shibler 	       curproc->p_pid, curproc->p_comm,
84453933Shibler 	       frame.fpsaveframe, frame.pc, frame.vector);
84553933Shibler 	panic("bad FP exception");
84653933Shibler }
84753933Shibler #endif
84853933Shibler #endif
84953933Shibler #endif
85053933Shibler 
85141475Smckusick /*
85249531Skarels  * Proces a system call.
85341475Smckusick  */
85441475Smckusick syscall(code, frame)
85554801Storek 	u_int code;
85641475Smckusick 	struct frame frame;
85741475Smckusick {
85841475Smckusick 	register caddr_t params;
85941475Smckusick 	register struct sysent *callp;
86054801Storek 	register struct proc *p;
86150753Skarels 	int error, opc, numsys, s;
86254801Storek 	u_int argsize;
86344018Skarels 	struct args {
86444018Skarels 		int i[8];
86544018Skarels 	} args;
86644018Skarels 	int rval[2];
86754801Storek 	u_quad_t sticks;
86841475Smckusick #ifdef HPUXCOMPAT
86941475Smckusick 	extern struct sysent hpuxsysent[];
87041475Smckusick 	extern int hpuxnsysent, notimp();
87141475Smckusick #endif
87241475Smckusick 
87341475Smckusick 	cnt.v_syscall++;
87441475Smckusick 	if (!USERMODE(frame.f_sr))
87541475Smckusick 		panic("syscall");
87654801Storek 	p = curproc;
87754801Storek 	sticks = p->p_sticks;
87852380Smckusick 	p->p_md.md_regs = frame.f_regs;
87941475Smckusick 	opc = frame.f_pc - 2;
88041475Smckusick #ifdef HPUXCOMPAT
88154801Storek 	if (p->p_flag & SHPUX)
88254801Storek 		callp = hpuxsysent, numsys = hpuxnsysent;
88354801Storek 	else
88441475Smckusick #endif
88554801Storek 		callp = sysent, numsys = nsysent;
88649531Skarels 	params = (caddr_t)frame.f_regs[SP] + sizeof(int);
88754801Storek 	switch (code) {
88854801Storek 
88954801Storek 	case SYS_indir:
89054801Storek 		/*
89154801Storek 		 * Code is first argument, followed by actual args.
89254801Storek 		 */
89342370Skarels 		code = fuword(params);
89449531Skarels 		params += sizeof(int);
89554801Storek 		break;
89654801Storek 
89754801Storek 	case SYS___indir:
89854801Storek 		/*
89954801Storek 		 * Like indir, but code is a quad, so as to maintain
90054801Storek 		 * quad alignment for the rest of the arguments.
90154801Storek 		 */
90241475Smckusick #ifdef HPUXCOMPAT
90341475Smckusick 		if (p->p_flag & SHPUX)
90454801Storek 			break;
90541475Smckusick #endif
90654865Smckusick 		code = fuword(params + _QUAD_LOWWORD * sizeof(int));
90754865Smckusick 		params += sizeof(quad_t);
90854801Storek 		break;
90954801Storek 
91054865Smckusick 	default:
91154865Smckusick 		/* nothing to do by default */
91254865Smckusick 		break;
91354801Storek 	}
91454801Storek 	if (code < numsys)
91554801Storek 		callp += code;
91654801Storek 	else
91754801Storek 		callp += SYS_indir;	/* => nosys */
91854801Storek 	argsize = callp->sy_narg * sizeof(int);
91954801Storek 	if (argsize && (error = copyin(params, (caddr_t)&args, argsize))) {
92041475Smckusick #ifdef KTRACE
92143641Skarels 		if (KTRPOINT(p, KTR_SYSCALL))
92244018Skarels 			ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
92341475Smckusick #endif
92454801Storek 		goto bad;
92541475Smckusick 	}
92641475Smckusick #ifdef KTRACE
92743641Skarels 	if (KTRPOINT(p, KTR_SYSCALL))
92844018Skarels 		ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
92941475Smckusick #endif
93043641Skarels 	rval[0] = 0;
93143641Skarels 	rval[1] = frame.f_regs[D1];
93241475Smckusick #ifdef HPUXCOMPAT
93342370Skarels 	/* debug kludge */
93442370Skarels 	if (callp->sy_call == notimp)
93548465Skarels 		error = notimp(p, args.i, rval, code, callp->sy_narg);
93642370Skarels 	else
93741475Smckusick #endif
93854801Storek 		error = (*callp->sy_call)(p, &args, rval);
93954801Storek 	switch (error) {
94042370Skarels 
94154801Storek 	case 0:
94241475Smckusick 		/*
94354801Storek 		 * Reinitialize proc pointer `p' as it may be different
94454801Storek 		 * if this is a child returning from fork syscall.
94541475Smckusick 		 */
94654801Storek 		p = curproc;
94754801Storek 		frame.f_regs[D0] = rval[0];
94854801Storek 		frame.f_regs[D1] = rval[1];
94954801Storek 		frame.f_sr &= ~PSL_C;
95054801Storek 		break;
95141475Smckusick 
95254801Storek 	case ERESTART:
95354801Storek 		frame.f_pc = opc;
95454801Storek 		break;
95554801Storek 
95654801Storek 	case EJUSTRETURN:
95754801Storek 		break;		/* nothing to do */
95854801Storek 
95954801Storek 	default:
96054801Storek 	bad:
96154801Storek #ifdef HPUXCOMPAT
96254801Storek 		if (p->p_flag & SHPUX)
96354801Storek 			error = bsdtohpuxerrno(error);
96441475Smckusick #endif
96554801Storek 		frame.f_regs[D0] = error;
96654801Storek 		frame.f_sr |= PSL_C;
96754801Storek 		break;
96841475Smckusick 	}
96954801Storek 
97054801Storek 	userret(p, &frame, sticks, (u_int)0, 0);
97141475Smckusick #ifdef KTRACE
97243641Skarels 	if (KTRPOINT(p, KTR_SYSRET))
97343641Skarels 		ktrsysret(p->p_tracep, code, error, rval[0]);
97441475Smckusick #endif
97541475Smckusick }
976