Annotation of XNU/osfmk/ppc/db_interface.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * @OSF_COPYRIGHT@
        !            24:  */
        !            25: 
        !            26: #include <cpus.h>
        !            27: #include <platforms.h>
        !            28: #include <time_stamp.h>
        !            29: #include <mach_mp_debug.h>
        !            30: #include <mach_ldebug.h>
        !            31: #include <db_machine_commands.h>
        !            32: 
        !            33: #include <kern/spl.h>
        !            34: #include <kern/cpu_number.h>
        !            35: #include <kern/kern_types.h>
        !            36: #include <kern/misc_protos.h>
        !            37: #include <vm/pmap.h>
        !            38: 
        !            39: #include <ppc/mem.h>
        !            40: #include <ppc/thread.h>
        !            41: #include <ppc/db_machdep.h>
        !            42: #include <ppc/trap.h>
        !            43: #include <ppc/setjmp.h>
        !            44: #include <ppc/pmap.h>
        !            45: #include <ppc/misc_protos.h>
        !            46: #include <ppc/exception.h>
        !            47: #include <ppc/db_machdep.h>
        !            48: #include <ppc/mappings.h>
        !            49: #include <ppc/Firmware.h>
        !            50: 
        !            51: #include <mach/vm_param.h>
        !            52: #include <mach/machine/vm_types.h>
        !            53: #include <vm/vm_map.h>
        !            54: #include <kern/thread.h>
        !            55: #include <kern/task.h>
        !            56: #include <kern/debug.h>
        !            57: 
        !            58: #include <ddb/db_command.h>
        !            59: #include <ddb/db_task_thread.h>
        !            60: #include <ddb/db_run.h>
        !            61: #include <ddb/db_trap.h>
        !            62: #include <ddb/db_output.h>
        !            63: #include <ddb/db_access.h>
        !            64: #include <ddb/db_sym.h>
        !            65: #include <ddb/db_break.h>
        !            66: #include <ddb/db_watch.h>
        !            67: 
        !            68: struct  ppc_saved_state *ppc_last_saved_statep;
        !            69: struct  ppc_saved_state ppc_nested_saved_state;
        !            70: unsigned ppc_last_kdb_sp;
        !            71: 
        !            72: extern int debugger_active[NCPUS];             /* Debugger active on CPU */
        !            73: extern int debugger_cpu;                               /* Current cpu running debugger */
        !            74: 
        !            75: int            db_all_set_up = 0;
        !            76: 
        !            77: 
        !            78: #if !MACH_KDP
        !            79: void kdp_register_send_receive(void);
        !            80: #endif
        !            81: 
        !            82: /*
        !            83:  *     Enter KDB through a keyboard trap.
        !            84:  *     We show the registers as of the keyboard interrupt
        !            85:  *     instead of those at its call to KDB.
        !            86:  */
        !            87: struct int_regs {
        !            88:        /* XXX more registers ? */
        !            89:        struct ppc_interrupt_state *is;
        !            90: };
        !            91: 
        !            92: extern char *  trap_type[];
        !            93: extern int     TRAP_TYPES;
        !            94: 
        !            95: /*
        !            96:  * Code used to synchronize kdb among all cpus, one active at a time, switch
        !            97:  * from on to another using kdb_on! #cpu or cpu #cpu
        !            98:  */
        !            99: 
        !           100: decl_simple_lock_data(, kdb_lock)      /* kdb lock                     */
        !           101: 
        !           102: #define        db_simple_lock_init(l, e)       hw_lock_init(&((l)->interlock))
        !           103: #define        db_simple_lock_try(l)           hw_lock_try(&((l)->interlock))
        !           104: #define        db_simple_unlock(l)             hw_lock_unlock(&((l)->interlock))
        !           105: 
        !           106: extern volatile unsigned int   cpus_holding_bkpts;     /* counter for number of cpus holding
        !           107:                                                   breakpoints (ie: cpus that did not
        !           108:                                                   insert back breakpoints) */
        !           109: extern boolean_t       db_breakpoints_inserted;
        !           110: 
        !           111: /* Forward */
        !           112: 
        !           113: extern void    kdbprinttrap(
        !           114:                        int                     type,
        !           115:                        int                     code,
        !           116:                        int                     *pc,
        !           117:                        int                     sp);
        !           118: extern int     db_user_to_kernel_address(
        !           119:                        task_t                  task,
        !           120:                        vm_offset_t             addr,
        !           121:                        unsigned                *kaddr,
        !           122:                        int                     flag);
        !           123: extern void    db_write_bytes_user_space(
        !           124:                        vm_offset_t             addr,
        !           125:                        int                     size,
        !           126:                        char                    *data,
        !           127:                        task_t                  task);
        !           128: extern int     db_search_null(
        !           129:                        task_t                  task,
        !           130:                        unsigned                *svaddr,
        !           131:                        unsigned                evaddr,
        !           132:                        unsigned                *skaddr,
        !           133:                        int                     flag);
        !           134: extern int     kdb_enter(int);
        !           135: extern void    kdb_leave(void);
        !           136: extern void    lock_kdb(void);
        !           137: extern void    unlock_kdb(void);
        !           138: 
        !           139: #if DB_MACHINE_COMMANDS
        !           140: struct db_command      ppc_db_commands[] = {
        !           141:        { "lt",         db_low_trace,   CS_MORE|CS_SET_DOT,     0 },
        !           142:        { (char *)0,    0,              0,                      0 }
        !           143: };
        !           144: #endif /* DB_MACHINE_COMMANDS */
        !           145: 
        !           146: #if !MACH_KDP
        !           147: void kdp_register_send_receive(void) {}
        !           148: #endif
        !           149: 
        !           150: extern jmp_buf_t *db_recover;
        !           151: spl_t  saved_ipl[NCPUS];       /* just to know what IPL was before trap */
        !           152: struct ppc_saved_state *saved_state[NCPUS];
        !           153: 
        !           154: /*
        !           155:  *  kdb_trap - field a TRACE or BPT trap
        !           156:  */
        !           157: void
        !           158: kdb_trap(
        !           159:        int                     type,
        !           160:        struct ppc_saved_state *regs)
        !           161: {
        !           162:        boolean_t       trap_from_user;
        !           163:        int                     previous_console_device;
        !           164:        int                     code=0;
        !           165: 
        !           166:        previous_console_device=switch_to_serial_console();
        !           167: 
        !           168:        switch (type) {
        !           169:            case T_TRACE:       /* single_step */
        !           170:            case T_PROGRAM:     /* breakpoint */
        !           171: #if 0
        !           172:            case T_WATCHPOINT:  /* watchpoint */
        !           173: #endif
        !           174:            case -1:    /* keyboard interrupt */
        !           175:                break;
        !           176: 
        !           177:            default:
        !           178:                if (db_recover) {
        !           179:                    ppc_nested_saved_state = *regs;
        !           180:                    db_printf("Caught ");
        !           181:                    if (type > TRAP_TYPES)
        !           182:                        db_printf("type %d", type);
        !           183:                    else
        !           184:                        db_printf("%s", trap_type[type]);
        !           185:                    db_printf(" trap, pc = %x\n",
        !           186:                              regs->srr0);
        !           187:                    db_error("");
        !           188:                    /*NOTREACHED*/
        !           189:                }
        !           190:                kdbprinttrap(type, code, (int *)&regs->srr0, regs->r1);
        !           191:        }
        !           192: 
        !           193:        saved_state[cpu_number()] = regs;
        !           194: 
        !           195:        ppc_last_saved_statep = regs;
        !           196:        ppc_last_kdb_sp = (unsigned) &type;
        !           197: 
        !           198:        if (!IS_USER_TRAP(regs)) {
        !           199:                bzero((char *)&ddb_regs, sizeof (ddb_regs));
        !           200:                ddb_regs = *regs;
        !           201:                trap_from_user = FALSE; 
        !           202: 
        !           203:        }
        !           204:        else {
        !           205:                ddb_regs = *regs;
        !           206:                trap_from_user = TRUE;
        !           207:        }
        !           208: 
        !           209:        db_task_trap(type, code, trap_from_user);
        !           210: 
        !           211:        *regs = ddb_regs;
        !           212: 
        !           213:        if ((type == T_PROGRAM) &&
        !           214:            (db_get_task_value(regs->srr0,
        !           215:                               BKPT_SIZE,
        !           216:                               FALSE,
        !           217:                               db_target_space(current_act(),
        !           218:                                               trap_from_user))
        !           219:                              == BKPT_INST))
        !           220:            regs->srr0 += BKPT_SIZE;
        !           221: 
        !           222: kdb_exit:
        !           223:        saved_state[cpu_number()] = 0;
        !           224:        switch_to_old_console(previous_console_device);
        !           225: 
        !           226: }
        !           227: 
        !           228: 
        !           229: /*
        !           230:  * Print trap reason.
        !           231:  */
        !           232: 
        !           233: void
        !           234: kdbprinttrap(
        !           235:        int     type,
        !           236:        int     code,
        !           237:        int     *pc,
        !           238:        int     sp)
        !           239: {
        !           240:        printf("kernel: ");
        !           241:        if (type > TRAP_TYPES)
        !           242:            db_printf("type %d", type);
        !           243:        else
        !           244:            db_printf("%s", trap_type[type]);
        !           245:        db_printf(" trap, code=%x pc@%x = %x sp=%x\n",
        !           246:                  code, pc, *(int *)pc, sp);
        !           247:        db_run_mode = STEP_CONTINUE;
        !           248: }
        !           249: 
        !           250: /*
        !           251:  *
        !           252:  */
        !           253: vm_offset_t db_vtophys(
        !           254:        space_t space,
        !           255:        vm_offset_t va)
        !           256: {
        !           257:        register mapping        *mp;
        !           258:        register vm_offset_t    pa;
        !           259: 
        !           260:        pa = (vm_offset_t)LRA(space,(void *)va);
        !           261: 
        !           262:        if (pa != 0)
        !           263:                return(pa);
        !           264: 
        !           265:        mp = hw_lock_phys_vir(space, va);
        !           266:        if((unsigned int)mp&1) {
        !           267:                return 0;
        !           268:        }
        !           269: 
        !           270:        if(!mp) { 
        !           271:                return 0;
        !           272:        }
        !           273: 
        !           274:        mp = hw_cpv(mp);                                                /* Convert to virtual address */
        !           275: 
        !           276:        if(!mp->physent) {
        !           277:                pa = (vm_offset_t)((mp->PTEr & -PAGE_SIZE) | ((unsigned int)va & (PAGE_SIZE-1)));
        !           278:        } else {
        !           279:                pa = (vm_offset_t)((mp->physent->pte1 & -PAGE_SIZE) | ((unsigned int)va & (PAGE_SIZE-1)));
        !           280:                hw_unlock_bit((unsigned int *)&mp->physent->phys_link, PHYS_LOCK);
        !           281:        }
        !           282: 
        !           283:        return(pa);
        !           284: }
        !           285: 
        !           286: int
        !           287: db_user_to_kernel_address(
        !           288:        task_t          task,
        !           289:        vm_offset_t     addr,
        !           290:        unsigned        *kaddr,
        !           291:        int             flag)
        !           292: {
        !           293:        unsigned int    sr_val, raddr;
        !           294: 
        !           295:        raddr = (unsigned int)db_vtophys(task->map->pmap->space, trunc_page(addr));     /* Get the real address */
        !           296: 
        !           297:        if (!raddr) {
        !           298:            if (flag) {
        !           299:                db_printf("\nno memory is assigned to address %08x\n", addr);
        !           300:                db_error(0);
        !           301:                /* NOTREACHED */
        !           302:            }
        !           303:            return -1;
        !           304:        }
        !           305:        sr_val = SEG_REG_PROT | task->map->pmap->space
        !           306:                 | ((addr >> 8) & 0x00F00000);
        !           307:                
        !           308:        mtsr(SR_COPYIN_NUM, sr_val);
        !           309:        sync();
        !           310:        *kaddr = (addr & 0x0fffffff) | (SR_COPYIN_NUM << 28);
        !           311:        return(0);
        !           312: }
        !           313:        
        !           314: /*
        !           315:  * Read bytes from task address space for debugger.
        !           316:  */
        !           317: void
        !           318: db_read_bytes(
        !           319:        vm_offset_t     addr,
        !           320:        int             size,
        !           321:        char            *data,
        !           322:        task_t          task)
        !           323: {
        !           324:        int             n,max;
        !           325:        unsigned        phys_dst;
        !           326:        unsigned        phys_src;
        !           327:        unsigned int    space;
        !           328:        
        !           329:        while (size > 0) {
        !           330:                if (task != NULL)
        !           331:                        space = task->map->pmap->space;
        !           332:                else
        !           333:                        space = PPC_SID_KERNEL;
        !           334: 
        !           335:                phys_src = (unsigned int)db_vtophys(space, trunc_page(addr));  
        !           336:                if (phys_src == 0) {
        !           337:                        db_printf("\nno memory is assigned to src address %08x\n",
        !           338:                                  addr);
        !           339:                        db_error(0);
        !           340:                        /* NOTREACHED */
        !           341:                }
        !           342:                phys_src = phys_src| (addr & page_mask);
        !           343: 
        !           344:                space = PPC_SID_KERNEL;
        !           345: 
        !           346:                phys_dst = (unsigned int)db_vtophys(space, trunc_page(data)); 
        !           347:                if (phys_dst == 0) {
        !           348:                        db_printf("\nno memory is assigned to dst address %08x\n",
        !           349:                                  data);
        !           350:                        db_error(0);
        !           351:                        /* NOTREACHED */
        !           352:                }
        !           353:                
        !           354:                phys_dst = phys_dst | (((vm_offset_t) data) & page_mask);
        !           355: 
        !           356:                /* don't over-run any page boundaries - check src range */
        !           357:                max = ppc_round_page(phys_src) - phys_src;
        !           358:                if (max > size)
        !           359:                        max = size;
        !           360:                /* Check destination won't run over boundary either */
        !           361:                n = ppc_round_page(phys_dst) - phys_dst;
        !           362:                if (n < max)
        !           363:                        max = n;
        !           364:                size -= max;
        !           365:                addr += max;
        !           366:                phys_copy(phys_src, phys_dst, max);
        !           367: 
        !           368:                /* resync I+D caches */
        !           369:                sync_cache(phys_dst, max);
        !           370: 
        !           371:                phys_src += max;
        !           372:                phys_dst += max;
        !           373:        }
        !           374: }
        !           375: 
        !           376: /*
        !           377:  * Write bytes to task address space for debugger.
        !           378:  */
        !           379: void
        !           380: db_write_bytes(
        !           381:        vm_offset_t     addr,
        !           382:        int             size,
        !           383:        char            *data,
        !           384:        task_t          task)
        !           385: {
        !           386:        int             n,max;
        !           387:        unsigned        phys_dst;
        !           388:        unsigned        phys_src;
        !           389:        unsigned int    space;
        !           390:        
        !           391:        while (size > 0) {
        !           392:                space = PPC_SID_KERNEL;
        !           393: 
        !           394:                phys_src = (unsigned int)db_vtophys(space, trunc_page(data)); 
        !           395:                if (phys_src == 0) {
        !           396:                        db_printf("\nno memory is assigned to src address %08x\n",
        !           397:                                  data);
        !           398:                        db_error(0);
        !           399:                        /* NOTREACHED */
        !           400:                }
        !           401:                
        !           402:                phys_src = phys_src | (((vm_offset_t) data) & page_mask);
        !           403: 
        !           404:                /* space stays as kernel space unless in another task */
        !           405:                if (task != NULL)
        !           406:                        space = task->map->pmap->space;
        !           407: 
        !           408:                phys_dst = (unsigned int)db_vtophys(space, trunc_page(addr));  
        !           409:                if (phys_dst == 0) {
        !           410:                        db_printf("\nno memory is assigned to dst address %08x\n",
        !           411:                                  addr);
        !           412:                        db_error(0);
        !           413:                        /* NOTREACHED */
        !           414:                }
        !           415:                phys_dst = phys_dst| (addr & page_mask);
        !           416: 
        !           417:                /* don't over-run any page boundaries - check src range */
        !           418:                max = ppc_round_page(phys_src) - phys_src;
        !           419:                if (max > size)
        !           420:                        max = size;
        !           421:                /* Check destination won't run over boundary either */
        !           422:                n = ppc_round_page(phys_dst) - phys_dst;
        !           423:                if (n < max)
        !           424:                        max = n;
        !           425:                size -= max;
        !           426:                addr += max;
        !           427:                phys_copy(phys_src, phys_dst, max);
        !           428: 
        !           429:                /* resync I+D caches */
        !           430:                sync_cache(phys_dst, max);
        !           431: 
        !           432:                phys_src += max;
        !           433:                phys_dst += max;
        !           434:        }
        !           435: }
        !           436:        
        !           437: boolean_t
        !           438: db_check_access(
        !           439:        vm_offset_t     addr,
        !           440:        int             size,
        !           441:        task_t          task)
        !           442: {
        !           443:        register int    n;
        !           444:        unsigned int    kern_addr;
        !           445: 
        !           446:        if (task == kernel_task || task == TASK_NULL) {
        !           447:            if (kernel_task == TASK_NULL)
        !           448:                return(TRUE);
        !           449:            task = kernel_task;
        !           450:        } else if (task == TASK_NULL) {
        !           451:            if (current_act() == THR_ACT_NULL)
        !           452:                return(FALSE);
        !           453:            task = current_act()->task;
        !           454:        }
        !           455:        while (size > 0) {
        !           456:            if (db_user_to_kernel_address(task, addr, &kern_addr, 0) < 0)
        !           457:                return(FALSE);
        !           458:            n = ppc_trunc_page(addr+PPC_PGBYTES) - addr;
        !           459:            if (n > size)
        !           460:                n = size;
        !           461:            size -= n;
        !           462:            addr += n;
        !           463:        }
        !           464:        return(TRUE);
        !           465: }
        !           466: 
        !           467: boolean_t
        !           468: db_phys_eq(
        !           469:        task_t          task1,
        !           470:        vm_offset_t     addr1,
        !           471:        task_t          task2,
        !           472:        vm_offset_t     addr2)
        !           473: {
        !           474:        vm_offset_t     *physa, *physb;
        !           475: 
        !           476:        if ((addr1 & (PPC_PGBYTES-1)) != (addr2 & (PPC_PGBYTES-1)))     /* Is byte displacement the same? */
        !           477:                return FALSE;
        !           478: 
        !           479:        if (task1 == TASK_NULL) {                                               /* See if there is a task active */
        !           480:                if (current_act() == THR_ACT_NULL)                      /* See if there is a current task */
        !           481:                        return FALSE;
        !           482:                task1 = current_act()->task;                            /* If so, use that one */
        !           483:        }
        !           484:        
        !           485:        if(!(physa = db_vtophys(task1->map->pmap->space, trunc_page(addr1)))) return FALSE;     /* Get real address of the first */
        !           486:        if(!(physb = db_vtophys(task2->map->pmap->space, trunc_page(addr2)))) return FALSE;     /* Get real address of the second */
        !           487:        
        !           488:        return (physa == physb);                                                /* Check if they are equal, then return... */
        !           489: }
        !           490: 
        !           491: #define DB_USER_STACK_ADDR             (0xc0000000)
        !           492: #define DB_NAME_SEARCH_LIMIT           (DB_USER_STACK_ADDR-(PPC_PGBYTES*3))
        !           493: 
        !           494: int
        !           495: db_search_null(
        !           496:        task_t          task,
        !           497:        unsigned        *svaddr,
        !           498:        unsigned        evaddr,
        !           499:        unsigned        *skaddr,
        !           500:        int             flag)
        !           501: {
        !           502:        register unsigned vaddr;
        !           503:        register unsigned *kaddr;
        !           504: 
        !           505:        kaddr = (unsigned *)*skaddr;
        !           506:        for (vaddr = *svaddr; vaddr > evaddr; ) {
        !           507:            if (vaddr % PPC_PGBYTES == 0) {
        !           508:                vaddr -= sizeof(unsigned);
        !           509:                if (db_user_to_kernel_address(task, vaddr, skaddr, 0) < 0)
        !           510:                    return(-1);
        !           511:                kaddr = (unsigned *)*skaddr;
        !           512:            } else {
        !           513:                vaddr -= sizeof(unsigned);
        !           514:                kaddr--;
        !           515:            }
        !           516:            if ((*kaddr == 0) ^ (flag  == 0)) {
        !           517:                *svaddr = vaddr;
        !           518:                *skaddr = (unsigned)kaddr;
        !           519:                return(0);
        !           520:            }
        !           521:        }
        !           522:        return(-1);
        !           523: }
        !           524: 
        !           525: void
        !           526: db_task_name(
        !           527:        task_t          task)
        !           528: {
        !           529:        register char *p;
        !           530:        register int n;
        !           531:        unsigned int vaddr, kaddr;
        !           532: 
        !           533:        vaddr = DB_USER_STACK_ADDR;
        !           534:        kaddr = 0;
        !           535: 
        !           536:        /*
        !           537:         * skip nulls at the end
        !           538:         */
        !           539:        if (db_search_null(task, &vaddr, DB_NAME_SEARCH_LIMIT, &kaddr, 0) < 0) {
        !           540:            db_printf(DB_NULL_TASK_NAME);
        !           541:            return;
        !           542:        }
        !           543:        /*
        !           544:         * search start of args
        !           545:         */
        !           546:        if (db_search_null(task, &vaddr, DB_NAME_SEARCH_LIMIT, &kaddr, 1) < 0) {
        !           547:            db_printf(DB_NULL_TASK_NAME);
        !           548:            return;
        !           549:        }
        !           550: 
        !           551:        n = DB_TASK_NAME_LEN-1;
        !           552:        p = (char *)kaddr + sizeof(unsigned);
        !           553:        for (vaddr += sizeof(int); vaddr < DB_USER_STACK_ADDR && n > 0; 
        !           554:                                                        vaddr++, p++, n--) {
        !           555:            if (vaddr % PPC_PGBYTES == 0) {
        !           556:                if (db_user_to_kernel_address(task, vaddr, &kaddr, 0) <0)
        !           557:                        return;
        !           558:                p = (char*)kaddr;
        !           559:            }
        !           560:            db_printf("%c", (*p < ' ' || *p > '~')? ' ': *p);
        !           561:        }
        !           562:        while (n-- >= 0)        /* compare with >= 0 for one more space */
        !           563:            db_printf(" ");
        !           564: }
        !           565: 
        !           566: void
        !           567: db_machdep_init(void) {
        !           568: #define KDB_READY       0x1
        !           569:        extern int     kdb_flag;  
        !           570: 
        !           571:        kdb_flag |= KDB_READY;
        !           572: }
        !           573: 
        !           574: 
        !           575: #ifdef __STDC__
        !           576: #define KDB_SAVE(type, name) extern type name; type name##_save = name
        !           577: #define KDB_RESTORE(name) name = name##_save
        !           578: #else  /* __STDC__ */
        !           579: #define KDB_SAVE(type, name) extern type name; type name/**/_save = name
        !           580: #define KDB_RESTORE(name) name = name/**/_save
        !           581: #endif /* __STDC__ */
        !           582: 
        !           583: #define KDB_SAVE_CTXT() \
        !           584:        KDB_SAVE(int, db_run_mode); \
        !           585:        KDB_SAVE(boolean_t, db_sstep_print); \
        !           586:        KDB_SAVE(int, db_loop_count); \
        !           587:        KDB_SAVE(int, db_call_depth); \
        !           588:        KDB_SAVE(int, db_inst_count); \
        !           589:        KDB_SAVE(int, db_last_inst_count); \
        !           590:        KDB_SAVE(int, db_load_count); \
        !           591:        KDB_SAVE(int, db_store_count); \
        !           592:        KDB_SAVE(boolean_t, db_cmd_loop_done); \
        !           593:        KDB_SAVE(jmp_buf_t *, db_recover); \
        !           594:        KDB_SAVE(db_addr_t, db_dot); \
        !           595:        KDB_SAVE(db_addr_t, db_last_addr); \
        !           596:        KDB_SAVE(db_addr_t, db_prev); \
        !           597:        KDB_SAVE(db_addr_t, db_next); \
        !           598:        KDB_SAVE(db_regs_t, ddb_regs); 
        !           599: 
        !           600: #define KDB_RESTORE_CTXT() \
        !           601:        KDB_RESTORE(db_run_mode); \
        !           602:        KDB_RESTORE(db_sstep_print); \
        !           603:        KDB_RESTORE(db_loop_count); \
        !           604:        KDB_RESTORE(db_call_depth); \
        !           605:        KDB_RESTORE(db_inst_count); \
        !           606:        KDB_RESTORE(db_last_inst_count); \
        !           607:        KDB_RESTORE(db_load_count); \
        !           608:        KDB_RESTORE(db_store_count); \
        !           609:        KDB_RESTORE(db_cmd_loop_done); \
        !           610:        KDB_RESTORE(db_recover); \
        !           611:        KDB_RESTORE(db_dot); \
        !           612:        KDB_RESTORE(db_last_addr); \
        !           613:        KDB_RESTORE(db_prev); \
        !           614:        KDB_RESTORE(db_next); \
        !           615:        KDB_RESTORE(ddb_regs); 
        !           616: 
        !           617: /*
        !           618:  * switch to another cpu
        !           619:  */
        !           620: void
        !           621: kdb_on(
        !           622:        int             cpu)
        !           623: {
        !           624:        KDB_SAVE_CTXT();
        !           625:        if (cpu < 0 || cpu >= NCPUS || !debugger_active[cpu])
        !           626:                return;
        !           627:        db_set_breakpoints();
        !           628:        db_set_watchpoints();
        !           629:        debugger_cpu = cpu;
        !           630:        unlock_debugger();
        !           631:        lock_debugger();
        !           632:        db_clear_breakpoints();
        !           633:        db_clear_watchpoints();
        !           634:        KDB_RESTORE_CTXT();
        !           635:        if (debugger_cpu == -1)  {/* someone continued */
        !           636:                debugger_cpu = cpu_number();
        !           637:                db_continue_cmd(0, 0, 0, "");
        !           638:        }
        !           639: }
        !           640: 
        !           641: /*
        !           642:  * system reboot
        !           643:  */
        !           644: void db_reboot(
        !           645:        db_expr_t       addr,
        !           646:        boolean_t       have_addr,
        !           647:        db_expr_t       count,
        !           648:        char            *modif)
        !           649: {
        !           650:        boolean_t       reboot = TRUE;
        !           651:        char            *cp, c;
        !           652:        
        !           653:        cp = modif;
        !           654:        while ((c = *cp++) != 0) {
        !           655:                if (c == 'r')   /* reboot */
        !           656:                        reboot = TRUE;
        !           657:                if (c == 'h')   /* halt */
        !           658:                        reboot = FALSE;
        !           659:        }
        !           660:        halt_all_cpus(reboot);
        !           661: }
        !           662: 
        !           663: /*
        !           664:  * Switch to gdb
        !           665:  */
        !           666: void
        !           667: db_to_gdb(
        !           668:        void)
        !           669: {
        !           670:        extern unsigned int switch_debugger;
        !           671: 
        !           672:        switch_debugger=1;
        !           673: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.