Home | History | Annotate | Line # | Download | only in hppa
trap.c revision 1.40.2.4
      1 /*	$NetBSD: trap.c,v 1.40.2.4 2007/04/10 14:25:51 skrll Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Matthew Fredette.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *      This product includes software developed by the NetBSD
     21  *      Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 /*	$OpenBSD: trap.c,v 1.30 2001/09/19 20:50:56 mickey Exp $	*/
     40 
     41 /*
     42  * Copyright (c) 1998-2000 Michael Shalayeff
     43  * All rights reserved.
     44  *
     45  * Redistribution and use in source and binary forms, with or without
     46  * modification, are permitted provided that the following conditions
     47  * are met:
     48  * 1. Redistributions of source code must retain the above copyright
     49  *    notice, this list of conditions and the following disclaimer.
     50  * 2. Redistributions in binary form must reproduce the above copyright
     51  *    notice, this list of conditions and the following disclaimer in the
     52  *    documentation and/or other materials provided with the distribution.
     53  * 3. All advertising materials mentioning features or use of this software
     54  *    must display the following acknowledgement:
     55  *	This product includes software developed by Michael Shalayeff.
     56  * 4. The name of the author may not be used to endorse or promote products
     57  *    derived from this software without specific prior written permission.
     58  *
     59  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     60  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     61  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     62  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     63  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     64  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     65  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     66  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     67  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     68  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     69  */
     70 
     71 #include <sys/cdefs.h>
     72 __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.40.2.4 2007/04/10 14:25:51 skrll Exp $");
     73 
     74 /* #define INTRDEBUG */
     75 /* #define TRAPDEBUG */
     76 /* #define USERTRACE */
     77 
     78 #include "opt_kgdb.h"
     79 #include "opt_ktrace.h"
     80 
     81 #include <sys/param.h>
     82 #include <sys/systm.h>
     83 #include <sys/kernel.h>
     84 #include <sys/syscall.h>
     85 #include <sys/mutex.h>
     86 #ifdef KTRACE
     87 #include <sys/ktrace.h>
     88 #endif
     89 #include <sys/proc.h>
     90 #include <sys/signalvar.h>
     91 #include <sys/user.h>
     92 #include <sys/acct.h>
     93 #include <sys/signal.h>
     94 #include <sys/device.h>
     95 #include <sys/pool.h>
     96 #include <sys/userret.h>
     97 
     98 #include <net/netisr.h>
     99 
    100 #ifdef KGDB
    101 #include <sys/kgdb.h>
    102 #endif
    103 
    104 #include <uvm/uvm.h>
    105 
    106 #include <machine/iomod.h>
    107 #include <machine/cpufunc.h>
    108 #include <machine/reg.h>
    109 #include <machine/autoconf.h>
    110 
    111 #include <machine/db_machdep.h>
    112 
    113 #include <hppa/hppa/machdep.h>
    114 
    115 #include <ddb/db_output.h>
    116 #include <ddb/db_interface.h>
    117 
    118 #if defined(DEBUG) || defined(DIAGNOSTIC)
    119 /*
    120  * 0x6fc1000 is a stwm r1, d(sr0, sp), which is the last
    121  * instruction in the function prologue that gcc -O0 uses.
    122  * When we have this instruction we know the relationship
    123  * between the stack pointer and the gcc -O0 frame pointer
    124  * (in r3, loaded with the initial sp) for the body of a
    125  * function.
    126  *
    127  * If the given instruction is a stwm r1, d(sr0, sp) where
    128  * d > 0, we evaluate to d, else we evaluate to zero.
    129  */
    130 #define STWM_R1_D_SR0_SP(inst) \
    131 	(((inst) & 0xffffc001) == 0x6fc10000 ? (((inst) & 0x00003ff) >> 1) : 0)
    132 #endif /* DEBUG || DIAGNOSTIC */
    133 
    134 const char *trap_type[] = {
    135 	"invalid",
    136 	"HPMC",
    137 	"power failure",
    138 	"recovery counter",
    139 	"external interrupt",
    140 	"LPMC",
    141 	"ITLB miss fault",
    142 	"instruction protection",
    143 	"Illegal instruction",
    144 	"break instruction",
    145 	"privileged operation",
    146 	"privileged register",
    147 	"overflow",
    148 	"conditional",
    149 	"assist exception",
    150 	"DTLB miss",
    151 	"ITLB non-access miss",
    152 	"DTLB non-access miss",
    153 	"data protection/rights/alignment",
    154 	"data break",
    155 	"TLB dirty",
    156 	"page reference",
    157 	"assist emulation",
    158 	"higher-priv transfer",
    159 	"lower-priv transfer",
    160 	"taken branch",
    161 	"data access rights",
    162 	"data protection",
    163 	"unaligned data ref",
    164 };
    165 int trap_types = sizeof(trap_type)/sizeof(trap_type[0]);
    166 
    167 uint8_t fpopmap[] = {
    168 	0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
    169 	0x00, 0x0c, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
    170 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    171 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    172 	0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00,
    173 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    174 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    175 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    176 };
    177 
    178 int want_resched;
    179 volatile int astpending;
    180 
    181 void pmap_hptdump(void);
    182 void syscall(struct trapframe *, int *);
    183 
    184 #ifdef USERTRACE
    185 /*
    186  * USERTRACE is a crude facility that traces the PC of
    187  * a single user process.  This tracing is normally
    188  * activated by the dispatching of a certain syscall
    189  * with certain arguments - see the activation code in
    190  * syscall().
    191  */
    192 u_int rctr_next_iioq;
    193 #endif
    194 
    195 static inline void
    196 userret(struct lwp *l, register_t pc, u_quad_t oticks)
    197 {
    198 	struct proc *p = l->l_proc;
    199 
    200 	l->l_priority = l->l_usrpri;
    201 	if (want_resched) {
    202 		preempt();
    203 	}
    204 
    205 	mi_userret(l);
    206 
    207 	/*
    208 	 * If profiling, charge recent system time to the trapped pc.
    209 	 */
    210 	if (p->p_stflag & PST_PROFIL) {
    211 		extern int psratio;
    212 
    213 		addupc_task(l, pc, (int)(p->p_sticks - oticks) * psratio);
    214 	}
    215 
    216 	curcpu()->ci_schedstate.spc_curpriority = l->l_priority;
    217 }
    218 
    219 /*
    220  * This handles some messy kernel debugger details.
    221  * It dispatches into either kgdb or DDB, and knows
    222  * about some special things to do, like skipping over
    223  * break instructions and how to really set up for
    224  * a single-step.
    225  */
    226 #if defined(KGDB) || defined(DDB)
    227 static int
    228 trap_kdebug(int type, int code, struct trapframe *frame)
    229 {
    230 	int handled;
    231 	u_int tf_iioq_head_old;
    232 	u_int tf_iioq_tail_old;
    233 
    234 	for(;;) {
    235 
    236 		/* This trap has not been handled. */
    237 		handled = 0;
    238 
    239 		/* Remember the instruction offset queue. */
    240 		tf_iioq_head_old = frame->tf_iioq_head;
    241 		tf_iioq_tail_old = frame->tf_iioq_tail;
    242 
    243 #ifdef	KGDB
    244 		/* Let KGDB handle it (if connected) */
    245 		if (!handled)
    246 			handled = kgdb_trap(type, frame);
    247 #endif
    248 #ifdef	DDB
    249 		/* Let DDB handle it. */
    250 		if (!handled)
    251 			handled = kdb_trap(type, code, frame);
    252 #endif
    253 
    254 		/* If this trap wasn't handled, return now. */
    255 		if (!handled)
    256 			return(0);
    257 
    258 		/*
    259 		 * If the instruction offset queue head changed,
    260 		 * but the offset queue tail didn't, assume that
    261 		 * the user wants to jump to the head offset, and
    262 		 * adjust the tail accordingly.  This should fix
    263 		 * the kgdb `jump' command, and can help DDB users
    264 		 * who `set' the offset head but forget the tail.
    265 		 */
    266 		if (frame->tf_iioq_head != tf_iioq_head_old &&
    267 		    frame->tf_iioq_tail == tf_iioq_tail_old)
    268 			frame->tf_iioq_tail = frame->tf_iioq_head + 4;
    269 
    270 		/*
    271 		 * This is some single-stepping support.
    272 		 * If we're trying to step through a nullified
    273 		 * instruction, just advance by hand and trap
    274 		 * again.  Otherwise, load the recovery counter
    275 		 * with zero.
    276 		 */
    277 		if (frame->tf_ipsw & PSW_R) {
    278 #ifdef TRAPDEBUG
    279 			printf("(single stepping at head 0x%x tail 0x%x)\n", frame->tf_iioq_head, frame->tf_iioq_tail);
    280 #endif
    281 			if (frame->tf_ipsw & PSW_N) {
    282 #ifdef TRAPDEBUG
    283 				printf("(single stepping past nullified)\n");
    284 #endif
    285 
    286 				/* Advance the program counter. */
    287 				frame->tf_iioq_head = frame->tf_iioq_tail;
    288 				frame->tf_iioq_tail = frame->tf_iioq_head + 4;
    289 
    290 				/* Clear flags. */
    291 				frame->tf_ipsw &= ~(PSW_N|PSW_X|PSW_Y|PSW_Z|PSW_B|PSW_T|PSW_H|PSW_L);
    292 
    293 				/* Simulate another trap. */
    294 				type = T_RECOVERY;
    295 				continue;
    296 			}
    297 			frame->tf_rctr = 0;
    298 		}
    299 
    300 		/* We handled this trap. */
    301 		return (1);
    302 	}
    303 	/* NOTREACHED */
    304 }
    305 #else	/* !KGDB && !DDB */
    306 #define trap_kdebug(t, c, f)	(0)
    307 #endif	/* !KGDB && !DDB */
    308 
    309 #if defined(DEBUG) || defined(USERTRACE)
    310 /*
    311  * These functions give a crude usermode backtrace.  They
    312  * really only work when code has been compiled without
    313  * optimization, as they assume a certain function prologue
    314  * sets up a frame pointer and stores the return pointer
    315  * and arguments in it.
    316  */
    317 static void user_backtrace_raw(u_int, u_int);
    318 static void
    319 user_backtrace_raw(u_int pc, u_int fp)
    320 {
    321 	int frame_number;
    322 	int arg_number;
    323 
    324 	for (frame_number = 0;
    325 	     frame_number < 100 && pc > HPPA_PC_PRIV_MASK && fp;
    326 	     frame_number++) {
    327 
    328 		printf("%3d: pc=%08x%s fp=0x%08x", frame_number,
    329 		    pc & ~HPPA_PC_PRIV_MASK, USERMODE(pc) ? "" : "**", fp);
    330 		for(arg_number = 0; arg_number < 4; arg_number++)
    331 			printf(" arg%d=0x%08x", arg_number,
    332 			    (int) fuword(HPPA_FRAME_CARG(arg_number, fp)));
    333 		printf("\n");
    334                 pc = fuword(((register_t *) fp) - 5);	/* fetch rp */
    335 		if (pc == -1) {
    336 			printf("  fuword for pc failed\n");
    337 			break;
    338 		}
    339                 fp = fuword(((register_t *) fp) + 0);	/* fetch previous fp */
    340 		if (fp == -1) {
    341 			printf("  fuword for fp failed\n");
    342 			break;
    343 		}
    344 	}
    345 	printf("  backtrace stopped with pc %08x fp 0x%08x\n", pc, fp);
    346 }
    347 
    348 static void user_backtrace(struct trapframe *, struct lwp *, int);
    349 static void
    350 user_backtrace(struct trapframe *tf, struct lwp *l, int type)
    351 {
    352 	struct proc *p = l->l_proc;
    353 	u_int pc, fp, inst;
    354 
    355 	/*
    356 	 * Display any trap type that we have.
    357 	 */
    358 	if (type >= 0)
    359 		printf("pid %d (%s) trap #%d\n",
    360 		    p->p_pid, p->p_comm, type & ~T_USER);
    361 
    362 	/*
    363 	 * Assuming that the frame pointer in r3 is valid,
    364 	 * dump out a stack trace.
    365 	 */
    366 	fp = tf->tf_r3;
    367 	printf("pid %d (%s) backtrace, starting with fp 0x%08x\n",
    368 		p->p_pid, p->p_comm, fp);
    369 	user_backtrace_raw(tf->tf_iioq_head, fp);
    370 
    371 	/*
    372 	 * In case the frame pointer in r3 is not valid,
    373 	 * assuming the stack pointer is valid and the
    374 	 * faulting function is a non-leaf, if we can
    375 	 * find its prologue we can recover its frame
    376 	 * pointer.
    377 	 */
    378 	pc = tf->tf_iioq_head;
    379 	fp = tf->tf_sp - HPPA_FRAME_SIZE;
    380 	printf("pid %d (%s) backtrace, starting with sp 0x%08x pc 0x%08x\n",
    381 		p->p_pid, p->p_comm, tf->tf_sp, pc);
    382 	for(pc &= ~HPPA_PC_PRIV_MASK; pc > 0; pc -= sizeof(inst)) {
    383 		inst = fuword((register_t *) pc);
    384 		if (inst == -1) {
    385 			printf("  fuword for inst at pc %08x failed\n", pc);
    386 			break;
    387 		}
    388 		/* Check for the prologue instruction that sets sp. */
    389 		if (STWM_R1_D_SR0_SP(inst)) {
    390 			fp = tf->tf_sp - STWM_R1_D_SR0_SP(inst);
    391 			printf("  sp from fp at pc %08x: %08x\n", pc, inst);
    392 			break;
    393 		}
    394 	}
    395 	user_backtrace_raw(tf->tf_iioq_head, fp);
    396 }
    397 #endif /* DEBUG || USERTRACE */
    398 
    399 #ifdef DEBUG
    400 /*
    401  * This sanity-checks a trapframe.  It is full of various
    402  * assumptions about what a healthy CPU state should be,
    403  * with some documented elsewhere, some not.
    404  */
    405 struct trapframe *sanity_frame;
    406 struct lwp *sanity_lwp;
    407 int sanity_checked = 0;
    408 void frame_sanity_check(int, int, struct trapframe *, struct lwp *);
    409 void
    410 frame_sanity_check(int where, int type, struct trapframe *tf, struct lwp *l)
    411 {
    412 	extern int kernel_text;
    413 	extern int etext;
    414 	extern register_t kpsw;
    415 	extern vaddr_t hpt_base;
    416 	extern vsize_t hpt_mask;
    417 #define SANITY(e)					\
    418 do {							\
    419 	if (sanity_frame == NULL && !(e)) {		\
    420 		sanity_frame = tf;			\
    421 		sanity_lwp = l;				\
    422 		sanity_checked = __LINE__;		\
    423 	}						\
    424 } while (/* CONSTCOND */ 0)
    425 
    426 	SANITY((tf->tf_ipsw & kpsw) == kpsw);
    427 	SANITY(tf->tf_hptm == hpt_mask && tf->tf_vtop == hpt_base);
    428 	SANITY((kpsw & PSW_I) == 0 || tf->tf_eiem != 0);
    429 	if (tf->tf_iisq_head == HPPA_SID_KERNEL) {
    430 		/*
    431 		 * If the trap happened in the gateway
    432 		 * page, we take the easy way out and
    433 		 * assume that the trapframe is okay.
    434 		 */
    435 		if ((tf->tf_iioq_head & ~PAGE_MASK) != SYSCALLGATE) {
    436 			SANITY(!USERMODE(tf->tf_iioq_head));
    437 			SANITY(!USERMODE(tf->tf_iioq_tail));
    438 			SANITY(tf->tf_iioq_head >= (u_int) &kernel_text);
    439 			SANITY(tf->tf_iioq_head < (u_int) &etext);
    440 			SANITY(tf->tf_iioq_tail >= (u_int) &kernel_text);
    441 			SANITY(tf->tf_iioq_tail < (u_int) &etext);
    442 			if ((type & ~T_USER) != T_INTERRUPT) {
    443 				vaddr_t minsp, maxsp;
    444 
    445 #ifdef HPPA_REDZONE
    446 				maxsp = (u_int)(l->l_addr) +
    447 				    HPPA_REDZONE;
    448 #else
    449 				maxsp = (u_int)(l->l_addr) +
    450 				    USPACE;
    451 #endif
    452 				minsp = (u_int)(l->l_addr) + PAGE_SIZE;
    453 
    454 				SANITY(l == NULL ||
    455 				    (tf->tf_sp >= minsp && tf->tf_sp < maxsp));
    456 			}
    457 		}
    458 	} else {
    459 		SANITY(USERMODE(tf->tf_iioq_head));
    460 		SANITY(USERMODE(tf->tf_iioq_tail));
    461 		SANITY(l != NULL && tf->tf_cr30 == kvtop((void *)l->l_addr));
    462 	}
    463 #undef SANITY
    464 	if (sanity_frame == tf) {
    465 		printf("insanity: where 0x%x type 0x%x tf %p lwp %p line %d "
    466 		       "sp 0x%x pc 0x%x\n",
    467 		       where, type, sanity_frame, sanity_lwp, sanity_checked,
    468 		       tf->tf_sp, tf->tf_iioq_head);
    469 		(void) trap_kdebug(T_IBREAK, 0, tf);
    470 		sanity_frame = NULL;
    471 		sanity_lwp = NULL;
    472 		sanity_checked = 0;
    473 	}
    474 }
    475 #endif /* DEBUG */
    476 
    477 void
    478 trap(int type, struct trapframe *frame)
    479 {
    480 	struct lwp *l;
    481 	struct proc *p;
    482 	struct pcb *pcbp;
    483 	vaddr_t va;
    484 	struct vm_map *map;
    485 	struct vmspace *vm;
    486 	vm_prot_t vftype;
    487 	pa_space_t space;
    488 	ksiginfo_t ksi;
    489 	u_int opcode, onfault;
    490 	int ret;
    491 	const char *tts;
    492 	int type_raw;
    493 #ifdef DIAGNOSTIC
    494 	extern int emergency_stack_start, emergency_stack_end;
    495 #endif
    496 
    497 	type_raw = type & ~T_USER;
    498 	opcode = frame->tf_iir;
    499 	if (type_raw == T_ITLBMISS || type_raw == T_ITLBMISSNA) {
    500 		va = frame->tf_iioq_head;
    501 		space = frame->tf_iisq_head;
    502 		vftype = VM_PROT_EXECUTE;
    503 	} else {
    504 		va = frame->tf_ior;
    505 		space = frame->tf_isr;
    506 		vftype = inst_store(opcode) ? VM_PROT_WRITE : VM_PROT_READ;
    507 	}
    508 
    509 	l = curlwp;
    510 	p = l ? l->l_proc : NULL;
    511 	if ((type & T_USER) != 0)
    512 		LWP_CACHE_CREDS(l, p);
    513 
    514 	tts = (type & ~T_USER) > trap_types ? "reserved" :
    515 		trap_type[type & ~T_USER];
    516 
    517 #ifdef DIAGNOSTIC
    518 	/*
    519 	 * If we are on the emergency stack, then we either got
    520 	 * a fault on the kernel stack, or we're just handling
    521 	 * a trap for the machine check handler (which also
    522 	 * runs on the emergency stack).
    523 	 *
    524 	 * We *very crudely* differentiate between the two cases
    525 	 * by checking the faulting instruction: if it is the
    526 	 * function prologue instruction that stores the old
    527 	 * frame pointer and updates the stack pointer, we assume
    528 	 * that we faulted on the kernel stack.
    529 	 *
    530 	 * In this case, not completing that instruction will
    531 	 * probably confuse backtraces in kgdb/ddb.  Completing
    532 	 * it would be difficult, because we already faulted on
    533 	 * that part of the stack, so instead we fix up the
    534 	 * frame as if the function called has just returned.
    535 	 * This has peculiar knowledge about what values are in
    536 	 * what registers during the "normal gcc -g" prologue.
    537 	 */
    538 	if (&type >= &emergency_stack_start &&
    539 	    &type < &emergency_stack_end &&
    540 	    type != T_IBREAK && STWM_R1_D_SR0_SP(opcode)) {
    541 		/* Restore the caller's frame pointer. */
    542 		frame->tf_r3 = frame->tf_r1;
    543 		/* Restore the caller's instruction offsets. */
    544 		frame->tf_iioq_head = frame->tf_rp;
    545 		frame->tf_iioq_tail = frame->tf_iioq_head + 4;
    546 		goto dead_end;
    547 	}
    548 #endif /* DIAGNOSTIC */
    549 
    550 #ifdef DEBUG
    551 	frame_sanity_check(0xdead01, type, frame, l);
    552 #endif /* DEBUG */
    553 
    554 	/* If this is a trap, not an interrupt, reenable interrupts. */
    555 	if (type_raw != T_INTERRUPT)
    556 		mtctl(frame->tf_eiem, CR_EIEM);
    557 
    558 	if (frame->tf_flags & TFF_LAST)
    559 		l->l_md.md_regs = frame;
    560 
    561 #ifdef TRAPDEBUG
    562 	if (type_raw != T_INTERRUPT && type_raw != T_IBREAK)
    563 		printf("trap: %d, %s for %x:%x at %x:%x, fp=%p, rp=%x\n",
    564 		    type, tts, space, (u_int)va, frame->tf_iisq_head,
    565 		    frame->tf_iioq_head, frame, frame->tf_rp);
    566 	else if (type_raw == T_IBREAK)
    567 		printf("trap: break instruction %x:%x at %x:%x, fp=%p\n",
    568 		    break5(opcode), break13(opcode),
    569 		    frame->tf_iisq_head, frame->tf_iioq_head, frame);
    570 
    571 	{
    572 		extern int etext;
    573 		if (frame < (struct trapframe *)&etext) {
    574 			printf("trap: bogus frame ptr %p\n", frame);
    575 			goto dead_end;
    576 		}
    577 	}
    578 #endif
    579 	switch (type) {
    580 	case T_NONEXIST:
    581 	case T_NONEXIST|T_USER:
    582 #if !defined(DDB) && !defined(KGDB)
    583 		/* we've got screwed up by the central scrutinizer */
    584 		panic ("trap: elvis has just left the building!");
    585 		break;
    586 #else
    587 		goto dead_end;
    588 #endif
    589 	case T_RECOVERY|T_USER:
    590 #ifdef USERTRACE
    591 		for(;;) {
    592 			if (frame->tf_iioq_head != rctr_next_iioq)
    593 				printf("-%08x\nr %08x",
    594 					rctr_next_iioq - 4,
    595 					frame->tf_iioq_head);
    596 			rctr_next_iioq = frame->tf_iioq_head + 4;
    597 			if (frame->tf_ipsw & PSW_N) {
    598 				/* Advance the program counter. */
    599 				frame->tf_iioq_head = frame->tf_iioq_tail;
    600 				frame->tf_iioq_tail = frame->tf_iioq_head + 4;
    601 				/* Clear flags. */
    602 				frame->tf_ipsw &= ~(PSW_N|PSW_X|PSW_Y|PSW_Z|PSW_B|PSW_T|PSW_H|PSW_L);
    603 				/* Simulate another trap. */
    604 				continue;
    605 			}
    606 			break;
    607 		}
    608 		frame->tf_rctr = 0;
    609 		break;
    610 #endif /* USERTRACE */
    611 	case T_RECOVERY:
    612 #if !defined(DDB) && !defined(KGDB)
    613 		/* XXX will implement later */
    614 		printf ("trap: handicapped");
    615 		break;
    616 #else
    617 		goto dead_end;
    618 #endif
    619 
    620 	case T_EMULATION | T_USER:
    621 #ifdef FPEMUL
    622 		hppa_fpu_emulate(frame, l, opcode);
    623 #else  /* !FPEMUL */
    624 		/*
    625 		 * We don't have FPU emulation, so signal the
    626 		 * process with a SIGFPE.
    627 		 */
    628 
    629 		KSI_INIT_TRAP(&ksi);
    630 		ksi.ksi_signo = SIGFPE;
    631 		ksi.ksi_code = SI_NOINFO;
    632 		ksi.ksi_trap = type;
    633 		ksi.ksi_addr = (void *)frame->tf_iioq_head;
    634 		trapsignal(l, &ksi);
    635 #endif /* !FPEMUL */
    636 		break;
    637 
    638 	case T_DATALIGN:
    639 		if (l->l_addr->u_pcb.pcb_onfault) {
    640 do_onfault:
    641 			pcbp = &l->l_addr->u_pcb;
    642 			frame->tf_iioq_tail = 4 +
    643 				(frame->tf_iioq_head =
    644 				 pcbp->pcb_onfault);
    645 			pcbp->pcb_onfault = 0;
    646 			break;
    647 		}
    648 		/*FALLTHROUGH*/
    649 
    650 #ifdef DIAGNOSTIC
    651 		/* these just can't happen ever */
    652 	case T_PRIV_OP:
    653 	case T_PRIV_REG:
    654 		/* these just can't make it to the trap() ever */
    655 	case T_HPMC:
    656 	case T_HPMC | T_USER:
    657 	case T_EMULATION:
    658 	case T_EXCEPTION:
    659 #endif
    660 	case T_IBREAK:
    661 	case T_DBREAK:
    662 	dead_end:
    663 		if (type & T_USER) {
    664 #ifdef DEBUG
    665 			user_backtrace(frame, l, type);
    666 #endif
    667 			KSI_INIT_TRAP(&ksi);
    668 			ksi.ksi_signo = SIGILL;
    669 			ksi.ksi_code = ILL_ILLTRP;
    670 			ksi.ksi_trap = type;
    671 			ksi.ksi_addr = (void *)frame->tf_iioq_head;
    672 			trapsignal(l, &ksi);
    673 			break;
    674 		}
    675 		if (trap_kdebug(type, va, frame))
    676 			return;
    677 		else if (type == T_DATALIGN)
    678 			panic ("trap: %s at 0x%x", tts, (u_int) va);
    679 		else
    680 			panic ("trap: no debugger for \"%s\" (%d)", tts, type);
    681 		break;
    682 
    683 	case T_IBREAK | T_USER:
    684 	case T_DBREAK | T_USER:
    685 		/* pass to user debugger */
    686 		break;
    687 
    688 	case T_EXCEPTION | T_USER: {	/* co-proc assist trap */
    689 		uint64_t *fpp;
    690 		uint32_t *pex, ex, inst;
    691 		int i;
    692 
    693 		hppa_fpu_flush(l);
    694 		fpp = l->l_addr->u_pcb.pcb_fpregs;
    695 		pex = (uint32_t *)&fpp[1];
    696 		for (i = 1; i < 8 && !*pex; i++, pex++)
    697 			;
    698 		KASSERT(i < 8);
    699 		ex = *pex;
    700 		*pex = 0;
    701 
    702 		/* reset the trap flag, as if there was none */
    703 		fpp[0] &= ~(((uint64_t)HPPA_FPU_T) << 32);
    704 
    705 		/* emulate the instruction */
    706 		inst = ((uint32_t)fpopmap[ex >> 26] << 26) | (ex & 0x03ffffff);
    707 		hppa_fpu_emulate(frame, l, inst);
    708 		}
    709 		break;
    710 
    711 	case T_OVERFLOW | T_USER:
    712 		KSI_INIT_TRAP(&ksi);
    713 		ksi.ksi_signo = SIGFPE;
    714 		ksi.ksi_code = SI_NOINFO;
    715 		ksi.ksi_trap = type;
    716 		ksi.ksi_addr = (void *)va;
    717 		trapsignal(l, &ksi);
    718 		break;
    719 
    720 	case T_CONDITION | T_USER:
    721 		KSI_INIT_TRAP(&ksi);
    722 		ksi.ksi_signo = SIGFPE;
    723 		ksi.ksi_code = FPE_INTDIV;
    724 		ksi.ksi_trap = type;
    725 		ksi.ksi_addr = (void *)va;
    726 		trapsignal(l, &ksi);
    727 		break;
    728 
    729 	case T_ILLEGAL | T_USER:
    730 #ifdef DEBUG
    731 		user_backtrace(frame, l, type);
    732 #endif
    733 		KSI_INIT_TRAP(&ksi);
    734 		ksi.ksi_signo = SIGILL;
    735 		ksi.ksi_code = ILL_ILLOPC;
    736 		ksi.ksi_trap = type;
    737 		ksi.ksi_addr = (void *)va;
    738 		trapsignal(l, &ksi);
    739 		break;
    740 
    741 	case T_PRIV_OP | T_USER:
    742 #ifdef DEBUG
    743 		user_backtrace(frame, l, type);
    744 #endif
    745 		KSI_INIT_TRAP(&ksi);
    746 		ksi.ksi_signo = SIGILL;
    747 		ksi.ksi_code = ILL_PRVOPC;
    748 		ksi.ksi_trap = type;
    749 		ksi.ksi_addr = (void *)va;
    750 		trapsignal(l, &ksi);
    751 		break;
    752 
    753 	case T_PRIV_REG | T_USER:
    754 #ifdef DEBUG
    755 		user_backtrace(frame, l, type);
    756 #endif
    757 		KSI_INIT_TRAP(&ksi);
    758 		ksi.ksi_signo = SIGILL;
    759 		ksi.ksi_code = ILL_PRVREG;
    760 		ksi.ksi_trap = type;
    761 		ksi.ksi_addr = (void *)va;
    762 		trapsignal(l, &ksi);
    763 		break;
    764 
    765 		/* these should never got here */
    766 	case T_HIGHERPL | T_USER:
    767 	case T_LOWERPL | T_USER:
    768 		KSI_INIT_TRAP(&ksi);
    769 		ksi.ksi_signo = SIGSEGV;
    770 		ksi.ksi_code = SEGV_ACCERR;
    771 		ksi.ksi_trap = type;
    772 		ksi.ksi_addr = (void *)va;
    773 		trapsignal(l, &ksi);
    774 		break;
    775 
    776 	case T_IPROT | T_USER:
    777 	case T_DPROT | T_USER:
    778 		KSI_INIT_TRAP(&ksi);
    779 		ksi.ksi_signo = SIGSEGV;
    780 		ksi.ksi_code = SEGV_ACCERR;
    781 		ksi.ksi_trap = type;
    782 		ksi.ksi_addr = (void *)va;
    783 		trapsignal(l, &ksi);
    784 		break;
    785 
    786 	case T_DATACC:   	case T_USER | T_DATACC:
    787 	case T_ITLBMISS:	case T_USER | T_ITLBMISS:
    788 	case T_DTLBMISS:	case T_USER | T_DTLBMISS:
    789 	case T_ITLBMISSNA:	case T_USER | T_ITLBMISSNA:
    790 	case T_DTLBMISSNA:	case T_USER | T_DTLBMISSNA:
    791 	case T_TLB_DIRTY:	case T_USER | T_TLB_DIRTY:
    792 		vm = p->p_vmspace;
    793 
    794 		if (!vm) {
    795 #ifdef TRAPDEBUG
    796 			printf("trap: no vm, p=%p\n", p);
    797 #endif
    798 			goto dead_end;
    799 		}
    800 
    801 		/*
    802 		 * it could be a kernel map for exec_map faults
    803 		 */
    804 		if (!(type & T_USER) && space == HPPA_SID_KERNEL)
    805 			map = kernel_map;
    806 		else
    807 			map = &vm->vm_map;
    808 
    809 		va = trunc_page(va);
    810 
    811 		if (map->pmap->pmap_space != space) {
    812 #ifdef TRAPDEBUG
    813 			printf("trap: space mismatch %d != %d\n",
    814 			    space, map->pmap->pmap_space);
    815 #endif
    816 			/* actually dump the user, crap the kernel */
    817 			goto dead_end;
    818 		}
    819 
    820 		/* Never call uvm_fault in interrupt context. */
    821 		KASSERT(hppa_intr_depth == 0);
    822 
    823 		onfault = l->l_addr->u_pcb.pcb_onfault;
    824 		l->l_addr->u_pcb.pcb_onfault = 0;
    825 		ret = uvm_fault(map, va, vftype);
    826 		l->l_addr->u_pcb.pcb_onfault = onfault;
    827 
    828 #ifdef TRAPDEBUG
    829 		printf("uvm_fault(%p, %x, %d)=%d\n",
    830 		    map, (u_int)va, vftype, ret);
    831 #endif
    832 
    833 		/*
    834 		 * If this was a stack access we keep track of the maximum
    835 		 * accessed stack size.  Also, if uvm_fault gets a protection
    836 		 * failure it is due to accessing the stack region outside
    837 		 * the current limit and we need to reflect that as an access
    838 		 * error.
    839 		 */
    840 		if (map != kernel_map && va >= (vaddr_t)vm->vm_minsaddr) {
    841 			if (ret == 0)
    842 				uvm_grow(l->l_proc, va);
    843 			else if (ret == EACCES)
    844 				ret = EFAULT;
    845 		}
    846 
    847 		if (ret != 0) {
    848 			if (type & T_USER) {
    849 #ifdef DEBUG
    850 				user_backtrace(frame, l, type);
    851 #endif
    852 				KSI_INIT_TRAP(&ksi);
    853 				ksi.ksi_signo = SIGSEGV;
    854 				ksi.ksi_code = (ret == EACCES ?
    855 						SEGV_ACCERR : SEGV_MAPERR);
    856 				ksi.ksi_trap = type;
    857 				ksi.ksi_addr = (void *)va;
    858 				trapsignal(l, &ksi);
    859 			} else {
    860 				if (l->l_addr->u_pcb.pcb_onfault) {
    861 					goto do_onfault;
    862 				}
    863 				panic("trap: uvm_fault(%p, %lx, %d): %d",
    864 				    map, va, vftype, ret);
    865 			}
    866 		}
    867 		break;
    868 
    869 	case T_DATALIGN | T_USER:
    870 #ifdef DEBUG
    871 		user_backtrace(frame, l, type);
    872 #endif
    873 		KSI_INIT_TRAP(&ksi);
    874 		ksi.ksi_signo = SIGBUS;
    875 		ksi.ksi_code = BUS_ADRALN;
    876 		ksi.ksi_trap = type;
    877 		ksi.ksi_addr = (void *)va;
    878 		trapsignal(l, &ksi);
    879 		break;
    880 
    881 	case T_INTERRUPT:
    882 	case T_INTERRUPT|T_USER:
    883 		hppa_intr(frame);
    884 		mtctl(frame->tf_eiem, CR_EIEM);
    885 		break;
    886 
    887 	case T_LOWERPL:
    888 	case T_DPROT:
    889 	case T_IPROT:
    890 	case T_OVERFLOW:
    891 	case T_CONDITION:
    892 	case T_ILLEGAL:
    893 	case T_HIGHERPL:
    894 	case T_TAKENBR:
    895 	case T_POWERFAIL:
    896 	case T_LPMC:
    897 	case T_PAGEREF:
    898 	case T_DATAPID:  	case T_DATAPID  | T_USER:
    899 		if (0 /* T-chip */) {
    900 			break;
    901 		}
    902 		/* FALLTHROUGH to unimplemented */
    903 	default:
    904 		panic ("trap: unimplemented \'%s\' (%d)", tts, type);
    905 	}
    906 
    907 	/*
    908 	 * In case we were interrupted from the syscall gate page
    909 	 * treat this as we were not really running user code anymore
    910 	 *
    911 	 * The problem is that if we preempt when returning from this
    912 	 * trap the interspace branch setting of IASQ to HPPA_SID_KERNEL
    913 	 * is not picked up by the syscall code. Instead, it will attempt
    914 	 * to return into the syscall gate page with the user space id
    915 	 * causing a (fatal) ITLB trap for the process.
    916 	 */
    917 
    918 	if (type & T_USER) {
    919 		if (!(frame->tf_iisq_head == HPPA_SID_KERNEL &&
    920 		     (frame->tf_iioq_head & ~PAGE_MASK) == SYSCALLGATE))
    921 			userret(l, l->l_md.md_regs->tf_iioq_head, 0);
    922 	}
    923 
    924 
    925 #ifdef DEBUG
    926 	frame_sanity_check(0xdead02, type, frame, l);
    927 	if (frame->tf_flags & TFF_LAST && (curlwp->l_flag & LW_IDLE) == 0)
    928 		frame_sanity_check(0xdead03, type, curlwp->l_md.md_regs,
    929 				   curlwp);
    930 #endif /* DEBUG */
    931 }
    932 
    933 void
    934 child_return(void *arg)
    935 {
    936 	struct lwp *l = arg;
    937 #ifdef KTRACE
    938 	struct proc *p = l->l_proc;
    939 #endif
    940 
    941 	userret(l, l->l_md.md_regs->tf_iioq_head, 0);
    942 #ifdef KTRACE
    943 	if (KTRPOINT(p, KTR_SYSRET))
    944 		ktrsysret(l, SYS_fork, 0, 0);
    945 #endif
    946 #ifdef DEBUG
    947 	frame_sanity_check(0xdead04, 0, l->l_md.md_regs, l);
    948 #endif /* DEBUG */
    949 }
    950 
    951 /*
    952  * call actual syscall routine
    953  * from the low-level syscall handler:
    954  * - all HPPA_FRAME_NARGS syscall's arguments supposed to be copied onto
    955  *   our stack, this wins compared to copyin just needed amount anyway
    956  * - register args are copied onto stack too
    957  */
    958 void
    959 syscall(struct trapframe *frame, int *args)
    960 {
    961 	struct lwp *l;
    962 	struct proc *p;
    963 	const struct sysent *callp;
    964 	int nsys, code, argsize, error;
    965 	int tmp;
    966 	int rval[2];
    967 
    968 	uvmexp.syscalls++;
    969 
    970 #ifdef DEBUG
    971 	frame_sanity_check(0xdead04, 0, frame, curlwp);
    972 #endif /* DEBUG */
    973 
    974 	if (!USERMODE(frame->tf_iioq_head))
    975 		panic("syscall");
    976 
    977 	l = curlwp;
    978 	p = l->l_proc;
    979 	l->l_md.md_regs = frame;
    980 	nsys = p->p_emul->e_nsysent;
    981 	callp = p->p_emul->e_sysent;
    982 	code = frame->tf_t1;
    983 	LWP_CACHE_CREDS(l, p);
    984 
    985 	/*
    986 	 * Restarting a system call is touchy on the HPPA,
    987 	 * because syscall arguments are passed in registers
    988 	 * and the program counter of the syscall "point"
    989 	 * isn't easily divined.
    990 	 *
    991 	 * We handle the first problem by assuming that we
    992 	 * will have to restart this system call, so we
    993 	 * stuff the first four words of the original arguments
    994 	 * back into the frame as arg0...arg3, which is where
    995 	 * we found them in the first place.  Any further
    996 	 * arguments are (still) on the user's stack and the
    997 	 * syscall code will fetch them from there (again).
    998 	 *
    999 	 * The program counter problem is addressed below.
   1000 	 */
   1001 	frame->tf_arg0 = args[0];
   1002 	frame->tf_arg1 = args[1];
   1003 	frame->tf_arg2 = args[2];
   1004 	frame->tf_arg3 = args[3];
   1005 
   1006 	/*
   1007 	 * Some special handling for the syscall(2) and
   1008 	 * __syscall(2) system calls.
   1009 	 */
   1010 	switch (code) {
   1011 	case SYS_syscall:
   1012 		code = *args;
   1013 		args += 1;
   1014 		break;
   1015 	case SYS___syscall:
   1016 		if (callp != sysent)
   1017 			break;
   1018 		/*
   1019 		 * NB: even though __syscall(2) takes a quad_t
   1020 		 * containing the system call number, because
   1021 		 * our argument copying word-swaps 64-bit arguments,
   1022 		 * the least significant word of that quad_t
   1023 		 * is the first word in the argument array.
   1024 		 */
   1025 		code = *args;
   1026 		args += 2;
   1027 	}
   1028 
   1029 	/*
   1030 	 * Stacks growing from lower addresses to higher
   1031 	 * addresses are not really such a good idea, because
   1032 	 * it makes it impossible to overlay a struct on top
   1033 	 * of C stack arguments (the arguments appear in
   1034 	 * reversed order).
   1035 	 *
   1036 	 * You can do the obvious thing (as locore.S does) and
   1037 	 * copy argument words one by one, laying them out in
   1038 	 * the "right" order in the destination buffer, but this
   1039 	 * ends up word-swapping multi-word arguments (like off_t).
   1040 	 *
   1041 	 * To compensate, we have some automatically-generated
   1042 	 * code that word-swaps these multi-word arguments.
   1043 	 * Right now the script that generates this code is
   1044 	 * in Perl, because I don't know awk.
   1045 	 *
   1046 	 * FIXME - this works only on native binaries and
   1047 	 * will probably screw up any and all emulation.
   1048 	 */
   1049 	switch (code) {
   1050 	/*
   1051 	 * BEGIN automatically generated
   1052 	 * by /home/fredette/project/hppa/makescargfix.pl
   1053 	 * do not edit!
   1054 	 */
   1055 	case SYS_pread:
   1056 		/*
   1057 		 * 	syscallarg(int) fd;
   1058 		 * 	syscallarg(void *) buf;
   1059 		 * 	syscallarg(size_t) nbyte;
   1060 		 * 	syscallarg(int) pad;
   1061 		 * 	syscallarg(off_t) offset;
   1062 		 */
   1063 		tmp = args[4];
   1064 		args[4] = args[4 + 1];
   1065 		args[4 + 1] = tmp;
   1066 		break;
   1067 	case SYS_pwrite:
   1068 		/*
   1069 		 * 	syscallarg(int) fd;
   1070 		 * 	syscallarg(const void *) buf;
   1071 		 * 	syscallarg(size_t) nbyte;
   1072 		 * 	syscallarg(int) pad;
   1073 		 * 	syscallarg(off_t) offset;
   1074 		 */
   1075 		tmp = args[4];
   1076 		args[4] = args[4 + 1];
   1077 		args[4 + 1] = tmp;
   1078 		break;
   1079 	case SYS_mmap:
   1080 		/*
   1081 		 * 	syscallarg(void *) addr;
   1082 		 * 	syscallarg(size_t) len;
   1083 		 * 	syscallarg(int) prot;
   1084 		 * 	syscallarg(int) flags;
   1085 		 * 	syscallarg(int) fd;
   1086 		 * 	syscallarg(long) pad;
   1087 		 * 	syscallarg(off_t) pos;
   1088 		 */
   1089 		tmp = args[6];
   1090 		args[6] = args[6 + 1];
   1091 		args[6 + 1] = tmp;
   1092 		break;
   1093 	case SYS_lseek:
   1094 		/*
   1095 		 * 	syscallarg(int) fd;
   1096 		 * 	syscallarg(int) pad;
   1097 		 * 	syscallarg(off_t) offset;
   1098 		 */
   1099 		tmp = args[2];
   1100 		args[2] = args[2 + 1];
   1101 		args[2 + 1] = tmp;
   1102 		break;
   1103 	case SYS_truncate:
   1104 		/*
   1105 		 * 	syscallarg(const char *) path;
   1106 		 * 	syscallarg(int) pad;
   1107 		 * 	syscallarg(off_t) length;
   1108 		 */
   1109 		tmp = args[2];
   1110 		args[2] = args[2 + 1];
   1111 		args[2 + 1] = tmp;
   1112 		break;
   1113 	case SYS_ftruncate:
   1114 		/*
   1115 		 * 	syscallarg(int) fd;
   1116 		 * 	syscallarg(int) pad;
   1117 		 * 	syscallarg(off_t) length;
   1118 		 */
   1119 		tmp = args[2];
   1120 		args[2] = args[2 + 1];
   1121 		args[2 + 1] = tmp;
   1122 		break;
   1123 	case SYS_preadv:
   1124 		/*
   1125 		 * 	syscallarg(int) fd;
   1126 		 * 	syscallarg(const struct iovec *) iovp;
   1127 		 * 	syscallarg(int) iovcnt;
   1128 		 * 	syscallarg(int) pad;
   1129 		 * 	syscallarg(off_t) offset;
   1130 		 */
   1131 		tmp = args[4];
   1132 		args[4] = args[4 + 1];
   1133 		args[4 + 1] = tmp;
   1134 		break;
   1135 	case SYS_pwritev:
   1136 		/*
   1137 		 * 	syscallarg(int) fd;
   1138 		 * 	syscallarg(const struct iovec *) iovp;
   1139 		 * 	syscallarg(int) iovcnt;
   1140 		 * 	syscallarg(int) pad;
   1141 		 * 	syscallarg(off_t) offset;
   1142 		 */
   1143 		tmp = args[4];
   1144 		args[4] = args[4 + 1];
   1145 		args[4 + 1] = tmp;
   1146 		break;
   1147 	default:
   1148 		break;
   1149 	/*
   1150 	 * END automatically generated
   1151 	 * by /home/fredette/project/hppa/makescargfix.pl
   1152 	 * do not edit!
   1153 	 */
   1154 	}
   1155 
   1156 #ifdef USERTRACE
   1157 	if (0) {
   1158 		user_backtrace(frame, l, -1);
   1159 		frame->tf_ipsw |= PSW_R;
   1160 		frame->tf_rctr = 0;
   1161 		printf("r %08x", frame->tf_iioq_head);
   1162 		rctr_next_iioq = frame->tf_iioq_head + 4;
   1163 	}
   1164 #endif
   1165 
   1166 	if (code < 0 || code >= nsys)
   1167 		callp += p->p_emul->e_nosys;	/* bad syscall # */
   1168 	else
   1169 		callp += code;
   1170 	argsize = callp->sy_argsize;
   1171 
   1172 	if ((error = trace_enter(l, code, code, NULL, args)) != 0)
   1173 		goto out;
   1174 
   1175 	rval[0] = 0;
   1176 	rval[1] = 0;
   1177 	error = (*callp->sy_call)(l, args, rval);
   1178 out:
   1179 	switch (error) {
   1180 	case 0:
   1181 		l = curlwp;			/* changes on exec() */
   1182 		frame = l->l_md.md_regs;
   1183 		frame->tf_ret0 = rval[0];
   1184 		frame->tf_ret1 = rval[1];
   1185 		frame->tf_t1 = 0;
   1186 		break;
   1187 	case ERESTART:
   1188 		/*
   1189 		 * Now we have to wind back the instruction
   1190 		 * offset queue to the point where the system
   1191 		 * call will be made again.  This is inherently
   1192 		 * tied to the SYSCALL macro.
   1193 		 *
   1194 		 * Currently, the part of the SYSCALL macro
   1195 		 * that we want to rerun reads as:
   1196 		 *
   1197 		 *	ldil	L%SYSCALLGATE, r1
   1198 		 *	ble	4(sr7, r1)
   1199 		 *	ldi	__CONCAT(SYS_,x), t1
   1200 		 *	ldw	HPPA_FRAME_ERP(sr0,sp), rp
   1201 		 *
   1202 		 * And our offset queue head points to the
   1203 		 * final ldw instruction.  So we need to
   1204 		 * subtract twelve to reach the ldil.
   1205 		 */
   1206 		frame->tf_iioq_head -= 12;
   1207 		frame->tf_iioq_tail = frame->tf_iioq_head + 4;
   1208 		break;
   1209 	case EJUSTRETURN:
   1210 		p = curproc;
   1211 		break;
   1212 	default:
   1213 		if (p->p_emul->e_errno)
   1214 			error = p->p_emul->e_errno[error];
   1215 		frame->tf_t1 = error;
   1216 		break;
   1217 	}
   1218 
   1219 	trace_exit(l, code, args, rval, error);
   1220 
   1221 	userret(l, frame->tf_iioq_head, 0);
   1222 #ifdef DEBUG
   1223 	frame_sanity_check(0xdead05, 0, frame, l);
   1224 #endif /* DEBUG */
   1225 }
   1226 
   1227 /*
   1228  * Start a new LWP
   1229  */
   1230 void
   1231 startlwp(void *arg)
   1232 {
   1233 	int err;
   1234 	ucontext_t *uc = arg;
   1235 	struct lwp *l = curlwp;
   1236 
   1237 	err = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
   1238 #if DIAGNOSTIC
   1239 	if (err) {
   1240 		printf("Error %d from cpu_setmcontext.", err);
   1241 	}
   1242 #endif
   1243 	pool_put(&lwp_uc_pool, uc);
   1244 
   1245 	userret(l, l->l_md.md_regs->tf_iioq_head, 0);
   1246 }
   1247