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

Annotation of sys/arch/mips64/mips64/db_machdep.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: db_machdep.c,v 1.11 2007/05/03 19:34:00 miod Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 1998-2003 Opsycon AB (www.opsycon.se)
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
                     16:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     18:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
                     19:  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     20:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     21:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     23:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     24:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     25:  * SUCH DAMAGE.
                     26:  *
                     27:  */
                     28:
                     29: #include <sys/param.h>
                     30: #include <sys/systm.h>
                     31: #include <sys/proc.h>
                     32: #include <dev/cons.h>
                     33:
                     34: #include <machine/autoconf.h>
                     35: #include <machine/db_machdep.h>
                     36: #include <machine/cpu.h>
                     37: #include <machine/mips_opcode.h>
                     38: #include <machine/pte.h>
                     39: #include <machine/frame.h>
                     40: #include <machine/regnum.h>
                     41:
                     42: #include <ddb/db_sym.h>
                     43: #include <ddb/db_extern.h>
                     44: #include <ddb/db_access.h>
                     45: #include <ddb/db_command.h>
                     46: #include <ddb/db_output.h>
                     47: #include <ddb/db_variables.h>
                     48: #include <ddb/db_interface.h>
                     49:
                     50: #define MIPS_JR_RA        0x03e00008      /* instruction code for jr ra */
                     51:
                     52: extern void trapDump(char *);
                     53: u_long MipsEmulateBranch(db_regs_t *, int, int, u_int);
                     54: void  stacktrace_subr(db_regs_t *, int (*)(const char*, ...));
                     55:
                     56: int   kdbpeek(void *);
                     57: int64_t kdbpeekd(void *);
                     58: short kdbpeekw(void *);
                     59: char  kdbpeekb(void *);
                     60: void  kdbpoke(vaddr_t, int);
                     61: void  kdbpoked(vaddr_t, int64_t);
                     62: void  kdbpokew(vaddr_t, short);
                     63: void  kdbpokeb(vaddr_t, char);
                     64: int   kdb_trap(int, struct trap_frame *);
                     65:
                     66: void db_trap_trace_cmd(db_expr_t, int, db_expr_t, char *);
                     67: void db_dump_tlb_cmd(db_expr_t, int, db_expr_t, char *);
                     68:
                     69: int   db_active = 0;
                     70: db_regs_t ddb_regs;
                     71:
                     72: struct db_variable db_regs[] = {
                     73:     { "at",  (long *)&ddb_regs.ast,     FCN_NULL },
                     74:     { "v0",  (long *)&ddb_regs.v0,      FCN_NULL },
                     75:     { "v1",  (long *)&ddb_regs.v1,      FCN_NULL },
                     76:     { "a0",  (long *)&ddb_regs.a0,      FCN_NULL },
                     77:     { "a1",  (long *)&ddb_regs.a1,      FCN_NULL },
                     78:     { "a2",  (long *)&ddb_regs.a2,      FCN_NULL },
                     79:     { "a3",  (long *)&ddb_regs.a3,      FCN_NULL },
                     80:     { "a4",  (long *)&ddb_regs.t0,      FCN_NULL },
                     81:     { "a5",  (long *)&ddb_regs.t1,      FCN_NULL },
                     82:     { "a6",  (long *)&ddb_regs.t2,      FCN_NULL },
                     83:     { "a7",  (long *)&ddb_regs.t3,      FCN_NULL },
                     84:     { "t0",  (long *)&ddb_regs.t4,      FCN_NULL },
                     85:     { "t1",  (long *)&ddb_regs.t5,      FCN_NULL },
                     86:     { "t2",  (long *)&ddb_regs.t6,      FCN_NULL },
                     87:     { "t3",  (long *)&ddb_regs.t7,      FCN_NULL },
                     88:     { "s0",  (long *)&ddb_regs.s0,      FCN_NULL },
                     89:     { "s1",  (long *)&ddb_regs.s1,      FCN_NULL },
                     90:     { "s2",  (long *)&ddb_regs.s2,      FCN_NULL },
                     91:     { "s3",  (long *)&ddb_regs.s3,      FCN_NULL },
                     92:     { "s4",  (long *)&ddb_regs.s4,      FCN_NULL },
                     93:     { "s5",  (long *)&ddb_regs.s5,      FCN_NULL },
                     94:     { "s6",  (long *)&ddb_regs.s6,      FCN_NULL },
                     95:     { "s7",  (long *)&ddb_regs.s7,      FCN_NULL },
                     96:     { "t8",  (long *)&ddb_regs.t8,      FCN_NULL },
                     97:     { "t9",  (long *)&ddb_regs.t9,      FCN_NULL },
                     98:     { "k0",  (long *)&ddb_regs.k0,      FCN_NULL },
                     99:     { "k1",  (long *)&ddb_regs.k1,      FCN_NULL },
                    100:     { "gp",  (long *)&ddb_regs.gp,      FCN_NULL },
                    101:     { "sp",  (long *)&ddb_regs.sp,      FCN_NULL },
                    102:     { "s8",  (long *)&ddb_regs.s8,      FCN_NULL },
                    103:     { "ra",  (long *)&ddb_regs.ra,      FCN_NULL },
                    104:     { "sr",  (long *)&ddb_regs.sr,      FCN_NULL },
                    105:     { "lo",  (long *)&ddb_regs.mullo,   FCN_NULL },
                    106:     { "hi",  (long *)&ddb_regs.mulhi,   FCN_NULL },
                    107:     { "bad", (long *)&ddb_regs.badvaddr,FCN_NULL },
                    108:     { "cs",  (long *)&ddb_regs.cause,   FCN_NULL },
                    109:     { "pc",  (long *)&ddb_regs.pc,      FCN_NULL },
                    110: };
                    111: struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
                    112:
                    113: extern label_t  *db_recover;
                    114:
                    115: int
                    116: kdb_trap(type, fp)
                    117:        int type;
                    118:        struct trap_frame *fp;
                    119: {
                    120:        switch(type) {
                    121:        case T_BREAK:           /* breakpoint */
                    122:                if (db_get_value((fp)->pc, sizeof(int), FALSE) == BREAK_SOVER) {
                    123:                        (fp)->pc += BKPT_SIZE;
                    124:                }
                    125:                break;
                    126:        case -1:
                    127:                break;
                    128:        default:
                    129: #if 0
                    130:                if (!db_panic)
                    131:                        return (0);
                    132: #endif
                    133:                if (db_recover != 0) {
                    134:                        db_error("Caught exception in ddb.\n");
                    135:                        /*NOTREACHED*/
                    136:                }
                    137:                printf("stoped on non ddb fault\n");
                    138:        }
                    139:
                    140:        bcopy((void *)fp, (void *)&ddb_regs, NUMSAVEREGS * sizeof(register_t));
                    141:
                    142:        db_active++;
                    143:        cnpollc(TRUE);
                    144:        db_trap(type, 0);
                    145:        cnpollc(FALSE);
                    146:        db_active--;
                    147:
                    148:        bcopy((void *)&ddb_regs, (void *)fp, NUMSAVEREGS * sizeof(register_t));
                    149:        return(TRUE);
                    150: }
                    151: void
                    152: db_read_bytes(addr, size, data)
                    153:        vaddr_t addr;
                    154:        size_t      size;
                    155:        char       *data;
                    156: {
                    157:        while(size >= sizeof(int)) {
                    158:                *((int *)data)++ = kdbpeek((void *)addr);
                    159:                addr += sizeof(int);
                    160:                size -= sizeof(int);
                    161:        }
                    162:
                    163:        if (size > sizeof(short)) {
                    164:                *((short *)data)++ = kdbpeekw((void *)addr);
                    165:                addr += sizeof(short);
                    166:                size -= sizeof(short);
                    167:        }
                    168:
                    169:        if (size) {
                    170:                *data++ = kdbpeekb((void *)addr);
                    171:        }
                    172: }
                    173:
                    174: void
                    175: db_write_bytes(addr, size, data)
                    176:        vaddr_t addr;
                    177:        size_t      size;
                    178:        char       *data;
                    179: {
                    180:        vaddr_t ptr = addr;
                    181:        size_t len = size;
                    182:
                    183:        while (len >= sizeof(int)) {
                    184:                kdbpoke(ptr, *((int *)data)++);
                    185:                ptr += sizeof(int);
                    186:                len -= sizeof(int);
                    187:        }
                    188:
                    189:        if (len >= sizeof(short)) {
                    190:                kdbpokew(ptr, *((short *)data)++);
                    191:                ptr += sizeof(int);
                    192:                len -= sizeof(int);
                    193:        }
                    194:
                    195:        if (len) {
                    196:                kdbpokeb(ptr, *data++);
                    197:        }
                    198:        if (addr < VM_MIN_KERNEL_ADDRESS) {
                    199:                Mips_HitSyncDCache(addr, size);
                    200:                Mips_InvalidateICache(PHYS_TO_KSEG0(addr & 0xffff), size);
                    201:        }
                    202: }
                    203:
                    204: void
                    205: db_stack_trace_print(addr, have_addr, count, modif, pr)
                    206:        db_expr_t       addr;
                    207:        boolean_t       have_addr;
                    208:        db_expr_t       count;
                    209:        char            *modif;
                    210:        int             (*pr)(const char *, ...);
                    211: {
                    212:        db_sym_t sym;
                    213:        db_expr_t diff;
                    214:        db_addr_t subr;
                    215:        char *symname;
                    216:        register_t pc, sp, ra, va;
                    217:        register_t a0, a1, a2, a3;
                    218:        unsigned instr, mask;
                    219:        InstFmt i;
                    220:        int more, stksize;
                    221:        extern char edata[];
                    222:        extern char k_intr[];
                    223:        extern char k_general[];
                    224:        extern char idle[];
                    225:        struct trap_frame *regs = &ddb_regs;
                    226:
                    227:        /* get initial values from the exception frame */
                    228:        sp = regs->sp;
                    229:        pc = regs->pc;
                    230:        ra = regs->ra;          /* May be a 'leaf' function */
                    231:        a0 = regs->a0;
                    232:        a1 = regs->a1;
                    233:        a2 = regs->a2;
                    234:        a3 = regs->a3;
                    235:
                    236: /* Jump here when done with a frame, to start a new one */
                    237: loop:
                    238:
                    239: /* Jump here after a nonstandard (interrupt handler) frame */
                    240:        stksize = 0;
                    241:
                    242:        /* check for bad SP: could foul up next frame */
                    243:        if (sp & 3 || (!IS_XKPHYS((vaddr_t)sp) && sp < KSEG0_BASE)) {
                    244:                (*pr)("SP %p: not in kernel\n", sp);
                    245:                ra = 0;
                    246:                subr = 0;
                    247:                goto done;
                    248:        }
                    249:
                    250: #if 0
                    251:        /* Backtraces should contine through interrupts from kernel mode */
                    252:        if (pc >= (unsigned)MipsKernIntr && pc < (unsigned)MipsUserIntr) {
                    253:                (*pr)("MipsKernIntr+%x: (%x, %x ,%x) -------\n",
                    254:                       pc-(unsigned)MipsKernIntr, a0, a1, a2);
                    255:                regs = (struct trap_frame *)(sp + STAND_ARG_SIZE);
                    256:                a0 = kdbpeek(&regs->a0);
                    257:                a1 = kdbpeek(&regs->a1);
                    258:                a2 = kdbpeek(&regs->a2);
                    259:                a3 = kdbpeek(&regs->a3);
                    260:
                    261:                pc = kdbpeek(&regs->pc); /* exc_pc - pc at time of exception */
                    262:                ra = kdbpeek(&regs->ra); /* ra at time of exception */
                    263:                sp = kdbpeek(&regs->sp);
                    264:                goto specialframe;
                    265:        }
                    266: #endif
                    267:
                    268:
                    269:        /* check for bad PC */
                    270:        if (pc & 3 || pc < KSEG0_BASE || pc >= (unsigned)edata) {
                    271:                (*pr)("PC %p: not in kernel\n", pc);
                    272:                ra = 0;
                    273:                goto done;
                    274:        }
                    275:
                    276:        /*
                    277:         * Dig out the function from the symbol table.
                    278:         * Watch out for function tail optimizations.
                    279:         */
                    280:        sym = db_search_symbol(pc, DB_STGY_ANY, &diff);
                    281:        if (sym != DB_SYM_NULL && diff == 0)
                    282:                sym = db_search_symbol(pc - 4, DB_STGY_ANY, &diff);
                    283:        db_symbol_values(sym, &symname, 0);
                    284:        if (sym != DB_SYM_NULL) {
                    285:                subr = pc - diff;
                    286:        } else {
                    287:                subr = 0;
                    288:        }
                    289:
                    290:        /*
                    291:         * Find the beginning of the current subroutine by scanning backwards
                    292:         * from the current PC for the end of the previous subroutine.
                    293:         */
                    294:        if (!subr) {
                    295:                va = pc - sizeof(int);
                    296:                while ((instr = kdbpeek((int *)va)) != MIPS_JR_RA)
                    297:                        va -= sizeof(int);
                    298:                va += 2 * sizeof(int);  /* skip back over branch & delay slot */
                    299:                /* skip over nulls which might separate .o files */
                    300:                while ((instr = kdbpeek((int *)va)) == 0)
                    301:                        va += sizeof(int);
                    302:                subr = va;
                    303:        }
                    304:
                    305:        /*
                    306:         * Jump here for locore entry points for which the preceding
                    307:         * function doesn't end in "j ra"
                    308:         */
                    309:        /* scan forwards to find stack size and any saved registers */
                    310:        stksize = 0;
                    311:        more = 3;
                    312:        mask = 0;
                    313:        for (va = subr; more; va += sizeof(int),
                    314:            more = (more == 3) ? 3 : more - 1) {
                    315:                /* stop if hit our current position */
                    316:                if (va >= pc)
                    317:                        break;
                    318:                instr = kdbpeek((int *)va);
                    319:                i.word = instr;
                    320:                switch (i.JType.op) {
                    321:                case OP_SPECIAL:
                    322:                        switch (i.RType.func) {
                    323:                        case OP_JR:
                    324:                        case OP_JALR:
                    325:                                more = 2; /* stop after next instruction */
                    326:                                break;
                    327:
                    328:                        case OP_SYSCALL:
                    329:                        case OP_BREAK:
                    330:                                more = 1; /* stop now */
                    331:                        };
                    332:                        break;
                    333:
                    334:                case OP_BCOND:
                    335:                case OP_J:
                    336:                case OP_JAL:
                    337:                case OP_BEQ:
                    338:                case OP_BNE:
                    339:                case OP_BLEZ:
                    340:                case OP_BGTZ:
                    341:                        more = 2; /* stop after next instruction */
                    342:                        break;
                    343:
                    344:                case OP_COP0:
                    345:                case OP_COP1:
                    346:                case OP_COP2:
                    347:                case OP_COP3:
                    348:                        switch (i.RType.rs) {
                    349:                        case OP_BCx:
                    350:                        case OP_BCy:
                    351:                                more = 2; /* stop after next instruction */
                    352:                        };
                    353:                        break;
                    354:
                    355:                case OP_SW:
                    356:                case OP_SD:
                    357:                        /* look for saved registers on the stack */
                    358:                        if (i.IType.rs != 29)
                    359:                                break;
                    360:                        /* only restore the first one */
                    361:                        if (mask & (1 << i.IType.rt))
                    362:                                break;
                    363:                        mask |= (1 << i.IType.rt);
                    364:                        switch (i.IType.rt) {
                    365:                        case 4: /* a0 */
                    366:                                a0 = kdbpeekd((long *)(sp + (short)i.IType.imm));
                    367:                                break;
                    368:
                    369:                        case 5: /* a1 */
                    370:                                a1 = kdbpeekd((long *)(sp + (short)i.IType.imm));
                    371:                                break;
                    372:
                    373:                        case 6: /* a2 */
                    374:                                a2 = kdbpeekd((long *)(sp + (short)i.IType.imm));
                    375:                                break;
                    376:
                    377:                        case 7: /* a3 */
                    378:                                a3 = kdbpeekd((long *)(sp + (short)i.IType.imm));
                    379:                                break;
                    380:
                    381:                        case 31: /* ra */
                    382:                                ra = kdbpeekd((long *)(sp + (short)i.IType.imm));
                    383:                                break;
                    384:                        }
                    385:                        break;
                    386:
                    387:                case OP_ADDI:
                    388:                case OP_ADDIU:
                    389:                case OP_DADDI:
                    390:                case OP_DADDIU:
                    391:                        /* look for stack pointer adjustment */
                    392:                        if (i.IType.rs != 29 || i.IType.rt != 29)
                    393:                                break;
                    394:                        stksize = - ((short)i.IType.imm);
                    395:                }
                    396:        }
                    397:
                    398: done:
                    399:        if (symname == NULL) {
                    400:                if (subr == (long)idle)
                    401:                        (*pr)("idle ");
                    402:                else
                    403:                        (*pr)("%p ", subr);
                    404:        } else {
                    405:                (*pr)("%s+%p ", symname, diff);
                    406:        }
                    407:        (*pr)("(%llx,%llx,%llx,%llx) sp %llx ra %llx, sz %d\n", a0, a1, a2, a3, sp, ra, stksize);
                    408:
                    409:        if (subr == (long)k_intr || subr == (long)k_general) {
                    410:                if (subr == (long)k_intr)
                    411:                        (*pr)("(KERNEL INTERRUPT)\n");
                    412:                else
                    413:                        (*pr)("(KERNEL TRAP)\n");
                    414:                sp = *(register_t *)sp;
                    415:                pc = ((struct trap_frame *)sp)->pc;
                    416:                ra = ((struct trap_frame *)sp)->ra;
                    417:                sp = ((struct trap_frame *)sp)->sp;     /* last */
                    418:                goto loop;
                    419:        }
                    420:
                    421:        if (ra) {
                    422:                if (pc == ra && stksize == 0)
                    423:                        (*pr)("stacktrace: loop!\n");
                    424:                else {
                    425:                        pc = ra;
                    426:                        sp += stksize;
                    427:                        ra = 0;
                    428:                        goto loop;
                    429:                }
                    430:        } else {
                    431:                if (curproc)
                    432:                        (*pr)("User-level: pid %d\n", curproc->p_pid);
                    433:                else
                    434:                        (*pr)("User-level: curproc NULL\n");
                    435:        }
                    436: }
                    437:
                    438: /*
                    439:  *     To do a single step ddb needs to know the next address
                    440:  *     that we will get to. It means that we need to find out
                    441:  *     both the address for a branch taken and for not taken, NOT! :-)
                    442:  *     MipsEmulateBranch will do the job to find out _exactly_ which
                    443:  *     address we will end up at so the 'dual bp' method is not
                    444:  *     requiered.
                    445:  */
                    446: db_addr_t
                    447: next_instr_address(db_addr_t pc, boolean_t bd)
                    448: {
                    449:        db_addr_t next;
                    450:
                    451:        next = MipsEmulateBranch(&ddb_regs, pc, 0, 0);
                    452:        return(next);
                    453: }
                    454:
                    455:
                    456: /*
                    457:  *     Decode instruction and figure out type.
                    458:  */
                    459: int
                    460: db_inst_type(ins)
                    461:        int     ins;
                    462: {
                    463:        InstFmt inst;
                    464:        int     ityp = 0;
                    465:
                    466:        inst.word = ins;
                    467:        switch ((int)inst.JType.op) {
                    468:        case OP_SPECIAL:
                    469:                switch ((int)inst.RType.func) {
                    470:                case OP_JR:
                    471:                        ityp = IT_BRANCH;
                    472:                        break;
                    473:                case OP_JALR:
                    474:                case OP_SYSCALL:
                    475:                        ityp = IT_CALL;
                    476:                        break;
                    477:                }
                    478:                break;
                    479:
                    480:        case OP_BCOND:
                    481:                switch ((int)inst.IType.rt) {
                    482:                case OP_BLTZ:
                    483:                case OP_BLTZL:
                    484:                case OP_BGEZ:
                    485:                case OP_BGEZL:
                    486:                        ityp = IT_BRANCH;
                    487:                        break;
                    488:
                    489:                case OP_BLTZAL:
                    490:                case OP_BLTZALL:
                    491:                case OP_BGEZAL:
                    492:                case OP_BGEZALL:
                    493:                        ityp = IT_CALL;
                    494:                        break;
                    495:                }
                    496:                break;
                    497:
                    498:        case OP_JAL:
                    499:                ityp = IT_CALL;
                    500:                break;
                    501:
                    502:        case OP_J:
                    503:        case OP_BEQ:
                    504:        case OP_BEQL:
                    505:        case OP_BNE:
                    506:        case OP_BNEL:
                    507:        case OP_BLEZ:
                    508:        case OP_BLEZL:
                    509:        case OP_BGTZ:
                    510:        case OP_BGTZL:
                    511:                ityp = IT_BRANCH;
                    512:                break;
                    513:
                    514:        case OP_COP1:
                    515:                switch (inst.RType.rs) {
                    516:                case OP_BCx:
                    517:                case OP_BCy:
                    518:                        ityp = IT_BRANCH;
                    519:                        break;
                    520:                }
                    521:                break;
                    522:
                    523:        case OP_LB:
                    524:        case OP_LH:
                    525:        case OP_LW:
                    526:        case OP_LD:
                    527:        case OP_LBU:
                    528:        case OP_LHU:
                    529:        case OP_LWU:
                    530:        case OP_LWC1:
                    531:                ityp = IT_LOAD;
                    532:                break;
                    533:
                    534:        case OP_SB:
                    535:        case OP_SH:
                    536:        case OP_SW:
                    537:        case OP_SD:
                    538:        case OP_SWC1:
                    539:                ityp = IT_STORE;
                    540:                break;
                    541:        }
                    542:        return (ityp);
                    543: }
                    544:
                    545: /*
                    546:  *  MIPS machine dependent DDB commands.
                    547:  */
                    548:
                    549: /*
                    550:  *  Do a trap traceback.
                    551:  */
                    552: void
                    553: db_trap_trace_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *m)
                    554: {
                    555:        trapDump("ddb trap trace");
                    556: }
                    557:
                    558: /*
                    559:  *     Dump TLB contents.
                    560:  */
                    561: void
                    562: db_dump_tlb_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *m)
                    563: {
                    564:        int tlbno, last, check, pid;
                    565:        struct tlb_entry tlb, tlbp;
                    566: char *attr[] = {
                    567:        "WTNA", "WTA ", "UCBL", "CWB ", "RES ", "RES ", "UCNB", "BPAS"
                    568: };
                    569:
                    570:        pid = -1;
                    571:
                    572:        if (m[0] == 'p') {
                    573:                if (have_addr && addr < 256) {
                    574:                        pid = addr;
                    575:                        tlbno = 0;
                    576:                        count = sys_config.cpu[0].tlbsize;
                    577:                }
                    578:        } else if (m[0] == 'c') {
                    579:                last = sys_config.cpu[0].tlbsize;
                    580:                for (tlbno = 0; tlbno < last; tlbno++) {
                    581:                        tlb_read(tlbno, &tlb);
                    582:                        for (check = tlbno + 1; check < last; check++) {
                    583:                                tlb_read(check, &tlbp);
                    584: if ((tlbp.tlb_hi == tlb.tlb_hi && (tlb.tlb_lo0 & PG_V || tlb.tlb_lo1 & PG_V)) ||
                    585: (pfn_to_pad(tlb.tlb_lo0) == pfn_to_pad(tlbp.tlb_lo0) && tlb.tlb_lo0 & PG_V) ||
                    586: (pfn_to_pad(tlb.tlb_lo1) == pfn_to_pad(tlbp.tlb_lo1) && tlb.tlb_lo1 & PG_V)) {
                    587:                                        printf("MATCH:\n");
                    588:                                        db_dump_tlb_cmd(tlbno, 1, 1, "");
                    589:                                        db_dump_tlb_cmd(check, 1, 1, "");
                    590:                                }
                    591:                        }
                    592:                }
                    593:                return;
                    594:        } else {
                    595:                if (have_addr && addr < sys_config.cpu[0].tlbsize) {
                    596:                        tlbno = addr;
                    597:                }
                    598:                        else {
                    599:                        tlbno = 0;
                    600:                        count = sys_config.cpu[0].tlbsize;
                    601:                }
                    602:        }
                    603:        last = tlbno + count;
                    604:
                    605:        for (; tlbno < sys_config.cpu[0].tlbsize && tlbno < last; tlbno++) {
                    606:                tlb_read(tlbno, &tlb);
                    607:
                    608:                if (pid >= 0 && (tlb.tlb_hi & 0xff) != pid)
                    609:                        continue;
                    610:
                    611:                if (tlb.tlb_lo0 & PG_V || tlb.tlb_lo1 & PG_V) {
                    612:                        printf("%2d v=%16llx", tlbno, tlb.tlb_hi & (long)~0xff);
                    613:                        printf("/%02x ", tlb.tlb_hi & 0xff);
                    614:
                    615:                        if (tlb.tlb_lo0 & PG_V) {
                    616:                                printf("%16llx ", pfn_to_pad(tlb.tlb_lo0));
                    617:                                printf("%c", tlb.tlb_lo0 & PG_M ? 'M' : ' ');
                    618:                                printf("%c", tlb.tlb_lo0 & PG_G ? 'G' : ' ');
                    619:                                printf("%s ", attr[(tlb.tlb_lo0 >> 3) & 7]);
                    620:                        } else {
                    621:                                printf("invalid             ");
                    622:                        }
                    623:
                    624:                        if (tlb.tlb_lo1 & PG_V) {
                    625:                                printf("%16llx ", pfn_to_pad(tlb.tlb_lo1));
                    626:                                printf("%c", tlb.tlb_lo1 & PG_M ? 'M' : ' ');
                    627:                                printf("%c", tlb.tlb_lo1 & PG_G ? 'G' : ' ');
                    628:                                printf("%s ", attr[(tlb.tlb_lo1 >> 3) & 7]);
                    629:                        } else {
                    630:                                printf("invalid             ");
                    631:                        }
                    632:                        printf(" sz=%x", tlb.tlb_mask);
                    633:                }
                    634:                else if (pid < 0) {
                    635:                        printf("%2d v=invalid    ", tlbno);
                    636:                }
                    637:                printf("\n");
                    638:        }
                    639: }
                    640:
                    641:
                    642: struct db_command mips_db_command_table[] = {
                    643:        { "tlb",        db_dump_tlb_cmd,        0,      NULL },
                    644:        { "trap",       db_trap_trace_cmd,      0,      NULL },
                    645:        { NULL,         NULL,                   0,      NULL }
                    646: };
                    647:
                    648: void
                    649: db_machine_init()
                    650: {
                    651: extern char *ssym;
                    652:        db_machine_commands_install(mips_db_command_table);
                    653:        if (ssym != NULL) {
                    654:                ddb_init();     /* Init symbols */
                    655:        }
                    656: }

CVSweb