[BACK]Return to trap.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / mips / mips

Annotation of src/sys/arch/mips/mips/trap.c, Revision 1.100

1.100   ! nisimura    1: /*     $NetBSD: trap.c,v 1.99 1999/01/15 01:23:15 castor Exp $ */
1.8       cgd         2:
1.1       deraadt     3: /*
                      4:  * Copyright (c) 1988 University of Utah.
1.3       glass       5:  * Copyright (c) 1992, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
1.1       deraadt     7:  *
                      8:  * This code is derived from software contributed to Berkeley by
                      9:  * the Systems Programming Group of the University of Utah Computer
                     10:  * Science Department and Ralph Campbell.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *     This product includes software developed by the University of
                     23:  *     California, Berkeley and its contributors.
                     24:  * 4. Neither the name of the University nor the names of its contributors
                     25:  *    may be used to endorse or promote products derived from this software
                     26:  *    without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     29:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     30:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     31:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     32:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     33:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     34:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     35:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     36:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     37:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     38:  * SUCH DAMAGE.
                     39:  *
                     40:  * from: Utah Hdr: trap.c 1.32 91/04/06
1.3       glass      41:  *
1.8       cgd        42:  *     @(#)trap.c      8.5 (Berkeley) 1/11/94
1.1       deraadt    43:  */
                     44:
1.78      jonathan   45: #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
1.100   ! nisimura   46: __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.99 1999/01/15 01:23:15 castor Exp $");
1.82      thorpej    47:
1.85      jonathan   48: #include "opt_cputype.h"       /* which mips CPU levels do we support? */
1.86      jonathan   49: #include "opt_inet.h"
                     50: #include "opt_atalk.h"
1.87      jonathan   51: #include "opt_ccitt.h"
                     52: #include "opt_iso.h"
1.88      jonathan   53: #include "opt_ns.h"
1.89      jonathan   54: #include "opt_natm.h"
1.84      thorpej    55: #include "opt_ktrace.h"
1.82      thorpej    56: #include "opt_uvm.h"
1.85      jonathan   57: #include "opt_ddb.h"
1.78      jonathan   58:
1.43      jonathan   59: #if !defined(MIPS1) && !defined(MIPS3)
1.57      mhitch     60: #error  Neither  "MIPS1" (r2000 family), "MIPS3" (r4000 family) was configured.
1.37      jonathan   61: #endif
                     62:
1.1       deraadt    63: #include <sys/param.h>
                     64: #include <sys/systm.h>
1.23      jonathan   65: #include <sys/device.h>
1.1       deraadt    66: #include <sys/proc.h>
                     67: #include <sys/kernel.h>
                     68: #include <sys/signalvar.h>
                     69: #include <sys/syscall.h>
                     70: #include <sys/user.h>
                     71: #include <sys/buf.h>
1.99      castor     72: #include <sys/reboot.h>
1.1       deraadt    73: #ifdef KTRACE
                     74: #include <sys/ktrace.h>
                     75: #endif
1.46      jonathan   76:
1.58      jonathan   77: #include <mips/locore.h>
                     78: #include <mips/mips_opcode.h>
                     79:
1.78      jonathan   80: #include <vm/vm.h>
                     81: #include <vm/vm_kern.h>
                     82: #include <vm/vm_page.h>
                     83:
1.82      thorpej    84: #if defined(UVM)
                     85: #include <uvm/uvm_extern.h>
                     86: #endif
                     87:
1.70      jonathan   88: #include <machine/cpu.h>
                     89: #include <mips/trap.h>
1.1       deraadt    90: #include <machine/psl.h>
1.70      jonathan   91: #include <mips/reg.h>
                     92: #include <mips/regnum.h>                       /* symbolic register indices */
                     93: #include <mips/pte.h>
1.1       deraadt    94:
1.16      jonathan   95: #include <sys/cdefs.h>
                     96: #include <sys/syslog.h>
1.37      jonathan   97: #include <miscfs/procfs/procfs.h>
                     98:
1.69      jonathan   99: #ifdef DDB
                    100: #include <mips/db_machdep.h>
1.77      mhitch    101: #include <ddb/db_sym.h>
1.69      jonathan  102: #endif
                    103:
1.37      jonathan  104: /* all this to get prototypes for ipintr() and arpintr() */
                    105: #include <sys/socket.h>
                    106: #include <net/if.h>
                    107: #include <netinet/in.h>
1.51      is        108: #include <netinet/if_inarp.h>
1.37      jonathan  109: #include <netinet/ip_var.h>
1.39      mhitch    110:
                    111: #include "ppp.h"
1.16      jonathan  112:
1.53      jonathan  113: #if NPPP > 0
                    114: #include <net/ppp_defs.h>              /* decls of struct pppstat for..  */
                    115: #include <net/if_pppvar.h>             /* decl of enum for... */
                    116: #include <net/if_ppp.h>                        /* pppintr() prototype */
                    117: #endif
                    118:
1.71      jonathan  119:
1.33      jonathan  120: /*
                    121:  * Port-specific hardware interrupt handler
                    122:  */
1.23      jonathan  123:
1.92      jonathan  124: int astpending;
                    125: int want_resched;
                    126:
1.99      castor    127: int  (*mips_hardware_intr) __P((unsigned, unsigned, unsigned, unsigned)) = 0;
                    128: void (*mips_software_intr) __P((int)) = 0;
                    129: int  softisr;  /* for extensible software interrupt framework */
1.1       deraadt   130:
1.92      jonathan  131: #if defined(MIPS3) && defined(MIPS3_INTERNAL_TIMER_INTERRUPT)
1.85      jonathan  132: u_int32_t mips3_intr_cycle_count;
1.92      jonathan  133: u_int32_t mips3_timer_delta;
1.85      jonathan  134: #endif
                    135:
1.99      castor    136: const char *trap_type[] = {
1.1       deraadt   137:        "external interrupt",
                    138:        "TLB modification",
                    139:        "TLB miss (load or instr. fetch)",
                    140:        "TLB miss (store)",
                    141:        "address error (load or I-fetch)",
                    142:        "address error (store)",
                    143:        "bus error (I-fetch)",
                    144:        "bus error (load or store)",
                    145:        "system call",
                    146:        "breakpoint",
                    147:        "reserved instruction",
                    148:        "coprocessor unusable",
                    149:        "arithmetic overflow",
1.32      jonathan  150:        "r4k trap/r3k reserved 13",
                    151:        "r4k virtual coherency instruction/r3k reserved 14",
                    152:        "r4k floating point/ r3k reserved 15",
                    153:        "reserved 16",
                    154:        "reserved 17",
                    155:        "reserved 18",
                    156:        "reserved 19",
                    157:        "reserved 20",
                    158:        "reserved 21",
                    159:        "reserved 22",
1.46      jonathan  160:        "r4000 watch",
1.32      jonathan  161:        "reserved 24",
                    162:        "reserved 25",
                    163:        "reserved 26",
                    164:        "reserved 27",
                    165:        "reserved 28",
                    166:        "reserved 29",
                    167:        "reserved 30",
1.46      jonathan  168:        "r4000 virtual coherency data",
1.1       deraadt   169: };
                    170:
1.99      castor    171: struct trapframe {
                    172:        mips_reg_t tf_regs[17];
                    173:        mips_reg_t tf_ra;
                    174:        mips_reg_t tf_sr;
                    175:        mips_reg_t tf_mullo;
                    176:        mips_reg_t tf_mulhi;
                    177:        mips_reg_t tf_epc;
                    178: };
                    179:
                    180: void userret __P((struct proc *, unsigned, u_quad_t));
                    181: void trap __P((unsigned, unsigned, unsigned, unsigned, struct trapframe *));
                    182: void syscall __P((unsigned, unsigned, unsigned));
                    183: void interrupt __P((unsigned, unsigned, unsigned));
                    184: void ast __P((unsigned));
                    185: void dealfpu __P((unsigned, unsigned, unsigned));
                    186:
                    187: extern void MachEmulateFP __P((unsigned));
                    188: extern void MachFPInterrupt __P((unsigned, unsigned, unsigned, mips_reg_t *));
1.66      mhitch    189:
1.33      jonathan  190: /*
                    191:  * Other forward declarations.
                    192:  */
1.98      nisimura  193: vaddr_t MachEmulateBranch __P((struct frame *, vaddr_t, unsigned, int));
1.16      jonathan  194:
1.99      castor    195: void
1.57      mhitch    196: userret(p, pc, sticks)
                    197:        struct proc *p;
                    198:        unsigned pc;
                    199:        u_quad_t sticks;
                    200: {
                    201:        int sig;
                    202:
                    203:        /* take pending signals */
                    204:        while ((sig = CURSIG(p)) != 0)
                    205:                postsig(sig);
                    206:        p->p_priority = p->p_usrpri;
                    207:        if (want_resched) {
                    208:                int s;
                    209:                /*
                    210:                 * Since we are curproc, a clock interrupt could
                    211:                 * change our priority without changing run queues
                    212:                 * (the running process is not kept on a run queue).
                    213:                 * If this happened after we setrunqueue ourselves but
                    214:                 * before we switch()'ed, we might not be on the queue
                    215:                 * indicated by our priority.
                    216:                 */
                    217:                s = splstatclock();
                    218:                setrunqueue(p);
                    219:                p->p_stats->p_ru.ru_nivcsw++;
                    220:                mi_switch();
                    221:                splx(s);
                    222:                while ((sig = CURSIG(p)) != 0)
                    223:                        postsig(sig);
                    224:        }
                    225:        /*
                    226:         * If profiling, charge system time to the trapped pc.
                    227:         */
                    228:        if (p->p_flag & P_PROFIL) {
                    229:                extern int psratio;
                    230:
                    231:                addupc_task(p, pc, (int)(p->p_sticks - sticks) * psratio);
                    232:        }
                    233:        curpriority = p->p_priority;
                    234: }
