Annotation of XNU/osfmk/ppc/db_interface.c, revision 1.1.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.