1 /* $NetBSD: trap.c,v 1.49 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.49 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 <machine/promlib.h>
115
116 #include <sun2/sun2/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 /* These are called from locore.s */
133 void trap(struct trapframe *, int type, u_int code, u_int v);
134 void trap_kdebug(int type, struct trapframe tf);
135 int _nodb_trap(int type, struct trapframe *);
136 void straytrap(struct trapframe);
137
138 static void userret(struct lwp *, struct trapframe *, u_quad_t);
139
140 volatile int astpending;
141
142 const char *trap_type[] = {
143 "Bus error",
144 "Address error",
145 "Illegal instruction",
146 "Zero divide",
147 "CHK instruction",
148 "TRAPV instruction",
149 "Privilege violation",
150 "Trace trap",
151 "MMU fault",
152 "SSIR trap",
153 "Format error",
154 "68881 exception",
155 "Coprocessor violation",
156 "Async system trap",
157 "Unused? (14)",
158 "Breakpoint",
159 "FPU instruction",
160 "FPU data format",
161 };
162 u_int trap_types = sizeof(trap_type) / sizeof(trap_type[0]);
163
164 /*
165 * Size of various exception stack frames (minus the standard 8 bytes)
166 */
167 short exframesize[] = {
168 FMT0SIZE, /* type 0 - normal (68020/030/040/060) */
169 FMT1SIZE, /* type 1 - throwaway (68020/030/040) */
170 FMT2SIZE, /* type 2 - normal 6-word (68020/030/040/060) */
171 FMT3SIZE, /* type 3 - FP post-instruction (68040/060) */
172 FMT4SIZE, /* type 4 - access error/fp disabled (68060) */
173 -1, -1, /* type 5-6 - undefined */
174 FMT7SIZE, /* type 7 - access error (68040) */
175 FMT8SIZE, /* type 8 - bus fault (68010) */
176 FMT9SIZE, /* type 9 - coprocessor mid-instruction (68020/030) */
177 FMTASIZE, /* type A - short bus fault (68020/030) */
178 FMTBSIZE, /* type B - long bus fault (68020/030) */
179 -1, -1, -1, -1 /* type C-F - undefined */
180 };
181
182 #define KDFAULT(c) (((c) & (SSW1_IF|SSW1_FCMASK)) == (FC_SUPERD))
183 #define WRFAULT(c) (((c) & (SSW1_IF|SSW1_DF|SSW1_RW)) == (0))
184
185 /* #define DEBUG XXX */
186
187 #ifdef DEBUG
188 unsigned short buserr_reg;
189 int mmudebug = 0;
190 int mmupid = -1;
191 #define MDB_ISPID(p) ((p) == mmupid)
192 #define MDB_FOLLOW 1
193 #define MDB_WBFOLLOW 2
194 #define MDB_WBFAILED 4
195 #define MDB_CPFAULT 8
196 #endif
197
198 /*
199 * trap and syscall both need the following work done before
200 * returning to user mode.
201 */
202 static void
userret(struct lwp * l,struct trapframe * tf,u_quad_t oticks)203 userret(struct lwp *l, struct trapframe *tf, u_quad_t oticks)
204 {
205 struct proc *p = l->l_proc;
206
207 /* Invoke MI userret code */
208 mi_userret(l);
209
210 /*
211 * If profiling, charge system time to the trapped pc.
212 */
213 if (p->p_stflag & PST_PROFIL) {
214 extern int psratio;
215 addupc_task(l, tf->tf_pc,
216 (int)(p->p_sticks - oticks) * psratio);
217 }
218 }
219
220 /*
221 * Used by the common m68k syscall() and child_return() functions.
222 * XXX: Temporary until all m68k ports share common trap()/userret() code.
223 */
224 void machine_userret(struct lwp *, struct frame *, u_quad_t);
225
226 void
machine_userret(struct lwp * l,struct frame * f,u_quad_t t)227 machine_userret(struct lwp *l, struct frame *f, u_quad_t t)
228 {
229
230 userret(l, &f->F_t, t);
231 }
232
233 /*
234 * Trap is called from locore to handle most types of processor traps,
235 * including events such as simulated software interrupts/AST's.
236 * System calls are broken out for efficiency.
237 */
238 /*ARGSUSED*/
239 void
trap(struct trapframe * tf,int type,u_int code,u_int v)240 trap(struct trapframe *tf, int type, u_int code, u_int v)
241 {
242 struct lwp *l;
243 struct proc *p;
244 struct pcb *pcb;
245 ksiginfo_t ksi;
246 int tmp;
247 int rv;
248 u_quad_t sticks;
249 void *onfault;
250
251 curcpu()->ci_data.cpu_ntrap++;
252 l = curlwp;
253 p = l->l_proc;
254 pcb = lwp_getpcb(l);
255 onfault = pcb->pcb_onfault;
256
257 KSI_INIT_TRAP(&ksi);
258 ksi.ksi_trap = type & ~T_USER;
259
260 KASSERT(pcb != NULL);
261
262 if (USERMODE(tf->tf_sr)) {
263 type |= T_USER;
264 sticks = p->p_sticks;
265 l->l_md.md_regs = tf->tf_regs;
266 } else {
267 sticks = 0;
268 /* XXX: Detect trap recursion? */
269 }
270
271 switch (type) {
272 default:
273 dopanic:
274 printf("trap type=0x%x, code=0x%x, v=0x%x\n", type, code, v);
275 /*
276 * Let the kernel debugger see the trap frame that
277 * caused us to panic. This is a convenience so
278 * one can see registers at the point of failure.
279 */
280 tmp = splhigh();
281 #ifdef KGDB
282 /* If connected, step or cont returns 1 */
283 if (kgdb_trap(type, tf))
284 goto kgdb_cont;
285 #endif
286 #ifdef DDB
287 (void) kdb_trap(type, (db_regs_t *) tf);
288 #endif
289 #ifdef KGDB
290 kgdb_cont:
291 #endif
292 splx(tmp);
293 if (panicstr) {
294 /*
295 * Note: panic is smart enough to do:
296 * boot(RB_AUTOBOOT | RB_NOSYNC, NULL)
297 * if we call it again.
298 */
299 panic("trap during panic!");
300 }
301 regdump(tf, 128);
302 type &= ~T_USER;
303 if ((u_int)type < trap_types)
304 panic(trap_type[type]);
305 panic("trap type 0x%x", type);
306
307 case T_BUSERR: /* kernel bus error */
308 if (onfault == NULL)
309 goto dopanic;
310 rv = EFAULT;
311 /*FALLTHROUGH*/
312
313 copyfault:
314 /*
315 * If we have arranged to catch this fault in any of the
316 * copy to/from user space routines, set PC to return to
317 * indicated location and set flag informing buserror code
318 * that it may need to clean up stack frame.
319 */
320 tf->tf_stackadj = exframesize[tf->tf_format];
321 tf->tf_format = tf->tf_vector = 0;
322 tf->tf_pc = (int)onfault;
323 tf->tf_regs[D0] = rv;
324 goto done;
325
326 case T_BUSERR|T_USER: /* bus error */
327 case T_ADDRERR|T_USER: /* address error */
328 ksi.ksi_addr = (void *)v;
329 ksi.ksi_signo = SIGBUS;
330 ksi.ksi_code = (type == (T_BUSERR|T_USER)) ?
331 BUS_OBJERR : BUS_ADRERR;
332 break;
333
334 case T_COPERR: /* kernel coprocessor violation */
335 case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */
336 case T_FMTERR: /* ...just in case... */
337 /*
338 * The user has most likely trashed the RTE or FP state info
339 * in the stack frame of a signal handler.
340 */
341 printf("pid %d: kernel %s exception\n", p->p_pid,
342 type==T_COPERR ? "coprocessor" : "format");
343 type |= T_USER;
344
345 mutex_enter(p->p_lock);
346 SIGACTION(p, SIGILL).sa_handler = SIG_DFL;
347 sigdelset(&p->p_sigctx.ps_sigignore, SIGILL);
348 sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL);
349 sigdelset(&l->l_sigmask, SIGILL);
350 mutex_exit(p->p_lock);
351
352 ksi.ksi_signo = SIGILL;
353 ksi.ksi_addr = (void *)(int)tf->tf_format;
354 ksi.ksi_code = (type == T_COPERR) ?
355 ILL_COPROC : ILL_ILLOPC;
356 break;
357
358 case T_COPERR|T_USER: /* user coprocessor violation */
359 /* What is a proper response here? */
360 ksi.ksi_signo = SIGFPE;
361 ksi.ksi_code = FPE_FLTINV;
362 break;
363
364 case T_FPERR|T_USER: /* 68881 exceptions */
365 /*
366 * We pass along the 68881 status register which locore stashed
367 * in code for us.
368 */
369 ksi.ksi_signo = SIGFPE;
370 ksi.ksi_code = fpsr2siginfocode(code);
371 break;
372
373 case T_FPEMULI: /* FPU faults in supervisor mode */
374 case T_FPEMULD:
375 if (nofault) /* Doing FPU probe? */
376 longjmp(nofault);
377 goto dopanic;
378
379 case T_FPEMULI|T_USER: /* unimplemented FP instruction */
380 case T_FPEMULD|T_USER: /* unimplemented FP data type */
381 #ifdef FPU_EMULATE
382 if (fpu_emulate(tf, &pcb->pcb_fpregs, &ksi) == 0)
383 ; /* XXX - Deal with tracing? (tf->tf_sr & PSL_T) */
384 #else
385 uprintf("pid %d killed: no floating point support\n", p->p_pid);
386 ksi.ksi_signo = SIGILL;
387 ksi.ksi_code = ILL_ILLOPC;
388 #endif
389 break;
390
391 case T_ILLINST|T_USER: /* illegal instruction fault */
392 case T_PRIVINST|T_USER: /* privileged instruction fault */
393 ksi.ksi_addr = (void *)(int)tf->tf_format;
394 ksi.ksi_signo = SIGILL;
395 ksi.ksi_code = (type == (T_PRIVINST|T_USER)) ?
396 ILL_PRVOPC : ILL_ILLOPC;
397 break;
398
399 case T_ZERODIV|T_USER: /* Divide by zero */
400 ksi.ksi_code = FPE_FLTDIV;
401 case T_CHKINST|T_USER: /* CHK instruction trap */
402 case T_TRAPVINST|T_USER: /* TRAPV instruction trap */
403 ksi.ksi_addr = (void *)(int)tf->tf_format;
404 ksi.ksi_signo = SIGFPE;
405 break;
406
407 /*
408 * XXX: Trace traps are a nightmare.
409 *
410 * HP-UX uses trap #1 for breakpoints,
411 * NetBSD/m68k uses trap #2,
412 * SUN 3.x uses trap #15,
413 * DDB and KGDB uses trap #15 (for kernel breakpoints;
414 * handled elsewhere).
415 *
416 * NetBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
417 * SUN 3.x traps get passed through as T_TRAP15 and are not really
418 * supported yet.
419 *
420 * XXX: We should never get kernel-mode T_TRAP15
421 * XXX: because locore.s now gives them special treatment.
422 */
423 case T_TRAP15: /* kernel breakpoint */
424 tf->tf_sr &= ~PSL_T;
425 goto done;
426
427 case T_TRACE|T_USER: /* user trace trap */
428 #ifdef COMPAT_SUNOS
429 /*
430 * SunOS uses Trap #2 for a "CPU cache flush"
431 * Just flush the on-chip caches and return.
432 * XXX - Too bad NetBSD uses trap 2...
433 */
434 if (p->p_emul == &emul_sunos) {
435 /* get out fast */
436 goto done;
437 }
438 #endif
439 /* FALLTHROUGH */
440 case T_TRACE: /* tracing a trap instruction */
441 case T_TRAP15|T_USER: /* SUN user trace trap */
442 tf->tf_sr &= ~PSL_T;
443 ksi.ksi_signo = SIGTRAP;
444 break;
445
446 case T_ASTFLT: /* system async trap, cannot happen */
447 goto dopanic;
448
449 case T_ASTFLT|T_USER: /* user async trap */
450 astpending = 0;
451 /* T_SSIR is not used on a Sun2. */
452 if (l->l_pflag & LP_OWEUPC) {
453 l->l_pflag &= ~LP_OWEUPC;
454 ADDUPROF(l);
455 }
456 goto douret;
457
458 case T_MMUFLT: /* kernel mode page fault */
459 /* Hacks to avoid calling VM code from debugger. */
460 #ifdef DDB
461 if (db_recover != 0)
462 goto dopanic;
463 #endif
464 #ifdef KGDB
465 if (kgdb_recover != 0)
466 goto dopanic;
467 #endif
468 /*FALLTHROUGH*/
469
470 case T_MMUFLT|T_USER: { /* page fault */
471 vaddr_t va;
472 struct vmspace *vm = p->p_vmspace;
473 struct vm_map *map;
474 vm_prot_t ftype;
475 extern struct vm_map *kernel_map;
476
477 #ifdef DEBUG
478 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
479 printf("trap: T_MMUFLT pid=%d, code=0x%x, v=0x%x, pc=0x%x, sr=0x%x\n",
480 p->p_pid, code, v, tf->tf_pc, tf->tf_sr);
481 #endif
482
483 /*
484 * It is only a kernel address space fault iff:
485 * 1. (type & T_USER) == 0 and: (2 or 3)
486 * 2. pcb_onfault not set or
487 * 3. pcb_onfault set but supervisor space data fault
488 * The last can occur during an exec() copyin where the
489 * argument space is lazy-allocated.
490 */
491 map = &vm->vm_map;
492 if ((type & T_USER) == 0) {
493 /* supervisor mode fault */
494 if (onfault == NULL || KDFAULT(code))
495 map = kernel_map;
496 }
497
498 if (WRFAULT(code))
499 ftype = VM_PROT_WRITE;
500 else
501 ftype = VM_PROT_READ;
502 va = m68k_trunc_page((vaddr_t)v);
503
504 /*
505 * Need to resolve the fault.
506 *
507 * We give the pmap code a chance to resolve faults by
508 * reloading translations that it was forced to unload.
509 * This function does that, and calls vm_fault if it
510 * could not resolve the fault by reloading the MMU.
511 * This function may also, for example, disallow any
512 * faults in the kernel text segment, etc.
513 */
514 pcb->pcb_onfault = NULL;
515 rv = _pmap_fault(map, va, ftype);
516 pcb->pcb_onfault = onfault;
517
518 #ifdef DEBUG
519 if (rv && MDB_ISPID(p->p_pid)) {
520 printf("vm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n",
521 map, va, ftype, rv);
522 if (mmudebug & MDB_WBFAILED)
523 Debugger();
524 }
525 #endif /* DEBUG */
526
527 /*
528 * If this was a stack access we keep track of the maximum
529 * accessed stack size. Also, if vm_fault gets a protection
530 * failure it is due to accessing the stack region outside
531 * the current limit and we need to reflect that as an access
532 * error.
533 */
534 if (rv == 0) {
535 if (map != kernel_map && (void *)va >= vm->vm_maxsaddr)
536 uvm_grow(p, va);
537
538 goto finish;
539 }
540 if (rv == EACCES) {
541 ksi.ksi_code = SEGV_ACCERR;
542 rv = EFAULT;
543 } else
544 ksi.ksi_code = SEGV_MAPERR;
545 if ((type & T_USER) == 0) {
546 /* supervisor mode fault */
547 if (onfault) {
548 #ifdef DEBUG
549 if (mmudebug & MDB_CPFAULT) {
550 printf("trap: copyfault pcb_onfault\n");
551 Debugger();
552 }
553 #endif
554 goto copyfault;
555 }
556 printf("vm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n",
557 map, va, ftype, rv);
558 goto dopanic;
559 }
560 ksi.ksi_addr = (void *)v;
561 switch (rv) {
562 case ENOMEM:
563 printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
564 p->p_pid, p->p_comm,
565 l->l_cred ?
566 kauth_cred_geteuid(l->l_cred) : -1);
567 ksi.ksi_signo = SIGKILL;
568 break;
569 case EINVAL:
570 ksi.ksi_signo = SIGBUS;
571 ksi.ksi_code = BUS_ADRERR;
572 break;
573 case EACCES:
574 ksi.ksi_signo = SIGSEGV;
575 ksi.ksi_code = SEGV_ACCERR;
576 break;
577 default:
578 ksi.ksi_signo = SIGSEGV;
579 ksi.ksi_code = SEGV_MAPERR;
580 break;
581 }
582 break;
583 } /* T_MMUFLT */
584 } /* switch */
585
586 finish:
587 /* If trap was from supervisor mode, just return. */
588 if ((type & T_USER) == 0)
589 goto done;
590 /* Post a signal if necessary. */
591 if (ksi.ksi_signo)
592 trapsignal(l, &ksi);
593 douret:
594 userret(l, tf, sticks);
595
596 done:;
597 /* XXX: Detect trap recursion? */
598 }
599
600 /*
601 * This is used if we hit a kernel breakpoint or trace trap
602 * when there is no debugger installed (or not attached).
603 * Drop into the PROM temporarily...
604 */
605 int
_nodb_trap(int type,struct trapframe * tf)606 _nodb_trap(int type, struct trapframe *tf)
607 {
608
609 printf("\r\nKernel ");
610 if ((0 <= type) && (type < trap_types))
611 printf("%s", trap_type[type]);
612 else
613 printf("trap 0x%x", type);
614 printf(", frame=%p\r\n", tf);
615 printf("No debugger; doing PROM abort.\r\n");
616 printf("To continue, type: c <RETURN>\r\n");
617 prom_abort();
618 /* OK then, just resume... */
619 tf->tf_sr &= ~PSL_T;
620 return(1);
621 }
622
623 /*
624 * This is called by locore for supervisor-mode trace and
625 * breakpoint traps. This is separate from trap() above
626 * so that breakpoints in trap() will work.
627 *
628 * If we have both DDB and KGDB, let KGDB see it first,
629 * because KGDB will just return 0 if not connected.
630 */
631 void
trap_kdebug(int type,struct trapframe tf)632 trap_kdebug(int type, struct trapframe tf)
633 {
634
635 #ifdef KGDB
636 /* Let KGDB handle it (if connected) */
637 if (kgdb_trap(type, &tf))
638 return;
639 #endif
640 #ifdef DDB
641 /* Let DDB handle it. */
642 if (kdb_trap(type, &tf))
643 return;
644 #endif
645
646 /* Drop into the PROM temporarily... */
647 (void)_nodb_trap(type, &tf);
648 }
649
650 /*
651 * Called by locore.s for an unexpected interrupt.
652 * XXX - Almost identical to trap_kdebug...
653 */
654 void
straytrap(struct trapframe tf)655 straytrap(struct trapframe tf)
656 {
657 int type = -1;
658
659 printf("unexpected trap; vector=0x%x at pc=0x%x\n",
660 tf.tf_vector, tf.tf_pc);
661
662 #ifdef KGDB
663 /* Let KGDB handle it (if connected) */
664 if (kgdb_trap(type, &tf))
665 return;
666 #endif
667 #ifdef DDB
668 /* Let DDB handle it. */
669 if (kdb_trap(type, &tf))
670 return;
671 #endif
672
673 /* Drop into the PROM temporarily... */
674 (void)_nodb_trap(type, &tf);
675 }
676