trap.c revision 1.16 1 /* $NetBSD: trap.c,v 1.16 2004/03/26 14:11:01 drochner 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.16 2004/03/26 14:11:01 drochner 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 /* XXX */
180 void hppa_trapsignal_hack(struct lwp *, int, u_long);
181
182 #ifdef USERTRACE
183 /*
184 * USERTRACE is a crude facility that traces the PC of
185 * a single user process. This tracing is normally
186 * activated by the dispatching of a certain syscall
187 * with certain arguments - see the activation code in
188 * syscall().
189 */
190 u_int rctr_next_iioq;
191 #endif
192
193 static __inline void
194 userret (struct lwp *l, register_t pc, u_quad_t oticks)
195 {
196 struct proc *p = l->l_proc;
197 int sig;
198
199 /* take pending signals */
200 while ((sig = CURSIG(l)) != 0)
201 postsig(sig);
202
203 l->l_priority = l->l_usrpri;
204 if (want_resched) {
205 /*
206 * We're being preempted.
207 */
208 preempt(0);
209 while ((sig = CURSIG(l)) != 0)
210 postsig(sig);
211 }
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)
233 static int
234 trap_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 #ifdef DIAGNOSTIC
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 */
323 static void user_backtrace_raw(u_int, u_int);
324 static void
325 user_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
354 static void user_backtrace(struct trapframe *, struct lwp *, int);
355 static void
356 user_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 /* DIAGNOSTIC */
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 */
411 struct trapframe *sanity_frame;
412 struct lwp *sanity_lwp;
413 int sanity_checked = 0;
414 void frame_sanity_check(struct trapframe *, struct lwp *);
415 void
416 frame_sanity_check(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) \
425 do { \
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 (void) trap_kdebug(T_IBREAK, 0, tf);
466 sanity_frame = NULL;
467 sanity_lwp = NULL;
468 sanity_checked = 0;
469 }
470 }
471 #endif /* DEBUG */
472
473 void
474 trap(int type, struct trapframe *frame)
475 {
476 struct lwp *l;
477 struct proc *p;
478 struct pcb *pcbp;
479 vaddr_t va;
480 struct vm_map *map;
481 struct vmspace *vm;
482 vm_prot_t vftype;
483 pa_space_t space;
484 u_int opcode;
485 int ret;
486 const char *tts;
487 int type_raw;
488 #ifdef DIAGNOSTIC
489 extern int emergency_stack_start, emergency_stack_end;
490 #endif
491
492 type_raw = type & ~T_USER;
493 opcode = frame->tf_iir;
494 if (type_raw == T_ITLBMISS || type_raw == T_ITLBMISSNA) {
495 va = frame->tf_iioq_head;
496 space = frame->tf_iisq_head;
497 vftype = VM_PROT_READ; /* XXX VM_PROT_EXECUTE ??? */
498 } else {
499 va = frame->tf_ior;
500 space = frame->tf_isr;
501 vftype = inst_store(opcode) ? VM_PROT_WRITE : VM_PROT_READ;
502 }
503
504 if ((l = curlwp) == NULL)
505 l = &lwp0;
506 p = l->l_proc;
507
508 #ifdef DIAGNOSTIC
509 /*
510 * If we are on the emergency stack, then we either got
511 * a fault on the kernel stack, or we're just handling
512 * a trap for the machine check handler (which also
513 * runs on the emergency stack).
514 *
515 * We *very crudely* differentiate between the two cases
516 * by checking the faulting instruction: if it is the
517 * function prologue instruction that stores the old
518 * frame pointer and updates the stack pointer, we assume
519 * that we faulted on the kernel stack.
520 *
521 * In this case, not completing that instruction will
522 * probably confuse backtraces in kgdb/ddb. Completing
523 * it would be difficult, because we already faulted on
524 * that part of the stack, so instead we fix up the
525 * frame as if the function called has just returned.
526 * This has peculiar knowledge about what values are in
527 * what registers during the "normal gcc -g" prologue.
528 */
529 if (&type >= &emergency_stack_start &&
530 &type < &emergency_stack_end &&
531 type != T_IBREAK && STWM_R1_D_SR0_SP(opcode)) {
532 /* Restore the caller's frame pointer. */
533 frame->tf_r3 = frame->tf_r1;
534 /* Restore the caller's instruction offsets. */
535 frame->tf_iioq_head = frame->tf_rp;
536 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
537 goto dead_end;
538 }
539 #endif /* DIAGNOSTIC */
540
541 #ifdef DEBUG
542 frame_sanity_check(frame, l);
543 #endif /* DEBUG */
544
545 /* If this is a trap, not an interrupt, reenable interrupts. */
546 if (type_raw != T_INTERRUPT)
547 mtctl(frame->tf_eiem, CR_EIEM);
548
549 if (frame->tf_flags & TFF_LAST)
550 l->l_md.md_regs = frame;
551
552 if ((type & ~T_USER) > trap_types)
553 tts = "reserved";
554 else
555 tts = trap_type[type & ~T_USER];
556
557 #ifdef TRAPDEBUG
558 if (type_raw != T_INTERRUPT && type_raw != T_IBREAK)
559 printf("trap: %d, %s for %x:%x at %x:%x, fp=%p, rp=%x\n",
560 type, tts, space, (u_int)va, frame->tf_iisq_head,
561 frame->tf_iioq_head, frame, frame->tf_rp);
562 else if (type_raw == T_IBREAK)
563 printf("trap: break instruction %x:%x at %x:%x, fp=%p\n",
564 break5(opcode), break13(opcode),
565 frame->tf_iisq_head, frame->tf_iioq_head, frame);
566
567 {
568 extern int etext;
569 if (frame < (struct trapframe *)&etext) {
570 printf("trap: bogus frame ptr %p\n", frame);
571 goto dead_end;
572 }
573 }
574 #endif
575 switch (type) {
576 case T_NONEXIST:
577 case T_NONEXIST|T_USER:
578 #if !defined(DDB) && !defined(KGDB)
579 /* we've got screwed up by the central scrutinizer */
580 panic ("trap: elvis has just left the building!");
581 break;
582 #else
583 goto dead_end;
584 #endif
585 case T_RECOVERY|T_USER:
586 #ifdef USERTRACE
587 for(;;) {
588 if (frame->tf_iioq_head != rctr_next_iioq)
589 printf("-%08x\nr %08x",
590 rctr_next_iioq - 4,
591 frame->tf_iioq_head);
592 rctr_next_iioq = frame->tf_iioq_head + 4;
593 if (frame->tf_ipsw & PSW_N) {
594 /* Advance the program counter. */
595 frame->tf_iioq_head = frame->tf_iioq_tail;
596 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
597 /* Clear flags. */
598 frame->tf_ipsw &= ~(PSW_N|PSW_X|PSW_Y|PSW_Z|PSW_B|PSW_T|PSW_H|PSW_L);
599 /* Simulate another trap. */
600 continue;
601 }
602 break;
603 }
604 frame->tf_rctr = 0;
605 break;
606 #endif /* USERTRACE */
607 case T_RECOVERY:
608 #if !defined(DDB) && !defined(KGDB)
609 /* XXX will implement later */
610 printf ("trap: handicapped");
611 break;
612 #else
613 goto dead_end;
614 #endif
615
616 case T_EMULATION | T_USER:
617 #ifdef FPEMUL
618 hppa_fpu_emulate(frame, l);
619 #else /* !FPEMUL */
620 /*
621 * We don't have FPU emulation, so signal the
622 * process with a SIGFPE.
623 */
624 hppa_trapsignal_hack(l, SIGFPE, frame->tf_iioq_head);
625 #endif /* !FPEMUL */
626 break;
627
628 #ifdef DIAGNOSTIC
629 case T_EXCEPTION:
630 panic("FPU/SFU emulation botch");
631
632 /* these just can't happen ever */
633 case T_PRIV_OP:
634 case T_PRIV_REG:
635 /* these just can't make it to the trap() ever */
636 case T_HPMC: case T_HPMC | T_USER:
637 case T_EMULATION:
638 #endif
639 case T_IBREAK:
640 case T_DATALIGN:
641 case T_DBREAK:
642 dead_end:
643 if (type & T_USER) {
644 #ifdef DEBUG
645 user_backtrace(frame, l, type);
646 #endif
647 hppa_trapsignal_hack(l, SIGILL, frame->tf_iioq_head);
648 break;
649 }
650 if (trap_kdebug(type, va, frame))
651 return;
652 else if (type == T_DATALIGN)
653 panic ("trap: %s at 0x%x", tts, (u_int) va);
654 else
655 panic ("trap: no debugger for \"%s\" (%d)", tts, type);
656 break;
657
658 case T_IBREAK | T_USER:
659 case T_DBREAK | T_USER:
660 /* pass to user debugger */
661 break;
662
663 case T_EXCEPTION | T_USER: /* co-proc assist trap */
664 hppa_trapsignal_hack(l, SIGFPE, va);
665 break;
666
667 case T_OVERFLOW | T_USER:
668 hppa_trapsignal_hack(l, SIGFPE, va);
669 break;
670
671 case T_CONDITION | T_USER:
672 break;
673
674 case T_ILLEGAL | T_USER:
675 #ifdef DEBUG
676 user_backtrace(frame, l, type);
677 #endif
678 hppa_trapsignal_hack(l, SIGILL, va);
679 break;
680
681 case T_PRIV_OP | T_USER:
682 #ifdef DEBUG
683 user_backtrace(frame, l, type);
684 #endif
685 hppa_trapsignal_hack(l, SIGILL, va);
686 break;
687
688 case T_PRIV_REG | T_USER:
689 #ifdef DEBUG
690 user_backtrace(frame, l, type);
691 #endif
692 hppa_trapsignal_hack(l, SIGILL, va);
693 break;
694
695 /* these should never got here */
696 case T_HIGHERPL | T_USER:
697 case T_LOWERPL | T_USER:
698 hppa_trapsignal_hack(l, SIGSEGV, va);
699 break;
700
701 case T_IPROT | T_USER:
702 case T_DPROT | T_USER:
703 hppa_trapsignal_hack(l, SIGSEGV, va);
704 break;
705
706 case T_DATACC: case T_USER | T_DATACC:
707 case T_ITLBMISS: case T_USER | T_ITLBMISS:
708 case T_DTLBMISS: case T_USER | T_DTLBMISS:
709 case T_ITLBMISSNA: case T_USER | T_ITLBMISSNA:
710 case T_DTLBMISSNA: case T_USER | T_DTLBMISSNA:
711 case T_TLB_DIRTY: case T_USER | T_TLB_DIRTY:
712 vm = p->p_vmspace;
713
714 if (!vm) {
715 #ifdef TRAPDEBUG
716 printf("trap: no vm, p=%p\n", p);
717 #endif
718 goto dead_end;
719 }
720
721 /*
722 * it could be a kernel map for exec_map faults
723 */
724 if (!(type & T_USER) && space == HPPA_SID_KERNEL)
725 map = kernel_map;
726 else {
727 map = &vm->vm_map;
728 if (l->l_flag & L_SA) {
729 l->l_savp->savp_faultaddr = va;
730 l->l_flag |= L_SA_PAGEFAULT;
731 }
732 }
733
734 va = hppa_trunc_page(va);
735
736 if (map->pmap->pmap_space != space) {
737 #ifdef TRAPDEBUG
738 printf("trap: space missmatch %d != %d\n",
739 space, map->pmap->pmap_space);
740 #endif
741 /* actually dump the user, crap the kernel */
742 goto dead_end;
743 }
744
745 /* Never call uvm_fault in interrupt context. */
746 KASSERT(hppa_intr_depth == 0);
747
748 ret = uvm_fault(map, va, 0, vftype);
749
750 #ifdef TRAPDEBUG
751 printf("uvm_fault(%p, %x, %d, %d)=%d\n",
752 map, (u_int)va, 0, vftype, ret);
753 #endif
754
755 if (map != kernel_map)
756 l->l_flag &= ~L_SA_PAGEFAULT;
757 /*
758 * If this was a stack access we keep track of the maximum
759 * accessed stack size. Also, if uvm_fault gets a protection
760 * failure it is due to accessing the stack region outside
761 * the current limit and we need to reflect that as an access
762 * error.
763 */
764 if (va >= (vaddr_t)vm->vm_maxsaddr + vm->vm_ssize) {
765 if (ret == 0) {
766 vsize_t nss = btoc(va - USRSTACK + PAGE_SIZE);
767 if (nss > vm->vm_ssize)
768 vm->vm_ssize = nss;
769 } else if (ret == EACCES)
770 ret = EFAULT;
771 }
772
773 if (ret != 0) {
774 if (type & T_USER) {
775 printf("trapsignal: uvm_fault(%p, %x, %d, %d)=%d\n",
776 map, (u_int)va, 0, vftype, ret);
777 #ifdef DEBUG
778 user_backtrace(frame, l, type);
779 #endif
780 hppa_trapsignal_hack(l, SIGSEGV, frame->tf_ior);
781 } else {
782 if (l && l->l_addr->u_pcb.pcb_onfault) {
783 #ifdef PMAPDEBUG
784 printf("trap: copyin/out %d\n",ret);
785 #endif
786 pcbp = &l->l_addr->u_pcb;
787 frame->tf_iioq_tail = 4 +
788 (frame->tf_iioq_head =
789 pcbp->pcb_onfault);
790 pcbp->pcb_onfault = 0;
791 break;
792 }
793 #if 1
794 if (trap_kdebug (type, va, frame))
795 return;
796 #else
797 panic("trap: uvm_fault(%p, %x, %d, %d): %d",
798 map, va, 0, vftype, ret);
799 #endif
800 }
801 }
802 break;
803
804 case T_DATALIGN | T_USER:
805 #ifdef DEBUG
806 user_backtrace(frame, l, type);
807 #endif
808 hppa_trapsignal_hack(l, SIGBUS, va);
809 break;
810
811 case T_INTERRUPT:
812 case T_INTERRUPT|T_USER:
813 hppa_intr(frame);
814 mtctl(frame->tf_eiem, CR_EIEM);
815 #if 0
816 if (trap_kdebug (type, va, frame))
817 return;
818 #endif
819 break;
820 case T_LOWERPL:
821 case T_DPROT:
822 case T_IPROT:
823 case T_OVERFLOW:
824 case T_CONDITION:
825 case T_ILLEGAL:
826 case T_HIGHERPL:
827 case T_TAKENBR:
828 case T_POWERFAIL:
829 case T_LPMC:
830 case T_PAGEREF:
831 case T_DATAPID: case T_DATAPID | T_USER:
832 if (0 /* T-chip */) {
833 break;
834 }
835 /* FALLTHROUGH to unimplemented */
836 default:
837 #if 1
838 if (trap_kdebug (type, va, frame))
839 return;
840 #endif
841 panic ("trap: unimplemented \'%s\' (%d)", tts, type);
842 }
843
844 if (type & T_USER)
845 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
846
847 #ifdef DEBUG
848 frame_sanity_check(frame, l);
849 if (frame->tf_flags & TFF_LAST && curlwp != NULL)
850 frame_sanity_check(curlwp->l_md.md_regs, curlwp);
851 #endif /* DEBUG */
852 }
853
854 void
855 child_return(void *arg)
856 {
857 struct lwp *l = arg;
858 struct proc *p = l->l_proc;
859
860 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
861 #ifdef KTRACE
862 if (KTRPOINT(p, KTR_SYSRET))
863 ktrsysret(p, SYS_fork, 0, 0);
864 #endif
865 #ifdef DEBUG
866 frame_sanity_check(l->l_md.md_regs, l);
867 #endif /* DEBUG */
868 }
869
870 /*
871 * call actual syscall routine
872 * from the low-level syscall handler:
873 * - all HPPA_FRAME_NARGS syscall's arguments supposed to be copied onto
874 * our stack, this wins compared to copyin just needed amount anyway
875 * - register args are copied onto stack too
876 */
877 void
878 syscall(struct trapframe *frame, int *args)
879 {
880 struct lwp *l;
881 struct proc *p;
882 const struct sysent *callp;
883 int nsys, code, argsize, error;
884 int tmp;
885 int rval[2];
886
887 uvmexp.syscalls++;
888
889 #ifdef DEBUG
890 frame_sanity_check(frame, curlwp);
891 #endif /* DEBUG */
892
893 if (!USERMODE(frame->tf_iioq_head))
894 panic("syscall");
895
896 l = curlwp;
897 p = l->l_proc;
898 l->l_md.md_regs = frame;
899 nsys = p->p_emul->e_nsysent;
900 callp = p->p_emul->e_sysent;
901 code = frame->tf_t1;
902
903 /*
904 * Restarting a system call is touchy on the HPPA,
905 * because syscall arguments are passed in registers
906 * and the program counter of the syscall "point"
907 * isn't easily divined.
908 *
909 * We handle the first problem by assuming that we
910 * will have to restart this system call, so we
911 * stuff the first four words of the original arguments
912 * back into the frame as arg0...arg3, which is where
913 * we found them in the first place. Any further
914 * arguments are (still) on the user's stack and the
915 * syscall code will fetch them from there (again).
916 *
917 * The program counter problem is addressed below.
918 */
919 frame->tf_arg0 = args[0];
920 frame->tf_arg1 = args[1];
921 frame->tf_arg2 = args[2];
922 frame->tf_arg3 = args[3];
923
924 /*
925 * Some special handling for the syscall(2) and
926 * __syscall(2) system calls.
927 */
928 switch (code) {
929 case SYS_syscall:
930 code = *args;
931 args += 1;
932 break;
933 case SYS___syscall:
934 if (callp != sysent)
935 break;
936 /*
937 * NB: even though __syscall(2) takes a quad_t
938 * containing the system call number, because
939 * our argument copying word-swaps 64-bit arguments,
940 * the least significant word of that quad_t
941 * is the first word in the argument array.
942 */
943 code = *args;
944 args += 2;
945 }
946
947 /*
948 * Stacks growing from lower addresses to higher
949 * addresses are not really such a good idea, because
950 * it makes it impossible to overlay a struct on top
951 * of C stack arguments (the arguments appear in
952 * reversed order).
953 *
954 * You can do the obvious thing (as locore.S does) and
955 * copy argument words one by one, laying them out in
956 * the "right" order in the destination buffer, but this
957 * ends up word-swapping multi-word arguments (like off_t).
958 *
959 * To compensate, we have some automatically-generated
960 * code that word-swaps these multi-word arguments.
961 * Right now the script that generates this code is
962 * in Perl, because I don't know awk.
963 *
964 * FIXME - this works only on native binaries and
965 * will probably screw up any and all emulation.
966 */
967 switch (code) {
968 /*
969 * BEGIN automatically generated
970 * by /home/fredette/project/hppa/makescargfix.pl
971 * do not edit!
972 */
973 case SYS_pread:
974 /*
975 * syscallarg(int) fd;
976 * syscallarg(void *) buf;
977 * syscallarg(size_t) nbyte;
978 * syscallarg(int) pad;
979 * syscallarg(off_t) offset;
980 */
981 tmp = args[4];
982 args[4] = args[4 + 1];
983 args[4 + 1] = tmp;
984 break;
985 case SYS_pwrite:
986 /*
987 * syscallarg(int) fd;
988 * syscallarg(const void *) buf;
989 * syscallarg(size_t) nbyte;
990 * syscallarg(int) pad;
991 * syscallarg(off_t) offset;
992 */
993 tmp = args[4];
994 args[4] = args[4 + 1];
995 args[4 + 1] = tmp;
996 break;
997 case SYS_mmap:
998 /*
999 * syscallarg(void *) addr;
1000 * syscallarg(size_t) len;
1001 * syscallarg(int) prot;
1002 * syscallarg(int) flags;
1003 * syscallarg(int) fd;
1004 * syscallarg(long) pad;
1005 * syscallarg(off_t) pos;
1006 */
1007 tmp = args[6];
1008 args[6] = args[6 + 1];
1009 args[6 + 1] = tmp;
1010 break;
1011 case SYS_lseek:
1012 /*
1013 * syscallarg(int) fd;
1014 * syscallarg(int) pad;
1015 * syscallarg(off_t) offset;
1016 */
1017 tmp = args[2];
1018 args[2] = args[2 + 1];
1019 args[2 + 1] = tmp;
1020 break;
1021 case SYS_truncate:
1022 /*
1023 * syscallarg(const char *) path;
1024 * syscallarg(int) pad;
1025 * syscallarg(off_t) length;
1026 */
1027 tmp = args[2];
1028 args[2] = args[2 + 1];
1029 args[2 + 1] = tmp;
1030 break;
1031 case SYS_ftruncate:
1032 /*
1033 * syscallarg(int) fd;
1034 * syscallarg(int) pad;
1035 * syscallarg(off_t) length;
1036 */
1037 tmp = args[2];
1038 args[2] = args[2 + 1];
1039 args[2 + 1] = tmp;
1040 break;
1041 case SYS_preadv:
1042 /*
1043 * syscallarg(int) fd;
1044 * syscallarg(const struct iovec *) iovp;
1045 * syscallarg(int) iovcnt;
1046 * syscallarg(int) pad;
1047 * syscallarg(off_t) offset;
1048 */
1049 tmp = args[4];
1050 args[4] = args[4 + 1];
1051 args[4 + 1] = tmp;
1052 break;
1053 case SYS_pwritev:
1054 /*
1055 * syscallarg(int) fd;
1056 * syscallarg(const struct iovec *) iovp;
1057 * syscallarg(int) iovcnt;
1058 * syscallarg(int) pad;
1059 * syscallarg(off_t) offset;
1060 */
1061 tmp = args[4];
1062 args[4] = args[4 + 1];
1063 args[4 + 1] = tmp;
1064 break;
1065 default:
1066 break;
1067 /*
1068 * END automatically generated
1069 * by /home/fredette/project/hppa/makescargfix.pl
1070 * do not edit!
1071 */
1072 }
1073
1074 #ifdef USERTRACE
1075 if (0) {
1076 user_backtrace(frame, p, -1);
1077 frame->tf_ipsw |= PSW_R;
1078 frame->tf_rctr = 0;
1079 printf("r %08x", frame->tf_iioq_head);
1080 rctr_next_iioq = frame->tf_iioq_head + 4;
1081 }
1082 #endif
1083
1084 if (code < 0 || code >= nsys)
1085 callp += p->p_emul->e_nosys; /* bad syscall # */
1086 else
1087 callp += code;
1088 argsize = callp->sy_argsize;
1089
1090 if ((error = trace_enter(l, code, code, NULL, args)) != 0)
1091 goto bad;
1092
1093 rval[0] = 0;
1094 rval[1] = 0;
1095 switch (error = (*callp->sy_call)(l, args, rval)) {
1096 case 0:
1097 l = curlwp; /* changes on exec() */
1098 frame = l->l_md.md_regs;
1099 frame->tf_ret0 = rval[0];
1100 frame->tf_ret1 = rval[1];
1101 frame->tf_t1 = 0;
1102 break;
1103 case ERESTART:
1104 /*
1105 * Now we have to wind back the instruction
1106 * offset queue to the point where the system
1107 * call will be made again. This is inherently
1108 * tied to the SYSCALL macro.
1109 *
1110 * Currently, the part of the SYSCALL macro
1111 * that we want to rerun reads as:
1112 *
1113 * ldil L%SYSCALLGATE, r1
1114 * ble 4(sr7, r1)
1115 * ldi __CONCAT(SYS_,x), t1
1116 * ldw HPPA_FRAME_ERP(sr0,sp), rp
1117 *
1118 * And our offset queue head points to the
1119 * final ldw instruction. So we need to
1120 * subtract twelve to reach the ldil.
1121 */
1122 frame->tf_iioq_head -= 12;
1123 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
1124 break;
1125 case EJUSTRETURN:
1126 p = curproc;
1127 break;
1128 default:
1129 bad:
1130 if (p->p_emul->e_errno)
1131 error = p->p_emul->e_errno[error];
1132 frame->tf_t1 = error;
1133 break;
1134 }
1135
1136 trace_exit(l, code, args, rval, error);
1137
1138 userret(l, frame->tf_iioq_head, 0);
1139 #ifdef DEBUG
1140 frame_sanity_check(frame, l);
1141 #endif /* DEBUG */
1142 }
1143
1144 /*
1145 * Start a new LWP
1146 */
1147 void
1148 startlwp(void *arg)
1149 {
1150 int err;
1151 ucontext_t *uc = arg;
1152 struct lwp *l = curlwp;
1153
1154 err = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
1155 #if DIAGNOSTIC
1156 if (err) {
1157 printf("Error %d from cpu_setmcontext.", err);
1158 }
1159 #endif
1160 pool_put(&lwp_uc_pool, uc);
1161
1162 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
1163 }
1164
1165 /*
1166 * XXX This is a terrible name.
1167 */
1168 void
1169 upcallret(struct lwp *l)
1170 {
1171 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
1172 }
1173
1174 /*
1175 * XXX for transition to SIGINFO
1176 */
1177 void
1178 hppa_trapsignal_hack(struct lwp *l, int signum, u_long code)
1179 {
1180 ksiginfo_t ksi;
1181
1182 KSI_INIT_TRAP(&ksi);
1183 ksi.ksi_signo = signum;
1184 ksi.ksi_trap = (int)code;
1185 trapsignal(l, &ksi);
1186 }
1187