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

Annotation of sys/arch/m88k/m88k/db_interface.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: db_interface.c,v 1.7 2007/05/19 20:33:49 miod Exp $   */
        !             2: /*
        !             3:  * Mach Operating System
        !             4:  * Copyright (c) 1993-1991 Carnegie Mellon University
        !             5:  * Copyright (c) 1991 OMRON Corporation
        !             6:  * All Rights Reserved.
        !             7:  *
        !             8:  * Permission to use, copy, modify and distribute this software and its
        !             9:  * documentation is hereby granted, provided that both the copyright
        !            10:  * notice and this permission notice appear in all copies of the
        !            11:  * software, derivative works or modified versions, and any portions
        !            12:  * thereof, and that both notices appear in supporting documentation.
        !            13:  *
        !            14:  * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            15:  * CONDITION.  CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
        !            16:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            17:  *
        !            18:  * Carnegie Mellon requests users of this software to return to
        !            19:  *
        !            20:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
        !            21:  *  School of Computer Science
        !            22:  *  Carnegie Mellon University
        !            23:  *  Pittsburgh PA 15213-3890
        !            24:  *
        !            25:  * any improvements or extensions that they make and grant Carnegie the
        !            26:  * rights to redistribute these changes.
        !            27:  */
        !            28:
        !            29: /*
        !            30:  * m88k interface to ddb debugger
        !            31:  */
        !            32:
        !            33: #include <sys/param.h>
        !            34: #include <sys/systm.h>
        !            35: #include <sys/proc.h>
        !            36: #include <sys/reboot.h>
        !            37:
        !            38: #include <uvm/uvm_extern.h>
        !            39:
        !            40: #include <machine/asm_macro.h>
        !            41: #include <machine/cmmu.h>
        !            42: #include <machine/trap.h>
        !            43: #include <machine/db_machdep.h>
        !            44: #include <machine/cpu.h>
        !            45: #ifdef M88100
        !            46: #include <machine/m88100.h>
        !            47: #include <machine/m8820x.h>
        !            48: #endif
        !            49:
        !            50: #include <ddb/db_access.h>
        !            51: #include <ddb/db_command.h>
        !            52: #include <ddb/db_extern.h>
        !            53: #include <ddb/db_interface.h>
        !            54: #include <ddb/db_output.h>
        !            55: #include <ddb/db_sym.h>
        !            56:
        !            57: extern label_t *db_recover;
        !            58: extern int frame_is_sane(db_regs_t *, int);    /* db_trace */
        !            59: extern void cnpollc(int);
        !            60:
        !            61: void   kdbprinttrap(int);
        !            62:
        !            63: int    m88k_dmx_print(u_int, u_int, u_int, u_int);
        !            64:
        !            65: void   m88k_db_trap(int, struct trapframe *);
        !            66: void   ddb_error_trap(char *, db_regs_t *);
        !            67: void   m88k_db_pause(u_int);
        !            68: void   m88k_db_print_frame(db_expr_t, int, db_expr_t, char *);
        !            69: void   m88k_db_registers(db_expr_t, int, db_expr_t, char *);
        !            70: void   m88k_db_where(db_expr_t, int, db_expr_t, char *);
        !            71: void   m88k_db_frame_search(db_expr_t, int, db_expr_t, char *);
        !            72: void   m88k_db_translate(db_expr_t, int, db_expr_t, char *);
        !            73: void   m88k_db_cmmucfg(db_expr_t, int, db_expr_t, char *);
        !            74:
        !            75: db_regs_t ddb_regs;
        !            76:
        !            77: #ifdef MULTIPROCESSOR
        !            78: #include <sys/mplock.h>
        !            79: struct __mp_lock ddb_mp_lock;
        !            80:
        !            81: void   m88k_db_cpu_cmd(db_expr_t, int, db_expr_t, char *);
        !            82: #endif
        !            83:
        !            84: /*
        !            85:  * If you really feel like understanding the following procedure and
        !            86:  * macros, see pages 6-22 to 6-30 (Section 6.7.3) of
        !            87:  *
        !            88:  * MC88100 RISC Microprocessor User's Manual Second Edition
        !            89:  * (Motorola Order: MC88100UM/AD REV 1)
        !            90:  *
        !            91:  * and ERRATA-5 (6-23, 6-24, 6-24) of
        !            92:  *
        !            93:  * Errata to MC88100 User's Manual Second Edition MC88100UM/AD Rev 1
        !            94:  * (Oct 2, 1990)
        !            95:  * (Motorola Order: MC88100UMAD/AD)
        !            96:  */
        !            97:
        !            98: #ifdef M88100
        !            99: /* macros for decoding dmt registers */
        !           100:
        !           101: /*
        !           102:  * return 1 if the printing of the next stage should be suppressed
        !           103:  */
        !           104: int
        !           105: m88k_dmx_print(u_int t, u_int d, u_int a, u_int no)
        !           106: {
        !           107:        static const u_int addr_mod[16] = {
        !           108:                0, 3, 2, 2, 1, 0, 0, 0,
        !           109:                0, 0, 0, 0, 0, 0, 0, 0
        !           110:        };
        !           111:        static const char *mode[16]  = {
        !           112:                "?", ".b", ".b", ".h", ".b", "?", "?", "?",
        !           113:                ".b", "?", "?" , "?" , ".h" , "?", "?", ""
        !           114:        };
        !           115:        static const u_int mask[16] = {
        !           116:                0, 0xff, 0xff00, 0xffff,
        !           117:                0xff0000, 0, 0, 0,
        !           118:                0xff000000, 0, 0, 0,
        !           119:                0xffff0000, 0, 0, 0xffffffff
        !           120:        };
        !           121:        static const u_int shift[16] = {
        !           122:                0,  0, 8, 0, 16, 0, 0, 0,
        !           123:                24, 0, 0, 0, 16, 0, 0, 0
        !           124:        };
        !           125:        int reg = DMT_DREGBITS(t);
        !           126:
        !           127:        if (ISSET(t, DMT_LOCKBAR)) {
        !           128:                db_printf("xmem%s%s r%d(0x%x) <-> mem(0x%x),",
        !           129:                    DMT_ENBITS(t) == 0x0f ? "" : ".bu",
        !           130:                    ISSET(t, DMT_DAS) ? "" : ".usr", reg,
        !           131:                    ((t >> 2 & 0xf) == 0xf) ? d : (d & 0xff), a);
        !           132:                return 1;
        !           133:        } else if (DMT_ENBITS(t) == 0xf) {
        !           134:                /* full or double word */
        !           135:                if (ISSET(t, DMT_WRITE)) {
        !           136:                        if (ISSET(t, DMT_DOUB1) && no == 2)
        !           137:                                db_printf("st.d%s -> mem(0x%x) (** restart sxip **)",
        !           138:                                    ISSET(t, DMT_DAS) ? "" : ".usr", a);
        !           139:                        else
        !           140:                                db_printf("st%s (0x%x) -> mem(0x%x)",
        !           141:                                    ISSET(t, DMT_DAS) ? "" : ".usr", d, a);
        !           142:                } else {
        !           143:                        /* load */
        !           144:                        if (ISSET(t, DMT_DOUB1) && no == 2)
        !           145:                                db_printf("ld.d%s r%d <- mem(0x%x), r%d <- mem(0x%x)",
        !           146:                                    ISSET(t, DMT_DAS) ? "" : ".usr", reg, a, reg+1, a+4);
        !           147:                        else
        !           148:                                db_printf("ld%s r%d <- mem(0x%x)",
        !           149:                                    ISSET(t, DMT_DAS) ? "" : ".usr", reg, a);
        !           150:                }
        !           151:        } else {
        !           152:                /* fractional word - check if load or store */
        !           153:                a += addr_mod[DMT_ENBITS(t)];
        !           154:                if (ISSET(t, DMT_WRITE))
        !           155:                        db_printf("st%s%s (0x%x) -> mem(0x%x)",
        !           156:                            mode[DMT_ENBITS(t)],
        !           157:                            ISSET(t, DMT_DAS) ? "" : ".usr",
        !           158:                            (d & mask[DMT_ENBITS(t)]) >> shift[DMT_ENBITS(t)],
        !           159:                            a);
        !           160:                else
        !           161:                        db_printf("ld%s%s%s r%d <- mem(0x%x)",
        !           162:                            mode[DMT_ENBITS(t)],
        !           163:                            ISSET(t, DMT_SIGNED) ? "" : "u",
        !           164:                            ISSET(t, DMT_DAS) ? "" : ".usr", reg, a);
        !           165:        }
        !           166:        return (0);
        !           167: }
        !           168: #endif /* M88100 */
        !           169:
        !           170: void
        !           171: m88k_db_print_frame(addr, have_addr, count, modif)
        !           172:        db_expr_t addr;
        !           173:        int have_addr;
        !           174:        db_expr_t count;
        !           175:        char *modif;
        !           176: {
        !           177:        struct trapframe *s = (struct trapframe *)addr;
        !           178:        char *name;
        !           179:        db_expr_t offset;
        !           180: #ifdef M88100
        !           181:        int suppress1 = 0, suppress2 = 0;
        !           182: #endif
        !           183:        int c, force = 0, help = 0;
        !           184:
        !           185:        if (!have_addr) {
        !           186:                db_printf("requires address of frame\n");
        !           187:                help = 1;
        !           188:        }
        !           189:
        !           190:        while (modif && *modif) {
        !           191:                switch (c = *modif++, c) {
        !           192:                case 'f':
        !           193:                        force = 1;
        !           194:                        break;
        !           195:                case 'h':
        !           196:                        help = 1;
        !           197:                        break;
        !           198:                default:
        !           199:                        db_printf("unknown modifier [%c]\n", c);
        !           200:                        help = 1;
        !           201:                        break;
        !           202:                }
        !           203:        }
        !           204:
        !           205:        if (help) {
        !           206:                db_printf("usage: mach frame/[f] ADDRESS\n");
        !           207:                db_printf("  /f force printing of insane frames.\n");
        !           208:                return;
        !           209:        }
        !           210:
        !           211:        if (badaddr((vaddr_t)s, 4) ||
        !           212:            badaddr((vaddr_t)(&((db_regs_t*)s)->fpit), 4)) {
        !           213:                db_printf("frame at %8p is unreadable\n", s);
        !           214:                return;
        !           215:        }
        !           216:
        !           217:        if (frame_is_sane((db_regs_t *)s, 0) == 0) {
        !           218:                if (force == 0)
        !           219:                        return;
        !           220:        }
        !           221:
        !           222: #define R(i) s->tf_r[i]
        !           223: #define IPMASK(x) ((x) &  ~(3))
        !           224:        db_printf("R00-05: 0x%08x  0x%08x  0x%08x  0x%08x  0x%08x  0x%08x\n",
        !           225:            R(0), R(1), R(2), R(3), R(4), R(5));
        !           226:        db_printf("R06-11: 0x%08x  0x%08x  0x%08x  0x%08x  0x%08x  0x%08x\n",
        !           227:            R(6), R(7), R(8), R(9), R(10), R(11));
        !           228:        db_printf("R12-17: 0x%08x  0x%08x  0x%08x  0x%08x  0x%08x  0x%08x\n",
        !           229:            R(12), R(13), R(14), R(15), R(16), R(17));
        !           230:        db_printf("R18-23: 0x%08x  0x%08x  0x%08x  0x%08x  0x%08x  0x%08x\n",
        !           231:            R(18), R(19), R(20), R(21), R(22), R(23));
        !           232:        db_printf("R24-29: 0x%08x  0x%08x  0x%08x  0x%08x  0x%08x  0x%08x\n",
        !           233:            R(24), R(25), R(26), R(27), R(28), R(29));
        !           234:        db_printf("R30-31: 0x%08x  0x%08x\n", R(30), R(31));
        !           235:
        !           236:        db_printf("%cxip: 0x%08x ",
        !           237:            CPU_IS88110 ? 'e' : 's', s->tf_sxip & XIP_ADDR);
        !           238:        db_find_xtrn_sym_and_offset((db_addr_t)IPMASK(s->tf_sxip),
        !           239:            &name, &offset);
        !           240:        if (name != NULL && (u_int)offset <= db_maxoff)
        !           241:                db_printf("%s+0x%08x", name, (u_int)offset);
        !           242:        db_printf("\n");
        !           243:
        !           244:        if (s->tf_snip != s->tf_sxip + 4) {
        !           245:                db_printf("%cnip: 0x%08x ",
        !           246:                    CPU_IS88110 ? 'e' : 's', s->tf_snip);
        !           247:                db_find_xtrn_sym_and_offset((db_addr_t)IPMASK(s->tf_snip),
        !           248:                    &name, &offset);
        !           249:                if (name != NULL && (u_int)offset <= db_maxoff)
        !           250:                        db_printf("%s+0x%08x", name, (u_int)offset);
        !           251:                db_printf("\n");
        !           252:        }
        !           253:
        !           254: #ifdef M88100
        !           255:        if (CPU_IS88100) {
        !           256:                if (s->tf_sfip != s->tf_snip + 4) {
        !           257:                        db_printf("sfip: 0x%08x ", s->tf_sfip);
        !           258:                        db_find_xtrn_sym_and_offset((db_addr_t)IPMASK(s->tf_sfip),
        !           259:                            &name, &offset);
        !           260:                        if (name != NULL && (u_int)offset <= db_maxoff)
        !           261:                                db_printf("%s+0x%08x", name, (u_int)offset);
        !           262:                        db_printf("\n");
        !           263:                }
        !           264:        }
        !           265: #endif
        !           266: #ifdef M88110
        !           267:        if (CPU_IS88110) {
        !           268:                db_printf("fpsr: 0x%08x fpcr: 0x%08x fpecr: 0x%08x\n",
        !           269:                          s->tf_fpsr, s->tf_fpcr, s->tf_fpecr);
        !           270:                db_printf("dsap 0x%08x duap 0x%08x dsr 0x%08x dlar 0x%08x dpar 0x%08x\n",
        !           271:                          s->tf_dsap, s->tf_duap, s->tf_dsr, s->tf_dlar, s->tf_dpar);
        !           272:                db_printf("isap 0x%08x iuap 0x%08x isr 0x%08x ilar 0x%08x ipar 0x%08x\n",
        !           273:                          s->tf_isap, s->tf_iuap, s->tf_isr, s->tf_ilar, s->tf_ipar);
        !           274:        }
        !           275: #endif
        !           276:
        !           277:        db_printf("epsr: 0x%08x                current process: %p\n",
        !           278:                  s->tf_epsr, curproc);
        !           279:        db_printf("vector: 0x%02x                    interrupt mask: 0x%08x\n",
        !           280:                  s->tf_vector, s->tf_mask);
        !           281:
        !           282:        /*
        !           283:         * If the vector indicates trap, instead of an exception or
        !           284:         * interrupt, skip the check of dmt and fp regs.
        !           285:         *
        !           286:         * Interrupt and exceptions are vectored at 0-10 and 114-127.
        !           287:         */
        !           288:        if (!(s->tf_vector <= 10 ||
        !           289:            (114 <= s->tf_vector && s->tf_vector <= 127))) {
        !           290:                db_printf("\n");
        !           291:                return;
        !           292:        }
        !           293:
        !           294: #ifdef M88100
        !           295:        if (CPU_IS88100) {
        !           296:                if (s->tf_vector == /*data*/3 || s->tf_dmt0 & DMT_VALID) {
        !           297:                        db_printf("dmt,d,a0: 0x%08x  0x%08x  0x%08x ",
        !           298:                            s->tf_dmt0, s->tf_dmd0, s->tf_dma0);
        !           299:                        db_find_xtrn_sym_and_offset((db_addr_t)s->tf_dma0,
        !           300:                            &name, &offset);
        !           301:                        if (name != NULL && (u_int)offset <= db_maxoff)
        !           302:                                db_printf("%s+0x%08x", name, (u_int)offset);
        !           303:                        db_printf("\n          ");
        !           304:
        !           305:                        suppress1 = m88k_dmx_print(s->tf_dmt0, s->tf_dmd0,
        !           306:                            s->tf_dma0, 0);
        !           307:                        db_printf("\n");
        !           308:
        !           309:                        if ((s->tf_dmt1 & DMT_VALID) && (!suppress1)) {
        !           310:                                db_printf("dmt,d,a1: 0x%08x  0x%08x  0x%08x ",
        !           311:                                    s->tf_dmt1, s->tf_dmd1, s->tf_dma1);
        !           312:                                db_find_xtrn_sym_and_offset((db_addr_t)s->tf_dma1,
        !           313:                                    &name, &offset);
        !           314:                                if (name != NULL && (u_int)offset <= db_maxoff)
        !           315:                                        db_printf("%s+0x%08x", name,
        !           316:                                            (u_int)offset);
        !           317:                                db_printf("\n          ");
        !           318:                                suppress2 = m88k_dmx_print(s->tf_dmt1,
        !           319:                                    s->tf_dmd1, s->tf_dma1, 1);
        !           320:                                db_printf("\n");
        !           321:
        !           322:                                if ((s->tf_dmt2 & DMT_VALID) && (!suppress2)) {
        !           323:                                        db_printf("dmt,d,a2: 0x%08x  0x%08x  0x%08x ",
        !           324:                                                  s->tf_dmt2, s->tf_dmd2, s->tf_dma2);
        !           325:                                        db_find_xtrn_sym_and_offset((db_addr_t)s->tf_dma2,
        !           326:                                            &name, &offset);
        !           327:                                        if (name != 0 &&
        !           328:                                            (u_int)offset <= db_maxoff)
        !           329:                                                db_printf("%s+0x%08x", name,
        !           330:                                                    (u_int)offset);
        !           331:                                        db_printf("\n          ");
        !           332:                                        m88k_dmx_print(s->tf_dmt2, s->tf_dmd2,
        !           333:                                            s->tf_dma2, 2);
        !           334:                                        db_printf("\n");
        !           335:                                }
        !           336:                        }
        !           337:
        !           338:                        db_printf("fault code %d\n",
        !           339:                            CMMU_PFSR_FAULT(s->tf_dpfsr));
        !           340:                }
        !           341:        }
        !           342: #endif /* M88100 */
        !           343:
        !           344:        if (s->tf_fpecr & 255) { /* floating point error occurred */
        !           345:                db_printf("fpecr: 0x%08x fpsr: 0x%08x fpcr: 0x%08x\n",
        !           346:                    s->tf_fpecr, s->tf_fpsr, s->tf_fpcr);
        !           347: #ifdef M88100
        !           348:                if (CPU_IS88100) {
        !           349:                        db_printf("fcr1-4: 0x%08x  0x%08x  0x%08x  0x%08x\n",
        !           350:                            s->tf_fphs1, s->tf_fpls1, s->tf_fphs2, s->tf_fpls2);
        !           351:                        db_printf("fcr5-8: 0x%08x  0x%08x  0x%08x  0x%08x\n",
        !           352:                            s->tf_fppt, s->tf_fprh, s->tf_fprl, s->tf_fpit);
        !           353:                }
        !           354: #endif
        !           355:        }
        !           356:        db_printf("\n");
        !           357: }
        !           358:
        !           359: void
        !           360: m88k_db_registers(addr, have_addr, count, modif)
        !           361:        db_expr_t addr;
        !           362:        int have_addr;
        !           363:        db_expr_t count;
        !           364:        char *modif;
        !           365: {
        !           366:        m88k_db_print_frame((db_expr_t)DDB_REGS, TRUE, 0, modif);
        !           367: }
        !           368:
        !           369: /*
        !           370:  * pause for 2*ticks many cycles
        !           371:  */
        !           372: void
        !           373: m88k_db_pause(ticks)
        !           374:        u_int volatile ticks;
        !           375: {
        !           376:        while (ticks)
        !           377:                ticks -= 1;
        !           378: }
        !           379:
        !           380: /*
        !           381:  * m88k_db_trap - field a TRACE or BPT trap
        !           382:  * Note that only the tf_regs part of the frame is valid - some ddb routines
        !           383:  * invoke this function with a promoted struct reg!
        !           384:  */
        !           385: void
        !           386: m88k_db_trap(type, frame)
        !           387:        int type;
        !           388:        struct trapframe *frame;
        !           389: {
        !           390:        if (get_psr() & PSR_IND)
        !           391:                db_printf("WARNING: entered debugger with interrupts disabled\n");
        !           392:
        !           393:        switch(type) {
        !           394:        case T_KDB_BREAK:
        !           395:        case T_KDB_TRACE:
        !           396:        case T_KDB_ENTRY:
        !           397:                break;
        !           398:        case -1:
        !           399:                break;
        !           400:        default:
        !           401:                kdbprinttrap(type);
        !           402:                if (db_recover != 0) {
        !           403:                        db_error("Caught exception in ddb.\n");
        !           404:                        /*NOTREACHED*/
        !           405:                }
        !           406:        }
        !           407:
        !           408: #ifdef MULTIPROCESSOR
        !           409:        curcpu()->ci_ddb_state = CI_DDB_ENTERDDB;
        !           410:        __mp_lock(&ddb_mp_lock);
        !           411:        curcpu()->ci_ddb_state = CI_DDB_INDDB;
        !           412:        m88k_broadcast_ipi(CI_IPI_DDB);         /* pause other processors */
        !           413: #endif
        !           414:
        !           415:        ddb_regs = frame->tf_regs;
        !           416:
        !           417:        cnpollc(TRUE);
        !           418:        db_trap(type, 0);
        !           419:        cnpollc(FALSE);
        !           420:
        !           421:        frame->tf_regs = ddb_regs;
        !           422:
        !           423: #ifdef MULTIPROCESSOR
        !           424:        curcpu()->ci_ddb_state = CI_DDB_RUNNING;
        !           425:        __mp_release_all(&ddb_mp_lock);
        !           426: #endif
        !           427: }
        !           428:
        !           429: extern const char *trap_type[];
        !           430: extern const int trap_types;
        !           431:
        !           432: /*
        !           433:  * Print trap reason.
        !           434:  */
        !           435: void
        !           436: kdbprinttrap(int type)
        !           437: {
        !           438:        printf("kernel: ");
        !           439:        if (type >= trap_types || type < 0)
        !           440:                printf("type %d", type);
        !           441:        else
        !           442:                printf("%s", trap_type[type]);
        !           443:        printf(" trap\n");
        !           444: }
        !           445:
        !           446: void
        !           447: Debugger()
        !           448: {
        !           449:        asm (ENTRY_ASM); /* entry trap */
        !           450:        /* ends up at ddb_entry_trap below */
        !           451:        return;
        !           452: }
        !           453:
        !           454: /*
        !           455:  * When the below routine is entered interrupts should be on
        !           456:  * but spl should be high
        !           457:  *
        !           458:  * The following routine is for breakpoint and watchpoint entry.
        !           459:  */
        !           460:
        !           461: /* breakpoint/watchpoint entry */
        !           462: int
        !           463: ddb_break_trap(type, eframe)
        !           464:        int type;
        !           465:        db_regs_t *eframe;
        !           466: {
        !           467:        m88k_db_trap(type, (struct trapframe *)eframe);
        !           468:
        !           469:        if (type == T_KDB_BREAK) {
        !           470:                /*
        !           471:                 * back up an instruction and retry the instruction
        !           472:                 * at the breakpoint address.  mc88110's exip reg
        !           473:                 * already has the address of the exception instruction.
        !           474:                 */
        !           475:                if (CPU_IS88100) {
        !           476:                        eframe->sfip = eframe->snip;
        !           477:                        eframe->snip = eframe->sxip;
        !           478:                }
        !           479:        }
        !           480:
        !           481:        return 0;
        !           482: }
        !           483:
        !           484: /* enter at splhigh */
        !           485: int
        !           486: ddb_entry_trap(level, eframe)
        !           487:        int level;
        !           488:        db_regs_t *eframe;
        !           489: {
        !           490:        m88k_db_trap(T_KDB_ENTRY, (struct trapframe *)eframe);
        !           491:
        !           492:        return 0;
        !           493: }
        !           494:
        !           495: /*
        !           496:  * When the below routine is entered interrupts should be on
        !           497:  * but spl should be high
        !           498:  */
        !           499: /* error trap - unreturnable */
        !           500: void
        !           501: ddb_error_trap(error, regs)
        !           502:        char *error;
        !           503:        db_regs_t *regs;
        !           504: {
        !           505:        db_printf("KERNEL:  unrecoverable error [%s]\n", error);
        !           506:        db_printf("KERNEL:  Exiting debugger will cause abort to rom\n");
        !           507:        db_printf("at 0x%x ", regs->sxip & XIP_ADDR);
        !           508:        db_printf("dmt0 0x%x dma0 0x%x", regs->dmt0, regs->dma0);
        !           509:        m88k_db_pause(1000000);
        !           510:        m88k_db_trap(T_KDB_BREAK, (struct trapframe *)regs);
        !           511: }
        !           512:
        !           513: /*
        !           514:  * Read bytes from kernel address space for debugger.
        !           515:  */
        !           516: void
        !           517: db_read_bytes(db_addr_t addr, size_t size, char *data)
        !           518: {
        !           519:        char *src;
        !           520:
        !           521:        src = (char *)addr;
        !           522:
        !           523:        while (size-- > 0) {
        !           524:                *data++ = *src++;
        !           525:        }
        !           526: }
        !           527:
        !           528: /*
        !           529:  * Write bytes to kernel address space for debugger.
        !           530:  */
        !           531: void
        !           532: db_write_bytes(db_addr_t addr, size_t size, char *data)
        !           533: {
        !           534:        extern pt_entry_t *pmap_pte(pmap_t, vaddr_t);
        !           535:        char *dst = (char *)addr;
        !           536:        vaddr_t va;
        !           537:        paddr_t pa;
        !           538:        pt_entry_t *pte, opte;
        !           539:        size_t len, olen;
        !           540:        int cpu = cpu_number();
        !           541:
        !           542:        while (size != 0) {
        !           543:                va = trunc_page((vaddr_t)dst);
        !           544:                pte = pmap_pte(pmap_kernel(), va);
        !           545:                opte = *pte;
        !           546:
        !           547:                pa = (opte & PG_FRAME) | ((vaddr_t)dst & PAGE_MASK);
        !           548:                len = PAGE_SIZE - ((vaddr_t)dst & PAGE_MASK);
        !           549:                if (len > size)
        !           550:                        len = size;
        !           551:                size -= olen = len;
        !           552:
        !           553:                if (opte & PG_RO) {
        !           554:                        *pte = opte & ~PG_RO;
        !           555:                        cmmu_flush_tlb(cpu, TRUE, va, 1);
        !           556:                }
        !           557:                while (len-- != 0)
        !           558:                        *dst++ = *data++;
        !           559:                if (opte & PG_RO) {
        !           560:                        *pte = opte;
        !           561:                        cmmu_flush_tlb(cpu, TRUE, va, 1);
        !           562:                }
        !           563:                cmmu_flush_cache(cpu, pa, olen);
        !           564:        }
        !           565: }
        !           566:
        !           567: /* display where all the cpus are stopped at */
        !           568: void
        !           569: m88k_db_where(addr, have_addr, count, modif)
        !           570:        db_expr_t addr;
        !           571:        int have_addr;
        !           572:        db_expr_t count;
        !           573:        char *modif;
        !           574: {
        !           575:        char *name;
        !           576:        db_expr_t offset;
        !           577:        db_addr_t l;
        !           578:
        !           579:        l = PC_REGS(DDB_REGS); /* clear low bits */
        !           580:
        !           581:        db_find_xtrn_sym_and_offset(l, &name, &offset);
        !           582:        if (name && (u_int)offset <= db_maxoff)
        !           583:                db_printf("stopped at 0x%lx  (%s+0x%x)\n", l, name, offset);
        !           584:        else
        !           585:                db_printf("stopped at 0x%lx\n", l);
        !           586: }
        !           587:
        !           588: /*
        !           589:  * Walk back a stack, looking for exception frames.
        !           590:  * These frames are recognized by the routine frame_is_sane. Frames
        !           591:  * only start with zero, so we only call frame_is_sane if the
        !           592:  * current address contains zero.
        !           593:  *
        !           594:  * If addr is given, it is assumed to an address on the stack to be
        !           595:  * searched. Otherwise, r31 of the current cpu is used.
        !           596:  */
        !           597: void
        !           598: m88k_db_frame_search(addr, have_addr, count, modif)
        !           599:        db_expr_t addr;
        !           600:        int have_addr;
        !           601:        db_expr_t count;
        !           602:        char *modif;
        !           603: {
        !           604:        if (have_addr)
        !           605:                addr &= ~3; /* round to word */
        !           606:        else
        !           607:                addr = (DDB_REGS->r[31]);
        !           608:
        !           609:        /* walk back up stack until 8k boundry, looking for 0 */
        !           610:        while (addr & ((8 * 1024) - 1)) {
        !           611:                if (frame_is_sane((db_regs_t *)addr, 1) != 0)
        !           612:                        db_printf("frame found at 0x%x\n", addr);
        !           613:                addr += 4;
        !           614:        }
        !           615:
        !           616:        db_printf("(Walked back until 0x%x)\n",addr);
        !           617: }
        !           618:
        !           619: #ifdef MULTIPROCESSOR
        !           620:
        !           621: void
        !           622: m88k_db_cpu_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
        !           623: {
        !           624:        cpuid_t cpu;
        !           625:        struct cpu_info *ci;
        !           626:
        !           627:        CPU_INFO_FOREACH(cpu, ci) {
        !           628:                db_printf("%c%4d: ", (cpu == cpu_number()) ? '*' : ' ',
        !           629:                    CPU_INFO_UNIT(ci));
        !           630:                switch (ci->ci_ddb_state) {
        !           631:                case CI_DDB_RUNNING:
        !           632:                        db_printf("running\n");
        !           633:                        break;
        !           634:                case CI_DDB_ENTERDDB:
        !           635:                        db_printf("entering ddb\n");
        !           636:                        break;
        !           637:                case CI_DDB_INDDB:
        !           638:                        db_printf("ddb\n");
        !           639:                        break;
        !           640:                default:
        !           641:                        db_printf("? (%d)\n",
        !           642:                            ci->ci_ddb_state);
        !           643:                        break;
        !           644:                }
        !           645:        }
        !           646: }
        !           647:
        !           648: #endif /* MULTIPROCESSOR */
        !           649:
        !           650: /************************/
        !           651: /* COMMAND TABLE / INIT */
        !           652: /************************/
        !           653:
        !           654: struct db_command db_machine_cmds[] = {
        !           655: #ifdef MULTIPROCESSOR
        !           656:        { "cpu",        m88k_db_cpu_cmd,        0,      NULL },
        !           657: #endif
        !           658:        { "frame",      m88k_db_print_frame,    0,      NULL },
        !           659:        { "regs",       m88k_db_registers,      0,      NULL },
        !           660:        { "searchframe",m88k_db_frame_search,   0,      NULL },
        !           661:        { "where",      m88k_db_where,          0,      NULL },
        !           662: #if defined(EXTRA_MACHDEP_COMMANDS)
        !           663:        EXTRA_MACHDEP_COMMANDS
        !           664: #endif
        !           665:        { NULL,         NULL,                   0,      NULL }
        !           666: };
        !           667:
        !           668: void
        !           669: db_machine_init()
        !           670: {
        !           671:        db_machine_commands_install(db_machine_cmds);
        !           672: #ifdef MULTIPROCESSOR
        !           673:        __mp_lock_init(&ddb_mp_lock);
        !           674: #endif
        !           675: }

CVSweb