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