[BACK]Return to db_interface.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc64 / sparc64

Annotation of sys/arch/sparc64/sparc64/db_interface.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: db_interface.c,v 1.23 2007/05/02 18:46:07 kettenis Exp $      */
                      2: /*     $NetBSD: db_interface.c,v 1.61 2001/07/31 06:55:47 eeh Exp $ */
                      3:
                      4: /*
                      5:  * Mach Operating System
                      6:  * Copyright (c) 1991,1990 Carnegie Mellon University
                      7:  * All Rights Reserved.
                      8:  *
                      9:  * Permission to use, copy, modify and distribute this software and its
                     10:  * documentation is hereby granted, provided that both the copyright
                     11:  * notice and this permission notice appear in all copies of the
                     12:  * software, derivative works or modified versions, and any portions
                     13:  * thereof, and that both notices appear in supporting documentation.
                     14:  *
                     15:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     16:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     17:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     18:  *
                     19:  * Carnegie Mellon requests users of this software to return to
                     20:  *
                     21:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     22:  *  School of Computer Science
                     23:  *  Carnegie Mellon University
                     24:  *  Pittsburgh PA 15213-3890
                     25:  *
                     26:  * any improvements or extensions that they make and grant Carnegie the
                     27:  * rights to redistribute these changes.
                     28:  *
                     29:  *     From: db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
                     30:  */
                     31:
                     32: #include <sys/param.h>
                     33: #include <sys/proc.h>
                     34: #include <sys/user.h>
                     35: #include <sys/reboot.h>
                     36: #include <sys/systm.h>
                     37:
                     38: #include <uvm/uvm_extern.h>
                     39:
                     40: #include <dev/cons.h>
                     41:
                     42: #include <machine/db_machdep.h>
                     43: #include <ddb/db_command.h>
                     44: #include <ddb/db_sym.h>
                     45: #include <ddb/db_variables.h>
                     46: #include <ddb/db_extern.h>
                     47: #include <ddb/db_access.h>
                     48: #include <ddb/db_output.h>
                     49: #include <ddb/db_interface.h>
                     50:
                     51: #include <machine/instr.h>
                     52: #include <machine/cpu.h>
                     53: #include <machine/openfirm.h>
                     54: #include <machine/ctlreg.h>
                     55: #include <machine/pmap.h>
                     56:
                     57: #ifdef notyet
                     58: #include "fb.h"
                     59: #include "esp_sbus.h"
                     60: #endif
                     61:
                     62: db_regs_t      ddb_regs;       /* register state */
                     63:
                     64: extern void OF_enter(void);
                     65:
                     66: extern struct traptrace {
                     67:        unsigned short tl:3,    /* Trap level */
                     68:                ns:4,           /* PCB nsaved */
                     69:                tt:9;           /* Trap type */
                     70:        unsigned short pid;     /* PID */
                     71:        u_int tstate;           /* tstate */
                     72:        u_int tsp;              /* sp */
                     73:        u_int tpc;              /* pc */
                     74:        u_int tfault;           /* MMU tag access */
                     75: } trap_trace[], trap_trace_end[];
                     76:
                     77: static long nil;
                     78:
                     79: static int
                     80: db__char_value(struct db_variable *var, db_expr_t *expr, int mode)
                     81: {
                     82:
                     83:        switch (mode) {
                     84:        case DB_VAR_SET:
                     85:                *var->valuep = *(char *)expr;
                     86:                break;
                     87:        case DB_VAR_GET:
                     88:                *expr = *(char *)var->valuep;
                     89:                break;
                     90: #ifdef DIAGNOSTIC
                     91:        default:
                     92:                printf("db__char_value: mode %d\n", mode);
                     93:                break;
                     94: #endif
                     95:        }
                     96:
                     97:        return 0;
                     98: }
                     99:
                    100: #ifdef notdef_yet
                    101: static int
                    102: db__short_value(struct db_variable *var, db_expr_t *expr, int mode)
                    103: {
                    104:
                    105:        switch (mode) {
                    106:        case DB_VAR_SET:
                    107:                *var->valuep = *(short *)expr;
                    108:                break;
                    109:        case DB_VAR_GET:
                    110:                *expr = *(short *)var->valuep;
                    111:                break;
                    112: #ifdef DIAGNOSTIC
                    113:        default:
                    114:                printf("db__short_value: mode %d\n", mode);
                    115:                break;
                    116: #endif
                    117:        }
                    118:
                    119:        return 0;
                    120: }
                    121: #endif
                    122:
                    123: struct db_variable db_regs[] = {
                    124:        { "tstate", (long *)&DDB_TF->tf_tstate, FCN_NULL, },
                    125:        { "pc", (long *)&DDB_TF->tf_pc, FCN_NULL, },
                    126:        { "npc", (long *)&DDB_TF->tf_npc, FCN_NULL, },
                    127:        { "ipl", (long *)&DDB_TF->tf_oldpil, db__char_value, },
                    128:        { "y", (long *)&DDB_TF->tf_y, db_var_rw_int, },
                    129:        { "g0", (long *)&nil, FCN_NULL, },
                    130:        { "g1", (long *)&DDB_TF->tf_global[1], FCN_NULL, },
                    131:        { "g2", (long *)&DDB_TF->tf_global[2], FCN_NULL, },
                    132:        { "g3", (long *)&DDB_TF->tf_global[3], FCN_NULL, },
                    133:        { "g4", (long *)&DDB_TF->tf_global[4], FCN_NULL, },
                    134:        { "g5", (long *)&DDB_TF->tf_global[5], FCN_NULL, },
                    135:        { "g6", (long *)&DDB_TF->tf_global[6], FCN_NULL, },
                    136:        { "g7", (long *)&DDB_TF->tf_global[7], FCN_NULL, },
                    137:        { "o0", (long *)&DDB_TF->tf_out[0], FCN_NULL, },
                    138:        { "o1", (long *)&DDB_TF->tf_out[1], FCN_NULL, },
                    139:        { "o2", (long *)&DDB_TF->tf_out[2], FCN_NULL, },
                    140:        { "o3", (long *)&DDB_TF->tf_out[3], FCN_NULL, },
                    141:        { "o4", (long *)&DDB_TF->tf_out[4], FCN_NULL, },
                    142:        { "o5", (long *)&DDB_TF->tf_out[5], FCN_NULL, },
                    143:        { "o6", (long *)&DDB_TF->tf_out[6], FCN_NULL, },
                    144:        { "o7", (long *)&DDB_TF->tf_out[7], FCN_NULL, },
                    145:        { "l0", (long *)&DDB_TF->tf_local[0], FCN_NULL, },
                    146:        { "l1", (long *)&DDB_TF->tf_local[1], FCN_NULL, },
                    147:        { "l2", (long *)&DDB_TF->tf_local[2], FCN_NULL, },
                    148:        { "l3", (long *)&DDB_TF->tf_local[3], FCN_NULL, },
                    149:        { "l4", (long *)&DDB_TF->tf_local[4], FCN_NULL, },
                    150:        { "l5", (long *)&DDB_TF->tf_local[5], FCN_NULL, },
                    151:        { "l6", (long *)&DDB_TF->tf_local[6], FCN_NULL, },
                    152:        { "l7", (long *)&DDB_TF->tf_local[7], FCN_NULL, },
                    153:        { "i0", (long *)&DDB_FR->fr_arg[0], FCN_NULL, },
                    154:        { "i1", (long *)&DDB_FR->fr_arg[1], FCN_NULL, },
                    155:        { "i2", (long *)&DDB_FR->fr_arg[2], FCN_NULL, },
                    156:        { "i3", (long *)&DDB_FR->fr_arg[3], FCN_NULL, },
                    157:        { "i4", (long *)&DDB_FR->fr_arg[4], FCN_NULL, },
                    158:        { "i5", (long *)&DDB_FR->fr_arg[5], FCN_NULL, },
                    159:        { "i6", (long *)&DDB_FR->fr_arg[6], FCN_NULL, },
                    160:        { "i7", (long *)&DDB_FR->fr_arg[7], FCN_NULL, },
                    161:        { "f0", (long *)&DDB_FP->fs_regs[0], FCN_NULL, },
                    162:        { "f2", (long *)&DDB_FP->fs_regs[2], FCN_NULL, },
                    163:        { "f4", (long *)&DDB_FP->fs_regs[4], FCN_NULL, },
                    164:        { "f6", (long *)&DDB_FP->fs_regs[6], FCN_NULL, },
                    165:        { "f8", (long *)&DDB_FP->fs_regs[8], FCN_NULL, },
                    166:        { "f10", (long *)&DDB_FP->fs_regs[10], FCN_NULL, },
                    167:        { "f12", (long *)&DDB_FP->fs_regs[12], FCN_NULL, },
                    168:        { "f14", (long *)&DDB_FP->fs_regs[14], FCN_NULL, },
                    169:        { "f16", (long *)&DDB_FP->fs_regs[16], FCN_NULL, },
                    170:        { "f18", (long *)&DDB_FP->fs_regs[18], FCN_NULL, },
                    171:        { "f20", (long *)&DDB_FP->fs_regs[20], FCN_NULL, },
                    172:        { "f22", (long *)&DDB_FP->fs_regs[22], FCN_NULL, },
                    173:        { "f24", (long *)&DDB_FP->fs_regs[24], FCN_NULL, },
                    174:        { "f26", (long *)&DDB_FP->fs_regs[26], FCN_NULL, },
                    175:        { "f28", (long *)&DDB_FP->fs_regs[28], FCN_NULL, },
                    176:        { "f30", (long *)&DDB_FP->fs_regs[30], FCN_NULL, },
                    177:        { "f32", (long *)&DDB_FP->fs_regs[32], FCN_NULL, },
                    178:        { "f34", (long *)&DDB_FP->fs_regs[34], FCN_NULL, },
                    179:        { "f36", (long *)&DDB_FP->fs_regs[36], FCN_NULL, },
                    180:        { "f38", (long *)&DDB_FP->fs_regs[38], FCN_NULL, },
                    181:        { "f40", (long *)&DDB_FP->fs_regs[40], FCN_NULL, },
                    182:        { "f42", (long *)&DDB_FP->fs_regs[42], FCN_NULL, },
                    183:        { "f44", (long *)&DDB_FP->fs_regs[44], FCN_NULL, },
                    184:        { "f46", (long *)&DDB_FP->fs_regs[46], FCN_NULL, },
                    185:        { "f48", (long *)&DDB_FP->fs_regs[48], FCN_NULL, },
                    186:        { "f50", (long *)&DDB_FP->fs_regs[50], FCN_NULL, },
                    187:        { "f52", (long *)&DDB_FP->fs_regs[52], FCN_NULL, },
                    188:        { "f54", (long *)&DDB_FP->fs_regs[54], FCN_NULL, },
                    189:        { "f56", (long *)&DDB_FP->fs_regs[56], FCN_NULL, },
                    190:        { "f58", (long *)&DDB_FP->fs_regs[58], FCN_NULL, },
                    191:        { "f60", (long *)&DDB_FP->fs_regs[60], FCN_NULL, },
                    192:        { "f62", (long *)&DDB_FP->fs_regs[62], FCN_NULL, },
                    193:        { "fsr", (long *)&DDB_FP->fs_fsr, FCN_NULL, },
                    194:        { "gsr", (long *)&DDB_FP->fs_gsr, FCN_NULL, },
                    195:
                    196: };
                    197: struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
                    198:
                    199: extern label_t *db_recover;
                    200:
                    201: int    db_active = 0;
                    202:
                    203: extern char *trap_type[];
                    204:
                    205: void kdb_kbd_trap(struct trapframe64 *);
                    206: void db_prom_cmd(db_expr_t, int, db_expr_t, char *);
                    207: void db_proc_cmd(db_expr_t, int, db_expr_t, char *);
                    208: void db_ctx_cmd(db_expr_t, int, db_expr_t, char *);
                    209: void db_dump_window(db_expr_t, int, db_expr_t, char *);
                    210: void db_dump_stack(db_expr_t, int, db_expr_t, char *);
                    211: void db_dump_trap(db_expr_t, int, db_expr_t, char *);
                    212: void db_dump_fpstate(db_expr_t, int, db_expr_t, char *);
                    213: void db_dump_ts(db_expr_t, int, db_expr_t, char *);
                    214: void db_dump_pcb(db_expr_t, int, db_expr_t, char *);
                    215: void db_dump_pv(db_expr_t, int, db_expr_t, char *);
                    216: void db_setpcb(db_expr_t, int, db_expr_t, char *);
                    217: void db_dump_dtlb(db_expr_t, int, db_expr_t, char *);
                    218: void db_dump_itlb(db_expr_t, int, db_expr_t, char *);
                    219: void db_dump_dtsb(db_expr_t, int, db_expr_t, char *);
                    220: void db_pmap_kernel(db_expr_t, int, db_expr_t, char *);
                    221: void db_pload_cmd(db_expr_t, int, db_expr_t, char *);
                    222: void db_pmap_cmd(db_expr_t, int, db_expr_t, char *);
                    223: void db_lock(db_expr_t, int, db_expr_t, char *);
                    224: void db_traptrace(db_expr_t, int, db_expr_t, char *);
                    225: void db_dump_buf(db_expr_t, int, db_expr_t, char *);
                    226: void db_dump_espcmd(db_expr_t, int, db_expr_t, char *);
                    227: void db_watch(db_expr_t, int, db_expr_t, char *);
                    228:
                    229: static void db_dump_pmap(struct pmap*);
                    230: static void db_print_trace_entry(struct traptrace *, int);
                    231:
                    232:
                    233: /*
                    234:  * Received keyboard interrupt sequence.
                    235:  */
                    236: void
                    237: kdb_kbd_trap(tf)
                    238:        struct trapframe64 *tf;
                    239: {
                    240:        if (db_active == 0 /* && (boothowto & RB_KDB) */) {
                    241:                printf("\n\nkernel: keyboard interrupt tf=%p\n", tf);
                    242:                kdb_trap(-1, tf);
                    243:        }
                    244: }
                    245:
                    246: /*
                    247:  *  kdb_trap - field a TRACE or BPT trap
                    248:  */
                    249: int
                    250: kdb_trap(type, tf)
                    251:        int     type;
                    252:        register struct trapframe64 *tf;
                    253: {
                    254:        int s, tl;
                    255:        struct trapstate *ts = &ddb_regs.ddb_ts[0];
                    256:        extern int savetstate(struct trapstate *ts);
                    257:        extern void restoretstate(int tl, struct trapstate *ts);
                    258:        extern int trap_trace_dis;
                    259:
                    260:        trap_trace_dis++;
                    261:
                    262:        fb_unblank();
                    263:
                    264:        switch (type) {
                    265:        case T_BREAKPOINT:      /* breakpoint */
                    266:                printf("kdb breakpoint at %llx\n",
                    267:                    (unsigned long long)tf->tf_pc);
                    268:                break;
                    269:        case -1:                /* keyboard interrupt */
                    270:                printf("kdb tf=%p\n", tf);
                    271:                break;
                    272:        default:
                    273:                printf("kernel trap %x: %s\n", type, trap_type[type & 0x1ff]);
                    274:                if (db_recover != 0) {
                    275:                        OF_enter();
                    276:                        db_error("Faulted in DDB; continuing...\n");
                    277:                        OF_enter();
                    278:                        /*NOTREACHED*/
                    279:                }
                    280:                db_recover = (label_t *)1;
                    281:        }
                    282:
                    283:        /* Should switch to kdb`s own stack here. */
                    284:        write_all_windows();
                    285:
                    286:        ddb_regs.ddb_tf = *tf;
                    287:        if (fpproc) {
                    288:                savefpstate(fpproc->p_md.md_fpstate);
                    289:                ddb_regs.ddb_fpstate = *fpproc->p_md.md_fpstate;
                    290:                loadfpstate(fpproc->p_md.md_fpstate);
                    291:        }
                    292:        /* We should do a proper copyin and xlate 64-bit stack frames, but... */
                    293: /*     if (tf->tf_tstate & TSTATE_PRIV) { */
                    294:
                    295: #if 0
                    296:        /* make sure this is not causing ddb problems. */
                    297:        if (tf->tf_out[6] & 1) {
                    298:                if ((unsigned)(tf->tf_out[6] + BIAS) > (unsigned)KERNBASE)
                    299:                        ddb_regs.ddb_fr = *(struct frame64 *)(tf->tf_out[6] + BIAS);
                    300:                else
                    301:                        copyin((caddr_t)(tf->tf_out[6] + BIAS), &ddb_regs.ddb_fr, sizeof(struct frame64));
                    302:        } else {
                    303:                struct frame32 tfr;
                    304:
                    305:                /* First get a local copy of the frame32 */
                    306:                if ((unsigned)(tf->tf_out[6]) > (unsigned)KERNBASE)
                    307:                        tfr = *(struct frame32 *)tf->tf_out[6];
                    308:                else
                    309:                        copyin((caddr_t)(tf->tf_out[6]), &tfr, sizeof(struct frame32));
                    310:                /* Now copy each field from the 32-bit value to the 64-bit value */
                    311:                for (i=0; i<8; i++)
                    312:                        ddb_regs.ddb_fr.fr_local[i] = tfr.fr_local[i];
                    313:                for (i=0; i<6; i++)
                    314:                        ddb_regs.ddb_fr.fr_arg[i] = tfr.fr_arg[i];
                    315:                ddb_regs.ddb_fr.fr_fp = (long)tfr.fr_fp;
                    316:                ddb_regs.ddb_fr.fr_pc = tfr.fr_pc;
                    317:        }
                    318: #endif
                    319:
                    320:        s = splhigh();
                    321:        db_active++;
                    322:        cnpollc(TRUE);
                    323:        /* Need to do spl stuff till cnpollc works */
                    324:        tl = ddb_regs.ddb_tl = savetstate(ts);
                    325:        db_dump_ts(0, 0, 0, 0);
                    326:        db_trap(type, 0/*code*/);
                    327:        restoretstate(tl,ts);
                    328:        cnpollc(FALSE);
                    329:        db_active--;
                    330:        splx(s);
                    331:
                    332:        if (fpproc) {
                    333:                *fpproc->p_md.md_fpstate = ddb_regs.ddb_fpstate;
                    334:                loadfpstate(fpproc->p_md.md_fpstate);
                    335:        }
                    336: #if 0
                    337:        /* We will not alter the machine's running state until we get everything else working */
                    338:        *(struct frame *)tf->tf_out[6] = ddb_regs.ddb_fr;
                    339: #endif
                    340:        *tf = ddb_regs.ddb_tf;
                    341:        trap_trace_dis--;
                    342:
                    343:        return (1);
                    344: }
                    345:
                    346: /*
                    347:  * Read bytes from kernel address space for debugger.
                    348:  */
                    349: void
                    350: db_read_bytes(addr, size, data)
                    351:        vaddr_t addr;
                    352:        register size_t size;
                    353:        register char   *data;
                    354: {
                    355:        register char   *src;
                    356:
                    357:        src = (char *)addr;
                    358:        while (size-- > 0) {
                    359:                if (src >= (char *)VM_MIN_KERNEL_ADDRESS)
                    360:                        *data++ = probeget((paddr_t)(u_long)src++, ASI_P, 1);
                    361:                else
                    362:                        copyin(src++, data++, sizeof(u_char));
                    363:        }
                    364: }
                    365:
                    366:
                    367: /*
                    368:  * Write bytes to kernel address space for debugger.
                    369:  */
                    370: void
                    371: db_write_bytes(addr, size, data)
                    372:        vaddr_t addr;
                    373:        register size_t size;
                    374:        register char   *data;
                    375: {
                    376:        register char   *dst;
                    377:        extern vaddr_t ktext;
                    378:        extern paddr_t ktextp;
                    379:
                    380:        dst = (char *)addr;
                    381:        while (size-- > 0) {
                    382:                if ((dst >= (char *)VM_MIN_KERNEL_ADDRESS+0x400000))
                    383:                        *dst = *data;
                    384:                else if ((dst >= (char *)VM_MIN_KERNEL_ADDRESS) &&
                    385:                         (dst < (char *)VM_MIN_KERNEL_ADDRESS+0x400000))
                    386:                        /* Read Only mapping -- need to do a bypass access */
                    387:                        stba((u_long)dst - ktext + ktextp, ASI_PHYS_CACHED, *data);
                    388:                else
                    389:                        copyout(data, dst, sizeof(char));
                    390:                dst++, data++;
                    391:        }
                    392:
                    393: }
                    394:
                    395: void
                    396: Debugger()
                    397: {
                    398:        /* We use the breakpoint to trap into DDB */
                    399:        asm("ta 1; nop");
                    400: }
                    401:
                    402: void
                    403: db_prom_cmd(addr, have_addr, count, modif)
                    404:        db_expr_t addr;
                    405:        int have_addr;
                    406:        db_expr_t count;
                    407:        char *modif;
                    408: {
                    409:        OF_enter();
                    410: }
                    411:
                    412: #define CHEETAHP (((getver()>>32) & 0x1ff) >= 0x14)
                    413: unsigned long db_get_dtlb_data(int entry), db_get_dtlb_tag(int entry),
                    414: db_get_itlb_data(int entry), db_get_itlb_tag(int entry);
                    415: void db_print_itlb_entry(int entry, int i, int endc);
                    416: void db_print_dtlb_entry(int entry, int i, int endc);
                    417:
                    418: extern __inline__ unsigned long db_get_dtlb_data(int entry)
                    419: {
                    420:        unsigned long r;
                    421:        __asm__ __volatile__("ldxa [%1] %2,%0"
                    422:                : "=r" (r)
                    423:                : "r" (entry <<3), "i" (ASI_DMMU_TLB_DATA));
                    424:        return r;
                    425: }
                    426: extern __inline__ unsigned long db_get_dtlb_tag(int entry)
                    427: {
                    428:        unsigned long r;
                    429:        __asm__ __volatile__("ldxa [%1] %2,%0"
                    430:                : "=r" (r)
                    431:                : "r" (entry <<3), "i" (ASI_DMMU_TLB_TAG));
                    432:        return r;
                    433: }
                    434: extern __inline__ unsigned long db_get_itlb_data(int entry)
                    435: {
                    436:        unsigned long r;
                    437:        __asm__ __volatile__("ldxa [%1] %2,%0"
                    438:                : "=r" (r)
                    439:                : "r" (entry <<3), "i" (ASI_IMMU_TLB_DATA));
                    440:        return r;
                    441: }
                    442: extern __inline__ unsigned long db_get_itlb_tag(int entry)
                    443: {
                    444:        unsigned long r;
                    445:        __asm__ __volatile__("ldxa [%1] %2,%0"
                    446:                : "=r" (r)
                    447:                : "r" (entry <<3), "i" (ASI_IMMU_TLB_TAG));
                    448:        return r;
                    449: }
                    450:
                    451: void db_print_dtlb_entry(int entry, int i, int endc)
                    452: {
                    453:        unsigned long tag, data;
                    454:        tag = db_get_dtlb_tag(entry);
                    455:        data = db_get_dtlb_data(entry);
                    456:        db_printf("%2d:%16.16lx %16.16lx%c", i, tag, data, endc);
                    457: }
                    458:
                    459: void db_print_itlb_entry(int entry, int i, int endc)
                    460: {
                    461:        unsigned long tag, data;
                    462:        tag = db_get_itlb_tag(entry);
                    463:        data = db_get_itlb_data(entry);
                    464:        db_printf("%2d:%16.16lx %16.16lx%c", i, tag, data, endc);
                    465: }
                    466:
                    467: void
                    468: db_dump_dtlb(addr, have_addr, count, modif)
                    469:        db_expr_t addr;
                    470:        int have_addr;
                    471:        db_expr_t count;
                    472:        char *modif;
                    473: {
                    474:        /* extern void print_dtlb(void); -- locore.s; no longer used here */
                    475:
                    476:        if (have_addr) {
                    477:                int i;
                    478:                int64_t* p = (int64_t*)addr;
                    479:                static int64_t buf[128];
                    480:                extern void dump_dtlb(int64_t *);
                    481:
                    482:        if (CHEETAHP) {
                    483:                db_printf("DTLB %ld\n", addr);
                    484:                switch(addr)
                    485:                {
                    486:                case 0:
                    487:                        for (i = 0; i < 16; ++i)
                    488:                                db_print_dtlb_entry(i, i, (i&1)?'\n':' ');
                    489:                        break;
                    490:                case 2:
                    491:                        for (i = 0; i < 512; ++i)
                    492:                                db_print_dtlb_entry(i+16384, i, (i&1)?'\n':' ');
                    493:                        break;
                    494:                }
                    495:        } else {
                    496:                dump_dtlb(buf);
                    497:                p = buf;
                    498:                for (i=0; i<64;) {
                    499:                        db_printf("%2d:%16.16llx %16.16llx ", i++, p[0], p[1]);
                    500:                        p += 2;
                    501:                        db_printf("%2d:%16.16llx %16.16llx\n", i++, p[0], p[1]);
                    502:                        p += 2;
                    503:                }
                    504:        }
                    505:        } else {
                    506: printf ("Usage: mach dtlb 0,2\n");
                    507:        }
                    508: }
                    509:
                    510: void
                    511: db_dump_itlb(addr, have_addr, count, modif)
                    512:        db_expr_t addr;
                    513:        int have_addr;
                    514:        db_expr_t count;
                    515:        char *modif;
                    516: {
                    517:        int i;
                    518:        if (!have_addr) {
                    519:                db_printf("Usage: mach itlb 0,1,2\n");
                    520:                return;
                    521:        }
                    522:        if (CHEETAHP) {
                    523:                db_printf("ITLB %ld\n", addr);
                    524:                switch(addr)
                    525:                {
                    526:                case 0:
                    527:                        for (i = 0; i < 16; ++i)
                    528:                                db_print_itlb_entry(i, i, (i&1)?'\n':' ');
                    529:                        break;
                    530:                case 2:
                    531:                        for (i = 0; i < 128; ++i)
                    532:                                db_print_itlb_entry(i+16384, i, (i&1)?'\n':' ');
                    533:                        break;
                    534:                }
                    535:        } else {
                    536:                for (i = 0; i < 63; ++i)
                    537:                        db_print_itlb_entry(i, i, (i&1)?'\n':' ');
                    538:        }
                    539: }
                    540:
                    541: void
                    542: db_pload_cmd(addr, have_addr, count, modif)
                    543:        db_expr_t addr;
                    544:        int have_addr;
                    545:        db_expr_t count;
                    546:        char *modif;
                    547: {
                    548:        static paddr_t oldaddr = -1;
                    549:        int asi = ASI_PHYS_CACHED;
                    550:
                    551:        if (!have_addr) {
                    552:                addr = oldaddr;
                    553:        }
                    554:        if (addr == -1) {
                    555:                db_printf("no address\n");
                    556:                return;
                    557:        }
                    558:        addr &= ~0x7; /* align */
                    559:        {
                    560:                register char c, *cp = modif;
                    561:                while ((c = *cp++) != 0)
                    562:                        if (c == 'u')
                    563:                                asi = ASI_AIUS;
                    564:        }
                    565:        while (count--) {
                    566:                if (db_print_position() == 0) {
                    567:                        /* Always print the address. */
                    568:                        db_printf("%16.16lx:\t", addr);
                    569:                }
                    570:                oldaddr=addr;
                    571:                db_printf("%8.8lx\n", (long)ldxa(addr, asi));
                    572:                addr += 8;
                    573:                if (db_print_position() != 0)
                    574:                        db_end_line(0);
                    575:        }
                    576: }
                    577:
                    578: int64_t pseg_get(struct pmap *, vaddr_t);
                    579:
                    580: void
                    581: db_dump_pmap(pm)
                    582: struct pmap* pm;
                    583: {
                    584:        /* print all valid pages in the kernel pmap */
                    585:        long i, j, k, n;
                    586:        paddr_t *pdir, *ptbl;
                    587:        /* Almost the same as pmap_collect() */
                    588:
                    589:        n = 0;
                    590:        for (i=0; i<STSZ; i++) {
                    591:                if((pdir = (paddr_t *)(u_long)ldxa((vaddr_t)&pm->pm_segs[i], ASI_PHYS_CACHED))) {
                    592:                        db_printf("pdir %ld at %lx:\n", i, (long)pdir);
                    593:                        for (k=0; k<PDSZ; k++) {
                    594:                                if ((ptbl = (paddr_t *)(u_long)ldxa((vaddr_t)&pdir[k], ASI_PHYS_CACHED))) {
                    595:                                        db_printf("\tptable %ld:%ld at %lx:\n", i, k, (long)ptbl);
                    596:                                        for (j=0; j<PTSZ; j++) {
                    597:                                                int64_t data0, data1;
                    598:                                                data0 = ldxa((vaddr_t)&ptbl[j], ASI_PHYS_CACHED);
                    599:                                                j++;
                    600:                                                data1 = ldxa((vaddr_t)&ptbl[j], ASI_PHYS_CACHED);
                    601:                                                if (data0 || data1) {
                    602:                                                        db_printf("%llx: %llx\t",
                    603:                                                                  (unsigned long long)(((u_int64_t)i<<STSHIFT)|(k<<PDSHIFT)|((j-1)<<PTSHIFT)),
                    604:                                                                  (unsigned long long)(data0));
                    605:                                                        db_printf("%llx: %llx\n",
                    606:                                                                  (unsigned long long)(((u_int64_t)i<<STSHIFT)|(k<<PDSHIFT)|(j<<PTSHIFT)),
                    607:                                                                  (unsigned long long)(data1));
                    608:                                                }
                    609:                                        }
                    610:                                }
                    611:                        }
                    612:                }
                    613:        }
                    614: }
                    615:
                    616: void
                    617: db_pmap_kernel(addr, have_addr, count, modif)
                    618:        db_expr_t addr;
                    619:        int have_addr;
                    620:        db_expr_t count;
                    621:        char *modif;
                    622: {
                    623:        extern struct pmap kernel_pmap_;
                    624:        int i, j, full = 0;
                    625:        u_int64_t data;
                    626:
                    627:        {
                    628:                register char c, *cp = modif;
                    629:                while ((c = *cp++) != 0)
                    630:                        if (c == 'f')
                    631:                                full = 1;
                    632:        }
                    633:        if (have_addr) {
                    634:                /* lookup an entry for this VA */
                    635:
                    636:                if ((data = pseg_get(&kernel_pmap_, (vaddr_t)addr))) {
                    637:                        db_printf("pmap_kernel(%p)->pm_segs[%lx][%lx][%lx]=>%qx\n",
                    638:                                  (void *)addr, (u_long)va_to_seg(addr),
                    639:                                  (u_long)va_to_dir(addr), (u_long)va_to_pte(addr),
                    640:                                  (unsigned long long)data);
                    641:                } else {
                    642:                        db_printf("No mapping for %p\n", (void *)addr);
                    643:                }
                    644:                return;
                    645:        }
                    646:
                    647:        db_printf("pmap_kernel(%p) psegs %p phys %llx\n",
                    648:                  &kernel_pmap_, kernel_pmap_.pm_segs,
                    649:                  (unsigned long long)kernel_pmap_.pm_physaddr);
                    650:        if (full) {
                    651:                db_dump_pmap(&kernel_pmap_);
                    652:        } else {
                    653:                for (j=i=0; i<STSZ; i++) {
                    654:                        long seg = (long)ldxa((vaddr_t)&kernel_pmap_.pm_segs[i], ASI_PHYS_CACHED);
                    655:                        if (seg)
                    656:                                db_printf("seg %d => %lx%c", i, seg, (j++%4)?'\t':'\n');
                    657:                }
                    658:        }
                    659: }
                    660:
                    661:
                    662: void
                    663: db_pmap_cmd(addr, have_addr, count, modif)
                    664:        db_expr_t addr;
                    665:        int have_addr;
                    666:        db_expr_t count;
                    667:        char *modif;
                    668: {
                    669:        struct pmap* pm=NULL;
                    670:        int i, j=0, full = 0;
                    671:
                    672:        {
                    673:                register char c, *cp = modif;
                    674:                if (modif)
                    675:                        while ((c = *cp++) != 0)
                    676:                                if (c == 'f')
                    677:                                        full = 1;
                    678:        }
                    679:        if (curproc && curproc->p_vmspace)
                    680:                pm = curproc->p_vmspace->vm_map.pmap;
                    681:        if (have_addr) {
                    682:                pm = (struct pmap*)addr;
                    683:        }
                    684:
                    685:        db_printf("pmap %p: ctx %x refs %d physaddr %llx psegs %p\n",
                    686:                pm, pm->pm_ctx, pm->pm_refs,
                    687:                (unsigned long long)pm->pm_physaddr, pm->pm_segs);
                    688:
                    689:        if (full) {
                    690:                db_dump_pmap(pm);
                    691:        } else {
                    692:                for (i=0; i<STSZ; i++) {
                    693:                        long seg = (long)ldxa((vaddr_t)&kernel_pmap_.pm_segs[i], ASI_PHYS_CACHED);
                    694:                        if (seg)
                    695:                                db_printf("seg %d => %lx%c", i, seg, (j++%4)?'\t':'\n');
                    696:                }
                    697:        }
                    698: }
                    699:
                    700:
                    701: void
                    702: db_lock(addr, have_addr, count, modif)
                    703:        db_expr_t addr;
                    704:        int have_addr;
                    705:        db_expr_t count;
                    706:        char *modif;
                    707: {
                    708: #if 0
                    709:        struct lock *l;
                    710:
                    711:        if (!have_addr) {
                    712:                db_printf("What lock address?\n");
                    713:                return;
                    714:        }
                    715:
                    716:        l = (struct lock *)addr;
                    717:        db_printf("flags=%x\n waitcount=%x sharecount=%x "
                    718:            "exclusivecount=%x\n wmesg=%s recurselevel=%x\n",
                    719:            l->lk_flags, l->lk_waitcount,
                    720:            l->lk_sharecount, l->lk_exclusivecount, l->lk_wmesg,
                    721:            l->lk_recurselevel);
                    722: #else
                    723:        db_printf("locks unsupported\n");
                    724: #endif
                    725: }
                    726:
                    727: void
                    728: db_dump_dtsb(addr, have_addr, count, modif)
                    729:        db_expr_t addr;
                    730:        int have_addr;
                    731:        db_expr_t count;
                    732:        char *modif;
                    733: {
                    734:        extern pte_t *tsb_dmmu;
                    735:        extern int tsbsize;
                    736: #define TSBENTS (512<<tsbsize)
                    737:        int i;
                    738:
                    739:        db_printf("TSB:\n");
                    740:        for (i=0; i<TSBENTS; i++) {
                    741:                db_printf("%4d:%4d:%08x %08x:%08x ", i,
                    742:                          (int)((tsb_dmmu[i].tag&TSB_TAG_G)?-1:TSB_TAG_CTX(tsb_dmmu[i].tag)),
                    743:                          (int)((i<<13)|TSB_TAG_VA(tsb_dmmu[i].tag)),
                    744:                          (int)(tsb_dmmu[i].data>>32), (int)tsb_dmmu[i].data);
                    745:                i++;
                    746:                db_printf("%4d:%4d:%08x %08x:%08x\n", i,
                    747:                          (int)((tsb_dmmu[i].tag&TSB_TAG_G)?-1:TSB_TAG_CTX(tsb_dmmu[i].tag)),
                    748:                          (int)((i<<13)|TSB_TAG_VA(tsb_dmmu[i].tag)),
                    749:                          (int)(tsb_dmmu[i].data>>32), (int)tsb_dmmu[i].data);
                    750:        }
                    751: }
                    752:
                    753: void db_page_cmd(db_expr_t, int, db_expr_t, char *);
                    754: void
                    755: db_page_cmd(addr, have_addr, count, modif)
                    756:        db_expr_t addr;
                    757:        int have_addr;
                    758:        db_expr_t count;
                    759:        char *modif;
                    760: {
                    761:
                    762:        if (!have_addr) {
                    763:                db_printf("Need paddr for page\n");
                    764:                return;
                    765:        }
                    766:
                    767:        db_printf("pa %llx pg %p\n", (unsigned long long)addr,
                    768:            PHYS_TO_VM_PAGE(addr));
                    769: }
                    770:
                    771:
                    772: void
                    773: db_proc_cmd(addr, have_addr, count, modif)
                    774:        db_expr_t addr;
                    775:        int have_addr;
                    776:        db_expr_t count;
                    777:        char *modif;
                    778: {
                    779:        struct proc *p;
                    780:
                    781:        p = curproc;
                    782:        if (have_addr)
                    783:                p = (struct proc*) addr;
                    784:        if (p == NULL) {
                    785:                db_printf("no current process\n");
                    786:                return;
                    787:        }
                    788:        db_printf("process %p:", p);
                    789:        db_printf("pid:%d vmspace:%p pmap:%p ctx:%x wchan:%p pri:%d upri:%d\n",
                    790:                  p->p_pid, p->p_vmspace, p->p_vmspace->vm_map.pmap,
                    791:                  p->p_vmspace->vm_map.pmap->pm_ctx,
                    792:                  p->p_wchan, p->p_priority, p->p_usrpri);
                    793:        db_printf("maxsaddr:%p ssiz:%dpg or %llxB\n",
                    794:                  p->p_vmspace->vm_maxsaddr, p->p_vmspace->vm_ssize,
                    795:                  (unsigned long long)ctob(p->p_vmspace->vm_ssize));
                    796:        db_printf("profile timer: %ld sec %ld usec\n",
                    797:                  p->p_stats->p_timer[ITIMER_PROF].it_value.tv_sec,
                    798:                  p->p_stats->p_timer[ITIMER_PROF].it_value.tv_usec);
                    799:        db_printf("pcb: %p fpstate: %p\n", &p->p_addr->u_pcb,
                    800:                p->p_md.md_fpstate);
                    801:        return;
                    802: }
                    803:
                    804: void
                    805: db_ctx_cmd(addr, have_addr, count, modif)
                    806:        db_expr_t addr;
                    807:        int have_addr;
                    808:        db_expr_t count;
                    809:        char *modif;
                    810: {
                    811:        struct proc *p;
                    812:
                    813:        /* XXX LOCKING XXX */
                    814:        LIST_FOREACH(p, &allproc, p_list) {
                    815:                if (p->p_stat) {
                    816:                        db_printf("process %p:", p);
                    817:                        db_printf("pid:%d pmap:%p ctx:%x tf:%p fpstate %p "
                    818:                                "lastcall:%s\n",
                    819:                                p->p_pid, p->p_vmspace->vm_map.pmap,
                    820:                                p->p_vmspace->vm_map.pmap->pm_ctx,
                    821:                                p->p_md.md_tf, p->p_md.md_fpstate,
                    822:                                (p->p_addr->u_pcb.lastcall)?
                    823:                                p->p_addr->u_pcb.lastcall : "Null");
                    824:                }
                    825:        }
                    826:        return;
                    827: }
                    828:
                    829: void
                    830: db_dump_pcb(addr, have_addr, count, modif)
                    831:        db_expr_t addr;
                    832:        int have_addr;
                    833:        db_expr_t count;
                    834:        char *modif;
                    835: {
                    836:        struct pcb *pcb;
                    837:        int i;
                    838:
                    839:        pcb = curpcb;
                    840:        if (have_addr)
                    841:                pcb = (struct pcb*) addr;
                    842:
                    843:        db_printf("pcb@%p sp:%p pc:%p cwp:%d pil:%d nsaved:%x onfault:%p\nlastcall:%s\nfull windows:\n",
                    844:                  pcb, (void *)(long)pcb->pcb_sp, (void *)(long)pcb->pcb_pc, pcb->pcb_cwp,
                    845:                  pcb->pcb_pil, pcb->pcb_nsaved, (void *)pcb->pcb_onfault,
                    846:                  (pcb->lastcall)?pcb->lastcall:"Null");
                    847:
                    848:        for (i=0; i<pcb->pcb_nsaved; i++) {
                    849:                db_printf("win %d: at %llx local, in\n", i,
                    850:                          (unsigned long long)pcb->pcb_rw[i+1].rw_in[6]);
                    851:                db_printf("%16llx %16llx %16llx %16llx\n",
                    852:                          (unsigned long long)pcb->pcb_rw[i].rw_local[0],
                    853:                          (unsigned long long)pcb->pcb_rw[i].rw_local[1],
                    854:                          (unsigned long long)pcb->pcb_rw[i].rw_local[2],
                    855:                          (unsigned long long)pcb->pcb_rw[i].rw_local[3]);
                    856:                db_printf("%16llx %16llx %16llx %16llx\n",
                    857:                          (unsigned long long)pcb->pcb_rw[i].rw_local[4],
                    858:                          (unsigned long long)pcb->pcb_rw[i].rw_local[5],
                    859:                          (unsigned long long)pcb->pcb_rw[i].rw_local[6],
                    860:                          (unsigned long long)pcb->pcb_rw[i].rw_local[7]);
                    861:                db_printf("%16llx %16llx %16llx %16llx\n",
                    862:                          (unsigned long long)pcb->pcb_rw[i].rw_in[0],
                    863:                          (unsigned long long)pcb->pcb_rw[i].rw_in[1],
                    864:                          (unsigned long long)pcb->pcb_rw[i].rw_in[2],
                    865:                          (unsigned long long)pcb->pcb_rw[i].rw_in[3]);
                    866:                db_printf("%16llx %16llx %16llx %16llx\n",
                    867:                          (unsigned long long)pcb->pcb_rw[i].rw_in[4],
                    868:                          (unsigned long long)pcb->pcb_rw[i].rw_in[5],
                    869:                          (unsigned long long)pcb->pcb_rw[i].rw_in[6],
                    870:                          (unsigned long long)pcb->pcb_rw[i].rw_in[7]);
                    871:        }
                    872: }
                    873:
                    874:
                    875: void
                    876: db_setpcb(addr, have_addr, count, modif)
                    877:        db_expr_t addr;
                    878:        int have_addr;
                    879:        db_expr_t count;
                    880:        char *modif;
                    881: {
                    882:        struct proc *p, *pp;
                    883:
                    884:        if (!have_addr) {
                    885:                db_printf("What PID do you want to map in?\n");
                    886:                return;
                    887:        }
                    888:
                    889:        LIST_FOREACH(p, &allproc, p_list) {
                    890:                pp = p->p_pptr;
                    891:                if (p->p_stat && p->p_pid == addr) {
                    892:                        curproc = p;
                    893:                        curpcb = (struct pcb*)p->p_addr;
                    894:                        if (p->p_vmspace->vm_map.pmap->pm_ctx) {
                    895:                                switchtoctx(p->p_vmspace->vm_map.pmap->pm_ctx);
                    896:                                return;
                    897:                        }
                    898:                        db_printf("PID %ld has a null context.\n", addr);
                    899:                        return;
                    900:                }
                    901:        }
                    902:        db_printf("PID %ld not found.\n", addr);
                    903: }
                    904:
                    905: static void
                    906: db_print_trace_entry(te, i)
                    907:        struct traptrace *te;
                    908:        int i;
                    909: {
                    910:        db_printf("%d:%d p:%d tt:%d:%llx:%llx %llx:%llx ", i,
                    911:                  (int)te->tl, (int)te->pid,
                    912:                  (int)te->tt, (unsigned long long)te->tstate,
                    913:                  (unsigned long long)te->tfault, (unsigned long long)te->tsp,
                    914:                  (unsigned long long)te->tpc);
                    915:        db_printsym((u_long)te->tpc, DB_STGY_PROC, db_printf);
                    916:        db_printf(": ");
                    917:        if ((te->tpc && !(te->tpc&0x3)) &&
                    918:            curproc &&
                    919:            (curproc->p_pid == te->pid)) {
                    920:                db_disasm((u_long)te->tpc, 0);
                    921:        } else db_printf("\n");
                    922: }
                    923:
                    924: void
                    925: db_traptrace(addr, have_addr, count, modif)
                    926:        db_expr_t addr;
                    927:        int have_addr;
                    928:        db_expr_t count;
                    929:        char *modif;
                    930: {
                    931:        int i, start = 0, full = 0, reverse = 0;
                    932:        struct traptrace *end;
                    933:
                    934:        start = 0;
                    935:        end = &trap_trace_end[0];
                    936:
                    937:        {
                    938:                register char c, *cp = modif;
                    939:                if (modif)
                    940:                        while ((c = *cp++) != 0) {
                    941:                                if (c == 'f')
                    942:                                        full = 1;
                    943:                                if (c == 'r')
                    944:                                        reverse = 1;
                    945:                        }
                    946:        }
                    947:
                    948:        if (have_addr) {
                    949:                start = addr / (sizeof (struct traptrace));
                    950:                if (&trap_trace[start] > &trap_trace_end[0]) {
                    951:                        db_printf("Address out of range.\n");
                    952:                        return;
                    953:                }
                    954:                if (!full) end =  &trap_trace[start+1];
                    955:        }
                    956:
                    957:        db_printf("#:tl p:pid tt:tt:tstate:tfault sp:pc\n");
                    958:        if (reverse) {
                    959:                if (full && start)
                    960:                        for (i=start; --i;) {
                    961:                                db_print_trace_entry(&trap_trace[i], i);
                    962:                        }
                    963:                i = (end - &trap_trace[0]);
                    964:                while(--i > start) {
                    965:                        db_print_trace_entry(&trap_trace[i], i);
                    966:                }
                    967:        } else {
                    968:                for (i=start; &trap_trace[i] < end ; i++) {
                    969:                        db_print_trace_entry(&trap_trace[i], i);
                    970:                }
                    971:                if (full && start)
                    972:                        for (i=0; i < start ; i++) {
                    973:                                db_print_trace_entry(&trap_trace[i], i);
                    974:                        }
                    975:        }
                    976: }
                    977:
                    978: /*
                    979:  * Use physical or virtual watchpoint registers -- ugh
                    980:  */
                    981: void
                    982: db_watch(addr, have_addr, count, modif)
                    983:        db_expr_t addr;
                    984:        int have_addr;
                    985:        db_expr_t count;
                    986:        char *modif;
                    987: {
                    988:        int phys = 0;
                    989:
                    990: #define WATCH_VR       (1L<<22)
                    991: #define WATCH_VW       (1L<<21)
                    992: #define WATCH_PR       (1L<<24)
                    993: #define WATCH_PW       (1L<<23)
                    994: #define WATCH_PM       (((u_int64_t)0xffffL)<<33)
                    995: #define WATCH_VM       (((u_int64_t)0xffffL)<<25)
                    996:
                    997:        {
                    998:                register char c, *cp = modif;
                    999:                if (modif)
                   1000:                        while ((c = *cp++) != 0)
                   1001:                                if (c == 'p')
                   1002:                                        phys = 1;
                   1003:        }
                   1004:        if (have_addr) {
                   1005:                /* turn on the watchpoint */
                   1006:                int64_t tmp = ldxa(0, ASI_MCCR);
                   1007:
                   1008:                if (phys) {
                   1009:                        tmp &= ~(WATCH_PM|WATCH_PR|WATCH_PW);
                   1010:                        stxa(PHYSICAL_WATCHPOINT, ASI_DMMU, addr);
                   1011:                } else {
                   1012:                        tmp &= ~(WATCH_VM|WATCH_VR|WATCH_VW);
                   1013:                        stxa(VIRTUAL_WATCHPOINT, ASI_DMMU, addr);
                   1014:                }
                   1015:                stxa(0, ASI_MCCR, tmp);
                   1016:        } else {
                   1017:                /* turn off the watchpoint */
                   1018:                int64_t tmp = ldxa(0, ASI_MCCR);
                   1019:                if (phys) tmp &= ~(WATCH_PM);
                   1020:                else tmp &= ~(WATCH_VM);
                   1021:                stxa(0, ASI_MCCR, tmp);
                   1022:        }
                   1023: }
                   1024:
                   1025:
                   1026: #include <uvm/uvm.h>
                   1027:
                   1028: #ifdef UVMHIST
                   1029: void db_uvmhistdump(db_expr_t, int, db_expr_t, char *);
                   1030: extern void uvmhist_dump(struct uvm_history *);
                   1031: extern struct uvm_history_head uvm_histories;
                   1032:
                   1033: void
                   1034: db_uvmhistdump(addr, have_addr, count, modif)
                   1035:        db_expr_t addr;
                   1036:        int have_addr;
                   1037:        db_expr_t count;
                   1038:        char *modif;
                   1039: {
                   1040:
                   1041:        uvmhist_dump(LIST_FIRST(&uvm_histories));
                   1042: }
                   1043: #endif
                   1044:
                   1045: #if NESP_SBUS
                   1046: extern void db_esp(db_expr_t, int, db_expr_t, char *);
                   1047: #endif
                   1048:
                   1049: struct db_command db_machine_command_table[] = {
                   1050:        { "ctx",        db_ctx_cmd,     0,      0 },
                   1051:        { "dtlb",       db_dump_dtlb,   0,      0 },
                   1052:        { "dtsb",       db_dump_dtsb,   0,      0 },
                   1053: #if NESP_SBUS
                   1054:        { "esp",        db_esp,         0,      0 },
                   1055: #endif
                   1056:        { "fpstate",    db_dump_fpstate,0,      0 },
                   1057:        { "itlb",       db_dump_itlb,   0,      0 },
                   1058:        { "kmap",       db_pmap_kernel, 0,      0 },
                   1059:        { "lock",       db_lock,        0,      0 },
                   1060:        { "pcb",        db_dump_pcb,    0,      0 },
                   1061:        { "pctx",       db_setpcb,      0,      0 },
                   1062:        { "page",       db_page_cmd,    0,      0 },
                   1063:        { "phys",       db_pload_cmd,   0,      0 },
                   1064:        { "pmap",       db_pmap_cmd,    0,      0 },
                   1065:        { "proc",       db_proc_cmd,    0,      0 },
                   1066:        { "prom",       db_prom_cmd,    0,      0 },
                   1067:        { "pv",         db_dump_pv,     0,      0 },
                   1068:        { "stack",      db_dump_stack,  0,      0 },
                   1069:        { "tf",         db_dump_trap,   0,      0 },
                   1070:        { "ts",         db_dump_ts,     0,      0 },
                   1071:        { "traptrace",  db_traptrace,   0,      0 },
                   1072: #ifdef UVMHIST
                   1073:        { "uvmdump",    db_uvmhistdump, 0,      0 },
                   1074: #endif
                   1075:        { "watch",      db_watch,       0,      0 },
                   1076:        { "window",     db_dump_window, 0,      0 },
                   1077:        { (char *)0, }
                   1078: };
                   1079:
                   1080: /*
                   1081:  * support for SOFTWARE_SSTEP:
                   1082:  * return the next pc if the given branch is taken.
                   1083:  *
                   1084:  * note: in the case of conditional branches with annul,
                   1085:  * this actually returns the next pc in the "not taken" path,
                   1086:  * but in that case next_instr_address() will return the
                   1087:  * next pc in the "taken" path.  so even tho the breakpoints
                   1088:  * are backwards, everything will still work, and the logic is
                   1089:  * much simpler this way.
                   1090:  */
                   1091: db_addr_t
                   1092: db_branch_taken(inst, pc, regs)
                   1093:        int inst;
                   1094:        db_addr_t pc;
                   1095:        db_regs_t *regs;
                   1096: {
                   1097:     union instr insn;
                   1098:     db_addr_t npc = ddb_regs.ddb_tf.tf_npc;
                   1099:
                   1100:     insn.i_int = inst;
                   1101:
                   1102:     /* the fancy union just gets in the way of this: */
                   1103:     switch(inst & 0xffc00000) {
                   1104:     case 0x30400000:   /* branch always, annul, with prediction */
                   1105:        return pc + ((inst<<(32-19))>>((32-19)-2));
                   1106:     case 0x30800000:   /* branch always, annul */
                   1107:        return pc + ((inst<<(32-22))>>((32-22)-2));
                   1108:     }
                   1109:
                   1110:     /*
                   1111:      * if this is not an annulled conditional branch, the next pc is "npc".
                   1112:      */
                   1113:
                   1114:     if (insn.i_any.i_op != IOP_OP2 || insn.i_branch.i_annul != 1)
                   1115:        return npc;
                   1116:
                   1117:     switch (insn.i_op2.i_op2) {
                   1118:       case IOP2_Bicc:
                   1119:       case IOP2_FBfcc:
                   1120:       case IOP2_BPcc:
                   1121:       case IOP2_FBPfcc:
                   1122:       case IOP2_CBccc:
                   1123:        /* branch on some condition-code */
                   1124:        switch (insn.i_branch.i_cond)
                   1125:        {
                   1126:          case Icc_A: /* always */
                   1127:            return pc + ((inst << 10) >> 8);
                   1128:
                   1129:          default: /* all other conditions */
                   1130:            return npc + 4;
                   1131:        }
                   1132:
                   1133:       case IOP2_BPr:
                   1134:        /* branch on register, always conditional */
                   1135:        return npc + 4;
                   1136:
                   1137:       default:
                   1138:        /* not a branch */
                   1139:        panic("branch_taken() on non-branch");
                   1140:     }
                   1141: }
                   1142:
                   1143: boolean_t
                   1144: db_inst_branch(inst)
                   1145:        int inst;
                   1146: {
                   1147:     union instr insn;
                   1148:
                   1149:     insn.i_int = inst;
                   1150:
                   1151:     /* the fancy union just gets in the way of this: */
                   1152:     switch(inst & 0xffc00000) {
                   1153:     case 0x30400000:   /* branch always, annul, with prediction */
                   1154:        return TRUE;
                   1155:     case 0x30800000:   /* branch always, annul */
                   1156:        return TRUE;
                   1157:     }
                   1158:
                   1159:     if (insn.i_any.i_op != IOP_OP2)
                   1160:        return FALSE;
                   1161:
                   1162:     switch (insn.i_op2.i_op2) {
                   1163:       case IOP2_BPcc:
                   1164:       case IOP2_Bicc:
                   1165:       case IOP2_BPr:
                   1166:       case IOP2_FBPfcc:
                   1167:       case IOP2_FBfcc:
                   1168:       case IOP2_CBccc:
                   1169:        return TRUE;
                   1170:
                   1171:       default:
                   1172:        return FALSE;
                   1173:     }
                   1174: }
                   1175:
                   1176:
                   1177: boolean_t
                   1178: db_inst_call(inst)
                   1179:        int inst;
                   1180: {
                   1181:     union instr insn;
                   1182:
                   1183:     insn.i_int = inst;
                   1184:
                   1185:     switch (insn.i_any.i_op) {
                   1186:       case IOP_CALL:
                   1187:        return TRUE;
                   1188:
                   1189:       case IOP_reg:
                   1190:        return (insn.i_op3.i_op3 == IOP3_JMPL) && !db_inst_return(inst);
                   1191:
                   1192:       default:
                   1193:        return FALSE;
                   1194:     }
                   1195: }
                   1196:
                   1197:
                   1198: boolean_t
                   1199: db_inst_unconditional_flow_transfer(inst)
                   1200:        int inst;
                   1201: {
                   1202:     union instr insn;
                   1203:
                   1204:     insn.i_int = inst;
                   1205:
                   1206:     if (db_inst_call(inst))
                   1207:        return TRUE;
                   1208:
                   1209:     if (insn.i_any.i_op != IOP_OP2)
                   1210:        return FALSE;
                   1211:
                   1212:     switch (insn.i_op2.i_op2)
                   1213:     {
                   1214:       case IOP2_BPcc:
                   1215:       case IOP2_Bicc:
                   1216:       case IOP2_FBPfcc:
                   1217:       case IOP2_FBfcc:
                   1218:       case IOP2_CBccc:
                   1219:        return insn.i_branch.i_cond == Icc_A;
                   1220:
                   1221:       default:
                   1222:        return FALSE;
                   1223:     }
                   1224: }
                   1225:
                   1226:
                   1227: boolean_t
                   1228: db_inst_return(inst)
                   1229:        int inst;
                   1230: {
                   1231:     return (inst == I_JMPLri(I_G0, I_O7, 8) ||         /* ret */
                   1232:            inst == I_JMPLri(I_G0, I_I7, 8));           /* retl */
                   1233: }
                   1234:
                   1235: boolean_t
                   1236: db_inst_trap_return(inst)
                   1237:        int inst;
                   1238: {
                   1239:     union instr insn;
                   1240:
                   1241:     insn.i_int = inst;
                   1242:
                   1243:     return (insn.i_any.i_op == IOP_reg &&
                   1244:            insn.i_op3.i_op3 == IOP3_RETT);
                   1245: }
                   1246:
                   1247:
                   1248: int
                   1249: db_inst_load(inst)
                   1250:        int inst;
                   1251: {
                   1252:     union instr insn;
                   1253:
                   1254:     insn.i_int = inst;
                   1255:
                   1256:     if (insn.i_any.i_op != IOP_mem)
                   1257:        return 0;
                   1258:
                   1259:     switch (insn.i_op3.i_op3) {
                   1260:       case IOP3_LD:
                   1261:       case IOP3_LDUB:
                   1262:       case IOP3_LDUH:
                   1263:       case IOP3_LDD:
                   1264:       case IOP3_LDSB:
                   1265:       case IOP3_LDSH:
                   1266:       case IOP3_LDSTUB:
                   1267:       case IOP3_SWAP:
                   1268:       case IOP3_LDA:
                   1269:       case IOP3_LDUBA:
                   1270:       case IOP3_LDUHA:
                   1271:       case IOP3_LDDA:
                   1272:       case IOP3_LDSBA:
                   1273:       case IOP3_LDSHA:
                   1274:       case IOP3_LDSTUBA:
                   1275:       case IOP3_SWAPA:
                   1276:       case IOP3_LDF:
                   1277:       case IOP3_LDFSR:
                   1278:       case IOP3_LDDF:
                   1279:       case IOP3_LFC:
                   1280:       case IOP3_LDCSR:
                   1281:       case IOP3_LDDC:
                   1282:        return 1;
                   1283:
                   1284:       default:
                   1285:        return 0;
                   1286:     }
                   1287: }
                   1288:
                   1289: int
                   1290: db_inst_store(inst)
                   1291:        int inst;
                   1292: {
                   1293:     union instr insn;
                   1294:
                   1295:     insn.i_int = inst;
                   1296:
                   1297:     if (insn.i_any.i_op != IOP_mem)
                   1298:        return 0;
                   1299:
                   1300:     switch (insn.i_op3.i_op3) {
                   1301:       case IOP3_ST:
                   1302:       case IOP3_STB:
                   1303:       case IOP3_STH:
                   1304:       case IOP3_STD:
                   1305:       case IOP3_LDSTUB:
                   1306:       case IOP3_SWAP:
                   1307:       case IOP3_STA:
                   1308:       case IOP3_STBA:
                   1309:       case IOP3_STHA:
                   1310:       case IOP3_STDA:
                   1311:       case IOP3_LDSTUBA:
                   1312:       case IOP3_SWAPA:
                   1313:       case IOP3_STF:
                   1314:       case IOP3_STFSR:
                   1315:       case IOP3_STQF:
                   1316:       case IOP3_STDF:
                   1317:       case IOP3_STC:
                   1318:       case IOP3_STCSR:
                   1319:       case IOP3_STQFA:
                   1320:       case IOP3_STDC:
                   1321:        return 1;
                   1322:
                   1323:       default:
                   1324:        return 0;
                   1325:     }
                   1326: }
                   1327:
                   1328: void
                   1329: db_machine_init()
                   1330: {
                   1331:        db_machine_commands_install(db_machine_command_table);
                   1332: }

CVSweb