diff options
-rw-r--r-- | sys/arm/at91/uart_dev_at91usart.c | 15 | ||||
-rw-r--r-- | sys/dev/dcons/dcons_os.c | 34 | ||||
-rw-r--r-- | sys/dev/ofw/ofw_console.c | 19 | ||||
-rw-r--r-- | sys/dev/sio/sio.c | 26 | ||||
-rw-r--r-- | sys/dev/uart/uart_core.c | 20 | ||||
-rw-r--r-- | sys/kern/subr_kdb.c | 46 | ||||
-rw-r--r-- | sys/pc98/cbus/sio.c | 27 | ||||
-rw-r--r-- | sys/sun4v/sun4v/hvcons.c | 18 | ||||
-rw-r--r-- | sys/sys/kdb.h | 7 |
9 files changed, 175 insertions, 37 deletions
diff --git a/sys/arm/at91/uart_dev_at91usart.c b/sys/arm/at91/uart_dev_at91usart.c index f87dcaa..8a7644f 100644 --- a/sys/arm/at91/uart_dev_at91usart.c +++ b/sys/arm/at91/uart_dev_at91usart.c @@ -506,9 +506,20 @@ static __inline void at91_rx_put(struct uart_softc *sc, int key) { #if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER) + int kdb_brk; + if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) { - if (kdb_alt_break(key, &sc->sc_altbrk)) - kdb_enter(KDB_WHY_BREAK, "Break sequence to console"); + if ((kdb_brk = kdb_alt_break(key, &sc->sc_altbrk)) != 0) { + case KDB_REQ_DEBUGGER: + kdb_enter(KDB_WHY_BREAK, "Break sequence on console"); + break; + case KDB_REQ_PANIC: + kdb_panic("Panic sequence on console"); + break; + case KDB_REQ_REBOOT: + kdb_reboot(); + break; + } } #endif uart_rx_put(sc, key); diff --git a/sys/dev/dcons/dcons_os.c b/sys/dev/dcons/dcons_os.c index 7eb89aa..5715343 100644 --- a/sys/dev/dcons/dcons_os.c +++ b/sys/dev/dcons/dcons_os.c @@ -198,22 +198,36 @@ extern struct gdb_dbgport *gdb_cur; static int dcons_check_break(struct dcons_softc *dc, int c) { +#if __FreeBSD_version >= 502122 + int kdb_brk; +#endif if (c < 0) return (c); #if __FreeBSD_version >= 502122 - if (kdb_alt_break(c, &dc->brk_state)) { - if ((dc->flags & DC_GDB) != 0) { + if ((kdb_brk = kdb_alt_break(c, &dc->brk_state)) != 0) { + switch (kdb_brk) { + case KDB_REQ_DEBUGGER: + + if ((dc->flags & DC_GDB) != 0) { #ifdef GDB - if (gdb_cur == &dcons_gdb_dbgport) { - kdb_dbbe_select("gdb"); - kdb_enter(KDB_WHY_BREAK, - "Break sequence on dcons gdb port"); - } + if (gdb_cur == &dcons_gdb_dbgport) { + kdb_dbbe_select("gdb"); + kdb_enter(KDB_WHY_BREAK, + "Break sequence on dcons gdb port"); + } #endif - } else - kdb_enter(KDB_WHY_BREAK, - "Break sequence on dcons console port"); + } else + kdb_enter(KDB_WHY_BREAK, + "Break sequence on dcons console port"); + break; + case KDB_REQ_PANIC: + kdb_panic("Panic sequence on dcons console port"); + break; + case KDB_REQ_BREAK: + kdb_reboot(); + break; + } } #else switch (dc->brk_state) { diff --git a/sys/dev/ofw/ofw_console.c b/sys/dev/ofw/ofw_console.c index 154bcc5..156f121 100644 --- a/sys/dev/ofw/ofw_console.c +++ b/sys/dev/ofw/ofw_console.c @@ -281,8 +281,23 @@ ofw_cngetc(struct consdev *cp) if (OF_read(stdin, &ch, 1) > 0) { #if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER) - if (kdb_alt_break(ch, &alt_break_state)) - kdb_enter(KDB_WHY_BREAK, "Break sequence on console"); + int kdb_brk; + + if ((kdb_brk = kdb_alt_break(ch, &alt_break_state)) != 0) { + switch (kdb_brk) { + case KDB_REQ_DEBUGGER: + kdb_enter(KDB_WHY_BREAK, + "Break sequence on console"); + break; + case KDB_REQ_PANIC: + kdb_panic("Panic sequence on console"); + break; + case KDB_REQ_REBOOT: + kdb_reboot(); + break; + + } + } #endif return (ch); } diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index a62b411..a4cca4d 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -1469,6 +1469,11 @@ siointr1(com) u_char modem_status; u_char *ioptr; u_char recv_data; +#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER) + int kdb_brk; + +again: +#endif if (COM_IIR_TXRDYBUG(com->flags)) { int_ctl = inb(com->int_ctl_port); @@ -1501,9 +1506,24 @@ siointr1(com) #ifdef KDB #ifdef ALT_BREAK_TO_DEBUGGER if (com->unit == comconsole && - kdb_alt_break(recv_data, &com->alt_brk_state) != 0) - kdb_enter(KDB_WHY_BREAK, - "Break sequence on console"); + (kdb_brk = kdb_alt_break(recv_data, + &com->alt_brk_state)) != 0) { + mtx_unlock_spin(&sio_lock); + switch (kdb_brk) { + case KDB_REQ_DEBUGGER: + kdb_enter(KDB_WHY_BREAK, + "Break sequence on console"); + break; + case KDB_REQ_PANIC: + kdb_panic("panic on console"); + break; + case KDB_REQ_REBOOT: + kdb_reboot(); + break; + } + mtx_lock_spin(&sio_lock); + goto again; + } #endif /* ALT_BREAK_TO_DEBUGGER */ #endif /* KDB */ if (line_status & (LSR_BI | LSR_FE | LSR_PE)) { diff --git a/sys/dev/uart/uart_core.c b/sys/dev/uart/uart_core.c index b4730418..3b0d64c 100644 --- a/sys/dev/uart/uart_core.c +++ b/sys/dev/uart/uart_core.c @@ -175,9 +175,23 @@ uart_intr_rxready(void *arg) #if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER) if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) { while (rxp != sc->sc_rxput) { - if (kdb_alt_break(sc->sc_rxbuf[rxp++], &sc->sc_altbrk)) - kdb_enter(KDB_WHY_BREAK, - "Break sequence on console"); + int kdb_brk; + + if ((kdb_brk = kdb_alt_break(sc->sc_rxbuf[rxp++], + &sc->sc_altbrk)) != 0) { + switch (kdb_brk) { + case KDB_REQ_DEBUGGER: + kdb_enter(KDB_WHY_BREAK, + "Break sequence on console"); + break; + case KDB_REQ_PANIC: + kdb_panic("Panic sequence on console"); + break; + case KDB_REQ_REBOOT: + kdb_reboot(); + break; + } + } if (rxp == sc->sc_rxbufsz) rxp = 0; } diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c index 8b66a58..602093b 100644 --- a/sys/kern/subr_kdb.c +++ b/sys/kern/subr_kdb.c @@ -221,6 +221,25 @@ kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS) return (0); } +void +kdb_panic(const char *msg) +{ + +#ifdef SMP + stop_cpus(PCPU_GET(other_cpus)); +#endif + printf("KDB: panic\n"); + panic(msg); +} + +void +kdb_reboot(void) +{ + + printf("KDB: reboot requested\n"); + shutdown_nice(0); +} + /* * Solaris implements a new BREAK which is initiated by a character sequence * CR ~ ^b which is similar to a familiar pattern used on Sun servers by the @@ -235,6 +254,8 @@ kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS) #define KEY_CR 13 /* CR '\r' */ #define KEY_TILDE 126 /* ~ */ #define KEY_CRTLB 2 /* ^B */ +#define KEY_CRTLP 16 /* ^P */ +#define KEY_CRTLR 18 /* ^R */ int kdb_alt_break(int key, int *state) @@ -242,20 +263,23 @@ kdb_alt_break(int key, int *state) int brk; brk = 0; - switch (key) { - case KEY_CR: - *state = KEY_TILDE; + switch (*state) { + case 0: + if (key == KEY_CR) + *state = 1; break; - case KEY_TILDE: - *state = (*state == KEY_TILDE) ? KEY_CRTLB : 0; + case 1: + if (key == KEY_TILDE) + *state = 2; break; - case KEY_CRTLB: - if (*state == KEY_CRTLB) - brk = 1; - /* FALLTHROUGH */ - default: + case 2: + if (key == KEY_CRTLB) + brk = KDB_REQ_DEBUGGER; + else if (key == KEY_CRTLP) + brk = KDB_REQ_PANIC; + else if (key == KEY_CRTLR) + brk = KDB_REQ_REBOOT; *state = 0; - break; } return (brk); } diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c index d0173af..7089578 100644 --- a/sys/pc98/cbus/sio.c +++ b/sys/pc98/cbus/sio.c @@ -2268,12 +2268,16 @@ siointr1(com) u_char modem_status; u_char *ioptr; u_char recv_data; - #ifdef PC98 u_char tmp = 0; u_char rsa_buf_status = 0; int rsa_tx_fifo_size = 0; #endif /* PC98 */ +#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER) + int kdb_brk; + +again: +#endif if (COM_IIR_TXRDYBUG(com->flags)) { int_ctl = inb(com->int_ctl_port); @@ -2368,9 +2372,24 @@ more_intr: #ifdef KDB #ifdef ALT_BREAK_TO_DEBUGGER if (com->unit == comconsole && - kdb_alt_break(recv_data, &com->alt_brk_state) != 0) - kdb_enter(KDB_WHY_BREAK, - "Break sequence on console"); + (kdb_brk = kdb_alt_break(recv_data, + &com->alt_brk_state)) != 0) { + mtx_unlock_spin(&sio_lock); + switch (kdb_brk) { + case KDB_REQ_DEBUGGER: + kdb_enter(KDB_WHY_BREAK, + "Break sequence on console"); + break; + case KDB_REQ_PANIC: + kdb_panic("panic on console"); + break; + case KDB_REQ_REBOOT: + kdb_reboot(); + break; + } + mtx_lock_spin(&sio_lock); + goto again; + } #endif /* ALT_BREAK_TO_DEBUGGER */ #endif /* KDB */ if (line_status & (LSR_BI | LSR_FE | LSR_PE)) { diff --git a/sys/sun4v/sun4v/hvcons.c b/sys/sun4v/sun4v/hvcons.c index 3329d05..0217a85 100644 --- a/sys/sun4v/sun4v/hvcons.c +++ b/sys/sun4v/sun4v/hvcons.c @@ -223,11 +223,25 @@ hvcn_cngetc(struct consdev *cp) while ((l = hv_cons_getchar(&ch)) != H_EOK) { #if defined(KDB) + int kdb_brk; + if (l == H_BREAK || l == H_HUP) kdb_enter(KDB_WHY_BREAK, "Break sequence on console"); - if (kdb_alt_break(ch, &alt_break_state)) - kdb_enter(KDB_WHY_BREAK, "Break sequence on console"); + if ((kdb_brk = kdb_alt_break(ch, &alt_break_state)) != 0) { + switch (kdb_brk) { + case KDB_REQ_DEBUGGER: + kdb_enter(KDB_WHY_BREAK, + "Break sequence on console"); + break; + case KDB_REQ_PANIC: + kdb_panic("Panic sequence on console"); + break; + case KDB_REQ_REBOOT: + kdb_reboot(); + break; + } + } #endif if (l != -2 && l != 0) { return (-1); diff --git a/sys/sys/kdb.h b/sys/sys/kdb.h index 0f989f5..c162852 100644 --- a/sys/sys/kdb.h +++ b/sys/sys/kdb.h @@ -69,6 +69,8 @@ int kdb_dbbe_select(const char *); void kdb_enter(const char *, const char *); void kdb_init(void); void * kdb_jmpbuf(jmp_buf); +void kdb_panic(const char *); +void kdb_reboot(void); void kdb_reenter(void); struct pcb *kdb_thr_ctx(struct thread *); struct thread *kdb_thr_first(void); @@ -105,4 +107,9 @@ extern const char * volatile kdb_why; #define KDB_WHY_POWERPC "powerpc" /* Unhandled powerpc intr. */ #define KDB_WHY_UNIONFS "unionfs" /* Unionfs bug. */ +/* Return values for kdb_alt_break */ +#define KDB_REQ_DEBUGGER 1 /* User requested Debugger */ +#define KDB_REQ_PANIC 2 /* User requested a panic */ +#define KDB_REQ_REBOOT 3 /* User requested a clean reboot */ + #endif /* !_SYS_KDB_H_ */ |