[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

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