Home | History | Annotate | Line # | Download | only in hppa
trap.c revision 1.15
      1 /*	$NetBSD: trap.c,v 1.15 2004/03/14 01:08:47 cl 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.15 2004/03/14 01:08:47 cl 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 				l->l_savp->savp_faultaddr = va;
    727 				l->l_flag |= L_SA_PAGEFAULT;
    728 			}
    729 		}
    730 
    731 		va = hppa_trunc_page(va);
    732 
    733 		if (map->pmap->pmap_space != space) {
    734 #ifdef TRAPDEBUG
    735 			printf("trap: space missmatch %d != %d\n",
    736 			    space, map->pmap->pmap_space);
    737 #endif
    738 			/* actually dump the user, crap the kernel */
    739 			goto dead_end;
    740 		}
    741 
    742 		/* Never call uvm_fault in interrupt context. */
    743 		KASSERT(hppa_intr_depth == 0);
    744 
    745 		ret = uvm_fault(map, va, 0, vftype);
    746 
    747 #ifdef TRAPDEBUG
    748 		printf("uvm_fault(%p, %x, %d, %d)=%d\n",
    749 		    map, (u_int)va, 0, vftype, ret);
    750 #endif
    751 
    752 		if (map != kernel_map)
    753 			l->l_flag &= ~L_SA_PAGEFAULT;
    754 		/*
    755 		 * If this was a stack access we keep track of the maximum
    756 		 * accessed stack size.  Also, if uvm_fault gets a protection
    757 		 * failure it is due to accessing the stack region outside
    758 		 * the current limit and we need to reflect that as an access
    759 		 * error.
    760 		 */
    761 		if (va >= (vaddr_t)vm->vm_maxsaddr + vm->vm_ssize) {
    762 			if (ret == 0) {
    763 				vsize_t nss = btoc(va - USRSTACK + PAGE_SIZE);
    764 				if (nss > vm->vm_ssize)
    765 					vm->vm_ssize = nss;
    766 			} else if (ret == EACCES)
    767 				ret = EFAULT;
    768 		}
    769 
    770 		if (ret != 0) {
    771 			if (type & T_USER) {
    772 printf("trapsignal: uvm_fault(%p, %x, %d, %d)=%d\n",
    773 	map, (u_int)va, 0, vftype, ret);
    774 #ifdef DEBUG
    775 				user_backtrace(frame, l, type);
    776 #endif
    777 				trapsignal(l, SIGSEGV, frame->tf_ior);
    778 			} else {
    779 				if (l && l->l_addr->u_pcb.pcb_onfault) {
    780 #ifdef PMAPDEBUG
    781 					printf("trap: copyin/out %d\n",ret);
    782 #endif
    783 					pcbp = &l->l_addr->u_pcb;
    784 					frame->tf_iioq_tail = 4 +
    785 					    (frame->tf_iioq_head =
    786 						pcbp->pcb_onfault);
    787 					pcbp->pcb_onfault = 0;
    788 					break;
    789 				}
    790 #if 1
    791 if (trap_kdebug (type, va, frame))
    792 	return;
    793 #else
    794 				panic("trap: uvm_fault(%p, %x, %d, %d): %d",
    795 				    map, va, 0, vftype, ret);
    796 #endif
    797 			}
    798 		}
    799 		break;
    800 
    801 	case T_DATALIGN | T_USER:
    802 #ifdef DEBUG
    803 		user_backtrace(frame, l, type);
    804 #endif
    805 		trapsignal(l, SIGBUS, va);
    806 		break;
    807 
    808 	case T_INTERRUPT:
    809 	case T_INTERRUPT|T_USER:
    810 		hppa_intr(frame);
    811 		mtctl(frame->tf_eiem, CR_EIEM);
    812 #if 0
    813 if (trap_kdebug (type, va, frame))
    814 return;
    815 #endif
    816 		break;
    817 	case T_LOWERPL:
    818 	case T_DPROT:
    819 	case T_IPROT:
    820 	case T_OVERFLOW:
    821 	case T_CONDITION:
    822 	case T_ILLEGAL:
    823 	case T_HIGHERPL:
    824 	case T_TAKENBR:
    825 	case T_POWERFAIL:
    826 	case T_LPMC:
    827 	case T_PAGEREF:
    828 	case T_DATAPID:  	case T_DATAPID  | T_USER:
    829 		if (0 /* T-chip */) {
    830 			break;
    831 		}
    832 		/* FALLTHROUGH to unimplemented */
    833 	default:
    834 #if 1
    835 if (trap_kdebug (type, va, frame))
    836 	return;
    837 #endif
    838 		panic ("trap: unimplemented \'%s\' (%d)", tts, type);
    839 	}
    840 
    841 	if (type & T_USER)
    842 		userret(l, l->l_md.md_regs->tf_iioq_head, 0);
    843 
    844 #ifdef DEBUG
    845 	frame_sanity_check(frame, l);
    846 	if (frame->tf_flags & TFF_LAST && curlwp != NULL)
    847 		frame_sanity_check(curlwp->l_md.md_regs, curlwp);
    848 #endif /* DEBUG */
    849 }
    850 
    851 void
    852 child_return(void *arg)
    853 {
    854 	struct lwp *l = arg;
    855 	struct proc *p = l->l_proc;
    856 
    857 	userret(l, l->l_md.md_regs->tf_iioq_head, 0);
    858 #ifdef KTRACE
    859 	if (KTRPOINT(p, KTR_SYSRET))
    860 		ktrsysret(p, SYS_fork, 0, 0);
    861 #endif
    862 #ifdef DEBUG
    863 	frame_sanity_check(l->l_md.md_regs, l);
    864 #endif /* DEBUG */
    865 }
    866 
    867 /*
    868  * call actual syscall routine
    869  * from the low-level syscall handler:
    870  * - all HPPA_FRAME_NARGS syscall's arguments supposed to be copied onto
    871  *   our stack, this wins compared to copyin just needed amount anyway
    872  * - register args are copied onto stack too
    873  */
    874 void
    875 syscall(struct trapframe *frame, int *args)
    876 {
    877 	struct lwp *l;
    878 	struct proc *p;
    879 	const struct sysent *callp;
    880 	int nsys, code, argsize, error;
    881 	int tmp;
    882 	int rval[2];
    883 
    884 	uvmexp.syscalls++;
    885 
    886 #ifdef DEBUG
    887 	frame_sanity_check(frame, curlwp);
    888 #endif /* DEBUG */
    889 
    890 	if (!USERMODE(frame->tf_iioq_head))
    891 		panic("syscall");
    892 
    893 	l = curlwp;
    894 	p = l->l_proc;
    895 	l->l_md.md_regs = frame;
    896 	nsys = p->p_emul->e_nsysent;
    897 	callp = p->p_emul->e_sysent;
    898 	code = frame->tf_t1;
    899 
    900 	/*
    901 	 * Restarting a system call is touchy on the HPPA,
    902 	 * because syscall arguments are passed in registers
    903 	 * and the program counter of the syscall "point"
    904 	 * isn't easily divined.
    905 	 *
    906 	 * We handle the first problem by assuming that we
    907 	 * will have to restart this system call, so we
    908 	 * stuff the first four words of the original arguments
    909 	 * back into the frame as arg0...arg3, which is where
    910 	 * we found them in the first place.  Any further
    911 	 * arguments are (still) on the user's stack and the
    912 	 * syscall code will fetch them from there (again).
    913 	 *
    914 	 * The program counter problem is addressed below.
    915 	 */
    916 	frame->tf_arg0 = args[0];
    917 	frame->tf_arg1 = args[1];
    918 	frame->tf_arg2 = args[2];
    919 	frame->tf_arg3 = args[3];
    920 
    921 	/*
    922 	 * Some special handling for the syscall(2) and
    923 	 * __syscall(2) system calls.
    924 	 */
    925 	switch (code) {
    926 	case SYS_syscall:
    927 		code = *args;
    928 		args += 1;
    929 		break;
    930 	case SYS___syscall:
    931 		if (callp != sysent)
    932 			break;
    933 		/*
    934 		 * NB: even though __syscall(2) takes a quad_t
    935 		 * containing the system call number, because
    936 		 * our argument copying word-swaps 64-bit arguments,
    937 		 * the least significant word of that quad_t
    938 		 * is the first word in the argument array.
    939 		 */
    940 		code = *args;
    941 		args += 2;
    942 	}
    943 
    944 	/*
    945 	 * Stacks growing from lower addresses to higher
    946 	 * addresses are not really such a good idea, because
    947 	 * it makes it impossible to overlay a struct on top
    948 	 * of C stack arguments (the arguments appear in
    949 	 * reversed order).
    950 	 *
    951 	 * You can do the obvious thing (as locore.S does) and
    952 	 * copy argument words one by one, laying them out in
    953 	 * the "right" order in the destination buffer, but this
    954 	 * ends up word-swapping multi-word arguments (like off_t).
    955 	 *
    956 	 * To compensate, we have some automatically-generated
    957 	 * code that word-swaps these multi-word arguments.
    958 	 * Right now the script that generates this code is
    959 	 * in Perl, because I don't know awk.
    960 	 *
    961 	 * FIXME - this works only on native binaries and
    962 	 * will probably screw up any and all emulation.
    963 	 */
    964 	switch (code) {
    965 	/*
    966 	 * BEGIN automatically generated
    967 	 * by /home/fredette/project/hppa/makescargfix.pl
    968 	 * do not edit!
    969 	 */
    970 	case SYS_pread:
    971 		/*
    972 		 * 	syscallarg(int) fd;
    973 		 * 	syscallarg(void *) buf;
    974 		 * 	syscallarg(size_t) nbyte;
    975 		 * 	syscallarg(int) pad;
    976 		 * 	syscallarg(off_t) offset;
    977 		 */
    978 		tmp = args[4];
    979 		args[4] = args[4 + 1];
    980 		args[4 + 1] = tmp;
    981 		break;
    982 	case SYS_pwrite:
    983 		/*
    984 		 * 	syscallarg(int) fd;
    985 		 * 	syscallarg(const void *) buf;
    986 		 * 	syscallarg(size_t) nbyte;
    987 		 * 	syscallarg(int) pad;
    988 		 * 	syscallarg(off_t) offset;
    989 		 */
    990 		tmp = args[4];
    991 		args[4] = args[4 + 1];
    992 		args[4 + 1] = tmp;
    993 		break;
    994 	case SYS_mmap:
    995 		/*
    996 		 * 	syscallarg(void *) addr;
    997 		 * 	syscallarg(size_t) len;
    998 		 * 	syscallarg(int) prot;
    999 		 * 	syscallarg(int) flags;
   1000 		 * 	syscallarg(int) fd;
   1001 		 * 	syscallarg(long) pad;
   1002 		 * 	syscallarg(off_t) pos;
   1003 		 */
   1004 		tmp = args[6];
   1005 		args[6] = args[6 + 1];
   1006 		args[6 + 1] = tmp;
   1007 		break;
   1008 	case SYS_lseek:
   1009 		/*
   1010 		 * 	syscallarg(int) fd;
   1011 		 * 	syscallarg(int) pad;
   1012 		 * 	syscallarg(off_t) offset;
   1013 		 */
   1014 		tmp = args[2];
   1015 		args[2] = args[2 + 1];
   1016 		args[2 + 1] = tmp;
   1017 		break;
   1018 	case SYS_truncate:
   1019 		/*
   1020 		 * 	syscallarg(const char *) path;
   1021 		 * 	syscallarg(int) pad;
   1022 		 * 	syscallarg(off_t) length;
   1023 		 */
   1024 		tmp = args[2];
   1025 		args[2] = args[2 + 1];
   1026 		args[2 + 1] = tmp;
   1027 		break;
   1028 	case SYS_ftruncate:
   1029 		/*
   1030 		 * 	syscallarg(int) fd;
   1031 		 * 	syscallarg(int) pad;
   1032 		 * 	syscallarg(off_t) length;
   1033 		 */
   1034 		tmp = args[2];
   1035 		args[2] = args[2 + 1];
   1036 		args[2 + 1] = tmp;
   1037 		break;
   1038 	case SYS_preadv:
   1039 		/*
   1040 		 * 	syscallarg(int) fd;
   1041 		 * 	syscallarg(const struct iovec *) iovp;
   1042 		 * 	syscallarg(int) iovcnt;
   1043 		 * 	syscallarg(int) pad;
   1044 		 * 	syscallarg(off_t) offset;
   1045 		 */
   1046 		tmp = args[4];
   1047 		args[4] = args[4 + 1];
   1048 		args[4 + 1] = tmp;
   1049 		break;
   1050 	case SYS_pwritev:
   1051 		/*
   1052 		 * 	syscallarg(int) fd;
   1053 		 * 	syscallarg(const struct iovec *) iovp;
   1054 		 * 	syscallarg(int) iovcnt;
   1055 		 * 	syscallarg(int) pad;
   1056 		 * 	syscallarg(off_t) offset;
   1057 		 */
   1058 		tmp = args[4];
   1059 		args[4] = args[4 + 1];
   1060 		args[4 + 1] = tmp;
   1061 		break;
   1062 	default:
   1063 		break;
   1064 	/*
   1065 	 * END automatically generated
   1066 	 * by /home/fredette/project/hppa/makescargfix.pl
   1067 	 * do not edit!
   1068 	 */
   1069 	}
   1070 
   1071 #ifdef USERTRACE
   1072 	if (0) {
   1073 		user_backtrace(frame, p, -1);
   1074 		frame->tf_ipsw |= PSW_R;
   1075 		frame->tf_rctr = 0;
   1076 		printf("r %08x", frame->tf_iioq_head);
   1077 		rctr_next_iioq = frame->tf_iioq_head + 4;
   1078 	}
   1079 #endif
   1080 
   1081 	if (code < 0 || code >= nsys)
   1082 		callp += p->p_emul->e_nosys;	/* bad syscall # */
   1083 	else
   1084 		callp += code;
   1085 	argsize = callp->sy_argsize;
   1086 
   1087 	if ((error = trace_enter(l, code, code, NULL, args)) != 0)
   1088 		goto bad;
   1089 
   1090 	rval[0] = 0;
   1091 	rval[1] = 0;
   1092 	switch (error = (*callp->sy_call)(l, args, rval)) {
   1093 	case 0:
   1094 		l = curlwp;			/* changes on exec() */
   1095 		frame = l->l_md.md_regs;
   1096 		frame->tf_ret0 = rval[0];
   1097 		frame->tf_ret1 = rval[1];
   1098 		frame->tf_t1 = 0;
   1099 		break;
   1100 	case ERESTART:
   1101 		/*
   1102 		 * Now we have to wind back the instruction
   1103 		 * offset queue to the point where the system
   1104 		 * call will be made again.  This is inherently
   1105 		 * tied to the SYSCALL macro.
   1106 		 *
   1107 		 * Currently, the part of the SYSCALL macro
   1108 		 * that we want to rerun reads as:
   1109 		 *
   1110 		 *	ldil	L%SYSCALLGATE, r1
   1111 		 *	ble	4(sr7, r1)
   1112 		 *	ldi	__CONCAT(SYS_,x), t1
   1113 		 *	ldw	HPPA_FRAME_ERP(sr0,sp), rp
   1114 		 *
   1115 		 * And our offset queue head points to the
   1116 		 * final ldw instruction.  So we need to
   1117 		 * subtract twelve to reach the ldil.
   1118 		 */
   1119 		frame->tf_iioq_head -= 12;
   1120 		frame->tf_iioq_tail = frame->tf_iioq_head + 4;
   1121 		break;
   1122 	case EJUSTRETURN:
   1123 		p = curproc;
   1124 		break;
   1125 	default:
   1126 	bad:
   1127 		if (p->p_emul->e_errno)
   1128 			error = p->p_emul->e_errno[error];
   1129 		frame->tf_t1 = error;
   1130 		break;
   1131 	}
   1132 
   1133 	trace_exit(l, code, args, rval, error);
   1134 
   1135 	userret(l, frame->tf_iioq_head, 0);
   1136 #ifdef DEBUG
   1137 	frame_sanity_check(frame, l);
   1138 #endif /* DEBUG */
   1139 }
   1140 
   1141 /*
   1142  * Start a new LWP
   1143  */
   1144 void
   1145 startlwp(void *arg)
   1146 {
   1147 	int err;
   1148 	ucontext_t *uc = arg;
   1149 	struct lwp *l = curlwp;
   1150 
   1151 	err = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
   1152 #if DIAGNOSTIC
   1153 	if (err) {
   1154 		printf("Error %d from cpu_setmcontext.", err);
   1155 	}
   1156 #endif
   1157 	pool_put(&lwp_uc_pool, uc);
   1158 
   1159 	userret(l, l->l_md.md_regs->tf_iioq_head, 0);
   1160 }
   1161 
   1162 /*
   1163  * XXX This is a terrible name.
   1164  */
   1165 void
   1166 upcallret(struct lwp *l)
   1167 {
   1168 	userret(l, l->l_md.md_regs->tf_iioq_head, 0);
   1169 }
   1170