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

1.1     ! root        1: /* 
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1993,1992 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             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.
        !            11:  * 
        !            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.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon 
        !            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: /*
        !           148:  * invoke kernel debugger on slave processors 
        !           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: 
        !           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.