[BACK]Return to db_mp.c CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / i386

Annotation of sys/arch/i386/i386/db_mp.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: db_mp.c,v 1.4 2004/07/20 20:18:53 art Exp $   */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2003, 2004 Andreas Gunnarsson <andreas@openbsd.org>
        !             5:  *
        !             6:  * Permission to use, copy, modify, and distribute this software for any
        !             7:  * purpose with or without fee is hereby granted, provided that the above
        !             8:  * copyright notice and this permission notice appear in all copies.
        !             9:  *
        !            10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            17:  */
        !            18:
        !            19: #include <sys/types.h>
        !            20: #include <sys/simplelock.h>
        !            21:
        !            22: #include <machine/db_machdep.h>
        !            23: #include <sys/mutex.h>
        !            24:
        !            25: #include <ddb/db_output.h>
        !            26:
        !            27: struct mutex ddb_mp_mutex = MUTEX_INITIALIZER(IPL_HIGH);
        !            28:
        !            29: volatile int ddb_state = DDB_STATE_NOT_RUNNING;        /* protected by ddb_mp_mutex */
        !            30: volatile cpuid_t ddb_active_cpu;               /* protected by ddb_mp_mutex */
        !            31:
        !            32: extern volatile boolean_t      db_switch_cpu;
        !            33: extern volatile long           db_switch_to_cpu;
        !            34:
        !            35: /*
        !            36:  * All processors wait in db_enter_ddb() (unless explicitly started from
        !            37:  * ddb) but only one owns ddb.  If the current processor should own ddb,
        !            38:  * db_enter_ddb() returns 1.  If the current processor should keep
        !            39:  * executing as usual (if ddb is exited or the processor is explicitly
        !            40:  * started), db_enter_ddb returns 0.
        !            41:  * If this is the first CPU entering ddb, db_enter_ddb() will stop all
        !            42:  * other CPUs by sending IPIs.
        !            43:  */
        !            44: int
        !            45: db_enter_ddb()
        !            46: {
        !            47:        int i;
        !            48:
        !            49:        mtx_enter(&ddb_mp_mutex);
        !            50:
        !            51:        /* If we are first in, grab ddb and stop all other CPUs */
        !            52:        if (ddb_state == DDB_STATE_NOT_RUNNING) {
        !            53:                ddb_active_cpu = cpu_number();
        !            54:                ddb_state = DDB_STATE_RUNNING;
        !            55:                curcpu()->ci_ddb_paused = CI_DDB_INDDB;
        !            56:                mtx_leave(&ddb_mp_mutex);
        !            57:                for (i = 0; i < I386_MAXPROCS; i++) {
        !            58:                        if (cpu_info[i] != NULL && i != cpu_number() &&
        !            59:                            cpu_info[i]->ci_ddb_paused != CI_DDB_STOPPED) {
        !            60:                                cpu_info[i]->ci_ddb_paused = CI_DDB_SHOULDSTOP;
        !            61:                                i386_send_ipi(cpu_info[i], I386_IPI_DDB);
        !            62:                        }
        !            63:                }
        !            64:                return (1);
        !            65:        }
        !            66:
        !            67:        /* Leaving ddb completely.  Start all other CPUs and return 0 */
        !            68:        if (ddb_active_cpu == cpu_number() && ddb_state == DDB_STATE_EXITING) {
        !            69:                for (i = 0; i < I386_MAXPROCS; i++) {
        !            70:                        if (cpu_info[i] != NULL) {
        !            71:                                cpu_info[i]->ci_ddb_paused = CI_DDB_RUNNING;
        !            72:                        }
        !            73:                }
        !            74:                mtx_leave(&ddb_mp_mutex);
        !            75:                return (0);
        !            76:        }
        !            77:
        !            78:        /* We're switching to another CPU.  db_ddbproc_cmd() has made sure
        !            79:         * it is waiting for ddb, we just have to set ddb_active_cpu. */
        !            80:        if (ddb_active_cpu == cpu_number() && db_switch_cpu) {
        !            81:                curcpu()->ci_ddb_paused = CI_DDB_SHOULDSTOP;
        !            82:                db_switch_cpu = 0;
        !            83:                ddb_active_cpu = db_switch_to_cpu;
        !            84:                cpu_info[db_switch_to_cpu]->ci_ddb_paused = CI_DDB_ENTERDDB;
        !            85:        }
        !            86:
        !            87:        /* Wait until we should enter ddb or resume */
        !            88:        while (ddb_active_cpu != cpu_number() &&
        !            89:            curcpu()->ci_ddb_paused != CI_DDB_RUNNING) {
        !            90:                if (curcpu()->ci_ddb_paused == CI_DDB_SHOULDSTOP)
        !            91:                        curcpu()->ci_ddb_paused = CI_DDB_STOPPED;
        !            92:                mtx_leave(&ddb_mp_mutex);
        !            93:
        !            94:                /* Busy wait without locking, we'll confirm with lock later */
        !            95:                while (ddb_active_cpu != cpu_number() &&
        !            96:                    curcpu()->ci_ddb_paused != CI_DDB_RUNNING)
        !            97:                        ;       /* Do nothing */
        !            98:
        !            99:                mtx_enter(&ddb_mp_mutex);
        !           100:        }
        !           101:
        !           102:        /* Either enter ddb or exit */
        !           103:        if (ddb_active_cpu == cpu_number() && ddb_state == DDB_STATE_RUNNING) {
        !           104:                curcpu()->ci_ddb_paused = CI_DDB_INDDB;
        !           105:                mtx_leave(&ddb_mp_mutex);
        !           106:                return (1);
        !           107:        } else {
        !           108:                mtx_leave(&ddb_mp_mutex);
        !           109:                return (0);
        !           110:        }
        !           111: }
        !           112:
        !           113: void
        !           114: db_startcpu(int cpu)
        !           115: {
        !           116:        if (cpu != cpu_number() && cpu_info[cpu] != NULL) {
        !           117:                mtx_enter(&ddb_mp_mutex);
        !           118:                cpu_info[cpu]->ci_ddb_paused = CI_DDB_RUNNING;
        !           119:                mtx_leave(&ddb_mp_mutex);
        !           120:        }
        !           121: }
        !           122:
        !           123: void
        !           124: db_stopcpu(int cpu)
        !           125: {
        !           126:        mtx_enter(&ddb_mp_mutex);
        !           127:        if (cpu != cpu_number() && cpu_info[cpu] != NULL &&
        !           128:            cpu_info[cpu]->ci_ddb_paused != CI_DDB_STOPPED) {
        !           129:                cpu_info[cpu]->ci_ddb_paused = CI_DDB_SHOULDSTOP;
        !           130:                mtx_leave(&ddb_mp_mutex);
        !           131:                i386_send_ipi(cpu_info[cpu], I386_IPI_DDB);
        !           132:        } else {
        !           133:                mtx_leave(&ddb_mp_mutex);
        !           134:        }
        !           135: }
        !           136:
        !           137: void
        !           138: i386_ipi_db(struct cpu_info *ci)
        !           139: {
        !           140:        Debugger();
        !           141: }

CVSweb