Annotation of Gnu-Mach/ddb/db_mp.c, revision 1.1.1.3

1.1.1.2   root        1: /*
1.1       root        2:  * Mach Operating System
                      3:  * Copyright (c) 1993,1992 Carnegie Mellon University
                      4:  * All Rights Reserved.
1.1.1.2   root        5:  *
1.1       root        6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
1.1.1.2   root       11:  *
1.1       root       12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1.1.1.2   root       15:  *
1.1       root       16:  * Carnegie Mellon requests users of this software to return to
1.1.1.2   root       17:  *
1.1       root       18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
1.1.1.2   root       22:  *
                     23:  * any improvements or extensions that they make and grant Carnegie Mellon
1.1       root       24:  * the rights to redistribute these changes.
                     25:  */
                     26: 
1.1.1.3 ! root       27: #if MACH_KDB
1.1       root       28: 
                     29: #if    NCPUS > 1
                     30: 
                     31: #include <mach/boolean.h>
                     32: #include <mach/machine.h>
                     33: 
                     34: #include <kern/cpu_number.h>
                     35: #include <kern/lock.h>
                     36: 
                     37: #include <machine/db_machdep.h>
                     38: 
                     39: #include <ddb/db_command.h>
                     40: #include <ddb/db_run.h>
                     41: 
                     42: /*
                     43:  * Routines to interlock access to the kernel debugger on
                     44:  * multiprocessors.
                     45:  */
                     46: 
                     47: decl_simple_lock_data(,db_lock)                /* lock to enter debugger */
                     48: volatile int   db_cpu = -1;            /* CPU currently in debugger */
                     49:                                        /* -1 if none */
                     50: int    db_active[NCPUS] = { 0 };       /* count recursive entries
                     51:                                           into debugger */
                     52: int    db_slave[NCPUS] = { 0 };        /* nonzero if cpu interrupted
                     53:                                           by another cpu in debugger */
                     54: 
                     55: int    db_enter_debug = 0;
                     56: 
                     57: void   remote_db();            /* forward */
                     58: void   lock_db();
                     59: void   unlock_db();
                     60: 
                     61: 
                     62: /*
                     63:  * Called when entering kernel debugger.
                     64:  * Takes db lock. If we were called remotely (slave state) we just
                     65:  * wait for db_cpu to be equal to cpu_number(). Otherwise enter debugger
                     66:  * if not active on another cpu
                     67:  */
                     68: 
                     69: boolean_t
                     70: db_enter()
                     71: {
                     72:        int     mycpu = cpu_number();
                     73: 
                     74:        /*
                     75:         * Count recursive entries to debugger.
                     76:         */
                     77:        db_active[mycpu]++;
                     78: 
                     79:        /*
                     80:         * Wait for other CPUS to leave debugger.
                     81:         */
                     82:        lock_db();
                     83: 
                     84:        if (db_enter_debug)
                     85:            db_printf(
                     86:                "db_enter: cpu %d[%d], master %d, db_cpu %d, run mode %d\n",
                     87:                mycpu, db_slave[mycpu], master_cpu, db_cpu, db_run_mode);
                     88: 
                     89:        /*
                     90:         * If no CPU in debugger, and I am not being stopped,
                     91:         * enter the debugger.
                     92:         */
                     93:        if (db_cpu == -1 && !db_slave[mycpu]) {
                     94:            remote_db();        /* stop other cpus */
                     95:            db_cpu = mycpu;
                     96:            return TRUE;
                     97:        }
                     98:        /*
                     99:         * If I am already in the debugger (recursive entry
                    100:         * or returning from single step), enter debugger.
                    101:         */
                    102:        else if (db_cpu == mycpu)
                    103:            return TRUE;
                    104:        /*
                    105:         * Otherwise, cannot enter debugger.
                    106:         */
                    107:        else
                    108:            return FALSE;
                    109: }
                    110: 
                    111: /*
                    112:  * Leave debugger.
                    113:  */
                    114: void
                    115: db_leave()
                    116: {
                    117:        int     mycpu = cpu_number();
                    118: 
                    119:        /*
                    120:         * If continuing, give up debugger
                    121:         */
                    122:        if (db_run_mode == STEP_CONTINUE)
                    123:            db_cpu = -1;
                    124: 
                    125:        /*
                    126:         * If I am a slave, drop my slave count.
                    127:         */
                    128:        if (db_slave[mycpu])
                    129:            db_slave[mycpu]--;
                    130:        if (db_enter_debug)
                    131:            db_printf("db_leave: cpu %d[%d], db_cpu %d, run_mode %d\n",
                    132:                      mycpu, db_slave[mycpu], db_cpu, db_run_mode);
                    133:        /*
                    134:         * Unlock debugger.
                    135:         */
                    136:        unlock_db();
                    137: 
                    138:        /*
                    139:         * Drop recursive entry count.
                    140:         */
                    141:        db_active[mycpu]--;
                    142: }
                    143: 
                    144: 
                    145: /*
1.1.1.2   root      146:  * invoke kernel debugger on slave processors
1.1       root      147:  */
                    148: 
                    149: void
                    150: remote_db() {
                    151:        int     my_cpu = cpu_number();
                    152:        register int    i;
                    153: 
                    154:        for (i = 0; i < NCPUS; i++) {
                    155:            if (i != my_cpu &&
                    156:                machine_slot[i].is_cpu &&
                    157:                machine_slot[i].running)
                    158:            {
                    159:                cpu_interrupt_to_db(i);
                    160:            }
                    161:        }
                    162: }
                    163: 
                    164: /*
                    165:  * Save and restore DB global registers.
                    166:  *
                    167:  * DB_SAVE_CTXT must be at the start of a block, and
                    168:  * DB_RESTORE_CTXT must be in the same block.
                    169:  */
                    170: 
                    171: #ifdef __STDC__
                    172: #define DB_SAVE(type, name) extern type name; type name##_save = name
                    173: #define DB_RESTORE(name) name = name##_save
                    174: #else  /* __STDC__ */
                    175: #define DB_SAVE(type, name) extern type name; type name/**/_save = name
                    176: #define DB_RESTORE(name) name = name/**/_save
                    177: #endif /* __STDC__ */
                    178: 
                    179: #define DB_SAVE_CTXT() \
                    180:        DB_SAVE(int, db_run_mode); \
                    181:        DB_SAVE(boolean_t, db_sstep_print); \
                    182:        DB_SAVE(int, db_loop_count); \
                    183:        DB_SAVE(int, db_call_depth); \
                    184:        DB_SAVE(int, db_inst_count); \
                    185:        DB_SAVE(int, db_last_inst_count); \
                    186:        DB_SAVE(int, db_load_count); \
                    187:        DB_SAVE(int, db_store_count); \
                    188:        DB_SAVE(boolean_t, db_cmd_loop_done); \
                    189:        DB_SAVE(jmp_buf_t *, db_recover); \
                    190:        DB_SAVE(db_addr_t, db_dot); \
                    191:        DB_SAVE(db_addr_t, db_last_addr); \
                    192:        DB_SAVE(db_addr_t, db_prev); \
                    193:        DB_SAVE(db_addr_t, db_next); \
                    194:        SAVE_DDB_REGS
                    195: 
                    196: #define DB_RESTORE_CTXT() \
                    197:        DB_RESTORE(db_run_mode); \
                    198:        DB_RESTORE(db_sstep_print); \
                    199:        DB_RESTORE(db_loop_count); \
                    200:        DB_RESTORE(db_call_depth); \
                    201:        DB_RESTORE(db_inst_count); \
                    202:        DB_RESTORE(db_last_inst_count); \
                    203:        DB_RESTORE(db_load_count); \
                    204:        DB_RESTORE(db_store_count); \
                    205:        DB_RESTORE(db_cmd_loop_done); \
                    206:        DB_RESTORE(db_recover); \
                    207:        DB_RESTORE(db_dot); \
                    208:        DB_RESTORE(db_last_addr); \
                    209:        DB_RESTORE(db_prev); \
                    210:        DB_RESTORE(db_next); \
                    211:        RESTORE_DDB_REGS
                    212: 
                    213: /*
                    214:  * switch to another cpu
                    215:  */
                    216: void
                    217: db_on(cpu)
                    218:        int     cpu;
                    219: {
                    220:        /*
                    221:         * Save ddb global variables
                    222:         */
                    223:        DB_SAVE_CTXT();
                    224: 
                    225:        /*
                    226:         * Don`t do if bad CPU number.
                    227:         * CPU must also be spinning in db_entry.
                    228:         */
                    229:        if (cpu < 0 || cpu >= NCPUS || !db_active[cpu])
                    230:            return;
                    231: 
                    232:        /*
                    233:         * Give debugger to that CPU
                    234:         */
                    235:        db_cpu = cpu;
                    236:        unlock_db();
                    237: 
                    238:        /*
                    239:         * Wait for it to come back again
                    240:         */
                    241:        lock_db();
                    242: 
                    243:        /*
                    244:         * Restore ddb globals
                    245:         */
                    246:        DB_RESTORE_CTXT();
                    247: 
                    248:        if (db_cpu == -1) /* someone continued */
                    249:            db_continue_cmd(0, 0, 0, "");
                    250: }
                    251: 
                    252: /*
                    253:  * Called by interprocessor interrupt when one CPU is
                    254:  * in kernel debugger and wants to stop other CPUs
                    255:  */
                    256: void
                    257: remote_db_enter()
                    258: {
                    259:        db_slave[cpu_number()]++;
                    260:        kdb_kintr();
                    261: }
                    262: 
                    263: /*
                    264:  * Acquire kernel debugger.
                    265:  * Conditional code for forwarding characters from slave to console
                    266:  * if console on master only.
                    267:  */
                    268: 
                    269: /*
                    270:  * As long as db_cpu is not -1 or cpu_number(), we know that debugger
                    271:  * is active on another cpu.
                    272:  */
                    273: void
                    274: lock_db()
                    275: {
                    276:        int     my_cpu = cpu_number();
                    277: 
                    278:        for (;;) {
                    279: #if    CONSOLE_ON_MASTER
                    280:            if (my_cpu == master_cpu) {
                    281:                db_console();
                    282:            }
                    283: #endif
                    284:            if (db_cpu != -1 && db_cpu != my_cpu)
                    285:                continue;
                    286: 
                    287: #if    CONSOLE_ON_MASTER
                    288:            if (my_cpu == master_cpu) {
                    289:                if (!simple_lock_try(&db_lock))
                    290:                    continue;
                    291:            }
                    292:            else {
                    293:                simple_lock(&db_lock);
                    294:            }
                    295: #else
                    296:            simple_lock(&db_lock);
                    297: #endif
                    298:            if (db_cpu == -1 || db_cpu == my_cpu)
                    299:                break;
                    300:            simple_unlock(&db_lock);
                    301:        }
                    302: }
                    303: 
                    304: void
                    305: unlock_db()
                    306: {
                    307:        simple_unlock(&db_lock);
                    308: }
                    309: 
                    310: #ifdef sketch
                    311: void
                    312: db_console()
                    313: {
                    314:                        if (i_bit(CBUS_PUT_CHAR, my_word)) {
                    315:                                volatile u_char c = cbus_ochar;
                    316:                                i_bit_clear(CBUS_PUT_CHAR, my_word);
                    317:                                cnputc(c);
                    318:                        } else if (i_bit(CBUS_GET_CHAR, my_word)) {
                    319:                                if (cbus_wait_char)
                    320:                                        cbus_ichar = cngetc();
                    321:                                else
                    322:                                        cbus_ichar = cnmaygetc();
                    323:                                i_bit_clear(CBUS_GET_CHAR, my_word);
                    324: #ifndef        notdef
                    325:                        } else if (!cnmaygetc()) {
                    326: #else  /* notdef */
                    327:                        } else if (com_is_char() && !com_getc(TRUE)) {
                    328: #endif /* notdef */
                    329:                                simple_unlock(&db_lock);
                    330:                                db_cpu = my_cpu;
                    331:                        }
                    332: }
                    333: #endif /* sketch */
                    334: 
                    335: #endif /* NCPUS > 1 */
                    336: 
1.1.1.2   root      337: #endif /* MACH_KDB */

unix.superglobalmegacorp.com

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