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