xref: /csrg-svn/sys/luna68k/luna68k/trap.c (revision 57401)
153994Sfujita /*
253994Sfujita  * Copyright (c) 1988 University of Utah.
353994Sfujita  * Copyright (c) 1992 OMRON Corporation.
453994Sfujita  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
553994Sfujita  * All rights reserved.
653994Sfujita  *
753994Sfujita  * This code is derived from software contributed to Berkeley by
853994Sfujita  * the Systems Programming Group of the University of Utah Computer
953994Sfujita  * Science Department.
1053994Sfujita  *
1153994Sfujita  * %sccs.include.redist.c%
1253994Sfujita  *
1353994Sfujita  * from: Utah $Hdr: trap.c 1.35 91/12/26$
14*57401Sakito  * from: hp300/hp300/trap.c	7.26 (Berkeley) 12/27/92
1553994Sfujita  *
16*57401Sakito  *	@(#)trap.c	7.4 (Berkeley) 01/02/93
1753994Sfujita  */
1853994Sfujita 
1956521Sbostic #include <sys/param.h>
2056521Sbostic #include <sys/systm.h>
2156521Sbostic #include <sys/proc.h>
2256521Sbostic #include <sys/acct.h>
2356521Sbostic #include <sys/kernel.h>
2456521Sbostic #include <sys/signalvar.h>
2556521Sbostic #include <sys/resourcevar.h>
2656521Sbostic #include <sys/syscall.h>
2756521Sbostic #include <sys/syslog.h>
2856521Sbostic #include <sys/user.h>
2953994Sfujita #ifdef KTRACE
3056521Sbostic #include <sys/ktrace.h>
3153994Sfujita #endif
3253994Sfujita 
3356521Sbostic #include <machine/psl.h>
3456521Sbostic #include <machine/trap.h>
3556521Sbostic #include <machine/cpu.h>
3656521Sbostic #include <machine/reg.h>
3756521Sbostic #include <machine/mtpr.h>
3853994Sfujita 
3956521Sbostic #include <vm/vm.h>
4056521Sbostic #include <vm/pmap.h>
4153994Sfujita 
4253994Sfujita struct	sysent	sysent[];
4353994Sfujita int	nsysent;
4453994Sfujita 
4553994Sfujita char	*trap_type[] = {
4653994Sfujita 	"Bus error",
4753994Sfujita 	"Address error",
4853994Sfujita 	"Illegal instruction",
4953994Sfujita 	"Zero divide",
5053994Sfujita 	"CHK instruction",
5153994Sfujita 	"TRAPV instruction",
5253994Sfujita 	"Privilege violation",
5353994Sfujita 	"Trace trap",
5453994Sfujita 	"MMU fault",
5553994Sfujita 	"SSIR trap",
5653994Sfujita 	"Format error",
5753994Sfujita 	"68881 exception",
5853994Sfujita 	"Coprocessor violation",
5953994Sfujita 	"Async system trap"
6053994Sfujita };
6153994Sfujita #define	TRAP_TYPES	(sizeof trap_type / sizeof trap_type[0])
6253994Sfujita 
6353994Sfujita /*
6453994Sfujita  * Size of various exception stack frames (minus the standard 8 bytes)
6553994Sfujita  */
6653994Sfujita short	exframesize[] = {
6753994Sfujita 	FMT0SIZE,	/* type 0 - normal (68020/030/040) */
6853994Sfujita 	FMT1SIZE,	/* type 1 - throwaway (68020/030/040) */
6953994Sfujita 	FMT2SIZE,	/* type 2 - normal 6-word (68020/030/040) */
7053994Sfujita 	FMT3SIZE,	/* type 3 - FP post-instruction (68040) */
7153994Sfujita 	-1, -1, -1,	/* type 4-6 - undefined */
7253994Sfujita 	FMT7SIZE,	/* type 7 - access error (68040) */
7353994Sfujita 	58,		/* type 8 - bus fault (68010) */
7453994Sfujita 	FMT9SIZE,	/* type 9 - coprocessor mid-instruction (68020/030) */
7553994Sfujita 	FMTASIZE,	/* type A - short bus fault (68020/030) */
7653994Sfujita 	FMTBSIZE,	/* type B - long bus fault (68020/030) */
7753994Sfujita 	-1, -1, -1, -1	/* type C-F - undefined */
7853994Sfujita };
7953994Sfujita 
8053994Sfujita #define KDFAULT(c)	(((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
8153994Sfujita #define WRFAULT(c)	(((c) & (SSW_DF|SSW_RW)) == SSW_DF)
8253994Sfujita 
8353994Sfujita #ifdef DEBUG
8453994Sfujita int mmudebug = 0;
8553994Sfujita int mmupid = -1;
8653994Sfujita #define MDB_FOLLOW	1
8753994Sfujita #define MDB_WBFOLLOW	2
8853994Sfujita #define MDB_WBFAILED	4
8953994Sfujita #define MDB_ISPID(p)	(p) == mmupid
9053994Sfujita #endif
9153994Sfujita 
9253994Sfujita /*
9355581Sfujita  * trap and syscall both need the following work done before returning
9455581Sfujita  * to user mode.
9555581Sfujita  */
9655581Sfujita static inline void
9755581Sfujita userret(p, fp, oticks, faultaddr, fromtrap)
9855581Sfujita 	register struct proc *p;
9955581Sfujita 	register struct frame *fp;
10055581Sfujita 	u_quad_t oticks;
10155581Sfujita 	u_int faultaddr;
10255581Sfujita 	int fromtrap;
10355581Sfujita {
10455581Sfujita 	int sig, s;
10555581Sfujita 
10655581Sfujita 	/* take pending signals */
10755581Sfujita 	while ((sig = CURSIG(p)) != 0)
10855581Sfujita 		psig(sig);
10955581Sfujita 	p->p_pri = p->p_usrpri;
11055581Sfujita 	if (want_resched) {
11155581Sfujita 		/*
11255581Sfujita 		 * Since we are curproc, clock will normally just change
11355581Sfujita 		 * our priority without moving us from one queue to another
11455581Sfujita 		 * (since the running process is not on a queue.)
11555581Sfujita 		 * If that happened after we setrq ourselves but before we
11655581Sfujita 		 * swtch()'ed, we might not be on the queue indicated by
11755581Sfujita 		 * our priority.
11855581Sfujita 		 */
11955581Sfujita 		s = splstatclock();
12055581Sfujita 		setrq(p);
12155581Sfujita 		p->p_stats->p_ru.ru_nivcsw++;
12255581Sfujita 		swtch();
12355581Sfujita 		splx(s);
12455581Sfujita 		while ((sig = CURSIG(p)) != 0)
12555581Sfujita 			psig(sig);
12655581Sfujita 	}
12755581Sfujita 
12855581Sfujita 	/*
12955581Sfujita 	 * If profiling, charge system time to the trapped pc.
13055581Sfujita 	 */
131*57401Sakito 	if (p->p_flag & SPROFIL) {
132*57401Sakito 		extern int psratio;
133*57401Sakito 
134*57401Sakito 		addupc_task(p, fp->f_pc,
135*57401Sakito 			    (int)(p->p_sticks - oticks) * psratio);
13655581Sfujita 	}
13755581Sfujita 	curpri = p->p_pri;
13855581Sfujita }
13955581Sfujita 
14055581Sfujita /*
14153994Sfujita  * Trap is called from locore to handle most types of processor traps,
14253994Sfujita  * including events such as simulated software interrupts/AST's.
14353994Sfujita  * System calls are broken out for efficiency.
14453994Sfujita  */
14553994Sfujita /*ARGSUSED*/
14653994Sfujita trap(type, code, v, frame)
14753994Sfujita 	int type;
14853994Sfujita 	unsigned code;
14953994Sfujita 	register unsigned v;
15053994Sfujita 	struct frame frame;
15153994Sfujita {
15253994Sfujita 	register int i;
15355581Sfujita 	unsigned ucode;
15455581Sfujita 	register struct proc *p;
15555581Sfujita 	u_quad_t sticks;
15653994Sfujita 	unsigned ncode;
15755581Sfujita 	extern char fswintr[];
15853994Sfujita 
15953994Sfujita 	cnt.v_trap++;
16055581Sfujita 	p = curproc;
16155581Sfujita 	ucode = 0;
16253994Sfujita 	if (USERMODE(frame.f_sr)) {
16353994Sfujita 		type |= T_USER;
16455581Sfujita 		sticks = p->p_sticks;
16553994Sfujita 		p->p_md.md_regs = frame.f_regs;
16653994Sfujita 	}
16753994Sfujita 	switch (type) {
16853994Sfujita 
16953994Sfujita 	default:
17053994Sfujita dopanic:
17153994Sfujita 		printf("trap type %d, code = %x, v = %x\n", type, code, v);
172*57401Sakito 		regdump(&frame, 128);
17353994Sfujita 		type &= ~T_USER;
17453994Sfujita 		if ((unsigned)type < TRAP_TYPES)
17553994Sfujita 			panic(trap_type[type]);
17653994Sfujita 		panic("trap");
17753994Sfujita 
17853994Sfujita 	case T_BUSERR:		/* kernel bus error */
17953994Sfujita 		if (!p->p_addr->u_pcb.pcb_onfault)
18053994Sfujita 			goto dopanic;
18153994Sfujita 		/*
18253994Sfujita 		 * If we have arranged to catch this fault in any of the
18353994Sfujita 		 * copy to/from user space routines, set PC to return to
18453994Sfujita 		 * indicated location and set flag informing buserror code
18553994Sfujita 		 * that it may need to clean up stack frame.
18653994Sfujita 		 */
18753994Sfujita copyfault:
18853994Sfujita 		frame.f_stackadj = exframesize[frame.f_format];
18953994Sfujita 		frame.f_format = frame.f_vector = 0;
19053994Sfujita 		frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault;
19153994Sfujita 		return;
19253994Sfujita 
19353994Sfujita 	case T_BUSERR|T_USER:	/* bus error */
19453994Sfujita 	case T_ADDRERR|T_USER:	/* address error */
19553994Sfujita 		ucode = v;
19653994Sfujita 		i = SIGBUS;
19753994Sfujita 		break;
19853994Sfujita 
19953994Sfujita #ifdef FPCOPROC
20053994Sfujita 	case T_COPERR:		/* kernel coprocessor violation */
20153994Sfujita #endif
20253994Sfujita 	case T_FMTERR|T_USER:	/* do all RTE errors come in as T_USER? */
20353994Sfujita 	case T_FMTERR:		/* ...just in case... */
20453994Sfujita 	/*
20553994Sfujita 	 * The user has most likely trashed the RTE or FP state info
20653994Sfujita 	 * in the stack frame of a signal handler.
20753994Sfujita 	 */
20853994Sfujita 		type |= T_USER;
20953994Sfujita 		printf("pid %d: kernel %s exception\n", p->p_pid,
21053994Sfujita 		       type==T_COPERR ? "coprocessor" : "format");
21153994Sfujita 		p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL;
21253994Sfujita 		i = sigmask(SIGILL);
21353994Sfujita 		p->p_sigignore &= ~i;
21453994Sfujita 		p->p_sigcatch &= ~i;
21553994Sfujita 		p->p_sigmask &= ~i;
21653994Sfujita 		i = SIGILL;
21753994Sfujita 		ucode = frame.f_format;	/* XXX was ILL_RESAD_FAULT */
21853994Sfujita 		break;
21953994Sfujita 
22053994Sfujita #ifdef FPCOPROC
22153994Sfujita 	case T_COPERR|T_USER:	/* user coprocessor violation */
22253994Sfujita 	/* What is a proper response here? */
22353994Sfujita 		ucode = 0;
22453994Sfujita 		i = SIGFPE;
22553994Sfujita 		break;
22653994Sfujita 
22753994Sfujita 	case T_FPERR|T_USER:	/* 68881 exceptions */
22853994Sfujita 	/*
22953994Sfujita 	 * We pass along the 68881 status register which locore stashed
23053994Sfujita 	 * in code for us.  Note that there is a possibility that the
23153994Sfujita 	 * bit pattern of this register will conflict with one of the
23253994Sfujita 	 * FPE_* codes defined in signal.h.  Fortunately for us, the
23353994Sfujita 	 * only such codes we use are all in the range 1-7 and the low
23453994Sfujita 	 * 3 bits of the status register are defined as 0 so there is
23553994Sfujita 	 * no clash.
23653994Sfujita 	 */
23753994Sfujita 		ucode = code;
23853994Sfujita 		i = SIGFPE;
23953994Sfujita 		break;
24053994Sfujita #endif
24153994Sfujita 
24253994Sfujita 	case T_ILLINST|T_USER:	/* illegal instruction fault */
24353994Sfujita 	case T_PRIVINST|T_USER:	/* privileged instruction fault */
24453994Sfujita 		ucode = frame.f_format;	/* XXX was ILL_PRIVIN_FAULT */
24553994Sfujita 		i = SIGILL;
24653994Sfujita 		break;
24753994Sfujita 
24853994Sfujita 	case T_ZERODIV|T_USER:	/* Divide by zero */
24953994Sfujita 		ucode = frame.f_format;	/* XXX was FPE_INTDIV_TRAP */
25053994Sfujita 		i = SIGFPE;
25153994Sfujita 		break;
25253994Sfujita 
25353994Sfujita 	case T_CHKINST|T_USER:	/* CHK instruction trap */
25453994Sfujita 		ucode = frame.f_format;	/* XXX was FPE_SUBRNG_TRAP */
25553994Sfujita 		i = SIGFPE;
25653994Sfujita 		break;
25753994Sfujita 
25853994Sfujita 	case T_TRAPVINST|T_USER:	/* TRAPV instruction trap */
25953994Sfujita 		ucode = frame.f_format;	/* XXX was FPE_INTOVF_TRAP */
26053994Sfujita 		i = SIGFPE;
26153994Sfujita 		break;
26253994Sfujita 
26353994Sfujita 	/*
26453994Sfujita 	 * XXX: Trace traps are a nightmare.
26553994Sfujita 	 *
26653994Sfujita 	 *	HP-UX uses trap #1 for breakpoints,
26753994Sfujita 	 *	HPBSD uses trap #2,
26853994Sfujita 	 *	SUN 3.x uses trap #15,
26953994Sfujita 	 *	KGDB uses trap #15 (for kernel breakpoints; handled elsewhere).
27053994Sfujita 	 *
27153994Sfujita 	 * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
27253994Sfujita 	 * SUN 3.x traps get passed through as T_TRAP15 and are not really
27353994Sfujita 	 * supported yet.
27453994Sfujita 	 */
27553994Sfujita 	case T_TRACE:		/* kernel trace trap */
27653994Sfujita 	case T_TRAP15:		/* SUN trace trap */
27753994Sfujita 		frame.f_sr &= ~PSL_T;
27853994Sfujita 		i = SIGTRAP;
27953994Sfujita 		break;
28053994Sfujita 
28153994Sfujita 	case T_TRACE|T_USER:	/* user trace trap */
28253994Sfujita 	case T_TRAP15|T_USER:	/* SUN user trace trap */
28353994Sfujita 		frame.f_sr &= ~PSL_T;
28453994Sfujita 		i = SIGTRAP;
28553994Sfujita 		break;
28653994Sfujita 
28753994Sfujita 	case T_ASTFLT:		/* system async trap, cannot happen */
28853994Sfujita 		goto dopanic;
28953994Sfujita 
29053994Sfujita 	case T_ASTFLT|T_USER:	/* user async trap */
29153994Sfujita 		astpending = 0;
29253994Sfujita 		/*
29353994Sfujita 		 * We check for software interrupts first.  This is because
29453994Sfujita 		 * they are at a higher level than ASTs, and on a VAX would
29553994Sfujita 		 * interrupt the AST.  We assume that if we are processing
29653994Sfujita 		 * an AST that we must be at IPL0 so we don't bother to
29753994Sfujita 		 * check.  Note that we ensure that we are at least at SIR
29853994Sfujita 		 * IPL while processing the SIR.
29953994Sfujita 		 */
30053994Sfujita 		spl1();
30153994Sfujita 		/* fall into... */
30253994Sfujita 
30353994Sfujita 	case T_SSIR:		/* software interrupt */
30453994Sfujita 	case T_SSIR|T_USER:
30553994Sfujita 		if (ssir & SIR_NET) {
30653994Sfujita 			siroff(SIR_NET);
30753994Sfujita 			cnt.v_soft++;
30853994Sfujita 			netintr();
30953994Sfujita 		}
31053994Sfujita 		if (ssir & SIR_CLOCK) {
31153994Sfujita 			siroff(SIR_CLOCK);
31253994Sfujita 			cnt.v_soft++;
31355581Sfujita 			softclock();
31453994Sfujita 		}
31553994Sfujita 		/*
31653994Sfujita 		 * If this was not an AST trap, we are all done.
31753994Sfujita 		 */
31853994Sfujita 		if (type != (T_ASTFLT|T_USER)) {
31953994Sfujita 			cnt.v_trap--;
32053994Sfujita 			return;
32153994Sfujita 		}
32253994Sfujita 		spl0();
32355581Sfujita 		if (p->p_flag & SOWEUPC) {
32453994Sfujita 			p->p_flag &= ~SOWEUPC;
32555581Sfujita 			ADDUPROF(p);
32653994Sfujita 		}
32753994Sfujita 		goto out;
32853994Sfujita 
32953994Sfujita 	case T_MMUFLT:		/* kernel mode page fault */
33055581Sfujita 		/*
33155581Sfujita 		 * If we were doing profiling ticks or other user mode
33255581Sfujita 		 * stuff from interrupt code, Just Say No.
33355581Sfujita 		 */
33455581Sfujita 		if (p->p_addr->u_pcb.pcb_onfault == fswintr)
33555581Sfujita 			goto copyfault;
33653994Sfujita 		/* fall into ... */
33753994Sfujita 
33853994Sfujita 	case T_MMUFLT|T_USER:	/* page fault */
33953994Sfujita 	    {
34053994Sfujita 		register vm_offset_t va;
34153994Sfujita 		register struct vmspace *vm = p->p_vmspace;
34253994Sfujita 		register vm_map_t map;
34353994Sfujita 		int rv;
34453994Sfujita 		vm_prot_t ftype;
34553994Sfujita 		extern vm_map_t kernel_map;
34653994Sfujita 
34753994Sfujita #ifdef DEBUG
34853994Sfujita 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
34953994Sfujita 		printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n",
35053994Sfujita 		       p->p_pid, code, v, frame.f_pc, frame.f_sr);
35153994Sfujita #endif
35253994Sfujita 		/*
35353994Sfujita 		 * It is only a kernel address space fault iff:
35453994Sfujita 		 * 	1. (type & T_USER) == 0  and
35553994Sfujita 		 * 	2. pcb_onfault not set or
35653994Sfujita 		 *	3. pcb_onfault set but supervisor space data fault
35753994Sfujita 		 * The last can occur during an exec() copyin where the
35853994Sfujita 		 * argument space is lazy-allocated.
35953994Sfujita 		 */
36053994Sfujita 		if (type == T_MMUFLT &&
36153994Sfujita 		    (!p->p_addr->u_pcb.pcb_onfault || KDFAULT(code)))
36253994Sfujita 			map = kernel_map;
36353994Sfujita 		else
36453994Sfujita 			map = &vm->vm_map;
36553994Sfujita 		if (WRFAULT(code))
36653994Sfujita 			ftype = VM_PROT_READ | VM_PROT_WRITE;
36753994Sfujita 		else
36853994Sfujita 			ftype = VM_PROT_READ;
36953994Sfujita 		va = trunc_page((vm_offset_t)v);
37053994Sfujita #ifdef DEBUG
37153994Sfujita 		if (map == kernel_map && va == 0) {
37253994Sfujita 			printf("trap: bad kernel access at %x\n", v);
37353994Sfujita 			goto dopanic;
37453994Sfujita 		}
37553994Sfujita #endif
37653994Sfujita 		rv = vm_fault(map, va, ftype, FALSE);
37753994Sfujita #ifdef DEBUG
37853994Sfujita 		if (rv && MDB_ISPID(p->p_pid))
37953994Sfujita 			printf("vm_fault(%x, %x, %x, 0) -> %x\n",
38053994Sfujita 			       map, va, ftype, rv);
38153994Sfujita #endif
38253994Sfujita 		/*
38353994Sfujita 		 * If this was a stack access we keep track of the maximum
38453994Sfujita 		 * accessed stack size.  Also, if vm_fault gets a protection
38553994Sfujita 		 * failure it is due to accessing the stack region outside
38653994Sfujita 		 * the current limit and we need to reflect that as an access
38753994Sfujita 		 * error.
38853994Sfujita 		 */
38953994Sfujita 		if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) {
39053994Sfujita 			if (rv == KERN_SUCCESS) {
39153994Sfujita 				unsigned nss;
39253994Sfujita 
39353994Sfujita 				nss = clrnd(btoc(USRSTACK-(unsigned)va));
39453994Sfujita 				if (nss > vm->vm_ssize)
39553994Sfujita 					vm->vm_ssize = nss;
39653994Sfujita 			} else if (rv == KERN_PROTECTION_FAILURE)
39753994Sfujita 				rv = KERN_INVALID_ADDRESS;
39853994Sfujita 		}
39953994Sfujita 		if (rv == KERN_SUCCESS) {
40053994Sfujita 			if (type == T_MMUFLT) {
40153994Sfujita 				return;
40253994Sfujita 			}
40353994Sfujita 			goto out;
40453994Sfujita 		}
40553994Sfujita 		if (type == T_MMUFLT) {
40653994Sfujita 			if (p->p_addr->u_pcb.pcb_onfault)
40753994Sfujita 				goto copyfault;
40853994Sfujita 			printf("vm_fault(%x, %x, %x, 0) -> %x\n",
40953994Sfujita 			       map, va, ftype, rv);
41053994Sfujita 			printf("  type %x, code [mmu,,ssw]: %x\n",
41153994Sfujita 			       type, code);
41253994Sfujita 			goto dopanic;
41353994Sfujita 		}
41453994Sfujita 		ucode = v;
41553994Sfujita 		i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV;
41653994Sfujita 		break;
41753994Sfujita 	    }
41853994Sfujita 	}
41953994Sfujita 	trapsignal(p, i, ucode);
42053994Sfujita 	if ((type & T_USER) == 0)
42153994Sfujita 		return;
42253994Sfujita out:
42355581Sfujita 	userret(p, &frame, sticks, v, 1);
42453994Sfujita }
42553994Sfujita 
42653994Sfujita /*
42753994Sfujita  * Proces a system call.
42853994Sfujita  */
42953994Sfujita syscall(code, frame)
43055581Sfujita 	u_int code;
43153994Sfujita 	struct frame frame;
43253994Sfujita {
43353994Sfujita 	register caddr_t params;
43453994Sfujita 	register struct sysent *callp;
43555581Sfujita 	register struct proc *p;
43653994Sfujita 	int error, opc, numsys, s;
43755581Sfujita 	u_int argsize;
43853994Sfujita 	struct args {
43953994Sfujita 		int i[8];
44053994Sfujita 	} args;
44153994Sfujita 	int rval[2];
44255581Sfujita 	u_quad_t sticks;
44353994Sfujita 
44453994Sfujita 	cnt.v_syscall++;
44553994Sfujita 	if (!USERMODE(frame.f_sr))
44653994Sfujita 		panic("syscall");
44755581Sfujita 	p = curproc;
44855581Sfujita 	sticks = p->p_sticks;
44953994Sfujita 	p->p_md.md_regs = frame.f_regs;
45053994Sfujita 	opc = frame.f_pc - 2;
45155581Sfujita 	callp = sysent, numsys = nsysent;
45253994Sfujita 	params = (caddr_t)frame.f_regs[SP] + sizeof(int);
45355581Sfujita 	switch (code) {
45455581Sfujita 
45555581Sfujita 	case SYS_indir:
45655581Sfujita 		/*
45755581Sfujita 		 * Code is first argument, followed by actual args.
45855581Sfujita 		 */
45953994Sfujita 		code = fuword(params);
46053994Sfujita 		params += sizeof(int);
461*57401Sakito 		/*
462*57401Sakito 		 * XXX sigreturn requires special stack manipulation
463*57401Sakito 		 * that is only done if entered via the sigreturn
464*57401Sakito 		 * trap.  Cannot allow it here so make sure we fail.
465*57401Sakito 		 */
466*57401Sakito 		if (code == SYS_sigreturn)
467*57401Sakito 			code = numsys;
46855581Sfujita 		break;
46955581Sfujita 
47055581Sfujita 	case SYS___indir:
47155581Sfujita 		/*
47255581Sfujita 		 * Like indir, but code is a quad, so as to maintain
47355581Sfujita 		 * quad alignment for the rest of the arguments.
47455581Sfujita 		 */
47555581Sfujita 		code = fuword(params + _QUAD_LOWWORD * sizeof(int));
47655581Sfujita 		params += sizeof(quad_t);
47755581Sfujita 		break;
47855581Sfujita 
47955581Sfujita 	default:
48055581Sfujita 		/* nothing to do by default */
48155581Sfujita 		break;
48253994Sfujita 	}
48355581Sfujita 	if (code < numsys)
48455581Sfujita 		callp += code;
48553994Sfujita 	else
48655581Sfujita 		callp += SYS_indir;	/* => nosys */
48755581Sfujita 	argsize = callp->sy_narg * sizeof(int);
48855581Sfujita 	if (argsize && (error = copyin(params, (caddr_t)&args, argsize))) {
48953994Sfujita #ifdef KTRACE
49053994Sfujita 		if (KTRPOINT(p, KTR_SYSCALL))
49153994Sfujita 			ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
49253994Sfujita #endif
49355581Sfujita 		goto bad;
49453994Sfujita 	}
49553994Sfujita #ifdef KTRACE
49653994Sfujita 	if (KTRPOINT(p, KTR_SYSCALL))
49753994Sfujita 		ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
49853994Sfujita #endif
49953994Sfujita 	rval[0] = 0;
50053994Sfujita 	rval[1] = frame.f_regs[D1];
50153994Sfujita 	error = (*callp->sy_call)(p, &args, rval);
50255581Sfujita 	switch (error) {
50353994Sfujita 
50455581Sfujita 	case 0:
50553994Sfujita 		/*
50655581Sfujita 		 * Reinitialize proc pointer `p' as it may be different
50755581Sfujita 		 * if this is a child returning from fork syscall.
50853994Sfujita 		 */
50955581Sfujita 		p = curproc;
51055581Sfujita 		frame.f_regs[D0] = rval[0];
51155581Sfujita 		frame.f_regs[D1] = rval[1];
51255581Sfujita 		frame.f_sr &= ~PSL_C;
51355581Sfujita 		break;
51455581Sfujita 
51555581Sfujita 	case ERESTART:
51655581Sfujita 		frame.f_pc = opc;
51755581Sfujita 		break;
51855581Sfujita 
51955581Sfujita 	case EJUSTRETURN:
52055581Sfujita 		break;		/* nothing to do */
52155581Sfujita 
52255581Sfujita 	default:
52355581Sfujita 	bad:
52455581Sfujita 		frame.f_regs[D0] = error;
52555581Sfujita 		frame.f_sr |= PSL_C;
52655581Sfujita 		break;
52753994Sfujita 	}
52853994Sfujita 
52955581Sfujita 	userret(p, &frame, sticks, (u_int)0, 0);
53053994Sfujita #ifdef KTRACE
53153994Sfujita 	if (KTRPOINT(p, KTR_SYSRET))
53253994Sfujita 		ktrsysret(p->p_tracep, code, error, rval[0]);
53353994Sfujita #endif
53453994Sfujita }
535