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