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