1.1       deraadt   235:
1.63      mhitch    236: #define DELAYBRANCH(x) ((int)(x)<0)
1.1       deraadt   237: /*
1.57      mhitch    238:  * Process a system call.
                    239:  *
                    240:  * System calls are strange beasts.  They are passed the syscall number
                    241:  * in v0, and the arguments in the registers (as normal).  They return
                    242:  * an error flag in a3 (if a3 != 0 on return, the syscall had an error),
                    243:  * and the return value (if any) in v0 and possibly v1.
                    244:  */
                    245: void
1.99      castor    246: syscall(status, cause, opc)
                    247:        unsigned status;
                    248:        unsigned cause;
                    249:        unsigned opc;
1.1       deraadt   250: {
1.57      mhitch    251:        struct proc *p = curproc;
1.99      castor    252:        struct frame *frame = (struct frame *)p->p_md.md_regs;
1.1       deraadt   253:        u_quad_t sticks;
1.57      mhitch    254:        int args[8], rval[2], error;
                    255:        size_t code, numsys, nsaved, argsiz;
                    256:        struct sysent *callp;
                    257:
1.82      thorpej   258: #if defined(UVM)
                    259:        uvmexp.syscalls++;
                    260: #else
1.57      mhitch    261:        cnt.v_syscall++;
1.82      thorpej   262: #endif
1.76      jonathan  263:
                    264:        if (status & ((CPUISMIPS3) ? MIPS_SR_INT_IE : MIPS1_SR_INT_ENA_PREV))
                    265:                splx(MIPS_SR_INT_IE | (status & MIPS_HARD_INT_MASK));
1.57      mhitch    266:
                    267:        sticks = p->p_sticks;
                    268:        if (DELAYBRANCH(cause))
1.98      nisimura  269:                frame->f_regs[PC] = MachEmulateBranch(frame, opc, 0, 0);
1.57      mhitch    270:        else
                    271:                frame->f_regs[PC] = opc + sizeof(int);
                    272:        callp = p->p_emul->e_sysent;
                    273:        numsys = p->p_emul->e_nsysent;
                    274:        code = frame->f_regs[V0];
                    275:        switch (code) {
                    276:        case SYS_syscall:
                    277:                /*
                    278:                 * Code is first argument, followed by actual args.
                    279:                 */
                    280:                code = frame->f_regs[A0];
                    281:                args[0] = frame->f_regs[A1];
                    282:                args[1] = frame->f_regs[A2];
                    283:                args[2] = frame->f_regs[A3];
                    284:                nsaved = 3;
                    285:                break;
                    286:        case SYS___syscall:
                    287:                /*
                    288:                 * Like syscall, but code is a quad, so as to maintain
                    289:                 * quad alignment for the rest of the arguments.
                    290:                 */
                    291:                code = frame->f_regs[A0 + _QUAD_LOWWORD];
                    292:                args[0] = frame->f_regs[A2];
                    293:                args[1] = frame->f_regs[A3];
                    294:                nsaved = 2;
                    295:                break;
                    296:        default:
                    297:                args[0] = frame->f_regs[A0];
                    298:                args[1] = frame->f_regs[A1];
                    299:                args[2] = frame->f_regs[A2];
                    300:                args[3] = frame->f_regs[A3];
                    301:                nsaved = 4;
                    302:                break;
                    303:        }
                    304:        if (code >= p->p_emul->e_nsysent)
                    305:                callp += p->p_emul->e_nosys;
                    306:        else
                    307:                callp += code;
                    308:        argsiz = callp->sy_argsize / sizeof(int);
                    309:        if (argsiz > nsaved) {
1.99      castor    310: #if 0
                    311:                error = copyin(
                    312:                        (void *)((int *)frame->f_regs[SP] + 4),
                    313:                        (void *)(args + nsaved),
                    314:                        (argsiz - nsaved) * sizeof(int));
                    315: #else
                    316:                int sp32;
                    317:                sp32 = frame->f_regs[SP];
1.57      mhitch    318:                error = copyin(
1.99      castor    319:                        (void *)((int *)sp32 + 4),
                    320:                        (void *)(args + nsaved),
1.57      mhitch    321:                        (argsiz - nsaved) * sizeof(int));
1.99      castor    322: #endif
1.57      mhitch    323:                if (error)
                    324:                        goto bad;
                    325:        }
                    326: #ifdef SYSCALL_DEBUG
                    327:        scdebug_call(p, code, args);
                    328: #endif
                    329: #ifdef KTRACE
                    330:        if (KTRPOINT(p, KTR_SYSCALL))
                    331:                ktrsyscall(p->p_tracep, code, callp->sy_argsize, args);
                    332: #endif
                    333:        rval[0] = 0;
                    334:        rval[1] = frame->f_regs[V1];
                    335: #ifdef DEBUG
                    336: /* XXX save code */
                    337: #endif
                    338:        error = (*callp->sy_call)(p, args, rval);
                    339:
                    340: #ifdef DEBUG
                    341: /* XXX save syscall result in trapdebug */
                    342: #endif
                    343:        switch (error) {
                    344:        case 0:
                    345:                frame->f_regs[V0] = rval[0];
                    346:                frame->f_regs[V1] = rval[1];
                    347:                frame->f_regs[A3] = 0;
                    348:                break;
                    349:        case ERESTART:
                    350:                frame->f_regs[PC] = opc;
                    351:                break;
                    352:        case EJUSTRETURN:
                    353:                break;  /* nothing to do */
                    354:        default:
                    355:        bad:
                    356:                frame->f_regs[V0] = error;
                    357:                frame->f_regs[A3] = 1;
                    358:                break;
                    359:        }
                    360: #ifdef SYSCALL_DEBUG
                    361:        scdebug_ret(p, code, error, rval);
                    362: #endif
                    363:        userret(p, opc, sticks);
                    364: #ifdef KTRACE
                    365:        if (KTRPOINT(p, KTR_SYSRET))
                    366:                ktrsysret(p->p_tracep, code, error, rval[0]);
                    367: #endif
                    368: }
                    369:
                    370: /*
                    371:  * fork syscall returns directly to user process via proc_trampoline,
                    372:  * which will be called the very first time when child gets running.
                    373:  * no more FORK_BRAINDAMAGED.
                    374:  */
                    375: void
1.95      thorpej   376: child_return(arg)
                    377:        void *arg;
1.57      mhitch    378: {
1.95      thorpej   379:        struct proc *p = arg;
1.57      mhitch    380:        struct frame *frame = (struct frame *)p->p_md.md_regs;
                    381:
                    382:        frame->f_regs[V0] = 0;
                    383:        frame->f_regs[V1] = 1;
                    384:        frame->f_regs[A3] = 0;
                    385:        userret(p, frame->f_regs[PC] - sizeof(int), 0); /* XXX */
                    386: #ifdef KTRACE
                    387:        if (KTRPOINT(p, KTR_SYSRET))
                    388:                ktrsysret(p->p_tracep, SYS_fork, 0, 0);
                    389: #endif
                    390: }
                    391:
                    392: #ifdef MIPS3
1.65      jonathan  393: #define TRAPTYPE(x) (((x) & MIPS3_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT)
1.57      mhitch    394: #else
1.65      jonathan  395: #define TRAPTYPE(x) (((x) & MIPS1_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT)
1.57      mhitch    396: #endif
                    397: #define KERNLAND(x) ((int)(x) < 0)
                    398:
                    399: /*
                    400:  * Trap is called from locore to handle most types of processor traps.
                    401:  * System calls are broken out for efficiency.  MIPS can handle software
                    402:  * interrupts as a part of real interrupt processing.
                    403:  */
                    404: void
                    405: trap(status, cause, vaddr, opc, frame)
1.99      castor    406:        unsigned status;
                    407:        unsigned cause;
                    408:        unsigned vaddr;
                    409:        unsigned opc;
                    410:        struct trapframe *frame;
