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

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