xref: /csrg-svn/sys/hp300/hp300/trap.c (revision 68359)
141475Smckusick /*
241475Smckusick  * Copyright (c) 1988 University of Utah.
363472Sbostic  * Copyright (c) 1982, 1986, 1990, 1993
463472Sbostic  *	The Regents of the University of California.  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  *
1257344Shibler  * from: Utah $Hdr: trap.c 1.37 92/12/20$
1341475Smckusick  *
14*68359Scgd  *	@(#)trap.c	8.7 (Berkeley) 02/19/95
1541475Smckusick  */
1641475Smckusick 
1756508Sbostic #include <sys/param.h>
1856508Sbostic #include <sys/systm.h>
1956508Sbostic #include <sys/proc.h>
2056508Sbostic #include <sys/acct.h>
2156508Sbostic #include <sys/kernel.h>
2256508Sbostic #include <sys/signalvar.h>
2356508Sbostic #include <sys/resourcevar.h>
2456508Sbostic #include <sys/syscall.h>
2556508Sbostic #include <sys/syslog.h>
2656508Sbostic #include <sys/user.h>
2748465Skarels #ifdef KTRACE
2856508Sbostic #include <sys/ktrace.h>
2948465Skarels #endif
3048465Skarels 
3156508Sbostic #include <machine/psl.h>
3256508Sbostic #include <machine/trap.h>
3356508Sbostic #include <machine/cpu.h>
3456508Sbostic #include <machine/reg.h>
3556508Sbostic #include <machine/mtpr.h>
3641475Smckusick 
3756508Sbostic #include <vm/vm.h>
3856508Sbostic #include <vm/pmap.h>
3945751Smckusick 
4041475Smckusick #ifdef HPUXCOMPAT
4156508Sbostic #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
userret(p,fp,oticks,faultaddr,fromtrap)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)
12364615Sbostic 		postsig(sig);
12464615Sbostic 	p->p_priority = 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.)
13064542Sbostic 		 * If that happened after we put ourselves on the run queue
13164615Sbostic 		 * but before we mi_switch()'ed, we might not be on the queue
13264542Sbostic 		 * indicated by our priority.
13354801Storek 		 */
13454801Storek 		s = splstatclock();
13564542Sbostic 		setrunqueue(p);
13654801Storek 		p->p_stats->p_ru.ru_nivcsw++;
13764615Sbostic 		mi_switch();
13854801Storek 		splx(s);
13954801Storek 		while ((sig = CURSIG(p)) != 0)
14064615Sbostic 			postsig(sig);
14154801Storek 	}
14254801Storek 
14354801Storek 	/*
14454801Storek 	 * If profiling, charge system time to the trapped pc.
14554801Storek 	 */
14664615Sbostic 	if (p->p_flag & P_PROFIL) {
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
17864615Sbostic 	curpriority = p->p_priority;
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*/
trap(type,code,v,frame)18741475Smckusick trap(type, code, v, frame)
18841475Smckusick 	int type;
18941475Smckusick 	unsigned code;
19041475Smckusick 	register unsigned v;
19141475Smckusick 	struct frame frame;
19241475Smckusick {
19365483Sbostic 	extern char fswintr[];
19465483Sbostic 	register struct proc *p;
19541475Smckusick 	register int i;
19665483Sbostic 	u_int ucode;
19754801Storek 	u_quad_t sticks;
19841475Smckusick 
19941475Smckusick 	cnt.v_trap++;
20054801Storek 	p = curproc;
20154801Storek 	ucode = 0;
20241475Smckusick 	if (USERMODE(frame.f_sr)) {
20349531Skarels 		type |= T_USER;
20454801Storek 		sticks = p->p_sticks;
20552380Smckusick 		p->p_md.md_regs = frame.f_regs;
20641475Smckusick 	}
20741475Smckusick 	switch (type) {
20841475Smckusick 
20941475Smckusick 	default:
21041475Smckusick dopanic:
21141475Smckusick 		printf("trap type %d, code = %x, v = %x\n", type, code, v);
21257344Shibler 		regdump(&frame, 128);
21349531Skarels 		type &= ~T_USER;
21441475Smckusick 		if ((unsigned)type < TRAP_TYPES)
21541475Smckusick 			panic(trap_type[type]);
21641475Smckusick 		panic("trap");
21741475Smckusick 
21841475Smckusick 	case T_BUSERR:		/* kernel bus error */
21949125Skarels 		if (!p->p_addr->u_pcb.pcb_onfault)
22041475Smckusick 			goto dopanic;
22141475Smckusick 		/*
22241475Smckusick 		 * If we have arranged to catch this fault in any of the
22341475Smckusick 		 * copy to/from user space routines, set PC to return to
22441475Smckusick 		 * indicated location and set flag informing buserror code
22541475Smckusick 		 * that it may need to clean up stack frame.
22641475Smckusick 		 */
22741475Smckusick copyfault:
22849317Shibler 		frame.f_stackadj = exframesize[frame.f_format];
22949317Shibler 		frame.f_format = frame.f_vector = 0;
23049125Skarels 		frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault;
23141475Smckusick 		return;
23241475Smckusick 
23349531Skarels 	case T_BUSERR|T_USER:	/* bus error */
23449531Skarels 	case T_ADDRERR|T_USER:	/* address error */
23553933Shibler 		ucode = v;
23641475Smckusick 		i = SIGBUS;
23741475Smckusick 		break;
23841475Smckusick 
23967274Shibler #ifdef HP380
24067274Shibler 	case T_ADDRERR:
24167274Shibler 		/*
24267274Shibler 		 * Yow!  Looks like we get a kernel exception if the PC
24367274Shibler 		 * in the RTE frame is odd on a 68040 (not on a 68030).
24467274Shibler 		 * It comes through as a user exception for access faults
24567274Shibler 		 * (T_MMUFLT).
24667274Shibler 		 */
24767274Shibler 		if (*(short *)frame.f_pc != 0x4e73)
24867274Shibler 			goto dopanic;
24967274Shibler 		/* fall through */
25067274Shibler #endif
25167274Shibler 
25241475Smckusick #ifdef FPCOPROC
25341475Smckusick 	case T_COPERR:		/* kernel coprocessor violation */
25441475Smckusick #endif
25553933Shibler 	case T_FMTERR|T_USER:	/* do all RTE errors come in as T_USER? */
25653933Shibler 	case T_FMTERR:		/* ...just in case... */
25767274Shibler 		/*
25867274Shibler 		 * The user has most likely trashed the RTE or FP state info
25967274Shibler 		 * in the stack frame of a signal handler.
26067274Shibler 		 */
26149531Skarels 		type |= T_USER;
26248465Skarels 		printf("pid %d: kernel %s exception\n", p->p_pid,
26367274Shibler 		       (type==T_COPERR|T_USER) ? "coprocessor" :
26467274Shibler 		       (type==T_ADDRERR|T_USER) ? "RTE address" :
26567274Shibler 		       "RTE format");
26648465Skarels 		p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL;
26741475Smckusick 		i = sigmask(SIGILL);
26841475Smckusick 		p->p_sigignore &= ~i;
26941475Smckusick 		p->p_sigcatch &= ~i;
27041475Smckusick 		p->p_sigmask &= ~i;
27142370Skarels 		i = SIGILL;
27241475Smckusick 		ucode = frame.f_format;	/* XXX was ILL_RESAD_FAULT */
27342370Skarels 		break;
27441475Smckusick 
27541475Smckusick #ifdef FPCOPROC
27649531Skarels 	case T_COPERR|T_USER:	/* user coprocessor violation */
27741475Smckusick 	/* What is a proper response here? */
27841475Smckusick 		ucode = 0;
27941475Smckusick 		i = SIGFPE;
28041475Smckusick 		break;
28141475Smckusick 
28249531Skarels 	case T_FPERR|T_USER:	/* 68881 exceptions */
28341475Smckusick 	/*
28441475Smckusick 	 * We pass along the 68881 status register which locore stashed
28541475Smckusick 	 * in code for us.  Note that there is a possibility that the
28641475Smckusick 	 * bit pattern of this register will conflict with one of the
28741475Smckusick 	 * FPE_* codes defined in signal.h.  Fortunately for us, the
28841475Smckusick 	 * only such codes we use are all in the range 1-7 and the low
28941475Smckusick 	 * 3 bits of the status register are defined as 0 so there is
29041475Smckusick 	 * no clash.
29141475Smckusick 	 */
29241475Smckusick 		ucode = code;
29341475Smckusick 		i = SIGFPE;
29441475Smckusick 		break;
29541475Smckusick #endif
29641475Smckusick 
29754801Storek #ifdef HP380
29853933Shibler 	case T_FPEMULI|T_USER:	/* unimplemented FP instuction */
29953933Shibler 	case T_FPEMULD|T_USER:	/* unimplemented FP data type */
30053933Shibler 		/* XXX need to FSAVE */
30153933Shibler 		printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n",
30253933Shibler 		       p->p_pid, p->p_comm,
30353933Shibler 		       frame.f_format == 2 ? "instruction" : "data type",
30453933Shibler 		       frame.f_pc, frame.f_fmt2.f_iaddr);
30553933Shibler 		/* XXX need to FRESTORE */
30653933Shibler 		i = SIGFPE;
30753933Shibler 		break;
30853933Shibler #endif
30953933Shibler 
31049531Skarels 	case T_ILLINST|T_USER:	/* illegal instruction fault */
31141475Smckusick #ifdef HPUXCOMPAT
31257344Shibler 		if (p->p_md.md_flags & MDP_HPUX) {
31341475Smckusick 			ucode = HPUX_ILL_ILLINST_TRAP;
31441475Smckusick 			i = SIGILL;
31541475Smckusick 			break;
31641475Smckusick 		}
31741475Smckusick 		/* fall through */
31841475Smckusick #endif
31949531Skarels 	case T_PRIVINST|T_USER:	/* privileged instruction fault */
32041475Smckusick #ifdef HPUXCOMPAT
32157344Shibler 		if (p->p_md.md_flags & MDP_HPUX)
32241475Smckusick 			ucode = HPUX_ILL_PRIV_TRAP;
32341475Smckusick 		else
32441475Smckusick #endif
32541475Smckusick 		ucode = frame.f_format;	/* XXX was ILL_PRIVIN_FAULT */
32641475Smckusick 		i = SIGILL;
32741475Smckusick 		break;
32841475Smckusick 
32949531Skarels 	case T_ZERODIV|T_USER:	/* Divide by zero */
33041475Smckusick #ifdef HPUXCOMPAT
33157344Shibler 		if (p->p_md.md_flags & MDP_HPUX)
33241475Smckusick 			ucode = HPUX_FPE_INTDIV_TRAP;
33341475Smckusick 		else
33441475Smckusick #endif
33541475Smckusick 		ucode = frame.f_format;	/* XXX was FPE_INTDIV_TRAP */
33641475Smckusick 		i = SIGFPE;
33741475Smckusick 		break;
33841475Smckusick 
33949531Skarels 	case T_CHKINST|T_USER:	/* CHK instruction trap */
34041475Smckusick #ifdef HPUXCOMPAT
34157344Shibler 		if (p->p_md.md_flags & MDP_HPUX) {
34241475Smckusick 			/* handled differently under hp-ux */
34341475Smckusick 			i = SIGILL;
34441475Smckusick 			ucode = HPUX_ILL_CHK_TRAP;
34541475Smckusick 			break;
34641475Smckusick 		}
34741475Smckusick #endif
34841475Smckusick 		ucode = frame.f_format;	/* XXX was FPE_SUBRNG_TRAP */
34941475Smckusick 		i = SIGFPE;
35041475Smckusick 		break;
35141475Smckusick 
35249531Skarels 	case T_TRAPVINST|T_USER:	/* TRAPV instruction trap */
35341475Smckusick #ifdef HPUXCOMPAT
35457344Shibler 		if (p->p_md.md_flags & MDP_HPUX) {
35541475Smckusick 			/* handled differently under hp-ux */
35641475Smckusick 			i = SIGILL;
35741475Smckusick 			ucode = HPUX_ILL_TRAPV_TRAP;
35841475Smckusick 			break;
35941475Smckusick 		}
36041475Smckusick #endif
36141475Smckusick 		ucode = frame.f_format;	/* XXX was FPE_INTOVF_TRAP */
36241475Smckusick 		i = SIGFPE;
36341475Smckusick 		break;
36441475Smckusick 
36541475Smckusick 	/*
36641475Smckusick 	 * XXX: Trace traps are a nightmare.
36741475Smckusick 	 *
36841475Smckusick 	 *	HP-UX uses trap #1 for breakpoints,
36941475Smckusick 	 *	HPBSD uses trap #2,
37041475Smckusick 	 *	SUN 3.x uses trap #15,
37148465Skarels 	 *	KGDB uses trap #15 (for kernel breakpoints; handled elsewhere).
37241475Smckusick 	 *
37341475Smckusick 	 * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
37441475Smckusick 	 * SUN 3.x traps get passed through as T_TRAP15 and are not really
37548465Skarels 	 * supported yet.
37641475Smckusick 	 */
37741475Smckusick 	case T_TRACE:		/* kernel trace trap */
37848465Skarels 	case T_TRAP15:		/* SUN trace trap */
37941475Smckusick 		frame.f_sr &= ~PSL_T;
38041475Smckusick 		i = SIGTRAP;
38141475Smckusick 		break;
38241475Smckusick 
38349531Skarels 	case T_TRACE|T_USER:	/* user trace trap */
38449531Skarels 	case T_TRAP15|T_USER:	/* SUN user trace trap */
38541475Smckusick 		frame.f_sr &= ~PSL_T;
38641475Smckusick 		i = SIGTRAP;
38741475Smckusick 		break;
38841475Smckusick 
38943413Shibler 	case T_ASTFLT:		/* system async trap, cannot happen */
39041475Smckusick 		goto dopanic;
39141475Smckusick 
39249531Skarels 	case T_ASTFLT|T_USER:	/* user async trap */
39349125Skarels 		astpending = 0;
39441475Smckusick 		/*
39541475Smckusick 		 * We check for software interrupts first.  This is because
39641475Smckusick 		 * they are at a higher level than ASTs, and on a VAX would
39741475Smckusick 		 * interrupt the AST.  We assume that if we are processing
39841475Smckusick 		 * an AST that we must be at IPL0 so we don't bother to
39941475Smckusick 		 * check.  Note that we ensure that we are at least at SIR
40041475Smckusick 		 * IPL while processing the SIR.
40141475Smckusick 		 */
40241475Smckusick 		spl1();
40341475Smckusick 		/* fall into... */
40441475Smckusick 
40541475Smckusick 	case T_SSIR:		/* software interrupt */
40649531Skarels 	case T_SSIR|T_USER:
40741475Smckusick 		if (ssir & SIR_NET) {
40841475Smckusick 			siroff(SIR_NET);
40941475Smckusick 			cnt.v_soft++;
41041475Smckusick 			netintr();
41141475Smckusick 		}
41241475Smckusick 		if (ssir & SIR_CLOCK) {
41341475Smckusick 			siroff(SIR_CLOCK);
41441475Smckusick 			cnt.v_soft++;
41554801Storek 			softclock();
41641475Smckusick 		}
41741475Smckusick 		/*
41841475Smckusick 		 * If this was not an AST trap, we are all done.
41941475Smckusick 		 */
42050753Skarels 		if (type != (T_ASTFLT|T_USER)) {
42141475Smckusick 			cnt.v_trap--;
42241475Smckusick 			return;
42341475Smckusick 		}
42441475Smckusick 		spl0();
42564615Sbostic 		if (p->p_flag & P_OWEUPC) {
42664615Sbostic 			p->p_flag &= ~P_OWEUPC;
42754801Storek 			ADDUPROF(p);
42841475Smckusick 		}
42941475Smckusick 		goto out;
43041475Smckusick 
43141475Smckusick 	case T_MMUFLT:		/* kernel mode page fault */
43254574Storek 		/*
43354574Storek 		 * If we were doing profiling ticks or other user mode
43454574Storek 		 * stuff from interrupt code, Just Say No.
43554574Storek 		 */
43654574Storek 		if (p->p_addr->u_pcb.pcb_onfault == fswintr)
43754574Storek 			goto copyfault;
43841475Smckusick 		/* fall into ... */
43941475Smckusick 
44049531Skarels 	case T_MMUFLT|T_USER:	/* page fault */
44145751Smckusick 	    {
44245751Smckusick 		register vm_offset_t va;
44348465Skarels 		register struct vmspace *vm = p->p_vmspace;
44445751Smckusick 		register vm_map_t map;
44545751Smckusick 		int rv;
44645751Smckusick 		vm_prot_t ftype;
44745751Smckusick 		extern vm_map_t kernel_map;
44845751Smckusick 
44953933Shibler #ifdef DEBUG
45053933Shibler 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
45153933Shibler 		printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n",
45253933Shibler 		       p->p_pid, code, v, frame.f_pc, frame.f_sr);
45353933Shibler #endif
45441475Smckusick 		/*
45545751Smckusick 		 * It is only a kernel address space fault iff:
45649531Skarels 		 * 	1. (type & T_USER) == 0  and
45745751Smckusick 		 * 	2. pcb_onfault not set or
45845751Smckusick 		 *	3. pcb_onfault set but supervisor space data fault
45945751Smckusick 		 * The last can occur during an exec() copyin where the
46045751Smckusick 		 * argument space is lazy-allocated.
46141475Smckusick 		 */
46245751Smckusick 		if (type == T_MMUFLT &&
46353933Shibler 		    (!p->p_addr->u_pcb.pcb_onfault || KDFAULT(code)))
46445751Smckusick 			map = kernel_map;
46545751Smckusick 		else
46648465Skarels 			map = &vm->vm_map;
46753933Shibler 		if (WRFAULT(code))
46845751Smckusick 			ftype = VM_PROT_READ | VM_PROT_WRITE;
46945751Smckusick 		else
47045751Smckusick 			ftype = VM_PROT_READ;
47145751Smckusick 		va = trunc_page((vm_offset_t)v);
47241475Smckusick #ifdef DEBUG
47345751Smckusick 		if (map == kernel_map && va == 0) {
47445751Smckusick 			printf("trap: bad kernel access at %x\n", v);
47541475Smckusick 			goto dopanic;
47641475Smckusick 		}
47741475Smckusick #endif
47857344Shibler #ifdef HPUXCOMPAT
47957344Shibler 		if (ISHPMMADDR(va)) {
48057344Shibler 			vm_offset_t bva;
48157344Shibler 
48257344Shibler 			rv = pmap_mapmulti(map->pmap, va);
48357344Shibler 			if (rv != KERN_SUCCESS) {
48457344Shibler 				bva = HPMMBASEADDR(va);
48557344Shibler 				rv = vm_fault(map, bva, ftype, FALSE);
48657344Shibler 				if (rv == KERN_SUCCESS)
48757344Shibler 					(void) pmap_mapmulti(map->pmap, va);
48857344Shibler 			}
48957344Shibler 		} else
49057344Shibler #endif
49149317Shibler 		rv = vm_fault(map, va, ftype, FALSE);
49253933Shibler #ifdef DEBUG
49353933Shibler 		if (rv && MDB_ISPID(p->p_pid))
49453933Shibler 			printf("vm_fault(%x, %x, %x, 0) -> %x\n",
49553933Shibler 			       map, va, ftype, rv);
49653933Shibler #endif
49741475Smckusick 		/*
49849317Shibler 		 * If this was a stack access we keep track of the maximum
49949317Shibler 		 * accessed stack size.  Also, if vm_fault gets a protection
50049317Shibler 		 * failure it is due to accessing the stack region outside
50149317Shibler 		 * the current limit and we need to reflect that as an access
50249317Shibler 		 * error.
50341475Smckusick 		 */
50448465Skarels 		if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) {
50549317Shibler 			if (rv == KERN_SUCCESS) {
50649317Shibler 				unsigned nss;
50749317Shibler 
50849317Shibler 				nss = clrnd(btoc(USRSTACK-(unsigned)va));
50949317Shibler 				if (nss > vm->vm_ssize)
51049317Shibler 					vm->vm_ssize = nss;
51149317Shibler 			} else if (rv == KERN_PROTECTION_FAILURE)
51249317Shibler 				rv = KERN_INVALID_ADDRESS;
51341475Smckusick 		}
51445751Smckusick 		if (rv == KERN_SUCCESS) {
51553933Shibler 			if (type == T_MMUFLT) {
51654801Storek #ifdef HP380
51753933Shibler 				if (mmutype == MMU_68040)
51853933Shibler 					(void) writeback(&frame, 1);
51953933Shibler #endif
52041475Smckusick 				return;
52153933Shibler 			}
52241475Smckusick 			goto out;
52341475Smckusick 		}
52445751Smckusick 		if (type == T_MMUFLT) {
52549125Skarels 			if (p->p_addr->u_pcb.pcb_onfault)
52645751Smckusick 				goto copyfault;
52745751Smckusick 			printf("vm_fault(%x, %x, %x, 0) -> %x\n",
52845751Smckusick 			       map, va, ftype, rv);
52945751Smckusick 			printf("  type %x, code [mmu,,ssw]: %x\n",
53045751Smckusick 			       type, code);
53145751Smckusick 			goto dopanic;
53245751Smckusick 		}
53348465Skarels 		ucode = v;
53445751Smckusick 		i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV;
53545751Smckusick 		break;
53645751Smckusick 	    }
53741475Smckusick 	}
53848465Skarels 	trapsignal(p, i, ucode);
53949531Skarels 	if ((type & T_USER) == 0)
54041475Smckusick 		return;
54141475Smckusick out:
54254801Storek 	userret(p, &frame, sticks, v, 1);
54341475Smckusick }
54441475Smckusick 
54554801Storek #ifdef HP380
54653933Shibler #ifdef DEBUG
54753933Shibler struct writebackstats {
54853933Shibler 	int calls;
54953933Shibler 	int cpushes;
55053933Shibler 	int move16s;
55153933Shibler 	int wb1s, wb2s, wb3s;
55253933Shibler 	int wbsize[4];
55353933Shibler } wbstats;
55453933Shibler 
55553933Shibler char *f7sz[] = { "longword", "byte", "word", "line" };
55653933Shibler char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" };
55753933Shibler char *f7tm[] = { "d-push", "u-data", "u-code", "M-data",
55853933Shibler 		 "M-code", "k-data", "k-code", "RES" };
55953933Shibler char wberrstr[] =
56053933Shibler     "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n";
56153933Shibler #endif
56253933Shibler 
56353933Shibler writeback(fp, docachepush)
56453933Shibler 	struct frame *fp;
56553933Shibler 	int docachepush;
56653933Shibler {
56753933Shibler 	register struct fmt7 *f = &fp->f_fmt7;
56853933Shibler 	register struct proc *p = curproc;
56953933Shibler 	int err = 0;
57053933Shibler 	u_int fa;
57153933Shibler 	caddr_t oonfault = p->p_addr->u_pcb.pcb_onfault;
57253933Shibler 
57353933Shibler #ifdef DEBUG
57453933Shibler 	if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) {
57553933Shibler 		printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa);
57653933Shibler 		dumpssw(f->f_ssw);
57753933Shibler 	}
57853933Shibler 	wbstats.calls++;
57953933Shibler #endif
58053933Shibler 	/*
58153933Shibler 	 * Deal with special cases first.
58253933Shibler 	 */
58353933Shibler 	if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) {
58453933Shibler 		/*
58553933Shibler 		 * Dcache push fault.
58653933Shibler 		 * Line-align the address and write out the push data to
58753933Shibler 		 * the indicated physical address.
58853933Shibler 		 */
58953933Shibler #ifdef DEBUG
59053933Shibler 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) {
59153933Shibler 			printf(" pushing %s to PA %x, data %x",
59253933Shibler 			       f7sz[(f->f_ssw & SSW4_SZMASK) >> 5],
59353933Shibler 			       f->f_fa, f->f_pd0);
59453933Shibler 			if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN)
59553933Shibler 				printf("/%x/%x/%x",
59653933Shibler 				       f->f_pd1, f->f_pd2, f->f_pd3);
59753933Shibler 			printf("\n");
59853933Shibler 		}
59953933Shibler 		if (f->f_wb1s & SSW4_WBSV)
60053933Shibler 			panic("writeback: cache push with WB1S valid");
60153933Shibler 		wbstats.cpushes++;
60253933Shibler #endif
60353933Shibler 		/*
60453933Shibler 		 * XXX there are security problems if we attempt to do a
60553933Shibler 		 * cache push after a signal handler has been called.
60653933Shibler 		 */
60753933Shibler 		if (docachepush) {
60853933Shibler 			pmap_enter(kernel_pmap, (vm_offset_t)vmmap,
60953933Shibler 				   trunc_page(f->f_fa), VM_PROT_WRITE, TRUE);
61053933Shibler 			fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF];
61153933Shibler 			bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16);
61253933Shibler 			DCFL(pmap_extract(kernel_pmap, (vm_offset_t)fa));
61353933Shibler 			pmap_remove(kernel_pmap, (vm_offset_t)vmmap,
61453933Shibler 				    (vm_offset_t)&vmmap[NBPG]);
61553933Shibler 		} else
61653933Shibler 			printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n",
61753933Shibler 			       p->p_pid, p->p_comm, p->p_ucred->cr_uid);
61853933Shibler 	} else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) {
61953933Shibler 		/*
62053933Shibler 		 * MOVE16 fault.
62153933Shibler 		 * Line-align the address and write out the push data to
62253933Shibler 		 * the indicated virtual address.
62353933Shibler 		 */
62453933Shibler #ifdef DEBUG
62553933Shibler 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
62653933Shibler 			printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n",
62753933Shibler 			       f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1,
62853933Shibler 			       f->f_pd2, f->f_pd3);
62953933Shibler 		if (f->f_wb1s & SSW4_WBSV)
63053933Shibler 			panic("writeback: MOVE16 with WB1S valid");
63153933Shibler 		wbstats.move16s++;
63253933Shibler #endif
63353933Shibler 		if (KDFAULT(f->f_wb1s))
63453933Shibler 			bcopy((caddr_t)&f->f_pd0, (caddr_t)(f->f_fa & ~0xF), 16);
63553933Shibler 		else
63653933Shibler 			err = suline((caddr_t)(f->f_fa & ~0xF), (caddr_t)&f->f_pd0);
63753933Shibler 		if (err) {
63853933Shibler 			fa = f->f_fa & ~0xF;
63953933Shibler #ifdef DEBUG
64053933Shibler 			if (mmudebug & MDB_WBFAILED)
64153933Shibler 				printf(wberrstr, p->p_pid, p->p_comm,
64253933Shibler 				       "MOVE16", fp->f_pc, f->f_fa,
64353933Shibler 				       f->f_fa & ~0xF, f->f_pd0);
64453933Shibler #endif
64553933Shibler 		}
64653933Shibler 	} else if (f->f_wb1s & SSW4_WBSV) {
64753933Shibler 		/*
64853933Shibler 		 * Writeback #1.
64953933Shibler 		 * Position the "memory-aligned" data and write it out.
65053933Shibler 		 */
65153933Shibler 		register u_int wb1d = f->f_wb1d;
65253933Shibler 		register int off;
65353933Shibler 
65453933Shibler #ifdef DEBUG
65553933Shibler 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
65653933Shibler 			dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d);
65753933Shibler 		wbstats.wb1s++;
65853933Shibler 		wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++;
65953933Shibler #endif
66053933Shibler 		off = (f->f_wb1a & 3) * 8;
66153933Shibler 		switch (f->f_wb1s & SSW4_SZMASK) {
66253933Shibler 		case SSW4_SZLW:
66353933Shibler 			if (off)
66453933Shibler 				wb1d = (wb1d >> (32 - off)) | (wb1d << off);
66553933Shibler 			if (KDFAULT(f->f_wb1s))
66653933Shibler 				*(long *)f->f_wb1a = wb1d;
66753933Shibler 			else
66853933Shibler 				err = suword((caddr_t)f->f_wb1a, wb1d);
66953933Shibler 			break;
67053933Shibler 		case SSW4_SZB:
67153933Shibler 			off = 24 - off;
67253933Shibler 			if (off)
67353933Shibler 				wb1d >>= off;
67453933Shibler 			if (KDFAULT(f->f_wb1s))
67553933Shibler 				*(char *)f->f_wb1a = wb1d;
67653933Shibler 			else
67753933Shibler 				err = subyte((caddr_t)f->f_wb1a, wb1d);
67853933Shibler 			break;
67953933Shibler 		case SSW4_SZW:
68053933Shibler 			off = (off + 16) % 32;
68153933Shibler 			if (off)
68253933Shibler 				wb1d = (wb1d >> (32 - off)) | (wb1d << off);
68353933Shibler 			if (KDFAULT(f->f_wb1s))
68453933Shibler 				*(short *)f->f_wb1a = wb1d;
68553933Shibler 			else
68653933Shibler 				err = susword((caddr_t)f->f_wb1a, wb1d);
68753933Shibler 			break;
68853933Shibler 		}
68953933Shibler 		if (err) {
69053933Shibler 			fa = f->f_wb1a;
69153933Shibler #ifdef DEBUG
69253933Shibler 			if (mmudebug & MDB_WBFAILED)
69353933Shibler 				printf(wberrstr, p->p_pid, p->p_comm,
69453933Shibler 				       "#1", fp->f_pc, f->f_fa,
69553933Shibler 				       f->f_wb1a, f->f_wb1d);
69653933Shibler #endif
69753933Shibler 		}
69853933Shibler 	}
69953933Shibler 	/*
70053933Shibler 	 * Deal with the "normal" writebacks.
70153933Shibler 	 *
70253933Shibler 	 * XXX writeback2 is known to reflect a LINE size writeback after
70353933Shibler 	 * a MOVE16 was already dealt with above.  Ignore it.
70453933Shibler 	 */
70553933Shibler 	if (err == 0 && (f->f_wb2s & SSW4_WBSV) &&
70653933Shibler 	    (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) {
70753933Shibler #ifdef DEBUG
70853933Shibler 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
70953933Shibler 			dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d);
71053933Shibler 		wbstats.wb2s++;
71153933Shibler 		wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++;
71253933Shibler #endif
71353933Shibler 		switch (f->f_wb2s & SSW4_SZMASK) {
71453933Shibler 		case SSW4_SZLW:
71553933Shibler 			if (KDFAULT(f->f_wb2s))
71653933Shibler 				*(long *)f->f_wb2a = f->f_wb2d;
71753933Shibler 			else
71853933Shibler 				err = suword((caddr_t)f->f_wb2a, f->f_wb2d);
71953933Shibler 			break;
72053933Shibler 		case SSW4_SZB:
72153933Shibler 			if (KDFAULT(f->f_wb2s))
72253933Shibler 				*(char *)f->f_wb2a = f->f_wb2d;
72353933Shibler 			else
72453933Shibler 				err = subyte((caddr_t)f->f_wb2a, f->f_wb2d);
72553933Shibler 			break;
72653933Shibler 		case SSW4_SZW:
72753933Shibler 			if (KDFAULT(f->f_wb2s))
72853933Shibler 				*(short *)f->f_wb2a = f->f_wb2d;
72953933Shibler 			else
73053933Shibler 				err = susword((caddr_t)f->f_wb2a, f->f_wb2d);
73153933Shibler 			break;
73253933Shibler 		}
73353933Shibler 		if (err) {
73453933Shibler 			fa = f->f_wb2a;
73553933Shibler #ifdef DEBUG
73653933Shibler 			if (mmudebug & MDB_WBFAILED) {
73753933Shibler 				printf(wberrstr, p->p_pid, p->p_comm,
73853933Shibler 				       "#2", fp->f_pc, f->f_fa,
73953933Shibler 				       f->f_wb2a, f->f_wb2d);
74053933Shibler 				dumpssw(f->f_ssw);
74153933Shibler 				dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d);
74253933Shibler 			}
74353933Shibler #endif
74453933Shibler 		}
74553933Shibler 	}
74653933Shibler 	if (err == 0 && (f->f_wb3s & SSW4_WBSV)) {
74753933Shibler #ifdef DEBUG
74853933Shibler 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
74953933Shibler 			dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d);
75053933Shibler 		wbstats.wb3s++;
75153933Shibler 		wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++;
75253933Shibler #endif
75353933Shibler 		switch (f->f_wb3s & SSW4_SZMASK) {
75453933Shibler 		case SSW4_SZLW:
75553933Shibler 			if (KDFAULT(f->f_wb3s))
75653933Shibler 				*(long *)f->f_wb3a = f->f_wb3d;
75753933Shibler 			else
75853933Shibler 				err = suword((caddr_t)f->f_wb3a, f->f_wb3d);
75953933Shibler 			break;
76053933Shibler 		case SSW4_SZB:
76153933Shibler 			if (KDFAULT(f->f_wb3s))
76253933Shibler 				*(char *)f->f_wb3a = f->f_wb3d;
76353933Shibler 			else
76453933Shibler 				err = subyte((caddr_t)f->f_wb3a, f->f_wb3d);
76553933Shibler 			break;
76653933Shibler 		case SSW4_SZW:
76753933Shibler 			if (KDFAULT(f->f_wb3s))
76853933Shibler 				*(short *)f->f_wb3a = f->f_wb3d;
76953933Shibler 			else
77053933Shibler 				err = susword((caddr_t)f->f_wb3a, f->f_wb3d);
77153933Shibler 			break;
77253933Shibler #ifdef DEBUG
77353933Shibler 		case SSW4_SZLN:
77453933Shibler 			panic("writeback: wb3s indicates LINE write");
77553933Shibler #endif
77653933Shibler 		}
77753933Shibler 		if (err) {
77853933Shibler 			fa = f->f_wb3a;
77953933Shibler #ifdef DEBUG
78053933Shibler 			if (mmudebug & MDB_WBFAILED)
78153933Shibler 				printf(wberrstr, p->p_pid, p->p_comm,
78253933Shibler 				       "#3", fp->f_pc, f->f_fa,
78353933Shibler 				       f->f_wb3a, f->f_wb3d);
78453933Shibler #endif
78553933Shibler 		}
78653933Shibler 	}
78753933Shibler 	p->p_addr->u_pcb.pcb_onfault = oonfault;
78853933Shibler 	/*
78953933Shibler 	 * Determine the cause of the failure if any translating to
79053933Shibler 	 * a signal.  If the corresponding VA is valid and RO it is
79153933Shibler 	 * a protection fault (SIGBUS) otherwise consider it an
79253933Shibler 	 * illegal reference (SIGSEGV).
79353933Shibler 	 */
79453933Shibler 	if (err) {
79553933Shibler 		if (vm_map_check_protection(&p->p_vmspace->vm_map,
79653933Shibler 					    trunc_page(fa), round_page(fa),
79753933Shibler 					    VM_PROT_READ) &&
79853933Shibler 		    !vm_map_check_protection(&p->p_vmspace->vm_map,
79953933Shibler 					     trunc_page(fa), round_page(fa),
80053933Shibler 					     VM_PROT_WRITE))
80153933Shibler 			err = SIGBUS;
80253933Shibler 		else
80353933Shibler 			err = SIGSEGV;
80453933Shibler 	}
80553933Shibler 	return(err);
80653933Shibler }
80753933Shibler 
80853933Shibler #ifdef DEBUG
dumpssw(ssw)80953933Shibler dumpssw(ssw)
81053933Shibler 	register u_short ssw;
81153933Shibler {
81253933Shibler 	printf(" SSW: %x: ", ssw);
81353933Shibler 	if (ssw & SSW4_CP)
81453933Shibler 		printf("CP,");
81553933Shibler 	if (ssw & SSW4_CU)
81653933Shibler 		printf("CU,");
81753933Shibler 	if (ssw & SSW4_CT)
81853933Shibler 		printf("CT,");
81953933Shibler 	if (ssw & SSW4_CM)
82053933Shibler 		printf("CM,");
82153933Shibler 	if (ssw & SSW4_MA)
82253933Shibler 		printf("MA,");
82353933Shibler 	if (ssw & SSW4_ATC)
82453933Shibler 		printf("ATC,");
82553933Shibler 	if (ssw & SSW4_LK)
82653933Shibler 		printf("LK,");
82753933Shibler 	if (ssw & SSW4_RW)
82853933Shibler 		printf("RW,");
82953933Shibler 	printf(" SZ=%s, TT=%s, TM=%s\n",
83053933Shibler 	       f7sz[(ssw & SSW4_SZMASK) >> 5],
83153933Shibler 	       f7tt[(ssw & SSW4_TTMASK) >> 3],
83253933Shibler 	       f7tm[ssw & SSW4_TMMASK]);
83353933Shibler }
83453933Shibler 
dumpwb(num,s,a,d)83553933Shibler dumpwb(num, s, a, d)
83653933Shibler 	int num;
83753933Shibler 	u_short s;
83853933Shibler 	u_int a, d;
83953933Shibler {
84053933Shibler 	register struct proc *p = curproc;
84153933Shibler 	vm_offset_t pa;
84253933Shibler 
84353933Shibler 	printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n",
84453933Shibler 	       num, a, d, f7sz[(s & SSW4_SZMASK) >> 5],
84553933Shibler 	       f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]);
84653933Shibler 	printf("               PA ");
84753933Shibler 	pa = pmap_extract(&p->p_vmspace->vm_pmap, (vm_offset_t)a);
84853933Shibler 	if (pa == 0)
84953933Shibler 		printf("<invalid address>");
85053933Shibler 	else
85153933Shibler 		printf("%x, current value %x", pa, fuword((caddr_t)a));
85253933Shibler 	printf("\n");
85353933Shibler }
85453933Shibler #endif
85553933Shibler #endif
85653933Shibler 
85741475Smckusick /*
85849531Skarels  * Proces a system call.
85941475Smckusick  */
syscall(code,frame)86041475Smckusick syscall(code, frame)
86154801Storek 	u_int code;
86241475Smckusick 	struct frame frame;
86341475Smckusick {
86441475Smckusick 	register caddr_t params;
86541475Smckusick 	register struct sysent *callp;
86654801Storek 	register struct proc *p;
86765483Sbostic 	int error, opc, numsys;
86854801Storek 	u_int argsize;
86944018Skarels 	struct args {
87044018Skarels 		int i[8];
87144018Skarels 	} args;
87244018Skarels 	int rval[2];
87354801Storek 	u_quad_t sticks;
87441475Smckusick #ifdef HPUXCOMPAT
87541475Smckusick 	extern struct sysent hpuxsysent[];
87641475Smckusick 	extern int hpuxnsysent, notimp();
87741475Smckusick #endif
87841475Smckusick 
87941475Smckusick 	cnt.v_syscall++;
88041475Smckusick 	if (!USERMODE(frame.f_sr))
88141475Smckusick 		panic("syscall");
88254801Storek 	p = curproc;
88354801Storek 	sticks = p->p_sticks;
88452380Smckusick 	p->p_md.md_regs = frame.f_regs;
88541475Smckusick 	opc = frame.f_pc - 2;
88641475Smckusick #ifdef HPUXCOMPAT
88757344Shibler 	if (p->p_md.md_flags & MDP_HPUX)
88854801Storek 		callp = hpuxsysent, numsys = hpuxnsysent;
88954801Storek 	else
89041475Smckusick #endif
89154801Storek 		callp = sysent, numsys = nsysent;
89249531Skarels 	params = (caddr_t)frame.f_regs[SP] + sizeof(int);
89354801Storek 	switch (code) {
89454801Storek 
89563469Smckusick 	case SYS_syscall:
89654801Storek 		/*
89754801Storek 		 * Code is first argument, followed by actual args.
89854801Storek 		 */
89942370Skarels 		code = fuword(params);
90049531Skarels 		params += sizeof(int);
90157344Shibler 		/*
90257344Shibler 		 * XXX sigreturn requires special stack manipulation
90357344Shibler 		 * that is only done if entered via the sigreturn
90457344Shibler 		 * trap.  Cannot allow it here so make sure we fail.
90557344Shibler 		 */
90657344Shibler 		if (code == SYS_sigreturn)
90757344Shibler 			code = numsys;
90854801Storek 		break;
90954801Storek 
91063469Smckusick 	case SYS___syscall:
91154801Storek 		/*
91263469Smckusick 		 * Like syscall, but code is a quad, so as to maintain
91354801Storek 		 * quad alignment for the rest of the arguments.
91454801Storek 		 */
91541475Smckusick #ifdef HPUXCOMPAT
91657344Shibler 		if (p->p_md.md_flags & MDP_HPUX)
91754801Storek 			break;
91841475Smckusick #endif
91954865Smckusick 		code = fuword(params + _QUAD_LOWWORD * sizeof(int));
92054865Smckusick 		params += sizeof(quad_t);
92154801Storek 		break;
92254801Storek 
92354865Smckusick 	default:
92454865Smckusick 		/* nothing to do by default */
92554865Smckusick 		break;
92654801Storek 	}
92754801Storek 	if (code < numsys)
92854801Storek 		callp += code;
92954801Storek 	else
93063469Smckusick 		callp += SYS_syscall;	/* => nosys */
931*68359Scgd 	argsize = callp->sy_argsize;
93254801Storek 	if (argsize && (error = copyin(params, (caddr_t)&args, argsize))) {
93341475Smckusick #ifdef KTRACE
93443641Skarels 		if (KTRPOINT(p, KTR_SYSCALL))
935*68359Scgd 			ktrsyscall(p->p_tracep, code, argsize, args.i);
93641475Smckusick #endif
93754801Storek 		goto bad;
93841475Smckusick 	}
93941475Smckusick #ifdef KTRACE
94043641Skarels 	if (KTRPOINT(p, KTR_SYSCALL))
941*68359Scgd 		ktrsyscall(p->p_tracep, code, argsize, args.i);
94241475Smckusick #endif
94343641Skarels 	rval[0] = 0;
94443641Skarels 	rval[1] = frame.f_regs[D1];
94541475Smckusick #ifdef HPUXCOMPAT
94642370Skarels 	/* debug kludge */
94742370Skarels 	if (callp->sy_call == notimp)
948*68359Scgd 		error = notimp(p, args.i, rval, code, argsize);
94942370Skarels 	else
95041475Smckusick #endif
95154801Storek 		error = (*callp->sy_call)(p, &args, rval);
95254801Storek 	switch (error) {
95342370Skarels 
95454801Storek 	case 0:
95541475Smckusick 		/*
95654801Storek 		 * Reinitialize proc pointer `p' as it may be different
95754801Storek 		 * if this is a child returning from fork syscall.
95841475Smckusick 		 */
95954801Storek 		p = curproc;
96054801Storek 		frame.f_regs[D0] = rval[0];
96154801Storek 		frame.f_regs[D1] = rval[1];
96254801Storek 		frame.f_sr &= ~PSL_C;
96354801Storek 		break;
96441475Smckusick 
96554801Storek 	case ERESTART:
96654801Storek 		frame.f_pc = opc;
96754801Storek 		break;
96854801Storek 
96954801Storek 	case EJUSTRETURN:
97054801Storek 		break;		/* nothing to do */
97154801Storek 
97254801Storek 	default:
97354801Storek 	bad:
97454801Storek #ifdef HPUXCOMPAT
97557344Shibler 		if (p->p_md.md_flags & MDP_HPUX)
97654801Storek 			error = bsdtohpuxerrno(error);
97741475Smckusick #endif
97854801Storek 		frame.f_regs[D0] = error;
97954801Storek 		frame.f_sr |= PSL_C;
98054801Storek 		break;
98141475Smckusick 	}
98254801Storek 
98354801Storek 	userret(p, &frame, sticks, (u_int)0, 0);
98441475Smckusick #ifdef KTRACE
98543641Skarels 	if (KTRPOINT(p, KTR_SYSRET))
98643641Skarels 		ktrsysret(p->p_tracep, code, error, rval[0]);
98741475Smckusick #endif
98841475Smckusick }
989