1.57      mhitch    411: {
                    412:        int type, sig;
                    413:        int ucode = 0;
                    414:        u_quad_t sticks = 0;
                    415:        struct proc *p = curproc;
1.1       deraadt   416:        vm_prot_t ftype;
1.99      castor    417:        extern struct proc *fpcurproc;
1.57      mhitch    418:        extern void fswintrberr __P((void));
1.1       deraadt   419:
1.82      thorpej   420: #if defined(UVM)
                    421:        uvmexp.traps++;
                    422: #else
1.1       deraadt   423:        cnt.v_trap++;
1.82      thorpej   424: #endif
1.57      mhitch    425:        type = TRAPTYPE(cause);
                    426:        if (USERMODE(status)) {
1.1       deraadt   427:                type |= T_USER;
                    428:                sticks = p->p_sticks;
                    429:        }
                    430:
1.60      jonathan  431:        if (status & ((CPUISMIPS3) ? MIPS_SR_INT_IE : MIPS1_SR_INT_ENA_PREV))
1.65      jonathan  432:                splx((status & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
1.1       deraadt   433:
                    434:        switch (type) {
1.57      mhitch    435:        default:
                    436:        dopanic:
1.97      nisimura  437:                printf("trap: %s in %s mode\n",
                    438:                        trap_type[TRAPTYPE(cause)],
                    439:                        USERMODE(status) ? "user" : "kernel");
                    440:                printf("status=0x%x, cause=0x%x, epc=0x%x, vaddr=0x%x\n",
                    441:                        status, cause, opc, vaddr);
1.57      mhitch    442:                if (curproc != NULL)
1.97      nisimura  443:                        printf("pid=%d cmd=%s usp=0x%x ",
                    444:                            p->p_pid, p->p_comm,
                    445:                            (int)((struct frame *)p->p_md.md_regs)->f_regs[SP]);
1.57      mhitch    446:                else
1.97      nisimura  447:                        printf("curproc == NULL ");
                    448:                printf("ksp=0x%x\n", (int)&status);
1.99      castor    449: #ifdef DDB
                    450:                kdb_trap(type, (mips_reg_t *) frame);
                    451:                /* XXX force halt XXX */
                    452: #else
1.57      mhitch    453:                panic("trap");
1.99      castor    454: #endif
1.57      mhitch    455:                /*NOTREACHED*/
1.1       deraadt   456:        case T_TLB_MOD:
1.57      mhitch    457:                if (KERNLAND(vaddr)) {
                    458:                        pt_entry_t *pte;
                    459:                        unsigned entry;
1.98      nisimura  460:                        vaddr_t pa;
1.1       deraadt   461:
1.57      mhitch    462:                        pte = kvtopte(vaddr);
1.1       deraadt   463:                        entry = pte->pt_entry;
1.60      jonathan  464:                        if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
1.57      mhitch    465:                                panic("ktlbmod: invalid pte");
                    466:                        }
1.60      jonathan  467: /*XXX MIPS3? */                if (entry & mips_pg_ro_bit()) {
1.1       deraadt   468:                                /* write to read only page in the kernel */
                    469:                                ftype = VM_PROT_WRITE;
1.57      mhitch    470:                                goto kernelfault;
1.1       deraadt   471:                        }
1.60      jonathan  472:                        entry |= mips_pg_m_bit();
1.1       deraadt   473:                        pte->pt_entry = entry;
1.57      mhitch    474:                        vaddr &= ~PGOFSET;
                    475:                        MachTLBUpdate(vaddr, entry);
                    476:                        pa = pfn_to_vad(entry);
1.96      mhitch    477:                        if (!IS_VM_PHYSADDR(pa)) {
                    478:                                printf("ktlbmod: va %x pa %lx\n", vaddr, pa);
1.57      mhitch    479:                                panic("ktlbmod: unmanaged page");
1.96      mhitch    480:                        }
                    481:                        pmap_set_modified(pa);
1.57      mhitch    482:                        return; /* KERN */
1.1       deraadt   483:                }
1.57      mhitch    484:                /*FALLTHROUGH*/
1.1       deraadt   485:        case T_TLB_MOD+T_USER:
                    486:            {
1.57      mhitch    487:                pt_entry_t *pte;
                    488:                unsigned entry;
1.98      nisimura  489:                vaddr_t pa;
1.57      mhitch    490:                pmap_t pmap;
                    491:
                    492:                pmap  = p->p_vmspace->vm_map.pmap;
                    493:                if (!(pte = pmap_segmap(pmap, vaddr)))
                    494:                        panic("utlbmod: invalid segmap");
                    495:                pte += (vaddr >> PGSHIFT) & (NPTEPG - 1);
1.3       glass     496:                entry = pte->pt_entry;
1.60      jonathan  497:                if (!mips_pg_v(entry) || (entry & mips_pg_m_bit()))
1.57      mhitch    498:                        panic("utlbmod: invalid pte");
                    499:
1.60      jonathan  500: /*XXX MIPS3? */        if (entry & mips_pg_ro_bit()) {
1.3       glass     501:                        /* write to read only page */
1.1       deraadt   502:                        ftype = VM_PROT_WRITE;
1.57      mhitch    503:                        goto pagefault;
1.1       deraadt   504:                }
1.60      jonathan  505:                entry |= mips_pg_m_bit();
1.3       glass     506:                pte->pt_entry = entry;
1.57      mhitch    507:                vaddr = (vaddr & ~PGOFSET) |
1.64      jonathan  508:                        (pmap->pm_tlbpid << MIPS_TLB_PID_SHIFT);
1.57      mhitch    509:                MachTLBUpdate(vaddr, entry);
                    510:                pa = pfn_to_vad(entry);
1.96      mhitch    511:                if (!IS_VM_PHYSADDR(pa)) {
                    512:                        printf("utlbmod: va %x pa %lx\n", vaddr, pa);
1.57      mhitch    513:                        panic("utlbmod: unmanaged page");
1.96      mhitch    514:                }
                    515:                pmap_set_modified(pa);
1.57      mhitch    516:                if (type & T_USER)
                    517:                        userret(p, opc, sticks);
                    518:                return; /* GEN */
1.1       deraadt   519:            }
                    520:        case T_TLB_LD_MISS:
                    521:        case T_TLB_ST_MISS:
1.57      mhitch    522:                ftype = (type == T_TLB_LD_MISS) ? VM_PROT_READ : VM_PROT_WRITE;
                    523:                if (KERNLAND(vaddr))
                    524:                        goto kernelfault;
1.1       deraadt   525:                /*
                    526:                 * It is an error for the kernel to access user space except
                    527:                 * through the copyin/copyout routines.
                    528:                 */
1.99      castor    529:                if (p->p_addr->u_pcb.pcb_onfault == NULL)
1.57      mhitch    530:                        goto dopanic;
1.1       deraadt   531:                /* check for fuswintr() or suswintr() getting a page fault */
1.99      castor    532:                if (p->p_addr->u_pcb.pcb_onfault == (caddr_t)fswintrberr) {
                    533:                        frame->tf_epc = (int)fswintrberr;
1.57      mhitch    534:                        return; /* KERN */
                    535:                }
                    536:                goto pagefault;
1.1       deraadt   537:        case T_TLB_LD_MISS+T_USER:
                    538:                ftype = VM_PROT_READ;
1.57      mhitch    539:                goto pagefault;
1.1       deraadt   540:        case T_TLB_ST_MISS+T_USER:
                    541:                ftype = VM_PROT_WRITE;
1.57      mhitch    542:        pagefault: ;
1.1       deraadt   543:            {
1.98      nisimura  544:                vaddr_t va;
1.57      mhitch    545:                struct vmspace *vm;
                    546:                vm_map_t map;
1.1       deraadt   547:                int rv;
                    548:
1.3       glass     549:                vm = p->p_vmspace;
                    550:                map = &vm->vm_map;
1.98      nisimura  551:                va = trunc_page(vaddr);
1.82      thorpej   552: #if defined(UVM)
                    553:                rv = uvm_fault(map, va, 0, ftype);
                    554: #ifdef VMFAULT_TRACE
                    555:                printf(
                    556:            "uvm_fault(%p (pmap %p), %lx (0x%x), 0, ftype) -> %d at pc %p\n",
                    557:                    map, vm->vm_map.pmap, va, vaddr, ftype, rv, (void*)opc);
                    558: #endif
                    559: #else /* ! UVM */
1.1       deraadt   560:                rv = vm_fault(map, va, ftype, FALSE);
1.5       glass     561: #ifdef VMFAULT_TRACE
1.57      mhitch    562:                printf(
1.75      jonathan  563:                "vm_fault(%p (pmap %p), %lx (0x%x), %d, %d) -> %d at pc %p\n",
                    564:                    map, vm->vm_map.pmap, va, vaddr, ftype, FALSE, rv,
                    565:                    (void*)opc);
1.5       glass     566: #endif
1.82      thorpej   567: #endif /* UVM */
1.1       deraadt   568:                /*
                    569:                 * If this was a stack access we keep track of the maximum
                    570:                 * accessed stack size.  Also, if vm_fault gets a protection
                    571:                 * failure it is due to accessing the stack region outside
                    572:                 * the current limit and we need to reflect that as an access
                    573:                 * error.
                    574:                 */
                    575:                if ((caddr_t)va >= vm->vm_maxsaddr) {
                    576:                        if (rv == KERN_SUCCESS) {
                    577:                                unsigned nss;
                    578:
                    579:                                nss = clrnd(btoc(USRSTACK-(unsigned)va));
                    580:                                if (nss > vm->vm_ssize)
                    581:                                        vm->vm_ssize = nss;
1.57      mhitch    582:                        }
                    583:                        else if (rv == KERN_PROTECTION_FAILURE)
1.1       deraadt   584:                                rv = KERN_INVALID_ADDRESS;
                    585:                }
                    586:                if (rv == KERN_SUCCESS) {
1.99      castor    587:                        if (type & T_USER) {
1.57      mhitch    588:                                userret(p, opc, sticks);
1.99      castor    589:                        }
1.57      mhitch    590:                        return; /* GEN */
                    591:                }
                    592:                if ((type & T_USER) == 0)
                    593:                        goto copyfault;
                    594:                sig = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV;
                    595:                ucode = vaddr;
                    596:                break; /* SIGNAL */
1.99      castor    597:            }
1.57      mhitch    598:        kernelfault: ;
                    599:            {
1.98      nisimura  600:                vaddr_t va;
1.57      mhitch    601:                int rv;
                    602:
1.98      nisimura  603:                va = trunc_page(vaddr);
1.82      thorpej   604: #if defined(UVM)
                    605:                rv = uvm_fault(kernel_map, va, 0, ftype);
                    606: #else
1.57      mhitch    607:                rv = vm_fault(kernel_map, va, ftype, FALSE);
1.82      thorpej   608: #endif
1.57      mhitch    609:                if (rv == KERN_SUCCESS)
                    610:                        return; /* KERN */
                    611:                /*FALLTHROUGH*/
1.1       deraadt   612:            }
1.57      mhitch    613:        case T_ADDR_ERR_LD:     /* misaligned access */
                    614:        case T_ADDR_ERR_ST:     /* misaligned access */
                    615:        case T_BUS_ERR_LD_ST:   /* BERR asserted to cpu */
                    616:        copyfault:
1.99      castor    617:                if (p->p_addr->u_pcb.pcb_onfault == NULL)
1.57      mhitch    618:                        goto dopanic;
1.99      castor    619:                frame->tf_epc = (int)p->p_addr->u_pcb.pcb_onfault;
1.57      mhitch    620:                return; /* KERN */
1.1       deraadt   621:
                    622:        case T_ADDR_ERR_LD+T_USER:      /* misaligned or kseg access */
                    623:        case T_ADDR_ERR_ST+T_USER:      /* misaligned or kseg access */
                    624:        case T_BUS_ERR_IFETCH+T_USER:   /* BERR asserted to cpu */
                    625:        case T_BUS_ERR_LD_ST+T_USER:    /* BERR asserted to cpu */
1.57      mhitch    626:                sig = SIGSEGV;
                    627:                ucode = vaddr;
                    628:                break; /* SIGNAL */
1.69      jonathan  629:
                    630:        case T_BREAK:
                    631: #ifdef DDB
1.99      castor    632:                kdb_trap(type, (mips_reg_t *) frame);
1.69      jonathan  633:                return; /* KERN */
                    634: #else
                    635:                goto dopanic;
                    636: #endif
1.1       deraadt   637:        case T_BREAK+T_USER:
                    638:            {
1.57      mhitch    639:                unsigned va, instr;
                    640:                int rv;
1.1       deraadt   641:
                    642:                /* compute address of break instruction */
1.57      mhitch    643:                va = (DELAYBRANCH(cause)) ? opc + sizeof(int) : opc;
1.1       deraadt   644:
                    645:                /* read break instruction */
1.99      castor    646:                instr = fuiword((void *)va);
1.69      jonathan  647: #ifdef DEBUG
                    648: /*XXX*/                printf("break insn  0x%x\n", instr);
                    649: #endif
1.57      mhitch    650:
1.65      jonathan  651:                if (p->p_md.md_ss_addr != va || instr != MIPS_BREAK_SSTEP) {
1.57      mhitch    652:                        sig = SIGTRAP;
1.1       deraadt   653:                        break;
                    654:                }
1.97      nisimura  655:                /*
1.57      mhitch    656:                 * Restore original instruction and clear BP
1.97      nisimura  657:                 */
1.99      castor    658:                rv = suiword((void *)va, p->p_md.md_ss_instr);
1.57      mhitch    659:                if (rv < 0) {
1.98      nisimura  660:                        vaddr_t sa, ea;
                    661:                        sa = trunc_page(va);
                    662:                        ea = round_page(va + sizeof(int) - 1);
1.82      thorpej   663: #if defined(UVM)
                    664:                        rv = uvm_map_protect(&p->p_vmspace->vm_map,
                    665:                                sa, ea, VM_PROT_DEFAULT, FALSE);
                    666:                        if (rv == KERN_SUCCESS) {
1.99      castor    667:                                rv = suiword((void *)va, MIPS_BREAK_SSTEP);
1.82      thorpej   668:                                (void)uvm_map_protect(&p->p_vmspace->vm_map,
                    669:                                sa, ea, VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
                    670:                        }
                    671: #else
1.57      mhitch    672:                        rv = vm_map_protect(&p->p_vmspace->vm_map,
                    673:                                sa, ea, VM_PROT_DEFAULT, FALSE);
1.1       deraadt   674:                        if (rv == KERN_SUCCESS) {
1.99      castor    675:                                rv = suiword((void *)va, MIPS_BREAK_SSTEP);
1.57      mhitch    676:                                (void)vm_map_protect(&p->p_vmspace->vm_map,
                    677:                                sa, ea, VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
1.1       deraadt   678:                        }
1.82      thorpej   679: #endif /* UVM */
1.97      nisimura  680:                }
1.69      jonathan  681:                MachFlushCache();
                    682:
1.57      mhitch    683:                if (rv < 0)
                    684:                        printf("Warning: can't restore instruction at 0x%x: 0x%x\n",
1.3       glass     685:                                p->p_md.md_ss_addr, p->p_md.md_ss_instr);
1.1       deraadt   686:                p->p_md.md_ss_addr = 0;
1.57      mhitch    687:                sig = SIGTRAP;
                    688:                break; /* SIGNAL */
1.99      castor    689:            }
1.1       deraadt   690:        case T_RES_INST+T_USER:
1.57      mhitch    691:                sig = SIGILL;
                    692:                break; /* SIGNAL */
1.1       deraadt   693:        case T_COP_UNUSABLE+T_USER:
1.65      jonathan  694:                if ((cause & MIPS_CR_COP_ERR) != 0x10000000) {
1.57      mhitch    695:                        sig = SIGILL;   /* only FPU instructions allowed */
                    696:                        break; /* SIGNAL */
1.97      nisimura  697:                }
1.57      mhitch    698:                switchfpregs(fpcurproc, p);
                    699:                fpcurproc = p;
1.97      nisimura  700:                ((struct frame *)p->p_md.md_regs)->f_regs[SR]
                    701:                        |= MIPS_SR_COP_1_BIT;
1.1       deraadt   702:                p->p_md.md_flags |= MDP_FPUSED;
1.57      mhitch    703:                userret(p, opc, sticks);
                    704:                return; /* GEN */
1.32      jonathan  705:        case T_FPE+T_USER:
1.99      castor    706:                /* dealfpu(status, cause, opc); */
1.57      mhitch    707:                MachFPInterrupt(status, cause, opc, p->p_md.md_regs);
                    708:                userret(p, opc, sticks);
                    709:                return; /* GEN */
1.1       deraadt   710:        case T_OVFLOW+T_USER:
1.57      mhitch    711:                sig = SIGFPE;
                    712:                break; /* SIGNAL */
1.97      nisimura  713:        }
                    714:        ((struct frame *)p->p_md.md_regs)->f_regs[CAUSE] = cause;
                    715:        ((struct frame *)p->p_md.md_regs)->f_regs[BADVADDR] = vaddr;
1.57      mhitch    716:        trapsignal(p, sig, ucode);
                    717:        if ((type & T_USER) == 0)
                    718:                panic("trapsignal");
                    719:        userret(p, opc, sticks);
                    720:        return;
                    721: }
1.1       deraadt   722:
1.57      mhitch    723: #include <net/netisr.h>
1.79      veego     724: #include "arp.h"
1.57      mhitch    725: #include "ppp.h"
1.1       deraadt   726:
1.80      wrstuden  727: #ifdef NS
1.87      jonathan  728: #include <netns/ns_var.h>
1.80      wrstuden  729: #endif
1.87      jonathan  730:
1.80      wrstuden  731: #ifdef ISO
1.87      jonathan  732: #include <netiso/iso.h>
                    733: #include <netiso/clnp.h>
                    734: #endif
                    735:
                    736: #ifdef CCITT
                    737: #include <netccitt/x25.h>
                    738: #include <netccitt/pk.h>
                    739: #include <netccitt/pk_extern.h>
                    740: #endif
                    741:
                    742: #ifdef NATM
                    743: #include <netnatm/natm.h>
                    744: #endif
                    745: #ifdef NETATALK
                    746: #include <netatalk/at_extern.h>
1.80      wrstuden  747: #endif
                    748:
1.57      mhitch    749: /*
                    750:  * Handle an interrupt.
1.99      castor    751:  * N.B., curproc might be NULL.
1.57      mhitch    752:  */
1.22      jonathan  753: void
1.99      castor    754: interrupt(status, cause, pc)
                    755:        unsigned status;
                    756:        unsigned cause;
                    757:        unsigned pc;
1.1       deraadt   758: {
1.57      mhitch    759:        unsigned mask;
1.85      jonathan  760:        extern u_int32_t mips3_cycle_count __P((void));
                    761:
                    762:        mask = cause & status;  /* pending interrupts & enable mask */
                    763:
1.99      castor    764: #if defined(MIPS3) && defined(MIPS_INT_MASK_CLOCK)
                    765:        if ((mask & MIPS_INT_MASK_CLOCK) && CPUISMIPS3)
1.85      jonathan  766:                mips3_intr_cycle_count = mips3_cycle_count();
1.1       deraadt   767: #endif
                    768:
1.82      thorpej   769: #if defined(UVM)
                    770:        uvmexp.intrs++;
                    771: #else
1.1       deraadt   772:        cnt.v_intr++;
1.82      thorpej   773: #endif
1.99      castor    774:        /* real device interrupt */
                    775:        if ((mask & INT_MASK_REAL_DEV) && mips_hardware_intr) {
1.57      mhitch    776:                splx((*mips_hardware_intr)(mask, pc, status, cause));
1.99      castor    777:        }
1.83      jonathan  778:
1.99      castor    779: #ifdef INT_MASK_FPU_DEAL
                    780:        if (mask & INT_MASK_FPU_DEAL) {
1.28      jonathan  781:                intrcnt[FPU_INTR]++;
1.99      castor    782:                if (!USERMODE(status))
                    783:                        panic("kernel used FPU: PC %x, CR %x, SR %x",
                    784:                            pc, cause, status);
                    785:                /* dealfpu(status, cause, pc); */
                    786:                MachFPInterrupt(status, cause, pc, curproc->p_md.md_regs);
1.1       deraadt   787:        }
1.99      castor    788: #endif
1.14      jonathan  789:
1.99      castor    790:        /* simulated interrupt */
1.65      jonathan  791:        if ((mask & MIPS_SOFT_INT_MASK_1)
1.99      castor    792:                    || ((netisr|softisr) && (status & MIPS_SOFT_INT_MASK_1))) {
                    793:                register int isr, sisr;
                    794:                isr = netisr; netisr = 0;
                    795:                sisr = softisr; softisr = 0;
1.1       deraadt   796:                clearsoftnet();
1.82      thorpej   797: #if defined(UVM)
                    798:                uvmexp.softs++;
                    799: #else
1.1       deraadt   800:                cnt.v_soft++;
1.82      thorpej   801: #endif
1.99      castor    802:                if (isr) {
                    803:                        intrcnt[SOFTNET_INTR]++;
1.1       deraadt   804: #ifdef INET
1.79      veego     805: #if NARP > 0
1.99      castor    806:                        if (isr & (1 << NETISR_ARP)) arpintr();
1.57      mhitch    807: #endif
1.99      castor    808:                        if (isr & (1 << NETISR_IP)) ipintr();
1.80      wrstuden  809: #endif
                    810: #ifdef NETATALK
1.99      castor    811:                        if (isr & (1 << NETISR_ATALK)) atintr();
1.1       deraadt   812: #endif
                    813: #ifdef NS
1.99      castor    814:                        if (isr & (1 << NETISR_NS)) nsintr();
1.1       deraadt   815: #endif
                    816: #ifdef ISO
1.99      castor    817:                        if (isr & (1 << NETISR_ISO)) clnlintr();
1.87      jonathan  818: #endif
                    819: #ifdef CCITT
1.99      castor    820:                        if (isr & (1 << NETISR_CCITT)) ccittintr();
1.1       deraadt   821: #endif
1.20      paulus    822: #if NPPP > 0
1.99      castor    823:                        if (isr & (1 << NETISR_PPP)) pppintr();
1.20      paulus    824: #endif
1.99      castor    825:                }
                    826:                if (sisr && mips_software_intr)
                    827:                        (*mips_software_intr)(sisr);
1.21      jonathan  828:        }
1.20      paulus    829:
1.99      castor    830:        /* 'softclock' interrupt */
1.65      jonathan  831:        if (mask & MIPS_SOFT_INT_MASK_0) {
1.14      jonathan  832:                clearsoftclock();
1.82      thorpej   833: #if defined(UVM)
                    834:                uvmexp.softs++;
                    835: #else
1.57      mhitch    836:                cnt.v_soft++;
1.82      thorpej   837: #endif
1.28      jonathan  838:                intrcnt[SOFTCLOCK_INTR]++;
1.14      jonathan  839:                softclock();
1.43      jonathan  840:        }
1.1       deraadt   841: }
                    842:
                    843: /*
1.57      mhitch    844:  * Handle asynchronous software traps.
                    845:  * This is called from MachUserIntr() either to deliver signals or
                    846:  * to make involuntary context switch (preemption).
1.1       deraadt   847:  */
1.22      jonathan  848: void
1.57      mhitch    849: ast(pc)
1.1       deraadt   850:        unsigned pc;            /* program counter where to continue */
                    851: {
1.57      mhitch    852:        struct proc *p = curproc;
1.1       deraadt   853:
1.82      thorpej   854: #if defined(UVM)
                    855:        uvmexp.softs++;
                    856: #else
1.1       deraadt   857:        cnt.v_soft++;
1.82      thorpej   858: #endif
1.1       deraadt   859:        astpending = 0;
1.3       glass     860:        if (p->p_flag & P_OWEUPC) {
                    861:                p->p_flag &= ~P_OWEUPC;
1.1       deraadt   862:                ADDUPROF(p);
                    863:        }
1.57      mhitch    864:        userret(p, pc, p->p_sticks);
                    865: }
1.1       deraadt   866:
1.99      castor    867: /* XXX XXX XXX */
                    868: #define        set_cp0sr(x)            \
                    869: {                              \
                    870:        register int _r = (x);  \
                    871:        __asm __volatile("      \
                    872:                .set noreorder  ; \
                    873:                mtc0    %0, $12 ; \
                    874:                nop;nop;nop;nop ; \
                    875:                .set reorder"   \
                    876:                : : "r"(_r));   \
                    877: }
                    878:
                    879: #define        get_fpcsr()             \
                    880: ({                             \
                    881:        register int _r;        \
                    882:        __asm __volatile("      \
                    883:                .set noreorder  ; \
                    884:                cfc1    %0, $31 ; \
                    885:                cfc1    %0, $31 ; \
                    886:                nop             ; \
                    887:                .set reorder"   \
                    888:                : "=r"(_r));    \
                    889:        _r;                     \
                    890: })
                    891:
                    892: #define        clr_fpcsr()             \
                    893:        __asm __volatile("ctc1  $0, $31")
                    894: /* XXX XXX XXX */
1.1       deraadt   895:
1.99      castor    896: /*
                    897:  * Software emulation of umimplemented floating point instructions
                    898:  */
1.22      jonathan  899: void
1.99      castor    900: dealfpu(status, cause, opc)
                    901:        unsigned status;
                    902:        unsigned cause;
                    903:        unsigned opc;
1.1       deraadt   904: {
1.99      castor    905:        struct frame *f = (struct frame *)curproc->p_md.md_regs;
                    906:        unsigned v0;
1.100   ! nisimura  907:        int sig;
1.1       deraadt   908:
1.99      castor    909:        set_cp0sr(status | MIPS_SR_COP_1_BIT);
                    910:        v0 = get_fpcsr();
1.100   ! nisimura  911:
        !           912:        /* was it 'unimplemented operation' ? */
        !           913:        if ((v0 & MIPS_FPU_EXCEPTION_UNIMPL) == 0) {
        !           914:                sig = SIGFPE;
        !           915:                goto notforemulation;
        !           916:        }
        !           917:
1.99      castor    918:        if (DELAYBRANCH(cause)) {
                    919:                f->f_regs[PC] = MachEmulateBranch(f, opc, v0, 0);
                    920:                v0 = *(unsigned *)(opc + sizeof(unsigned));
                    921:        }
                    922:        else {
                    923:                f->f_regs[PC] = opc + sizeof(unsigned);
                    924:                v0 = *(unsigned *)opc;
                    925:        }
1.100   ! nisimura  926:        /* make sure the instruction is for FPU */
        !           927:        if (MIPS_OPCODE_C1 != (v0 >> MIPS_OPCODE_SHIFT)) {
        !           928:                sig = SIGILL;
        !           929:                goto notforemulation;
        !           930:        }
1.99      castor    931:
                    932:        MachEmulateFP(v0);
                    933:        set_cp0sr(status &~ MIPS_SR_COP_1_BIT);
                    934:        return;
                    935:
1.100   ! nisimura  936: notforemulation:
1.99      castor    937:        clr_fpcsr();
1.100   ! nisimura  938:        trapsignal(curproc, sig, v0);
1.99      castor    939:        set_cp0sr(status &~ MIPS_SR_COP_1_BIT);
                    940:        return;
1.1       deraadt   941: }
                    942:
1.46      jonathan  943: /*
1.98      nisimura  944:  * Analyse 'next' PC address taking account of branch/jump instructions
1.46      jonathan  945:  */
1.98      nisimura  946: vaddr_t
                    947: MachEmulateBranch(f, instpc, fpuCSR, allowNonBranch)
                    948:        struct frame *f;
                    949:        vaddr_t instpc;
                    950:        unsigned fpuCSR;
1.1       deraadt   951:        int allowNonBranch;
                    952: {
1.98      nisimura  953: #define        BRANCHTARGET(p) (4 + (p) + ((short)((InstFmt *)(p))->IType.imm << 2))
1.1       deraadt   954:        InstFmt inst;
1.98      nisimura  955:        vaddr_t nextpc;
1.24      jonathan  956:
1.98      nisimura  957:        if (instpc < MIPS_KSEG0_START)
                    958:                inst.word = fuiword((void *)instpc);
                    959:        else
                    960:                inst.word = *(unsigned *)instpc;
1.46      jonathan  961:
1.1       deraadt   962:        switch ((int)inst.JType.op) {
                    963:        case OP_SPECIAL:
1.98      nisimura  964:                if (inst.RType.func == OP_JR || inst.RType.func == OP_JALR)
                    965:                        nextpc = f->f_regs[inst.RType.rs];
                    966:                else if (allowNonBranch)
                    967:                        nextpc = instpc + 4;
                    968:                else
                    969:                        panic("MachEmulateBranch: Non-branch");
1.1       deraadt   970:                break;
                    971:
                    972:        case OP_BCOND:
                    973:                switch ((int)inst.IType.rt) {
                    974:                case OP_BLTZ:
                    975:                case OP_BLTZAL:
1.34      jonathan  976:                case OP_BLTZL:          /* squashed */
                    977:                case OP_BLTZALL:        /* squashed */
1.98      nisimura  978:                        if ((int)(f->f_regs[inst.RType.rs]) < 0)
                    979:                                nextpc = BRANCHTARGET(instpc);
1.1       deraadt   980:                        else
1.98      nisimura  981:                                nextpc = instpc + 8;
1.1       deraadt   982:                        break;
                    983:
1.34      jonathan  984:                case OP_BGEZ:
1.1       deraadt   985:                case OP_BGEZAL:
1.34      jonathan  986:                case OP_BGEZL:          /* squashed */
                    987:                case OP_BGEZALL:        /* squashed */
1.98      nisimura  988:                        if ((int)(f->f_regs[inst.RType.rs]) >= 0)
                    989:                                nextpc = BRANCHTARGET(instpc);
1.1       deraadt   990:                        else
1.98      nisimura  991:                                nextpc = instpc + 8;
1.1       deraadt   992:                        break;
                    993:
                    994:                default:
                    995:                        panic("MachEmulateBranch: Bad branch cond");
                    996:                }
                    997:                break;
                    998:
                    999:        case OP_J:
                   1000:        case OP_JAL:
1.98      nisimura 1001:                nextpc = (inst.JType.target << 2) |
                   1002:                        ((unsigned)instpc & 0xF0000000);
1.1       deraadt  1003:                break;
                   1004:
                   1005:        case OP_BEQ:
1.98      nisimura 1006:        case OP_BEQL:   /* squashed */
                   1007:                if (f->f_regs[inst.RType.rs] == f->f_regs[inst.RType.rt])
                   1008:                        nextpc = BRANCHTARGET(instpc);
1.1       deraadt  1009:                else
1.98      nisimura 1010:                        nextpc = instpc + 8;
1.1       deraadt  1011:                break;
                   1012:
                   1013:        case OP_BNE:
1.98      nisimura 1014:        case OP_BNEL:   /* squashed */
                   1015:                if (f->f_regs[inst.RType.rs] != f->f_regs[inst.RType.rt])
                   1016:                        nextpc = BRANCHTARGET(instpc);
1.1       deraadt  1017:                else
1.98      nisimura 1018:                        nextpc = instpc + 8;
1.1       deraadt  1019:                break;
                   1020:
                   1021:        case OP_BLEZ:
1.98      nisimura 1022:        case OP_BLEZL:  /* squashed */
                   1023:                if ((int)(f->f_regs[inst.RType.rs]) <= 0)
                   1024:                        nextpc = BRANCHTARGET(instpc);
1.1       deraadt  1025:                else
1.98      nisimura 1026:                        nextpc = instpc + 8;
1.1       deraadt  1027:                break;
                   1028:
                   1029:        case OP_BGTZ:
1.98      nisimura 1030:        case OP_BGTZL:  /* squashed */
                   1031:                if ((int)(f->f_regs[inst.RType.rs]) > 0)
                   1032:                        nextpc = BRANCHTARGET(instpc);
1.1       deraadt  1033:                else
1.98      nisimura 1034:                        nextpc = instpc + 8;
1.1       deraadt  1035:                break;
                   1036:
                   1037:        case OP_COP1:
1.98      nisimura 1038:                if (inst.RType.rs == OP_BCx || inst.RType.rs == OP_BCy) {
                   1039:                        int condition = (fpuCSR & MIPS_FPU_COND_BIT) != 0;
                   1040:                        if ((inst.RType.rt & COPz_BC_TF_MASK) != COPz_BC_TRUE)
                   1041:                                condition = !condition;
1.1       deraadt  1042:                        if (condition)
1.98      nisimura 1043:                                nextpc = BRANCHTARGET(instpc);
1.1       deraadt  1044:                        else
1.98      nisimura 1045:                                nextpc = instpc + 8;
1.1       deraadt  1046:                }
1.98      nisimura 1047:                else if (allowNonBranch)
                   1048:                        nextpc = instpc + 4;
                   1049:                else
                   1050:                        panic("MachEmulateBranch: Bad COP1 branch instruction");
1.1       deraadt  1051:                break;
                   1052:
                   1053:        default:
                   1054:                if (!allowNonBranch)
                   1055:                        panic("MachEmulateBranch: Non-branch instruction");
1.98      nisimura 1056:                nextpc = instpc + 4;
1.1       deraadt  1057:        }
1.98      nisimura 1058:        return nextpc;
                   1059: #undef BRANCHTARGET
1.1       deraadt  1060: }
                   1061:
1.99      castor   1062: /* XXX need to rewrite acient comment XXX
1.1       deraadt  1063:  * This routine is called by procxmt() to single step one instruction.
                   1064:  * We do this by storing a break instruction after the current instruction,
                   1065:  * resuming execution, and then restoring the old instruction.
                   1066:  */
1.22      jonathan 1067: int
1.54      jonathan 1068: mips_singlestep(p)
1.57      mhitch   1069:        struct proc *p;
1.1       deraadt  1070: {
1.97      nisimura 1071:        struct frame *f = (struct frame *)p->p_md.md_regs;
1.98      nisimura 1072:        vaddr_t pc, va;
1.97      nisimura 1073:        int rv;
1.1       deraadt  1074:
1.97      nisimura 1075:        if (p->p_md.md_ss_addr) {
1.45      christos 1076:                printf("SS %s (%d): breakpoint already set at %x (va %x)\n",
1.99      castor   1077:                        p->p_comm, p->p_pid, p->p_md.md_ss_addr, (int)va);
1.97      nisimura 1078:                return EFAULT;
1.1       deraadt  1079:        }
1.98      nisimura 1080:        pc = (vaddr_t)f->f_regs[PC];
                   1081:        if (fuiword((void *)pc) != 0) /* not a NOP instruction */
                   1082:                va = MachEmulateBranch(f, pc,
1.97      nisimura 1083:                        p->p_addr->u_pcb.pcb_fpregs.r_regs[32], 1);
                   1084:        else
1.99      castor   1085:                va = pc + sizeof(int);
1.1       deraadt  1086:        p->p_md.md_ss_addr = va;
1.99      castor   1087:        p->p_md.md_ss_instr = fuiword((void *)va);
                   1088:        rv = suiword((void *)va, MIPS_BREAK_SSTEP);
1.97      nisimura 1089:        if (rv < 0) {
1.98      nisimura 1090:                vaddr_t sa, ea;
                   1091:                sa = trunc_page(va);
                   1092:                ea = round_page(va + sizeof(int) - 1);
1.82      thorpej  1093: #if defined(UVM)
                   1094:                rv = uvm_map_protect(&p->p_vmspace->vm_map,
                   1095:                    sa, ea, VM_PROT_DEFAULT, FALSE);
1.1       deraadt  1096:                if (rv == KERN_SUCCESS) {
1.99      castor   1097:                        rv = suiword((void *)va, MIPS_BREAK_SSTEP);
1.82      thorpej  1098:                        (void)uvm_map_protect(&p->p_vmspace->vm_map,
                   1099:                            sa, ea, VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
                   1100:                }
                   1101: #else
                   1102:                rv = vm_map_protect(&p->p_vmspace->vm_map,
                   1103:                    sa, ea, VM_PROT_DEFAULT, FALSE);
                   1104:                if (rv == KERN_SUCCESS) {
1.99      castor   1105:                        rv = suiword((void *)va, MIPS_BREAK_SSTEP);
1.82      thorpej  1106:                        (void)vm_map_protect(&p->p_vmspace->vm_map,
                   1107:                            sa, ea, VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
1.1       deraadt  1108:                }
1.82      thorpej  1109: #endif /* UVM */
1.1       deraadt  1110:        }
1.3       glass    1111: #if 0
1.45      christos 1112:        printf("SS %s (%d): breakpoint set at %x: %x (pc %x) br %x\n",
1.1       deraadt  1113:                p->p_comm, p->p_pid, p->p_md.md_ss_addr,
1.99      castor   1114:                p->p_md.md_ss_instr, pc, fuword((void *)va)); /* XXX */
1.3       glass    1115: #endif
1.97      nisimura 1116:        return 0;
1.1       deraadt  1117: }
                   1118:
1.99      castor   1119:
                   1120: #ifndef DDB_TRACE
                   1121:
1.73      jonathan 1122: #if defined(DEBUG) || defined(DDB)
1.99      castor   1123: mips_reg_t kdbrpeek __P((vaddr_t));
                   1124: extern void stacktrace __P((void)); /*XXX*/
                   1125: extern void logstacktrace __P((void)); /*XXX*/
                   1126:
                   1127:
1.22      jonathan 1128: int
1.1       deraadt  1129: kdbpeek(addr)
1.98      nisimura 1130:        vaddr_t addr;
1.1       deraadt  1131: {
1.99      castor   1132:        int rc;
1.1       deraadt  1133:        if (addr & 3) {
1.56      jonathan 1134:                printf("kdbpeek: unaligned address %lx\n", addr);
1.99      castor   1135:                /* We might have been called from DDB, so do not go there. */
                   1136:                stacktrace();
                   1137:                rc = -1 ;
                   1138:        } else if (addr == NULL) {
                   1139:                printf("kdbpeek: NULL\n");
                   1140:                rc = 0xdeadfeed;
                   1141:        } else {
                   1142:                rc = *(int *)addr;
                   1143:        }
                   1144:        return rc;
                   1145: }
                   1146:
                   1147: mips_reg_t
                   1148: kdbrpeek(addr)
                   1149:        vaddr_t addr;
                   1150: {
                   1151:        mips_reg_t rc;
                   1152:        if (addr & (sizeof(mips_reg_t) - 1)) {
                   1153:                printf("kdbrpeek: unaligned address %lx\n", addr);
                   1154:                /* We might have been called from DDB, so do not go there. */
1.69      jonathan 1155:                stacktrace();
1.99      castor   1156:                rc = -1 ;
                   1157:        } else if (addr == NULL) {
                   1158:                printf("kdbrpeek: NULL\n");
                   1159:                rc = 0xdeadfeed;
                   1160:        } else {
                   1161:                rc = *(mips_reg_t *)addr;
1.1       deraadt  1162:        }
1.99      castor   1163:        return rc;
1.1       deraadt  1164: }
                   1165:
1.99      castor   1166: extern char start[], edata[], verylocore[];
                   1167: extern char mips1_KernGenException[];
                   1168: extern char mips1_UserGenException[];
                   1169: extern char mips1_KernIntr[];
                   1170: extern char mips1_UserIntr[];
                   1171: extern char mips1_SystemCall[];
                   1172: extern char mips3_KernGenException[];
                   1173: extern char mips3_UserGenException[];
                   1174: extern char mips3_KernIntr[];
                   1175: extern char mips3_UserIntr[];
                   1176: extern char mips3_SystemCall[];
                   1177: extern int main __P((void*));
                   1178: extern void idle __P((void));
                   1179: extern void cpu_switch __P((struct proc *));
                   1180:
                   1181: /*
                   1182:  *  stack trace code, also useful to DDB one day
                   1183:  */
1.1       deraadt  1184:
1.16      jonathan 1185: /* forward */
                   1186: char *fn_name(unsigned addr);
1.69      jonathan 1187: void stacktrace_subr __P((int a0, int a1, int a2, int a3,
                   1188:                          u_int pc, u_int sp, u_int fp, u_int ra,
                   1189:                          void (*)(const char*, ...)));
1.16      jonathan 1190:
1.99      castor   1191: #define        MIPS_JR_RA      0x03e00008      /* instruction code for jr ra */
                   1192: #define        MIPS_JR_K0      0x03400008      /* instruction code for jr k0 */
                   1193: #define        MIPS_ERET       0x12345678      /* instruction code for eret */
                   1194:
1.1       deraadt  1195: /*
1.56      jonathan 1196:  * Do a stack backtrace.
                   1197:  * (*printfn)()  prints the output to either the system log,
                   1198:  * the console, or both.
1.1       deraadt  1199:  */
1.16      jonathan 1200: void
1.69      jonathan 1201: stacktrace_subr(a0, a1, a2, a3, pc, sp, fp, ra, printfn)
1.16      jonathan 1202:        int a0, a1, a2, a3;
1.69      jonathan 1203:        u_int  pc, sp, fp, ra;
1.16      jonathan 1204:        void (*printfn) __P((const char*, ...));
                   1205: {
1.69      jonathan 1206:        unsigned va, subr;
1.1       deraadt  1207:        unsigned instr, mask;
                   1208:        InstFmt i;
                   1209:        int more, stksize;
1.16      jonathan 1210:        unsigned int frames =  0;
1.71      jonathan 1211:        int foundframesize = 0;
1.1       deraadt  1212:
1.16      jonathan 1213: /* Jump here when done with a frame, to start a new one */
1.1       deraadt  1214: loop:
1.99      castor   1215: /* Jump here after a nonstandard (interrupt handler) frame
                   1216: specialframe: */
1.16      jonathan 1217:        stksize = 0;
                   1218:        subr = 0;
1.99      castor   1219:        if (frames++ > 100) {
1.16      jonathan 1220:                (*printfn)("\nstackframe count exceeded\n");
1.17      jonathan 1221:                /* return breaks stackframe-size heuristics with gcc -O2 */
                   1222:                goto finish;    /*XXX*/
1.16      jonathan 1223:        }
                   1224:
                   1225:        /* check for bad SP: could foul up next frame */
                   1226:        if (sp & 3 || sp < 0x80000000) {
                   1227:                (*printfn)("SP 0x%x: not in kernel\n", sp);
                   1228:                ra = 0;
                   1229:                subr = 0;
                   1230:                goto done;
                   1231:        }
                   1232:
1.99      castor   1233: #if 0 /* special locore arrangements made unnecssary following */
                   1234:
1.35      jonathan 1235: /*
                   1236:  * check for PC between two entry points
                   1237:  */
                   1238: # define Between(x, y, z) \
                   1239:                ( ((x) <= (y)) && ((y) < (z)) )
                   1240: # define pcBetween(a,b) \
                   1241:                Between((unsigned)a, pc, (unsigned)b)
                   1242:
1.43      jonathan 1243:        /* Backtraces should continue through interrupts from kernel mode */
1.42      jonathan 1244: #ifdef MIPS1   /*  r2000 family  (mips-I cpu) */
1.92      jonathan 1245:        if (pcBetween(mips1_KernIntr, mips1_KernIntrEnd)) {
1.1       deraadt  1246:                /* NOTE: the offsets depend on the code in locore.s */
1.99      castor   1247:                (*printfn)("mips1 KernIntr+%x: (%x, %x ,%x) -------\n",
1.50      jonathan 1248:                       pc-(unsigned)mips1_KernIntr, a0, a1, a2);
1.57      mhitch   1249:                a0 = kdbpeek(sp + 40);
                   1250:                a1 = kdbpeek(sp + 44);
                   1251:                a2 = kdbpeek(sp + 48);
                   1252:                a3 = kdbpeek(sp + 52);
1.99      castor   1253:                pc = kdbpeek(sp + 112); /* exc_pc - pc at time of exception */
                   1254:                ra = kdbpeek(sp + 96);  /* ra at time of exception */
                   1255:                sp = sp + 116;
1.16      jonathan 1256:                goto specialframe;
1.1       deraadt  1257:        }
1.92      jonathan 1258:        else if (pcBetween(mips1_KernGenException, mips1_KernGenExceptionEnd)) {
1.71      jonathan 1259:                /* NOTE: the offsets depend on the code in locore.s */
                   1260:                (*printfn)("------ kernel trap+%x: (%x, %x ,%x) -------\n",
                   1261:                       pc-(unsigned)mips1_KernGenException, a0, a1, a2);
                   1262:
                   1263:                a0 = kdbpeek(sp + 40);
                   1264:                a1 = kdbpeek(sp + 44);
                   1265:                a2 = kdbpeek(sp + 48);
                   1266:                a3 = kdbpeek(sp + 52);
1.99      castor   1267:                pc = kdbpeek(sp + 112); /* exc_pc - pc at time of exception */
                   1268:                ra = kdbpeek(sp + 96);  /* ra at time of exception */
                   1269:                sp = sp + 116;
1.71      jonathan 1270:                goto specialframe;
                   1271:        }
1.42      jonathan 1272: #endif /* MIPS1 */
1.35      jonathan 1273:
1.42      jonathan 1274: #ifdef MIPS3           /* r4000 family (mips-III cpu) */
1.92      jonathan 1275:        if (pcBetween(mips3_KernIntr, mips3_KernIntrEnd)) {
1.35      jonathan 1276:                /* NOTE: the offsets depend on the code in locore.s */
1.71      jonathan 1277:                (*printfn)("------ mips3 KernIntr+%x: (%x, %x ,%x) -------\n",
1.50      jonathan 1278:                       pc-(unsigned)mips3_KernIntr, a0, a1, a2);
1.99      castor   1279:                a0 = kdbrpeek(sp + 28 + sizeof(mips_reg_t) * 3);
                   1280:                a1 = kdbrpeek(sp + 28 + sizeof(mips_reg_t) * 4);
                   1281:                a2 = kdbrpeek(sp + 28 + sizeof(mips_reg_t) * 5);
                   1282:                a3 = kdbrpeek(sp + 28 + sizeof(mips_reg_t) * 6);
                   1283:                pc = kdbrpeek(sp + 28 + sizeof(mips_reg_t) * 21);
                   1284:                ra = kdbrpeek(sp + 28 + sizeof(mips_reg_t) * 17);
                   1285:                sp = sp + 4 * 5 + 4 + 4 + 22 * sizeof(mips_reg_t);
1.35      jonathan 1286:                goto specialframe;
                   1287:        }
1.92      jonathan 1288:        else if (pcBetween(mips3_KernGenException, mips3_KernGenExceptionEnd)) {
1.71      jonathan 1289:                /* NOTE: the offsets depend on the code in locore.s */
                   1290:                (*printfn)("------ kernel trap+%x: (%x, %x ,%x) -------\n",
                   1291:                       pc-(unsigned)mips3_KernGenException, a0, a1, a2);
                   1292:
1.99      castor   1293:                a0 = kdbrpeek(sp + 28 + sizeof(mips_reg_t) * 3);
                   1294:                a1 = kdbrpeek(sp + 28 + sizeof(mips_reg_t) * 4);
                   1295:                a2 = kdbrpeek(sp + 28 + sizeof(mips_reg_t) * 5);
                   1296:                a3 = kdbrpeek(sp + 28 + sizeof(mips_reg_t) * 6);
                   1297:                pc = kdbrpeek(sp + 28 + sizeof(mips_reg_t) * 21);
                   1298:                ra = kdbrpeek(sp + 28 + sizeof(mips_reg_t) * 17);
                   1299:                sp = sp + 4 * 5 + 4 + 4 + 22 * sizeof(mips_reg_t);
1.71      jonathan 1300:                goto specialframe;
                   1301:        }
1.42      jonathan 1302: #endif /* MIPS3 */
1.1       deraadt  1303:
1.99      castor   1304: #endif
1.47      jonathan 1305:
                   1306:        /* Check for bad PC */
1.1       deraadt  1307:        if (pc & 3 || pc < 0x80000000 || pc >= (unsigned)edata) {
1.37      jonathan 1308:                (*printfn)("PC 0x%x: not in kernel space\n", pc);
                   1309:                ra = 0;
                   1310:                goto done;
                   1311:        }
1.1       deraadt  1312:
                   1313:        /*
                   1314:         * Find the beginning of the current subroutine by scanning backwards
                   1315:         * from the current PC for the end of the previous subroutine.
                   1316:         */
1.99      castor   1317:        va = pc;
                   1318:        do {
1.1       deraadt  1319:                va -= sizeof(int);
1.99      castor   1320:                if (va <= (unsigned)verylocore)
                   1321:                        goto finish;
                   1322:                instr = kdbpeek(va);
                   1323:                if (instr == MIPS_ERET)
                   1324:                        goto mips3_eret;
                   1325:        } while (instr != MIPS_JR_RA && instr != MIPS_JR_K0);
                   1326:        /* skip back over branch & delay slot */
                   1327:        va += sizeof(int);
                   1328: mips3_eret:
                   1329:        va += sizeof(int);
                   1330:        /* skip over nulls which might separate .o files */
                   1331:        while ((instr = kdbpeek(va)) == 0)
                   1332:                va += sizeof(int);
                   1333:        subr = va;
1.1       deraadt  1334:
                   1335:        /* scan forwards to find stack size and any saved registers */
                   1336:        stksize = 0;
                   1337:        more = 3;
                   1338:        mask = 0;
1.71      jonathan 1339:        foundframesize = 0;
1.16      jonathan 1340:        for (va = subr; more; va += sizeof(int),
1.97      nisimura 1341:                              more = (more == 3) ? 3 : more - 1) {
1.1       deraadt  1342:                /* stop if hit our current position */
                   1343:                if (va >= pc)
                   1344:                        break;
                   1345:                instr = kdbpeek(va);
                   1346:                i.word = instr;
                   1347:                switch (i.JType.op) {
                   1348:                case OP_SPECIAL:
                   1349:                        switch (i.RType.func) {
                   1350:                        case OP_JR:
                   1351:                        case OP_JALR:
                   1352:                                more = 2; /* stop after next instruction */
                   1353:                                break;
                   1354:
                   1355:                        case OP_SYSCALL:
                   1356:                        case OP_BREAK:
                   1357:                                more = 1; /* stop now */
                   1358:                        };
                   1359:                        break;
                   1360:
                   1361:                case OP_BCOND:
                   1362:                case OP_J:
                   1363:                case OP_JAL:
                   1364:                case OP_BEQ:
                   1365:                case OP_BNE:
                   1366:                case OP_BLEZ:
                   1367:                case OP_BGTZ:
                   1368:                        more = 2; /* stop after next instruction */
                   1369:                        break;
                   1370:
                   1371:                case OP_COP0:
                   1372:                case OP_COP1:
                   1373:                case OP_COP2:
                   1374:                case OP_COP3:
                   1375:                        switch (i.RType.rs) {
                   1376:                        case OP_BCx:
                   1377:                        case OP_BCy:
                   1378:                                more = 2; /* stop after next instruction */
                   1379:                        };
                   1380:                        break;
                   1381:
                   1382:                case OP_SW:
                   1383:                        /* look for saved registers on the stack */
                   1384:                        if (i.IType.rs != 29)
                   1385:                                break;
                   1386:                        /* only restore the first one */
                   1387:                        if (mask & (1 << i.IType.rt))
                   1388:                                break;
1.16      jonathan 1389:                        mask |= (1 << i.IType.rt);
1.1       deraadt  1390:                        switch (i.IType.rt) {
                   1391:                        case 4: /* a0 */
                   1392:                                a0 = kdbpeek(sp + (short)i.IType.imm);
                   1393:                                break;
                   1394:
                   1395:                        case 5: /* a1 */
                   1396:                                a1 = kdbpeek(sp + (short)i.IType.imm);
                   1397:                                break;
                   1398:
                   1399:                        case 6: /* a2 */
                   1400:                                a2 = kdbpeek(sp + (short)i.IType.imm);
                   1401:                                break;
                   1402:
                   1403:                        case 7: /* a3 */
                   1404:                                a3 = kdbpeek(sp + (short)i.IType.imm);
                   1405:                                break;
                   1406:
                   1407:                        case 30: /* fp */
                   1408:                                fp = kdbpeek(sp + (short)i.IType.imm);
                   1409:                                break;
                   1410:
                   1411:                        case 31: /* ra */
                   1412:                                ra = kdbpeek(sp + (short)i.IType.imm);
                   1413:                        }
                   1414:                        break;
                   1415:
                   1416:                case OP_ADDI:
                   1417:                case OP_ADDIU:
                   1418:                        /* look for stack pointer adjustment */
                   1419:                        if (i.IType.rs != 29 || i.IType.rt != 29)
                   1420:                                break;
1.71      jonathan 1421:                        /* don't count pops for mcount */
                   1422:                        if (!foundframesize) {
                   1423:                                stksize = - ((short)i.IType.imm);
                   1424:                                foundframesize = 1;
                   1425:                        }
1.1       deraadt  1426:                }
                   1427:        }
                   1428: done:
1.16      jonathan 1429:        (*printfn)("%s+%x (%x,%x,%x,%x) ra %x sz %d\n",
                   1430:                fn_name(subr), pc - subr, a0, a1, a2, a3, ra, stksize);
1.1       deraadt  1431:
                   1432:        if (ra) {
                   1433:                if (pc == ra && stksize == 0)
1.16      jonathan 1434:                        (*printfn)("stacktrace: loop!\n");
1.1       deraadt  1435:                else {
                   1436:                        pc = ra;
1.16      jonathan 1437:                        sp += stksize;
                   1438:                        ra = 0;
1.1       deraadt  1439:                        goto loop;
                   1440:                }
1.16      jonathan 1441:        } else {
1.17      jonathan 1442: finish:
1.16      jonathan 1443:                if (curproc)
                   1444:                        (*printfn)("User-level: pid %d\n", curproc->p_pid);
                   1445:                else
                   1446:                        (*printfn)("User-level: curproc NULL\n");
1.1       deraadt  1447:        }
                   1448: }
1.16      jonathan 1449:
                   1450: /*
                   1451:  * Functions ``special'' enough to print by name
                   1452:  */
                   1453: #ifdef __STDC__
                   1454: #define Name(_fn)  { (void*)_fn, # _fn }
                   1455: #else
                   1456: #define Name(_fn) { _fn, "_fn"}
                   1457: #endif
                   1458: static struct { void *addr; char *name;} names[] = {
1.23      jonathan 1459:        Name(stacktrace),
                   1460:        Name(stacktrace_subr),
                   1461:        Name(main),
1.16      jonathan 1462:        Name(interrupt),
                   1463:        Name(trap),
1.42      jonathan 1464:
                   1465: #ifdef MIPS1   /*  r2000 family  (mips-I cpu) */
1.50      jonathan 1466:        Name(mips1_KernGenException),
                   1467:        Name(mips1_UserGenException),
1.57      mhitch   1468:        Name(mips1_SystemCall),
1.50      jonathan 1469:        Name(mips1_KernIntr),
                   1470:        Name(mips1_UserIntr),
1.42      jonathan 1471: #endif /* MIPS1 */
1.35      jonathan 1472:
1.42      jonathan 1473: #ifdef MIPS3           /* r4000 family (mips-III cpu) */
1.50      jonathan 1474:        Name(mips3_KernGenException),
                   1475:        Name(mips3_UserGenException),
1.57      mhitch   1476:        Name(mips3_SystemCall),
1.50      jonathan 1477:        Name(mips3_KernIntr),
                   1478:        Name(mips3_UserIntr),
1.42      jonathan 1479: #endif /* MIPS3 */
1.35      jonathan 1480:
1.16      jonathan 1481:        Name(idle),
                   1482:        Name(cpu_switch),
                   1483:        {0, 0}
                   1484: };
                   1485:
                   1486: /*
                   1487:  * Map a function address to a string name, if known; or a hex string.
                   1488:  */
                   1489: char *
                   1490: fn_name(unsigned addr)
                   1491: {
                   1492:        static char buf[17];
                   1493:        int i = 0;
1.77      mhitch   1494: #ifdef DDB
                   1495:        db_expr_t diff;
                   1496:        db_sym_t sym;
                   1497:        char *symname;
                   1498: #endif
1.16      jonathan 1499:
1.77      mhitch   1500: #ifdef DDB
                   1501:        diff = 0;
                   1502:        symname = NULL;
                   1503:        sym = db_search_symbol(addr, DB_STGY_ANY, &diff);
                   1504:        db_symbol_values(sym, &symname, 0);
                   1505:        if (symname && diff == 0)
                   1506:                return (symname);
                   1507: #endif
1.16      jonathan 1508:        for (i = 0; names[i].name; i++)
                   1509:                if (names[i].addr == (void*)addr)
                   1510:                        return (names[i].name);
1.45      christos 1511:        sprintf(buf, "%x", addr);
1.16      jonathan 1512:        return (buf);
                   1513: }
                   1514:
1.1       deraadt  1515: #endif /* DEBUG */
1.57      mhitch   1516:
1.99      castor   1517: #endif /* DDB_TRACE */

CVSweb <webmaster@jp.NetBSD.org>