From 35e61cbd71f82f4d81f75d39a54c90e52d1bd056 Mon Sep 17 00:00:00 2001 From: Kazutaka YOKOTA Date: Tue, 11 Jan 2000 14:54:01 +0000 Subject: [PATCH] Add a new mechanism, cndbctl(), to tell the console driver that ddb is entered. Don't refer to `in_Debugger' to see if we are in the debugger. (The variable used to be static in Debugger() and wasn't updated if ddb is entered via traps and panic anyway.) - Don't refer to `in_Debugger'. - Add `db_active' to i386/i386/db_interface.d (as in alpha/alpha/db_interface.c). - Remove cnpollc() stub from ddb/db_input.c. - Add the dbctl function to syscons, pcvt, and sio. (The function for pcvt and sio is noop at the moment.) Jointly developed by: bde and me (The final version was tweaked by me and not reviewed by bde. Thus, if there is any error in this commit, that is entirely of mine, not his.) Some changes were obtained from: NetBSD --- sys/alpha/alpha/db_interface.c | 11 +++---- sys/amd64/amd64/db_interface.c | 16 +++++----- sys/amd64/amd64/trap.c | 6 ++-- sys/ddb/db_input.c | 7 ----- sys/ddb/ddb.h | 3 +- sys/dev/sio/sio.c | 4 +-- sys/dev/syscons/syscons.c | 55 +++++++++++++++++----------------- sys/i386/i386/db_interface.c | 16 +++++----- sys/i386/i386/trap.c | 6 ++-- sys/i386/isa/pcvt/pcvt_drv.c | 3 +- sys/isa/sio.c | 4 +-- sys/kern/subr_trap.c | 6 ++-- sys/kern/tty_cons.c | 18 ++++++++++- sys/sys/cons.h | 8 +++-- 14 files changed, 87 insertions(+), 76 deletions(-) diff --git a/sys/alpha/alpha/db_interface.c b/sys/alpha/alpha/db_interface.c index f1189f1cf67..1e015aecce7 100644 --- a/sys/alpha/alpha/db_interface.c +++ b/sys/alpha/alpha/db_interface.c @@ -1,4 +1,5 @@ /* $NetBSD: db_interface.c,v 1.2 1997/09/16 19:07:19 thorpej Exp $ */ +/* $FreeBSD$ */ /* * Mach Operating System @@ -83,7 +84,7 @@ extern char *trap_type[]; extern int trap_types; #endif -int db_active = 0; +int db_active; void ddbprinttrap __P((unsigned long, unsigned long, unsigned long, unsigned long)); @@ -188,14 +189,14 @@ kdb_trap(a0, a1, a2, entry, regs) s = splhigh(); db_active++; - cnpollc(TRUE); /* Set polling mode, unblank video */ - if (ddb_mode) + if (ddb_mode) { + cndbctl(TRUE); /* DDB active, unblank video */ db_trap(entry, a0); /* Where the work happens */ - else + cndbctl(FALSE); /* DDB inactive */ + } else gdb_handle_exception(&ddb_regs, entry, a0); - cnpollc(FALSE); /* Resume interrupt mode */ db_active--; splx(s); diff --git a/sys/amd64/amd64/db_interface.c b/sys/amd64/amd64/db_interface.c index 23691541920..839d9b7c603 100644 --- a/sys/amd64/amd64/db_interface.c +++ b/sys/amd64/amd64/db_interface.c @@ -52,6 +52,7 @@ extern jmp_buf db_jmpbuf; extern void gdb_handle_exception __P((db_regs_t *, int, int)); +int db_active; db_regs_t ddb_regs; static jmp_buf db_global_jmpbuf; @@ -132,8 +133,6 @@ kdb_trap(type, code, regs) ddb_regs.tf_ss = rss(); } - cnpollc(TRUE); - #ifdef SMP #ifdef CPUSTOP_ON_DDBBREAK @@ -153,10 +152,14 @@ kdb_trap(type, code, regs) (void) setjmp(db_global_jmpbuf); db_global_jmpbuf_valid = TRUE; - if (ddb_mode) + db_active++; + if (ddb_mode) { + cndbctl(TRUE); db_trap(type, code); - else + cndbctl(FALSE); + } else gdb_handle_exception(&ddb_regs, type, code); + db_active--; db_global_jmpbuf_valid = FALSE; #ifdef SMP @@ -181,8 +184,6 @@ kdb_trap(type, code, regs) #endif /* CPUSTOP_ON_DDBBREAK */ #endif /* SMP */ - cnpollc(FALSE); - regs->tf_eip = ddb_regs.tf_eip; regs->tf_eflags = ddb_regs.tf_eflags; regs->tf_eax = ddb_regs.tf_eax; @@ -296,12 +297,11 @@ db_write_bytes(addr, size, data) * Move this to machdep.c and allow it to be called if any debugger is * installed. */ -volatile int in_Debugger = 0; - void Debugger(msg) const char *msg; { + static volatile u_char in_Debugger; /* * XXX diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index e1bfac496b6..4199346bd5a 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -90,9 +90,7 @@ #include -#ifdef DDB - extern int in_Debugger, debugger_on_panic; -#endif +#include #include "isa.h" #include "npx.h" @@ -900,7 +898,7 @@ trap_fatal(frame, eva) return; #endif #ifdef DDB - if ((debugger_on_panic || in_Debugger) && kdb_trap(type, 0, frame)) + if ((debugger_on_panic || db_active) && kdb_trap(type, 0, frame)) return; #endif printf("trap number = %d\n", type); diff --git a/sys/ddb/db_input.c b/sys/ddb/db_input.c index d97de6b0e4b..a09f003de7a 100644 --- a/sys/ddb/db_input.c +++ b/sys/ddb/db_input.c @@ -361,10 +361,3 @@ db_check_interrupt() break; } } - -/* called from kdb_trap in db_interface.c */ -void -cnpollc (flag) - int flag; -{ -} diff --git a/sys/ddb/ddb.h b/sys/ddb/ddb.h index 46fb2b5e250..972772f836d 100644 --- a/sys/ddb/ddb.h +++ b/sys/ddb/ddb.h @@ -67,9 +67,11 @@ func_name(addr, have_addr, count, modif) \ extern char *esym; extern db_expr_t db_maxoff; +extern int db_active; extern int db_indent; extern int db_inst_count; extern int db_load_count; +extern int debugger_on_panic; extern int db_store_count; extern db_expr_t db_radix; extern db_expr_t db_max_width; @@ -77,7 +79,6 @@ extern db_expr_t db_tab_stop_width; struct vm_map; -void cnpollc __P((int)); void db_check_interrupt __P((void)); void db_clear_watchpoints __P((void)); db_addr_t db_disasm __P((db_addr_t loc, boolean_t altfmt)); diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index 81dd1d7be8c..476c967143a 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -2682,8 +2682,8 @@ static cn_getc_t siocngetc; static cn_putc_t siocnputc; #ifdef __i386__ -CONS_DRIVER(sio, siocnprobe, siocninit, NULL, siocngetc, siocncheckc, siocnputc); - +CONS_DRIVER(sio, siocnprobe, siocninit, NULL, siocngetc, siocncheckc, + siocnputc, NULL); #endif /* To get the GDB related variables */ diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index 822d42b4d1d..64ecd738535 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -124,15 +124,7 @@ SYSCTL_INT(_machdep, OID_AUTO, enable_panic_key, CTLFLAG_RW, &enable_panic_key, #define VIRTUAL_TTY(sc, x) (SC_DEV((sc), (x))->si_tty) -#define debugger FALSE - -#ifdef __i386__ -#ifdef DDB -extern int in_Debugger; -#undef debugger -#define debugger in_Debugger -#endif /* DDB */ -#endif /* __i386__ */ +static int debugger; /* prototypes */ static int scvidprobe(int unit, int flags, int cons); @@ -199,13 +191,15 @@ static cn_init_t sccninit; static cn_getc_t sccngetc; static cn_checkc_t sccncheckc; static cn_putc_t sccnputc; +static cn_dbctl_t sccndbctl; static cn_term_t sccnterm; #if __alpha__ void sccnattach(void); #endif -CONS_DRIVER(sc, sccnprobe, sccninit, sccnterm, sccngetc, sccncheckc, sccnputc); +CONS_DRIVER(sc, sccnprobe, sccninit, sccnterm, sccngetc, sccncheckc, sccnputc, + sccndbctl); static d_open_t scopen; static d_close_t scclose; @@ -1474,6 +1468,28 @@ sccncheckc(dev_t dev) return sccngetch(SCGETC_NONBLOCK); } +static void +sccndbctl(dev_t dev, int on) +{ + /* try to switch to the kernel console screen */ + if (on && debugger == 0) { + /* + * TRY to make sure the screen saver is stopped, + * and the screen is updated before switching to + * the vty0. + */ + scrn_timer(NULL); + if (!cold + && sc_console->sc->cur_scp->smode.mode == VT_AUTO + && sc_console->smode.mode == VT_AUTO) + switch_scr(sc_console->sc, sc_console->index); + } + if (on) + ++debugger; + else + --debugger; +} + static int sccngetch(int flags) { @@ -1553,7 +1569,7 @@ sccnupdate(scr_stat *scp) if (scp->sc->font_loading_in_progress || scp->sc->videoio_in_progress) return; - if (debugger || panicstr || shutdown_in_progress) { + if (debugger > 0 || panicstr || shutdown_in_progress) { sc_touch_scrn_saver(); } else if (scp != scp->sc->cur_scp) { return; @@ -1626,7 +1642,7 @@ scrn_timer(void *arg) /* should we stop the screen saver? */ getmicrouptime(&tv); - if (debugger || panicstr || shutdown_in_progress) + if (debugger > 0 || panicstr || shutdown_in_progress) sc_touch_scrn_saver(); if (run_scrn_saver) { if (tv.tv_sec > sc->scrn_time_stamp + scrn_blank_time) @@ -3720,21 +3736,6 @@ next_code: case DBG: #ifndef SC_DISABLE_DDBKEY #ifdef DDB - if (debugger) - break; - /* try to switch to the kernel console screen */ - if (sc_console) { - /* - * TRY to make sure the screen saver is stopped, - * and the screen is updated before switching to - * the vty0. - */ - scrn_timer(NULL); - if (!cold - && sc_console->sc->cur_scp->smode.mode == VT_AUTO - && sc_console->smode.mode == VT_AUTO) - switch_scr(sc_console->sc, sc_console->index); - } Debugger("manual escape to debugger"); #else printf("No debugger in kernel\n"); diff --git a/sys/i386/i386/db_interface.c b/sys/i386/i386/db_interface.c index 23691541920..839d9b7c603 100644 --- a/sys/i386/i386/db_interface.c +++ b/sys/i386/i386/db_interface.c @@ -52,6 +52,7 @@ extern jmp_buf db_jmpbuf; extern void gdb_handle_exception __P((db_regs_t *, int, int)); +int db_active; db_regs_t ddb_regs; static jmp_buf db_global_jmpbuf; @@ -132,8 +133,6 @@ kdb_trap(type, code, regs) ddb_regs.tf_ss = rss(); } - cnpollc(TRUE); - #ifdef SMP #ifdef CPUSTOP_ON_DDBBREAK @@ -153,10 +152,14 @@ kdb_trap(type, code, regs) (void) setjmp(db_global_jmpbuf); db_global_jmpbuf_valid = TRUE; - if (ddb_mode) + db_active++; + if (ddb_mode) { + cndbctl(TRUE); db_trap(type, code); - else + cndbctl(FALSE); + } else gdb_handle_exception(&ddb_regs, type, code); + db_active--; db_global_jmpbuf_valid = FALSE; #ifdef SMP @@ -181,8 +184,6 @@ kdb_trap(type, code, regs) #endif /* CPUSTOP_ON_DDBBREAK */ #endif /* SMP */ - cnpollc(FALSE); - regs->tf_eip = ddb_regs.tf_eip; regs->tf_eflags = ddb_regs.tf_eflags; regs->tf_eax = ddb_regs.tf_eax; @@ -296,12 +297,11 @@ db_write_bytes(addr, size, data) * Move this to machdep.c and allow it to be called if any debugger is * installed. */ -volatile int in_Debugger = 0; - void Debugger(msg) const char *msg; { + static volatile u_char in_Debugger; /* * XXX diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index e1bfac496b6..4199346bd5a 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -90,9 +90,7 @@ #include -#ifdef DDB - extern int in_Debugger, debugger_on_panic; -#endif +#include #include "isa.h" #include "npx.h" @@ -900,7 +898,7 @@ trap_fatal(frame, eva) return; #endif #ifdef DDB - if ((debugger_on_panic || in_Debugger) && kdb_trap(type, 0, frame)) + if ((debugger_on_panic || db_active) && kdb_trap(type, 0, frame)) return; #endif printf("trap number = %d\n", type); diff --git a/sys/i386/isa/pcvt/pcvt_drv.c b/sys/i386/isa/pcvt/pcvt_drv.c index 112014e7b2a..5c50173ac4e 100644 --- a/sys/i386/isa/pcvt/pcvt_drv.c +++ b/sys/i386/isa/pcvt/pcvt_drv.c @@ -92,7 +92,8 @@ static cn_getc_t pccngetc; static cn_checkc_t pccncheckc; static cn_putc_t pccnputc; -CONS_DRIVER(pc, pccnprobe, pccninit, pccnterm, pccngetc, pccncheckc, pccnputc); +CONS_DRIVER(pc, pccnprobe, pccninit, pccnterm, pccngetc, pccncheckc, pccnputc, + NULL); static d_open_t pcopen; static d_close_t pcclose; diff --git a/sys/isa/sio.c b/sys/isa/sio.c index 81dd1d7be8c..476c967143a 100644 --- a/sys/isa/sio.c +++ b/sys/isa/sio.c @@ -2682,8 +2682,8 @@ static cn_getc_t siocngetc; static cn_putc_t siocnputc; #ifdef __i386__ -CONS_DRIVER(sio, siocnprobe, siocninit, NULL, siocngetc, siocncheckc, siocnputc); - +CONS_DRIVER(sio, siocnprobe, siocninit, NULL, siocngetc, siocncheckc, + siocnputc, NULL); #endif /* To get the GDB related variables */ diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index e1bfac496b6..4199346bd5a 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -90,9 +90,7 @@ #include -#ifdef DDB - extern int in_Debugger, debugger_on_panic; -#endif +#include #include "isa.h" #include "npx.h" @@ -900,7 +898,7 @@ trap_fatal(frame, eva) return; #endif #ifdef DDB - if ((debugger_on_panic || in_Debugger) && kdb_trap(type, 0, frame)) + if ((debugger_on_panic || db_active) && kdb_trap(type, 0, frame)) return; #endif printf("trap number = %d\n", type); diff --git a/sys/kern/tty_cons.c b/sys/kern/tty_cons.c index bac331205c4..32656f88930 100644 --- a/sys/kern/tty_cons.c +++ b/sys/kern/tty_cons.c @@ -97,7 +97,7 @@ static d_open_t *cn_phys_open; /* physical device open function */ struct consdev *cn_tab; /* physical console device info */ static dev_t condev_t; /* represents the device private info */ -CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL, NULL); +CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL, NULL, NULL); void cninit() @@ -423,6 +423,22 @@ cnputc(c) } } +void +cndbctl(on) + int on; +{ + static int refcount; + + if (cn_tab == NULL) + return; + if (!on) + refcount--; + if (refcount == 0 && cn_tab->cn_dbctl != NULL) + (*cn_tab->cn_dbctl)(cn_tab->cn_dev, on); + if (on) + refcount++; +} + static void cn_drvinit(void *unused) { diff --git a/sys/sys/cons.h b/sys/sys/cons.h index 7314dbcf993..48be3712d3c 100644 --- a/sys/sys/cons.h +++ b/sys/sys/cons.h @@ -49,6 +49,7 @@ typedef void cn_term_t __P((struct consdev *)); typedef int cn_getc_t __P((dev_t)); typedef int cn_checkc_t __P((dev_t)); typedef void cn_putc_t __P((dev_t, int)); +typedef void cn_dbctl_t __P((dev_t, int)); struct consdev { cn_probe_t *cn_probe; @@ -63,6 +64,8 @@ struct consdev { /* kernel "return char if available" interface */ cn_putc_t *cn_putc; /* kernel putchar interface */ + cn_dbctl_t *cn_dbctl; + /* debugger control interface */ struct tty *cn_tp; /* tty structure for console device */ dev_t cn_dev; /* major/minor of device */ short cn_pri; /* pecking order; the higher the better */ @@ -79,9 +82,9 @@ extern struct linker_set cons_set; extern int cons_unavail; extern struct consdev *cn_tab; -#define CONS_DRIVER(name, probe, init, term, getc, checkc, putc) \ +#define CONS_DRIVER(name, probe, init, term, getc, checkc, putc, dbctl) \ static struct consdev name##_consdev = { \ - probe, init, term, getc, checkc, putc \ + probe, init, term, getc, checkc, putc, dbctl \ }; \ DATA_SET(cons_set, name##_consdev) @@ -90,6 +93,7 @@ int cncheckc __P((void)); int cngetc __P((void)); void cninit __P((void)); void cninit_finish __P((void)); +void cndbctl __P((int)); void cnputc __P((int)); #endif /* _KERNEL */