Index: ddb/db_trap.c =================================================================== RCS file: /home/ncvs/src/sys/ddb/db_trap.c,v retrieving revision 1.15 diff -u -r1.15 db_trap.c --- ddb/db_trap.c 8 Jul 2001 04:56:05 -0000 1.15 +++ ddb/db_trap.c 3 Nov 2002 23:25:46 -0000 @@ -34,6 +34,7 @@ /* * Trap entry point to kernel debugger. */ +#include "opt_ddb.h" #include #include @@ -74,3 +75,69 @@ db_restart_at_pc(watchpt); } + +#ifdef GDB_AUTO_ENTER +#include +#include +#include +static enum { + STATE_NONE, + STATE_DATA, + STATE_CHKSUM1, + STATE_CHKSUM2, +} gdb_auto_state; +#define MAX_GDB_PACKET_LEN 16 + +int gdb_auto_enter = 0; +SYSCTL_INT(_debug, OID_AUTO, gdb_auto_enter, CTLFLAG_RW, &gdb_auto_enter, 0, + "Enter GDB automatically after receiving a valid frame"); + +/* Return non-zero if we see a valid GDB packet */ +int +gdb_state_machine(char c) +{ + static int gdb_plen; + int ret; + + ret = 0; + switch (gdb_auto_state) { + case STATE_NONE: + if (c == '$') { + gdb_plen++; + gdb_auto_state = STATE_DATA; + } + break; + case STATE_DATA: + if (++gdb_plen < MAX_GDB_PACKET_LEN - 1) { + if (c == '#') + gdb_auto_state = STATE_CHKSUM1; + } else { + gdb_plen = 0; + } + break; + case STATE_CHKSUM1: + case STATE_CHKSUM2: + if (++gdb_plen <= MAX_GDB_PACKET_LEN && isxdigit(c)) { + if (gdb_auto_state == STATE_CHKSUM1) { + gdb_auto_state = STATE_CHKSUM2; + } else { + /* Found a complete packet */ + KASSERT(gdb_auto_state == STATE_CHKSUM2, + ("invalid gdb_auto state")); + ret = 1; + gdb_auto_state = STATE_NONE; + gdb_plen = 0; + } + } else { + gdb_auto_state = STATE_NONE; + gdb_plen = 0; + } + break; + default: + panic("unknown gdb_auto_state 0x%x", gdb_auto_state); + /* NOTREACHED */ + } + + return (ret); +} +#endif /* GDB_AUTO_ENTER */ Index: ddb/ddb.h =================================================================== RCS file: /home/ncvs/src/sys/ddb/ddb.h,v retrieving revision 1.30 diff -u -r1.30 ddb.h --- ddb/ddb.h 21 Sep 2002 17:29:36 -0000 1.30 +++ ddb/ddb.h 3 Nov 2002 23:19:29 -0000 @@ -161,4 +161,7 @@ extern cn_putc_t *gdb_putc; #endif +extern int gdb_auto_enter; +extern int gdb_state_machine(char c); + #endif /* !_DDB_DDB_H_ */ Index: dev/sio/sio.c =================================================================== RCS file: /home/ncvs/src/sys/dev/sio/sio.c,v retrieving revision 1.382 diff -u -r1.382 sio.c --- dev/sio/sio.c 11 Oct 2002 20:22:20 -0000 1.382 +++ dev/sio/sio.c 3 Nov 2002 23:19:17 -0000 @@ -71,6 +71,10 @@ #include #include #include +#include +#if DDB > 0 +#include +#endif #include @@ -1123,13 +1127,14 @@ } if (ret) device_printf(dev, "could not activate interrupt\n"); -#if defined(DDB) && (defined(BREAK_TO_DEBUGGER) || \ - defined(ALT_BREAK_TO_DEBUGGER)) +#if defined(DDB) && (defined(BREAK_TO_DEBUGGER) || \ + defined(ALT_BREAK_TO_DEBUGGER) || \ + defined(GDB_AUTO_ENTER)) /* * Enable interrupts for early break-to-debugger support - * on the console. + * on the console and/or gdb port. */ - if (ret == 0 && unit == comconsole) + if (ret == 0 && (unit == comconsole || unit == siogdbunit)) outb(siocniobase + com_ier, IER_ERXRDY | IER_ERLS | IER_EMSC); #endif @@ -1381,14 +1386,15 @@ sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK); tp = com->tp; -#if defined(DDB) && (defined(BREAK_TO_DEBUGGER) || \ - defined(ALT_BREAK_TO_DEBUGGER)) +#if defined(DDB) && (defined(BREAK_TO_DEBUGGER) || \ + defined(ALT_BREAK_TO_DEBUGGER) || \ + defined(GDB_AUTO_ENTER)) /* * Leave interrupts enabled and don't clear DTR if this is the * console. This allows us to detect break-to-debugger events * while the console device is closed. */ - if (com->unit != comconsole) + if (com->unit != comconsole || com->unit != siogdbunit) #endif { sio_setreg(com, com_ier, 0); @@ -1746,7 +1752,8 @@ recv_data = 0; else recv_data = inb(com->data_port); -#if defined(DDB) && defined(ALT_BREAK_TO_DEBUGGER) +#ifdef DDB +#ifdef ALT_BREAK_TO_DEBUGGER /* * Solaris implements a new BREAK which is initiated * by a character sequence CR ~ ^b which is similar @@ -1778,7 +1785,17 @@ } else brk_state1 = 0; } -#endif +#endif /* ALT_BREAK_TO_DEBUGGER */ +#ifdef GDB_AUTO_ENTER + if (gdb_auto_enter != 0 && com->unit == siogdbunit) { + if (gdb_state_machine(recv_data) != 0) { + boothowto |= RB_GDB; + breakpoint(); + goto cont; + } + } +#endif /* GDB_AUTO_ENTER */ +#endif /* DDB */ if (line_status & (LSR_BI | LSR_FE | LSR_PE)) { /* * Don't store BI if IGNBRK or FE/PE if IGNPAR. @@ -2733,8 +2750,6 @@ /* * Following are all routines needed for SIO to act as console */ -#include - struct siocnstate { u_char dlbl; u_char dlbh; Index: conf/options =================================================================== RCS file: /home/ncvs/src/sys/conf/options,v retrieving revision 1.364 diff -u -r1.364 options --- conf/options 18 Nov 2002 06:17:07 -0000 1.364 +++ conf/options 24 Nov 2002 00:44:19 -0000 @@ -87,6 +87,7 @@ DDB_UNATTENDED GDB_REMOTE_CHAT opt_ddb.h GDBSPEED opt_ddb.h +GDB_AUTO_ENTER opt_ddb.h NO_GEOM opt_geom.h GEOM_AES opt_geom.h GEOM_BDE opt_geom.h