Annotation of XNU/osfmk/ppc/model_dep.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:  * @APPLE_FREE_COPYRIGHT@
                     27:  */
                     28: /*
                     29:  *  (c) Copyright 1988 HEWLETT-PACKARD COMPANY
                     30:  *
                     31:  *  To anyone who acknowledges that this file is provided "AS IS"
                     32:  *  without any express or implied warranty:
                     33:  *      permission to use, copy, modify, and distribute this file
                     34:  *  for any purpose is hereby granted without fee, provided that
                     35:  *  the above copyright notice and this notice appears in all
                     36:  *  copies, and that the name of Hewlett-Packard Company not be
                     37:  *  used in advertising or publicity pertaining to distribution
                     38:  *  of the software without specific, written prior permission.
                     39:  *  Hewlett-Packard Company makes no representations about the
                     40:  *  suitability of this software for any purpose.
                     41:  */
                     42: /*
                     43:  * Copyright (c) 1990,1991,1992,1994 The University of Utah and
                     44:  * the Computer Systems Laboratory (CSL).  All rights reserved.
                     45:  *
                     46:  * THE UNIVERSITY OF UTAH AND CSL PROVIDE THIS SOFTWARE IN ITS "AS IS"
                     47:  * CONDITION, AND DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
                     48:  * WHATSOEVER RESULTING FROM ITS USE.
                     49:  *
                     50:  * CSL requests users of this software to return to [email protected] any
                     51:  * improvements that they make and grant CSL redistribution rights.
                     52:  *
                     53:  *     Utah $Hdr: model_dep.c 1.34 94/12/14$
                     54:  */
                     55: 
                     56: #include <debug.h>
                     57: #include <mach_kdb.h>
                     58: #include <mach_kdp.h>
                     59: #include <db_machine_commands.h>
                     60: #include <cpus.h>
                     61: 
                     62: #include <kern/thread.h>
                     63: #include <machine/pmap.h>
                     64: #include <machine/mach_param.h>
                     65: #include <device/device_types.h>
                     66: 
                     67: #include <mach/vm_param.h>
                     68: #include <mach/clock_types.h>
                     69: #include <mach/machine.h>
                     70: #include <ppc/boot.h>
                     71: 
                     72: #include <kern/misc_protos.h>
                     73: #include <kern/startup.h>
                     74: #include <ppc/misc_protos.h>
                     75: #include <ppc/proc_reg.h>
                     76: #include <ppc/thread.h>
                     77: #include <ppc/asm.h>
                     78: #include <ppc/mem.h>
                     79: #include <ppc/Firmware.h>
                     80: #include <ppc/mappings.h>
                     81: #include <ppc/FirmwareCalls.h>
                     82: #include <ppc/setjmp.h>
                     83: #include <ppc/exception.h>
                     84: 
                     85: #include <kern/clock.h>
                     86: #include <kern/debug.h>
                     87: #include <machine/trap.h>
                     88: #include <kern/spl.h>
                     89: #include <pexpert/pexpert.h>
                     90: #include <ppc/mp.h>
                     91: 
                     92: #include <IOKit/IOPlatformExpert.h>
                     93: 
                     94: #include <mach/vm_prot.h>
                     95: #include <vm/pmap.h>
                     96: #include <mach/time_value.h>
                     97: #include <machine/machparam.h> /* for btop */
                     98: 
                     99: #if    MACH_KDB
                    100: #include <ddb/db_aout.h>
                    101: #include <ddb/db_output.h>
                    102: #include <ddb/db_command.h>
                    103: #include <machine/db_machdep.h>
                    104: 
                    105: extern struct db_command ppc_db_commands[];
                    106: #endif /* MACH_KDB */
                    107: 
                    108: char kernel_args_buf[256] = "/mach_kernel";
                    109: char boot_args_buf[256] = "/mach_servers/bootstrap";
                    110: char env_buf[256];
                    111: 
                    112: #define TRAP_DEBUGGER  __asm__ volatile("tw 4,r3,r3");
                    113: #define TRAP_DEBUGGER_INST     0x7c831808
                    114: #define TRAP_DIRECT    __asm__ volatile("tw 4,r4,r4");
                    115: #define TRAP_DIRECT_INST       0x7c842008
                    116: #define TRAP_INST_SIZE 4
                    117: #define BREAK_TO_KDP0 0x7fe00008
                    118: #define BREAK_TO_KDP1 0x7c800008
                    119: #define BREAK_TO_KDB0 0x7c810808
                    120: 
                    121: /*
                    122:  * Code used to synchronize debuggers among all cpus, one active at a time, switch
                    123:  * from on to another using kdb_on! #cpu or cpu #cpu
                    124:  */
                    125: 
                    126: decl_simple_lock_data(, debugger_lock) /* debugger lock */
                    127: 
                    128: int                    debugger_cpu = -1;                      /* current cpu running debugger */
                    129: int                    debugger_debug = 0;                     /* Debug debugger */
                    130: int                    debugger_is_slave[NCPUS];       /* Show that we were entered via sigp */
                    131: int                    debugger_active[NCPUS];         /* Debugger active on CPU */
                    132: int                    debugger_pending[NCPUS];        /* Debugger entry pending on CPU (this is a HACK) */
                    133: int                    debugger_holdoff[NCPUS];        /* Holdoff debugger entry on this CPU (this is a HACK) */
                    134: int            db_run_mode;                            /* Debugger run mode */
                    135: unsigned int debugger_sync = 0;                        /* Cross processor debugger entry sync */
                    136: 
                    137: unsigned int lastTrace;                                        /* Value of low-level exception trace controls */
                    138: 
                    139: volatile unsigned int  cpus_holding_bkpts;     /* counter for number of cpus holding
                    140:                                                                                           breakpoints (ie: cpus that did not
                    141:                                                                                           insert back breakpoints) */
                    142: void unlock_debugger(void);
                    143: void lock_debugger(void);
                    144: 
                    145: #if !MACH_KDB
                    146: boolean_t      db_breakpoints_inserted = TRUE;
                    147: jmp_buf_t *db_recover = 0;
                    148: #endif
                    149: 
                    150: #if    MACH_KDB
                    151: #include <ddb/db_run.h>
                    152: int    kdb_flag=0;
                    153: extern boolean_t db_breakpoints_inserted;
                    154: extern jmp_buf_t *db_recover;
                    155: #define        KDB_READY       0x1
                    156: #endif
                    157: 
                    158: #if    MACH_KDP
                    159: extern int     kdp_flag;
                    160: #define        KDP_READY       0x1
                    161: #endif
                    162: 
                    163: extern const char version[];
                    164: 
                    165: #if !MACH_KDB
                    166: void kdb_trap(int type, struct ppc_saved_state *regs);
                    167: void kdb_trap(int type, struct ppc_saved_state *regs) {
                    168:        return;
                    169: }
                    170: #endif
                    171: 
                    172: #if !MACH_KDP
                    173: void kdp_trap(int type, struct ppc_saved_state *regs);
                    174: void kdp_trap(int type, struct ppc_saved_state *regs) {
                    175:        return;
                    176: }
                    177: #endif
                    178: 
                    179: void
                    180: machine_startup(boot_args *args)
                    181: {
                    182:        int     boot_arg;
                    183: 
                    184:        if (PE_parse_boot_arg("cpus", &wncpu)) {
                    185:                if (!((wncpu > 0) && (wncpu < NCPUS)))
                    186:                         wncpu = NCPUS;
                    187:        } else 
                    188:                wncpu = NCPUS;
                    189: 
                    190:        if( PE_get_hotkey( kPEControlKey ))
                    191:             halt_in_debugger = halt_in_debugger ? 0 : 1;
                    192: 
                    193:        if (PE_parse_boot_arg("debug", &boot_arg)) {
                    194:                if (boot_arg & DB_HALT) halt_in_debugger=1;
                    195:                if (boot_arg & DB_PRT) disableDebugOuput=FALSE; 
                    196:        }
                    197: 
                    198:        hw_lock_init(&debugger_lock);                           /* initialized debugger lock */
                    199: 
                    200: #if    MACH_KDB
                    201:        /*
                    202:         * Initialize KDB
                    203:         */
                    204: #if    DB_MACHINE_COMMANDS
                    205:        db_machine_commands_install(ppc_db_commands);
                    206: #endif /* DB_MACHINE_COMMANDS */
                    207:        ddb_init();
                    208: 
                    209:        if (boot_arg & DB_KDB)
                    210:                current_debugger = KDB_CUR_DB;
                    211: 
                    212:        /*
                    213:         * Cause a breakpoint trap to the debugger before proceeding
                    214:         * any further if the proper option bit was specified in
                    215:         * the boot flags.
                    216:         */
                    217:        if (halt_in_debugger && (current_debugger == KDB_CUR_DB)) {
                    218:                Debugger("inline call to debugger(machine_startup)");
                    219:                halt_in_debugger = 0;
                    220:                active_debugger =1;
                    221:        }
                    222: #endif /* MACH_KDB */
                    223:        if (PE_parse_boot_arg("preempt", &boot_arg)) {
                    224:                extern int default_preemption_rate;
                    225: 
                    226:                default_preemption_rate = boot_arg;
                    227:        }
                    228: 
                    229:        machine_conf();
                    230: 
                    231:        /*
                    232:         * Start the system.
                    233:         */
                    234:        setup_main();
                    235: 
                    236:        /* Should never return */
                    237: }
                    238: 
                    239: char *
                    240: machine_boot_info(
                    241:        char *buf, 
                    242:        vm_size_t size)
                    243: {
                    244:        return(PE_boot_args());
                    245: }
                    246: 
                    247: const char * getenv(const char *name);
                    248: 
                    249: const char * getenv(const char *name)
                    250: {
                    251:        return NULL;
                    252: }
                    253: 
                    254: void
                    255: machine_conf(void)
                    256: {
                    257:        machine_info.max_cpus = NCPUS;
                    258:        machine_info.avail_cpus = 1;
                    259:        machine_info.memory_size = mem_size;
                    260: }
                    261: 
                    262: void
                    263: machine_init(void)
                    264: {
                    265:        clock_config();
                    266: }
                    267: 
                    268: void slave_machine_init(void)
                    269: {
                    270:     clock_init();
                    271:        cpu_machine_init();
                    272: }                               
                    273: 
                    274: void
                    275: halt_all_cpus(boolean_t        reboot)
                    276: {
                    277:        if(reboot)
                    278:        {
                    279:                printf("MACH Reboot\n");
                    280:                PEHaltRestart(kPERestartCPU);
                    281:        }
                    282:        else
                    283:        {
                    284:                printf("CPU halted\n");
                    285:                PEHaltRestart(kPEHaltCPU);
                    286:        } 
                    287:        while(1);
                    288: }
                    289: 
                    290: void
                    291: halt_cpu(void)
                    292: {
                    293:         halt_all_cpus(FALSE);
                    294: }
                    295: 
                    296: #if    MACH_ASSERT
                    297: /*
                    298:  * Machine-dependent routine to fill in an array with up to callstack_max
                    299:  * levels of return pc information.
                    300:  */
                    301: void machine_callstack(
                    302:        natural_t       *buf,
                    303:        vm_size_t       callstack_max)
                    304: {
                    305: }
                    306: #endif /* MACH_ASSERT */
                    307: 
                    308: void
                    309: print_backtrace(struct ppc_saved_state *ssp)
                    310: {
                    311:        unsigned int *stackptr, *raddr, *rstack, trans;
                    312:        int i, skip_top_frames;
                    313:        unsigned int store[8];                  /* Buffer for real storage reads */
                    314: 
                    315:        printf("backtrace: ");
                    316: 
                    317:        /* Get our stackpointer for backtrace */
                    318:        if (ssp==NULL) {
                    319:                __asm__ volatile("mr %0,        r1" : "=r" (stackptr));
                    320:                skip_top_frames = 1;
                    321:        } else {
                    322:                stackptr = (unsigned int *)(ssp->r1);
                    323:                skip_top_frames = 0;
                    324:                printf("0x%08x ", ssp->srr0);
                    325:        }
                    326: 
                    327:        for (i = 0; i < 32; i++) {
                    328: 
                    329:                if(!stackptr) break;    /* No more to get... */
                    330: 
                    331:                /* Avoid causing page fault */
                    332:                if (!(raddr = LRA(PPC_SID_KERNEL, (void *)((unsigned int)stackptr+FM_LR_SAVE))))
                    333:                                break;
                    334:                ReadReal((unsigned int)raddr, &store[0]);
                    335:                if (skip_top_frames)
                    336:                        skip_top_frames--;
                    337:                else
                    338:                        printf("0x%08x ",store[0]);
                    339:                if (!(raddr = LRA(PPC_SID_KERNEL, (void *)stackptr))) 
                    340:                        break;
                    341:                ReadReal((unsigned int)raddr, &store[0]);
                    342:                stackptr=(unsigned int *)store[0];
                    343:        }
                    344:        printf("\n");
                    345: }
                    346: 
                    347: void 
                    348: Debugger(const char    *message) {
                    349: 
                    350:        int i;
                    351:        unsigned int store[8];
                    352:        spl_t spl;
                    353:        
                    354:        spl = splhigh();                                                                /* No interruptions from here on */
                    355: 
                    356: /*
                    357:  *     backtrace for Debugger() call  from panic() if no current debugger
                    358:  *     backtrace and return for double panic() call
                    359:  */
                    360:        if ((panicstr != (char *)0) && 
                    361:          (((nestedpanic != 0) && (current_debugger == 1)) || (active_debugger == 0))) {
                    362:                print_backtrace(NULL);
                    363:                if (nestedpanic != 0)  {
                    364:                        splx(spl);
                    365:                        return;                                                                         /* Yeah, don't enter again... */
                    366:                }
                    367:        }
                    368: 
                    369:        if (debug_mode && debugger_active[cpu_number()]) {      /* Are we already on debugger on this processor? */
                    370:                splx(spl);
                    371:                return;                                                                         /* Yeah, don't do it again... */
                    372:        }
                    373: 
                    374:        if ((current_debugger != NO_CUR_DB)) {                  /* If there is a debugger configured, enter it */
                    375:                printf("Debugger(%s)\n", message);
                    376:                TRAP_DEBUGGER;
                    377:                splx(spl);
                    378:                return;                                                                         /* Done debugging for a while */
                    379:        }
                    380: 
                    381:        printf("\nNo debugger configured - dumping debug information\n");
                    382:        printf("\nversion string : %s\n",version);
                    383:        mfdbatu(store[0],0);
                    384:        mfdbatl(store[1],0);    
                    385:        mfdbatu(store[2],1);                                    
                    386:        mfdbatl(store[3],1);                                    
                    387:        mfdbatu(store[4],2);                            
                    388:        mfdbatl(store[5],2);                                    
                    389:        mfdbatu(store[6],3);                            
                    390:        mfdbatl(store[7],3);                                    
                    391:        printf("DBAT0: %08X %08X\n", store[0], store[1]);
                    392:        printf("DBAT1: %08X %08X\n", store[2], store[3]);
                    393:        printf("DBAT2: %08X %08X\n", store[4], store[5]);
                    394:        printf("DBAT3: %08X %08X\n", store[6], store[7]);
                    395:        printf("MSR=%08X\n",mfmsr());
                    396:        print_backtrace(NULL);
                    397:        splx(spl);
                    398:        return;
                    399: }
                    400: 
                    401: /*
                    402:  *     When we get here, interruptions are disabled and we are on the debugger stack
                    403:  *     Never, ever, ever, ever enable interruptions from here on
                    404:  */
                    405: 
                    406: int Call_DebuggerC(
                    407:         int    type,
                    408:         struct ppc_saved_state *saved_state)
                    409: {
                    410:        int                             directcall, wait;
                    411:        vm_offset_t             instr_ptr;
                    412:        unsigned int    instr;
                    413:        int                     my_cpu, tcpu;
                    414: 
                    415:        my_cpu = cpu_number();                                                          /* Get our CPU */
                    416: 
                    417: #if    MACH_KDB
                    418:        if((debugger_cpu == my_cpu) &&                                          /* Do we already own debugger? */
                    419:          debugger_active[my_cpu] &&                                            /* and are we really active? */
                    420:          db_recover &&                                                                         /* and have we set up recovery? */
                    421:          (current_debugger == KDB_CUR_DB)) {                           /* and are we in KDB (only it handles recovery) */
                    422:                kdb_trap(type, saved_state);                                    /* Then reenter it... */
                    423:        }
                    424: #endif
                    425: 
                    426:        
                    427:        hw_atomic_add(&debug_mode, 1);                                          /* Indicate we are in debugger */
                    428:        debugger_active[my_cpu]++;                                                      /* Show active on our CPU */
                    429:        lock_debugger();                                                                        /* Insure that only one CPU is in debugger */
                    430: 
                    431:        if (debugger_debug) {
                    432: #if 0
                    433:                kprintf("Call_DebuggerC(%d): %08X %08X, debact = %d\n", my_cpu, type, saved_state, debug_mode); /* (TEST/DEBUG) */
                    434: #endif
                    435:                printf("Call_Debugger: enter - cpu %d, is_slave %d, debugger_cpu %d, pc %08X\n",
                    436:                   my_cpu, debugger_is_slave[my_cpu], debugger_cpu, saved_state->srr0);
                    437:        }
                    438:        
                    439:        if (instr_ptr = (vm_offset_t)LRA(PPC_SID_KERNEL, (void *)(saved_state->srr0))) {
                    440:                instr = ml_phys_read(instr_ptr);                                /* Get the trap that caused entry */
                    441:        } 
                    442:        else instr = 0;
                    443: 
                    444: #if 0
                    445:        if (debugger_debug) kprintf("Call_DebuggerC(%d): instr_ptr = %08X, instr = %08X\n", my_cpu, instr_ptr, instr);  /* (TEST/DEBUG) */
                    446: #endif
                    447: 
                    448:        if (db_breakpoints_inserted) cpus_holding_bkpts++;      /* Bump up the holding count */
                    449:        if (debugger_cpu == -1 && !debugger_is_slave[my_cpu]) {
                    450: #if 0
                    451:                if (debugger_debug) kprintf("Call_DebuggerC(%d): lasttrace = %08X\n", my_cpu, lastTrace);       /* (TEST/DEBUG) */
                    452: #endif
                    453:                debugger_cpu = my_cpu;                                                  /* Show that we are debugger */
                    454:                lastTrace = LLTraceSet(0);                                              /* Disable low-level tracing */
                    455: 
                    456:                for(tcpu = 0; tcpu < NCPUS; tcpu++) {                   /* Stop all the other guys */
                    457:                        if(tcpu == my_cpu) continue;                            /* Don't diddle ourselves */
                    458:                        hw_atomic_add(&debugger_sync, 1);                       /* Count signal sent */
                    459:                        (void)cpu_signal(tcpu, SIGPdebug);                      /* Tell 'em to enter debugger */
                    460:                }
                    461:                (void)hw_cpu_sync(&debugger_sync, LockTimeOut); /* Wait for the other processors to enter debug */
                    462:                debugger_sync = 0;                                                              /* We're done with it */
                    463:        } 
                    464:        else if (debugger_cpu != my_cpu)  goto debugger_exit;   /* We are not debugger, don't continue... */
                    465:        
                    466: 
                    467:        if (instr == TRAP_DIRECT_INST) {
                    468:                disableDebugOuput = FALSE;
                    469:                print_backtrace(saved_state);
                    470:        }
                    471: 
                    472:        switch_debugger = 0;                                                            /* Make sure switch request is off */
                    473:        directcall = 1;                                                                         /* Assume direct call */
                    474: 
                    475:        if (saved_state->srr1 & MASK(SRR1_PRG_TRAP)) {          /* Trap instruction? */
                    476:                
                    477:                directcall = 0;                                                                 /* We had a trap not a direct call */
                    478: 
                    479:                switch (instr) {                                                                /* Select trap type */
                    480: 
                    481: #if    MACH_KDP
                    482:                        case BREAK_TO_KDP0:                                                     /* Breakpoint into KDP? */
                    483:                        case BREAK_TO_KDP1:                                                     /* Breakpoint into KDP? */
                    484:                                current_debugger = KDP_CUR_DB;                  /* Yes, set KDP */
                    485:                                kdp_trap(type, saved_state);                    /* Enter it */
                    486:                                break;
                    487: #endif
                    488:        
                    489: #if    MACH_KDB
                    490:                        case BREAK_TO_KDB0:                                             /* Breakpoint to KDB (the "good" debugger)? */
                    491:                                current_debugger = KDB_CUR_DB;                  /* Yes, set it */
                    492:                                kdb_trap(type, saved_state);                    /* Enter it */
                    493:                                break;
                    494: #endif
                    495:                                
                    496:                        case TRAP_DEBUGGER_INST:                                        /* Should we enter the current debugger? */
                    497:                        case TRAP_DIRECT_INST:                                          /* Should we enter the current debugger? */
                    498:                                if (current_debugger == KDP_CUR_DB)     /* Is current KDP? */
                    499:                                        kdp_trap(type, saved_state);            /* Yes, enter it */
                    500:                                else if (current_debugger == KDB_CUR_DB)        /* Is this KDB? */
                    501:                                        kdb_trap(type, saved_state);            /* Yes, go ahead and enter */
                    502:                                else goto debugger_error;                               /* No debugger active */
                    503:                                break;
                    504:                                
                    505:                        default:                                                                        /* Unknown/bogus trap type */
                    506:                                goto debugger_error;
                    507:                }
                    508:        }
                    509: 
                    510:        while(1) {                                                                                      /* We are here to handle debugger switches */
                    511:                
                    512:                if(!directcall) {                                                               /* Was this a direct call? */
                    513:                        if(!switch_debugger) break;                                     /* No, then leave if no switch requested... */
                    514: 
                    515: /*
                    516:  *                     Note: we can only switch to a debugger we have.  Ignore bogus switch requests.
                    517:  */
                    518: #if 0
                    519:                        if (debugger_debug) kprintf("Call_DebuggerC(%d): switching debuggers\n", my_cpu);       /* (TEST/DEBUG) */
                    520: #endif
                    521: #if MACH_KDB
                    522:                        if(current_debugger == KDP_CUR_DB) current_debugger = KDB_CUR_DB; /* Switch to KDB */
                    523: #if MACH_KDP
                    524:                        else 
                    525: #endif
                    526: #endif
                    527: #if MACH_KDP
                    528:                        if(current_debugger == KDB_CUR_DB) current_debugger = KDP_CUR_DB;               /* Switch to KDP */
                    529: #endif
                    530:                }
                    531:                
                    532:                switch_debugger = 0;                                                    /* Clear request */
                    533:                directcall = 0;                                                                 /* Clear first-time direct call indication */
                    534: 
                    535:                switch (current_debugger) {                                             /* Enter correct debugger */
                    536:                
                    537:                        case KDP_CUR_DB:                                                        /* Enter KDP */
                    538:                                kdp_trap(type, saved_state);
                    539:                                break;
                    540:                                
                    541:                        case KDB_CUR_DB:                                                        /* Enter KDB */
                    542:                                kdb_trap(type, saved_state);
                    543:                                break;
                    544:                                
                    545:                        default:                                                                        /* No debugger installed */
                    546:                                goto debugger_error;
                    547:                                break;
                    548:                }
                    549:        }
                    550: 
                    551: debugger_exit:
                    552: #if 0
                    553:        if (debugger_debug) kprintf("Call_DebuggerC(%d): exit - inst = %08X, cpu=%d(%d), run=%d\n", my_cpu, 
                    554:                instr, my_cpu, debugger_cpu, db_run_mode);      /* (TEST/DEBUG) */
                    555: #endif
                    556:        if ((instr == TRAP_DEBUGGER_INST) ||                            /* Did we trap to enter debugger? */
                    557:                (instr == TRAP_DIRECT_INST)) saved_state->srr0 += TRAP_INST_SIZE;       /* Yes, point past trap */
                    558: 
                    559:        if(debugger_cpu == my_cpu) LLTraceSet(lastTrace);       /* Enable tracing on the way out if we are debugger */
                    560: 
                    561:        wait = FALSE;                                                                           /* Assume we are not going to wait */
                    562:        if (db_run_mode == STEP_CONTINUE) {                                     /* Are we going to run? */
                    563:                wait = TRUE;                                                                    /* Yeah, remember to wait for breakpoints to clear */
                    564:                debugger_cpu = -1;                                                              /* Release other processor's debuggers */
                    565:                debugger_pending[0] = 0;                                                /* Release request (this is a HACK) */
                    566:                debugger_pending[1] = 0;                                                /* Release request (this is a HACK) */
                    567:        }
                    568:        
                    569:        if (db_breakpoints_inserted) cpus_holding_bkpts--;      /* If any breakpoints, back off count */
                    570:        if (debugger_is_slave[my_cpu]) debugger_is_slave[my_cpu]--;     /* If we were a slove, uncount us */
                    571:        if (debugger_debug)
                    572:                printf("Call_Debugger: exit - cpu %d, debugger_cpu %d, run_mode %d holds %d\n",
                    573:                          my_cpu, debugger_cpu, db_run_mode,
                    574:                          cpus_holding_bkpts);
                    575: 
                    576:        unlock_debugger();                                                                      /* Release the lock */
                    577:        debugger_active[my_cpu]--;                                                      /* Say we aren't active anymore */
                    578: 
                    579:        if (wait) while(cpus_holding_bkpts);                            /* Wait for breakpoints to clear */
                    580: 
                    581:        hw_atomic_sub(&debug_mode, 1);                                          /* Set out of debug now */
                    582: 
                    583:        return(1);                                                                                      /* Exit debugger normally */
                    584: 
                    585: debugger_error:
                    586:        hw_atomic_sub(&debug_mode, 1);                                          /* Set out of debug now */
                    587:        return(0);                                                                                      /* Return in shame... */
                    588: 
                    589: }
                    590: 
                    591: void lock_debugger(void) {
                    592:        int             my_cpu;
                    593:        register int    i;
                    594: 
                    595:        my_cpu = cpu_number();                                                          /* Get our CPU number */
                    596: 
                    597:        while(1) {                                                                                      /* Check until we get it */
                    598: 
                    599:                if (debugger_cpu != -1 && debugger_cpu != my_cpu) continue;     /* Someone, not us, is debugger... */
                    600:                if (hw_lock_try(&debugger_lock)) {                              /* Get the debug lock */                        
                    601:                        if (debugger_cpu == -1 || debugger_cpu == my_cpu) break;        /* Is it us? */
                    602:                        hw_lock_unlock(&debugger_lock);                         /* Not us, release lock */
                    603:                }
                    604:        } 
                    605: }
                    606: 
                    607: void unlock_debugger(void) {
                    608: 
                    609:        hw_lock_unlock(&debugger_lock);
                    610: 
                    611: }
                    612: 
                    613: 

unix.superglobalmegacorp.com

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