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