1 /* $NetBSD: trap.c,v 1.150 2024/01/20 00:15:33 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 1982, 1986, 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer
9 * Science Department.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * from: Utah Hdr: trap.c 1.37 92/12/20
36 * from: @(#)trap.c 8.5 (Berkeley) 1/4/94
37 */
38
39 /*
40 * Copyright (c) 1994 Gordon W. Ross
41 * Copyright (c) 1993 Adam Glass
42 * Copyright (c) 1988 University of Utah.
43 *
44 * This code is derived from software contributed to Berkeley by
45 * the Systems Programming Group of the University of Utah Computer
46 * Science Department.
47 *
48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions
50 * are met:
51 * 1. Redistributions of source code must retain the above copyright
52 * notice, this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright
54 * notice, this list of conditions and the following disclaimer in the
55 * documentation and/or other materials provided with the distribution.
56 * 3. All advertising materials mentioning features or use of this software
57 * must display the following acknowledgement:
58 * This product includes software developed by the University of
59 * California, Berkeley and its contributors.
60 * 4. Neither the name of the University nor the names of its contributors
61 * may be used to endorse or promote products derived from this software
62 * without specific prior written permission.
63 *
64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * SUCH DAMAGE.
75 *
76 * from: Utah Hdr: trap.c 1.37 92/12/20
77 * from: @(#)trap.c 8.5 (Berkeley) 1/4/94
78 */
79
80 #include <sys/cdefs.h>
81 __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.150 2024/01/20 00:15:33 thorpej Exp $");
82
83 #include "opt_ddb.h"
84 #include "opt_execfmt.h"
85 #include "opt_fpu_emulate.h"
86 #include "opt_kgdb.h"
87 #include "opt_compat_aout_m68k.h"
88 #include "opt_compat_sunos.h"
89
90 #include <sys/param.h>
91 #include <sys/systm.h>
92 #include <sys/proc.h>
93 #include <sys/acct.h>
94 #include <sys/kernel.h>
95 #include <sys/signalvar.h>
96 #include <sys/resourcevar.h>
97 #include <sys/syscall.h>
98 #include <sys/syslog.h>
99 #include <sys/userret.h>
100 #include <sys/kauth.h>
101 #ifdef KGDB
102 #include <sys/kgdb.h>
103 #endif
104
105 #include <uvm/uvm_extern.h>
106
107 #include <machine/cpu.h>
108 #include <machine/endian.h>
109 #include <machine/fcode.h>
110 #include <machine/pcb.h>
111 #include <machine/psl.h>
112 #include <machine/trap.h>
113 #include <machine/reg.h>
114 #include <m68k/cacheops.h>
115
116 #include <sun3/sun3/machdep.h>
117
118 #ifdef DDB
119 #include <machine/db_machdep.h>
120 #include <ddb/db_extern.h>
121 #endif
122
123 #ifdef COMPAT_SUNOS
124 #include <compat/sunos/sunos_syscall.h>
125 extern struct emul emul_sunos;
126 #endif
127
128 #ifdef COMPAT_AOUT_M68K
129 extern struct emul emul_netbsd_aoutm68k;
130 #endif
131
132 /*
133 * The sun3 wants faults to go through the pmap code, but
134 * the sun3x just goes directly to the common VM code.
135 */
136 #ifdef _SUN3X_
137 # define _pmap_fault(map, va, ftype) \
138 uvm_fault(map, va, ftype)
139 #endif /* SUN3X */
140
141 /* These are called from locore.s */
142 void trap(struct trapframe *, int type, u_int code, u_int v);
143 void trap_kdebug(int type, struct trapframe tf);
144 int _nodb_trap(int type, struct trapframe *);
145 void straytrap(struct trapframe);
146
147 static void userret(struct lwp *, struct trapframe *, u_quad_t);
148
149 volatile int astpending;
150
151 const char *trap_type[] = {
152 "Bus error",
153 "Address error",
154 "Illegal instruction",
155 "Zero divide",
156 "CHK instruction",
157 "TRAPV instruction",
158 "Privilege violation",
159 "Trace trap",
160 "MMU fault",
161 "SSIR trap",
162 "Format error",
163 "68881 exception",
164 "Coprocessor violation",
165 "Async system trap",
166 "Unused? (14)",
167 "Breakpoint",
168 "FPU instruction",
169 "FPU data format",
170 };
171 u_int trap_types = sizeof(trap_type) / sizeof(trap_type[0]);
172
173 /*
174 * Size of various exception stack frames (minus the standard 8 bytes)
175 */
176 short exframesize[] = {
177 FMT0SIZE, /* type 0 - normal (68020/030/040/060) */
178 FMT1SIZE, /* type 1 - throwaway (68020/030/040) */
179 FMT2SIZE, /* type 2 - normal 6-word (68020/030/040/060) */
180 FMT3SIZE, /* type 3 - FP post-instruction (68040/060) */
181 FMT4SIZE, /* type 4 - access error/fp disabled (68060) */
182 -1, -1, /* type 5-6 - undefined */
183 FMT7SIZE, /* type 7 - access error (68040) */
184 58, /* type 8 - bus fault (68010) */
185 FMT9SIZE, /* type 9 - coprocessor mid-instruction (68020/030) */
186 FMTASIZE, /* type A - short bus fault (68020/030) */
187 FMTBSIZE, /* type B - long bus fault (68020/030) */
188 -1, -1, -1, -1 /* type C-F - undefined */
189 };
190
191 #define KDFAULT(c) (((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
192 #define WRFAULT(c) (((c) & SSW_DF) != 0 && \
193 ((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0)))
194
195 /* #define DEBUG XXX */
196
197 #ifdef DEBUG
198 int mmudebug = 0;
199 int mmupid = -1;
200 #define MDB_ISPID(p) ((p) == mmupid)
201 #define MDB_FOLLOW 1
202 #define MDB_WBFOLLOW 2
203 #define MDB_WBFAILED 4
204 #define MDB_CPFAULT 8
205 #endif
206
207 /*
208 * trap and syscall both need the following work done before
209 * returning to user mode.
210 */
211 static void
userret(struct lwp * l,struct trapframe * tf,u_quad_t oticks)212 userret(struct lwp *l, struct trapframe *tf, u_quad_t oticks)
213 {
214 struct proc *p = l->l_proc;
215
216 /* Invoke MI userret code */
217 mi_userret(l);
218
219 /*
220 * If profiling, charge system time to the trapped pc.
221 */
222 if (p->p_stflag & PST_PROFIL) {
223 extern int psratio;
224 addupc_task(l, tf->tf_pc,
225 (int)(p->p_sticks - oticks) * psratio);
226 }
227 }
228
229 /*
230 * Used by the common m68k syscall() and child_return() functions.
231 * XXX: Temporary until all m68k ports share common trap()/userret() code.
232 */
233 void machine_userret(struct lwp *, struct frame *, u_quad_t);
234
235 void
machine_userret(struct lwp * l,struct frame * f,u_quad_t t)236 machine_userret(struct lwp *l, struct frame *f, u_quad_t t)
237 {
238
239 userret(l, &f->F_t, t);
240 }
241
242 /*
243 * Trap is called from locore to handle most types of processor traps,
244 * including events such as simulated software interrupts/AST's.
245 * System calls are broken out for efficiency.
246 */
247 /*ARGSUSED*/
248 void
trap(struct trapframe * tf,int type,u_int code,u_int v)249 trap(struct trapframe *tf, int type, u_int code, u_int v)
250 {
251 struct lwp *l;
252 struct proc *p;
253 struct pcb *pcb;
254 ksiginfo_t ksi;
255 int tmp;
256 int rv;
257 u_quad_t sticks;
258 void *onfault;
259
260 curcpu()->ci_data.cpu_ntrap++;
261 l = curlwp;
262 p = l->l_proc;
263 pcb = lwp_getpcb(l);
264 onfault = pcb->pcb_onfault;
265
266 KSI_INIT_TRAP(&ksi);
267 ksi.ksi_trap = type & ~T_USER;
268
269 if (USERMODE(tf->tf_sr)) {
270 type |= T_USER;
271 sticks = p->p_sticks;
272 l->l_md.md_regs = tf->tf_regs;
273 } else {
274 sticks = 0;
275 /* XXX: Detect trap recursion? */
276 }
277
278 switch (type) {
279 default:
280 dopanic:
281 printf("trap type=0x%x, code=0x%x, v=0x%x\n", type, code, v);
282 /*
283 * Let the kernel debugger see the trap frame that
284 * caused us to panic. This is a convenience so
285 * one can see registers at the point of failure.
286 */
287 tmp = splhigh();
288 #ifdef KGDB
289 /* If connected, step or cont returns 1 */
290 if (kgdb_trap(type, tf))
291 goto kgdb_cont;
292 #endif
293 #ifdef DDB
294 (void) kdb_trap(type, (db_regs_t *) tf);
295 #endif
296 #ifdef KGDB
297 kgdb_cont:
298 #endif
299 splx(tmp);
300 if (panicstr) {
301 /*
302 * Note: panic is smart enough to do:
303 * boot(RB_AUTOBOOT | RB_NOSYNC, NULL)
304 * if we call it again.
305 */
306 panic("trap during panic!");
307 }
308 regdump(tf, 128);
309 type &= ~T_USER;
310 if ((u_int)type < trap_types)
311 panic(trap_type[type]);
312 panic("trap type 0x%x", type);
313
314 case T_BUSERR: /* kernel bus error */
315 if (onfault == NULL)
316 goto dopanic;
317 rv = EFAULT;
318 /*FALLTHROUGH*/
319
320 copyfault:
321 /*
322 * If we have arranged to catch this fault in any of the
323 * copy to/from user space routines, set PC to return to
324 * indicated location and set flag informing buserror code
325 * that it may need to clean up stack frame.
326 */
327 tf->tf_stackadj = exframesize[tf->tf_format];
328 tf->tf_format = tf->tf_vector = 0;
329 tf->tf_pc = (int)onfault;
330 tf->tf_regs[D0] = rv;
331 goto done;
332
333 case T_BUSERR|T_USER: /* bus error */
334 case T_ADDRERR|T_USER: /* address error */
335 ksi.ksi_addr = (void *)v;
336 ksi.ksi_signo = SIGBUS;
337 ksi.ksi_code = (type == (T_BUSERR|T_USER)) ?
338 BUS_OBJERR : BUS_ADRERR;
339 break;
340
341 case T_COPERR: /* kernel coprocessor violation */
342 case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */
343 case T_FMTERR: /* ...just in case... */
344 /*
345 * The user has most likely trashed the RTE or FP state info
346 * in the stack frame of a signal handler.
347 */
348 printf("pid %d: kernel %s exception\n", p->p_pid,
349 type==T_COPERR ? "coprocessor" : "format");
350 type |= T_USER;
351
352 mutex_enter(p->p_lock);
353 SIGACTION(p, SIGILL).sa_handler = SIG_DFL;
354 sigdelset(&p->p_sigctx.ps_sigignore, SIGILL);
355 sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL);
356 sigdelset(&l->l_sigmask, SIGILL);
357 mutex_exit(p->p_lock);
358
359 ksi.ksi_signo = SIGILL;
360 ksi.ksi_addr = (void *)(int)tf->tf_format;
361 ksi.ksi_code = (type == T_COPERR) ?
362 ILL_COPROC : ILL_ILLOPC;
363 break;
364
365 case T_COPERR|T_USER: /* user coprocessor violation */
366 /* What is a proper response here? */
367 ksi.ksi_signo = SIGFPE;
368 ksi.ksi_code = FPE_FLTINV;
369 break;
370
371 case T_FPERR|T_USER: /* 68881 exceptions */
372 /*
373 * We pass along the 68881 status register which locore stashed
374 * in code for us.
375 */
376 ksi.ksi_signo = SIGFPE;
377 ksi.ksi_code = fpsr2siginfocode(code);
378 break;
379
380 case T_FPEMULI: /* FPU faults in supervisor mode */
381 case T_FPEMULD:
382 if (nofault) /* Doing FPU probe? */
383 longjmp(nofault);
384 goto dopanic;
385
386 case T_FPEMULI|T_USER: /* unimplemented FP instruction */
387 case T_FPEMULD|T_USER: /* unimplemented FP data type */
388 #ifdef FPU_EMULATE
389 if (fpu_emulate(tf, &pcb->pcb_fpregs, &ksi) == 0)
390 ; /* XXX - Deal with tracing? (tf->tf_sr & PSL_T) */
391 #else
392 uprintf("pid %d killed: no floating point support\n", p->p_pid);
393 ksi.ksi_signo = SIGILL;
394 ksi.ksi_code = ILL_ILLOPC;
395 #endif
396 break;
397
398 case T_ILLINST|T_USER: /* illegal instruction fault */
399 case T_PRIVINST|T_USER: /* privileged instruction fault */
400 ksi.ksi_addr = (void *)(int)tf->tf_format;
401 ksi.ksi_signo = SIGILL;
402 ksi.ksi_code = (type == (T_PRIVINST|T_USER)) ?
403 ILL_PRVOPC : ILL_ILLOPC;
404 break;
405
406 case T_ZERODIV|T_USER: /* Integer divide by zero */
407 ksi.ksi_code = FPE_INTDIV;
408 case T_CHKINST|T_USER: /* CHK instruction trap */
409 case T_TRAPVINST|T_USER: /* TRAPV instruction trap */
410 ksi.ksi_addr = (void *)(int)tf->tf_format;
411 ksi.ksi_signo = SIGFPE;
412 break;
413
414 /*
415 * XXX: Trace traps are a nightmare.
416 *
417 * HP-UX uses trap #1 for breakpoints,
418 * NetBSD/m68k uses trap #2,
419 * SUN 3.x uses trap #15,
420 * DDB and KGDB uses trap #15 (for kernel breakpoints;
421 * handled elsewhere).
422 *
423 * NetBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
424 * SUN 3.x traps get passed through as T_TRAP15 and are not really
425 * supported yet.
426 *
427 * XXX: We should never get kernel-mode T_TRAP15
428 * XXX: because locore.s now gives them special treatment.
429 */
430 case T_TRAP15: /* kernel breakpoint */
431 tf->tf_sr &= ~PSL_T;
432 goto done;
433
434 case T_TRACE|T_USER: /* user trace trap */
435 #ifdef COMPAT_SUNOS
436 /*
437 * SunOS uses Trap #2 for a "CPU cache flush"
438 * Just flush the on-chip caches and return.
439 * XXX - Too bad NetBSD uses trap 2...
440 */
441 if (p->p_emul == &emul_sunos) {
442 ICIA();
443 DCIU();
444 /* get out fast */
445 goto done;
446 }
447 #endif
448 /* FALLTHROUGH */
449 case T_TRACE: /* tracing a trap instruction */
450 case T_TRAP15|T_USER: /* SUN user trace trap */
451 tf->tf_sr &= ~PSL_T;
452 ksi.ksi_addr = (void *)tf->tf_pc;
453 ksi.ksi_signo = SIGTRAP;
454 if (type == (T_TRAP15|T_USER))
455 ksi.ksi_code = TRAP_BRKPT;
456 else
457 ksi.ksi_code = TRAP_TRACE;
458 break;
459
460 case T_ASTFLT: /* system async trap, cannot happen */
461 goto dopanic;
462
463 case T_ASTFLT|T_USER: /* user async trap */
464 astpending = 0;
465 /* T_SSIR is not used on a Sun3. */
466 if (l->l_pflag & LP_OWEUPC) {
467 l->l_pflag &= ~LP_OWEUPC;
468 ADDUPROF(l);
469 }
470 goto douret;
471
472 case T_MMUFLT: /* kernel mode page fault */
473 /* Hacks to avoid calling VM code from debugger. */
474 #ifdef DDB
475 if (db_recover != 0)
476 goto dopanic;
477 #endif
478 #ifdef KGDB
479 if (kgdb_recover != 0)
480 goto dopanic;
481 #endif
482 /*FALLTHROUGH*/
483
484 case T_MMUFLT|T_USER: { /* page fault */
485 vaddr_t va;
486 struct vmspace *vm = p->p_vmspace;
487 struct vm_map *map;
488 vm_prot_t ftype;
489 extern struct vm_map *kernel_map;
490
491 #ifdef DEBUG
492 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
493 printf("trap: T_MMUFLT pid=%d, code=0x%x, v=0x%x, pc=0x%x, sr=0x%x\n",
494 p->p_pid, code, v, tf->tf_pc, tf->tf_sr);
495 #endif
496
497 /*
498 * It is only a kernel address space fault iff:
499 * 1. (type & T_USER) == 0 and: (2 or 3)
500 * 2. pcb_onfault not set or
501 * 3. pcb_onfault set but supervisor space data fault
502 * The last can occur during an exec() copyin where the
503 * argument space is lazy-allocated.
504 */
505 map = &vm->vm_map;
506 if ((type & T_USER) == 0) {
507 /* supervisor mode fault */
508 if (onfault == NULL || KDFAULT(code))
509 map = kernel_map;
510 }
511
512 if (WRFAULT(code))
513 ftype = VM_PROT_WRITE;
514 else
515 ftype = VM_PROT_READ;
516 va = m68k_trunc_page((vaddr_t)v);
517
518 /*
519 * Need to resolve the fault.
520 *
521 * We give the pmap code a chance to resolve faults by
522 * reloading translations that it was forced to unload.
523 * This function does that, and calls vm_fault if it
524 * could not resolve the fault by reloading the MMU.
525 * This function may also, for example, disallow any
526 * faults in the kernel text segment, etc.
527 */
528
529 pcb->pcb_onfault = NULL;
530 rv = _pmap_fault(map, va, ftype);
531 pcb->pcb_onfault = onfault;
532
533 #ifdef DEBUG
534 if (rv && MDB_ISPID(p->p_pid)) {
535 printf("vm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n",
536 map, va, ftype, rv);
537 if (mmudebug & MDB_WBFAILED)
538 Debugger();
539 }
540 #endif /* DEBUG */
541
542 /*
543 * If this was a stack access we keep track of the maximum
544 * accessed stack size. Also, if vm_fault gets a protection
545 * failure it is due to accessing the stack region outside
546 * the current limit and we need to reflect that as an access
547 * error.
548 */
549 if (rv == 0) {
550 if (map != kernel_map && (void *)va >= vm->vm_maxsaddr)
551 uvm_grow(p, va);
552
553 goto finish;
554 }
555 if (rv == EACCES) {
556 ksi.ksi_code = SEGV_ACCERR;
557 rv = EFAULT;
558 } else
559 ksi.ksi_code = SEGV_MAPERR;
560 if ((type & T_USER) == 0) {
561 /* supervisor mode fault */
562 if (onfault) {
563 #ifdef DEBUG
564 if (mmudebug & MDB_CPFAULT) {
565 printf("trap: copyfault pcb_onfault\n");
566 Debugger();
567 }
568 #endif
569 goto copyfault;
570 }
571 printf("vm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n",
572 map, va, ftype, rv);
573 goto dopanic;
574 }
575 ksi.ksi_addr = (void *)v;
576 switch (rv) {
577 case ENOMEM:
578 printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
579 p->p_pid, p->p_comm,
580 l->l_cred ?
581 kauth_cred_geteuid(l->l_cred) : -1);
582 ksi.ksi_signo = SIGKILL;
583 break;
584 case EINVAL:
585 ksi.ksi_signo = SIGBUS;
586 ksi.ksi_code = BUS_ADRERR;
587 break;
588 case EACCES:
589 ksi.ksi_signo = SIGSEGV;
590 ksi.ksi_code = SEGV_ACCERR;
591 break;
592 default:
593 ksi.ksi_signo = SIGSEGV;
594 ksi.ksi_code = SEGV_MAPERR;
595 break;
596 }
597 break;
598 } /* T_MMUFLT */
599 } /* switch */
600
601 finish:
602 /* If trap was from supervisor mode, just return. */
603 if ((type & T_USER) == 0)
604 goto done;
605 /* Post a signal if necessary. */
606 if (ksi.ksi_signo)
607 trapsignal(l, &ksi);
608 douret:
609 userret(l, tf, sticks);
610
611 done:;
612 /* XXX: Detect trap recursion? */
613 }
614
615 /*
616 * This is used if we hit a kernel breakpoint or trace trap
617 * when there is no debugger installed (or not attached).
618 * Drop into the PROM temporarily...
619 */
620 int
_nodb_trap(int type,struct trapframe * tf)621 _nodb_trap(int type, struct trapframe *tf)
622 {
623
624 printf("\r\nKernel ");
625 if ((0 <= type) && (type < trap_types))
626 printf("%s", trap_type[type]);
627 else
628 printf("trap 0x%x", type);
629 printf(", frame=%p\r\n", tf);
630 printf("No debugger; doing PROM abort.\r\n");
631 printf("To continue, type: c <RETURN>\r\n");
632 sunmon_abort();
633 /* OK then, just resume... */
634 tf->tf_sr &= ~PSL_T;
635 return(1);
636 }
637
638 /*
639 * This is called by locore for supervisor-mode trace and
640 * breakpoint traps. This is separate from trap() above
641 * so that breakpoints in trap() will work.
642 *
643 * If we have both DDB and KGDB, let KGDB see it first,
644 * because KGDB will just return 0 if not connected.
645 */
646 void
trap_kdebug(int type,struct trapframe tf)647 trap_kdebug(int type, struct trapframe tf)
648 {
649
650 #ifdef KGDB
651 /* Let KGDB handle it (if connected) */
652 if (kgdb_trap(type, &tf))
653 return;
654 #endif
655 #ifdef DDB
656 /* Let DDB handle it. */
657 if (kdb_trap(type, &tf))
658 return;
659 #endif
660
661 /* Drop into the PROM temporarily... */
662 (void)_nodb_trap(type, &tf);
663 }
664
665 /*
666 * Called by locore.s for an unexpected interrupt.
667 * XXX - Almost identical to trap_kdebug...
668 */
669 void
straytrap(struct trapframe tf)670 straytrap(struct trapframe tf)
671 {
672 int type = -1;
673
674 printf("unexpected trap; vector=0x%x at pc=0x%x\n",
675 tf.tf_vector, tf.tf_pc);
676
677 #ifdef KGDB
678 /* Let KGDB handle it (if connected) */
679 if (kgdb_trap(type, &tf))
680 return;
681 #endif
682 #ifdef DDB
683 /* Let DDB handle it. */
684 if (kdb_trap(type, &tf))
685 return;
686 #endif
687
688 /* Drop into the PROM temporarily... */
689 (void)_nodb_trap(type, &tf);
690 }
691