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

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