From e244fe31d6789109d257d572331deeb0b6125118 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Fri, 7 May 1999 06:50:41 +0000 Subject: [PATCH] Generalize to allow any serial port to be used as the GDB port. Mark the GDB port in the config file with flags 0x80. Currently only the sio driver checks these flags and sets up a GDB port, but adding similar code to other serial drivers would be easy. For backward compatibility, if an sio port is marked as the console and no port is marked as the gdb port, the GDB port will be mapped to the console port. This hack should go away at some point. --- sys/amd64/amd64/amd64-gdbstub.c | 19 +++++--- sys/dev/sio/sio.c | 86 +++++++++++++++++++++++++-------- sys/i386/i386/i386-gdbstub.c | 19 +++++--- sys/isa/sio.c | 86 +++++++++++++++++++++++++-------- 4 files changed, 154 insertions(+), 56 deletions(-) diff --git a/sys/amd64/amd64/amd64-gdbstub.c b/sys/amd64/amd64/amd64-gdbstub.c index 739b7e6a7f2c..59ff3a999b86 100644 --- a/sys/amd64/amd64/amd64-gdbstub.c +++ b/sys/amd64/amd64/amd64-gdbstub.c @@ -150,23 +150,28 @@ strcpy (char *dst, const char *src) return retval; } -/* XXX sio always uses its major with minor 0 no matter what we specify. */ -#define REMOTE_DEV 0 - -cn_getc_t siocngetc; -cn_putc_t siocnputc; +/* + * These are set up by the serial card that is configured to be the gdb port. + */ +dev_t gdbdev = -1; +cn_getc_t *gdb_getc; +cn_putc_t *gdb_putc; static int putDebugChar (int c) /* write a single character */ { - siocnputc (REMOTE_DEV, c); + if (gdbdev == -1) + return 0; + (*gdb_putc)(gdbdev, c); return 1; } static int getDebugChar (void) /* read and return a single char */ { - return siocngetc (REMOTE_DEV); + if (gdbdev == -1) + return -1; + return (*gdb_getc)(gdbdev); } static const char hexchars[]="0123456789abcdef"; diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index 333235fa6af8..5e27f69743a3 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: sio.c,v 1.228 1999/04/27 11:15:42 phk Exp $ + * $Id: sio.c,v 1.229 1999/05/06 18:44:35 peter Exp $ * from: @(#)com.c 7.5 (Berkeley) 5/16/91 * from: i386/isa sio.c,v 1.234 */ @@ -150,6 +150,7 @@ #define COM_CONSOLE(flags) ((flags) & 0x10) #define COM_FORCECONSOLE(flags) ((flags) & 0x20) #define COM_LLCONSOLE(flags) ((flags) & 0x40) +#define COM_DEBUGGER(flags) ((flags) & 0x80) #define COM_LOSESOUTINTS(flags) ((flags) & 0x08) #define COM_NOFIFO(flags) ((flags) & 0x02) #define COM_ST16650A(flags) ((flags) & 0x20000) @@ -377,9 +378,9 @@ static volatile speed_t gdbdefaultrate = CONSPEED; #endif static u_int com_events; /* input chars + weighted output completions */ static Port_t siocniobase; -#ifdef __alpha__ +static int siocnunit; static Port_t siogdbiobase; -#endif +static int siogdbunit = -1; static bool_t sio_registered; static int sio_timeout; static int sio_timeouts_until_log; @@ -2642,6 +2643,13 @@ static cn_checkc_t siocncheckc; CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc); +/* + * Routines to support GDB on an sio port. + */ +extern dev_t gdbdev; +extern cn_getc_t *gdb_getc; +extern cn_putc_t *gdb_putc; + #endif static void @@ -2796,15 +2804,16 @@ siocnprobe(cp) int flags; if (resource_int_value("sio", unit, "flags", &flags)) continue; - if (COM_CONSOLE(flags)) { + if (COM_CONSOLE(flags) || COM_DEBUGGER(flags)) { int port; + Port_t iobase; + if (resource_int_value("sio", unit, "port", &port)) continue; - siocniobase = port; + iobase = port; s = spltty(); if (boothowto & RB_SERIAL) { - boot_speed = siocngetspeed(siocniobase, - comspeedtab); + boot_speed = siocngetspeed(iobase, comspeedtab); if (boot_speed) comdefaultrate = boot_speed; } @@ -2818,25 +2827,49 @@ siocnprobe(cp) * need to set the speed in hardware so that * switching it later is null. */ - cfcr = inb(siocniobase + com_cfcr); - outb(siocniobase + com_cfcr, CFCR_DLAB | cfcr); - outb(siocniobase + com_dlbl, + cfcr = inb(iobase + com_cfcr); + outb(iobase + com_cfcr, CFCR_DLAB | cfcr); + outb(iobase + com_dlbl, COMBRD(comdefaultrate) & 0xff); - outb(siocniobase + com_dlbh, + outb(iobase + com_dlbh, (u_int) COMBRD(comdefaultrate) >> 8); - outb(siocniobase + com_cfcr, cfcr); + outb(iobase + com_cfcr, cfcr); + + siocnopen(&sp, iobase, comdefaultrate); - siocnopen(&sp, siocniobase, comdefaultrate); splx(s); - if (!COM_LLCONSOLE(flags)) { + if (COM_CONSOLE(flags) && !COM_LLCONSOLE(flags)) { cp->cn_dev = makedev(CDEV_MAJOR, unit); cp->cn_pri = COM_FORCECONSOLE(flags) || boothowto & RB_SERIAL ? CN_REMOTE : CN_NORMAL; + printf("sio%d: system console\n", unit); + siocniobase = iobase; + siocnunit = unit; + } + if (COM_DEBUGGER(flags) && !COM_LLCONSOLE(flags)) { + printf("sio%d: gdb debugging port\n", unit); + siogdbiobase = iobase; + siogdbunit = unit; + gdbdev = makedev(CDEV_MAJOR, unit); + gdb_getc = siocngetc; + gdb_putc = siocnputc; } - break; } } + /* + * XXX Ugly Compatability. + * If no gdb port has been specified, set it to be the console + * as some configuration files don't specify the gdb port. + */ + if (gdbdev == -1) { + printf("sio%d: gdb debugging port\n", siocnunit); + siogdbiobase = siocniobase; + siogdbunit = siocnunit; + gdbdev = makedev(CDEV_MAJOR, siocnunit); + gdb_getc = siocngetc; + gdb_putc = siocnputc; + } } #ifdef __alpha__ @@ -2947,7 +2980,10 @@ siocncheckc(dev) int s; struct siocnstate sp; - iobase = siocniobase; + if (minor(dev) == siogdbunit) + iobase = siogdbiobase; + else + iobase = siocniobase; s = spltty(); siocnopen(&sp, iobase, comdefaultrate); if (inb(iobase + com_lsr) & LSR_RXRDY) @@ -2969,7 +3005,10 @@ siocngetc(dev) int s; struct siocnstate sp; - iobase = siocniobase; + if (minor(dev) == siogdbunit) + iobase = siogdbiobase; + else + iobase = siocniobase; s = spltty(); siocnopen(&sp, iobase, comdefaultrate); while (!(inb(iobase + com_lsr) & LSR_RXRDY)) @@ -2987,12 +3026,17 @@ siocnputc(dev, c) { int s; struct siocnstate sp; + Port_t iobase; + if (minor(dev) == siogdbunit) + iobase = siogdbiobase; + else + iobase = siocniobase; s = spltty(); - siocnopen(&sp, siocniobase, comdefaultrate); - siocntxwait(siocniobase); - outb(siocniobase + com_data, c); - siocnclose(&sp, siocniobase); + siocnopen(&sp, iobase, comdefaultrate); + siocntxwait(iobase); + outb(iobase + com_data, c); + siocnclose(&sp, iobase); splx(s); } diff --git a/sys/i386/i386/i386-gdbstub.c b/sys/i386/i386/i386-gdbstub.c index 739b7e6a7f2c..59ff3a999b86 100644 --- a/sys/i386/i386/i386-gdbstub.c +++ b/sys/i386/i386/i386-gdbstub.c @@ -150,23 +150,28 @@ strcpy (char *dst, const char *src) return retval; } -/* XXX sio always uses its major with minor 0 no matter what we specify. */ -#define REMOTE_DEV 0 - -cn_getc_t siocngetc; -cn_putc_t siocnputc; +/* + * These are set up by the serial card that is configured to be the gdb port. + */ +dev_t gdbdev = -1; +cn_getc_t *gdb_getc; +cn_putc_t *gdb_putc; static int putDebugChar (int c) /* write a single character */ { - siocnputc (REMOTE_DEV, c); + if (gdbdev == -1) + return 0; + (*gdb_putc)(gdbdev, c); return 1; } static int getDebugChar (void) /* read and return a single char */ { - return siocngetc (REMOTE_DEV); + if (gdbdev == -1) + return -1; + return (*gdb_getc)(gdbdev); } static const char hexchars[]="0123456789abcdef"; diff --git a/sys/isa/sio.c b/sys/isa/sio.c index 333235fa6af8..5e27f69743a3 100644 --- a/sys/isa/sio.c +++ b/sys/isa/sio.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: sio.c,v 1.228 1999/04/27 11:15:42 phk Exp $ + * $Id: sio.c,v 1.229 1999/05/06 18:44:35 peter Exp $ * from: @(#)com.c 7.5 (Berkeley) 5/16/91 * from: i386/isa sio.c,v 1.234 */ @@ -150,6 +150,7 @@ #define COM_CONSOLE(flags) ((flags) & 0x10) #define COM_FORCECONSOLE(flags) ((flags) & 0x20) #define COM_LLCONSOLE(flags) ((flags) & 0x40) +#define COM_DEBUGGER(flags) ((flags) & 0x80) #define COM_LOSESOUTINTS(flags) ((flags) & 0x08) #define COM_NOFIFO(flags) ((flags) & 0x02) #define COM_ST16650A(flags) ((flags) & 0x20000) @@ -377,9 +378,9 @@ static volatile speed_t gdbdefaultrate = CONSPEED; #endif static u_int com_events; /* input chars + weighted output completions */ static Port_t siocniobase; -#ifdef __alpha__ +static int siocnunit; static Port_t siogdbiobase; -#endif +static int siogdbunit = -1; static bool_t sio_registered; static int sio_timeout; static int sio_timeouts_until_log; @@ -2642,6 +2643,13 @@ static cn_checkc_t siocncheckc; CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc); +/* + * Routines to support GDB on an sio port. + */ +extern dev_t gdbdev; +extern cn_getc_t *gdb_getc; +extern cn_putc_t *gdb_putc; + #endif static void @@ -2796,15 +2804,16 @@ siocnprobe(cp) int flags; if (resource_int_value("sio", unit, "flags", &flags)) continue; - if (COM_CONSOLE(flags)) { + if (COM_CONSOLE(flags) || COM_DEBUGGER(flags)) { int port; + Port_t iobase; + if (resource_int_value("sio", unit, "port", &port)) continue; - siocniobase = port; + iobase = port; s = spltty(); if (boothowto & RB_SERIAL) { - boot_speed = siocngetspeed(siocniobase, - comspeedtab); + boot_speed = siocngetspeed(iobase, comspeedtab); if (boot_speed) comdefaultrate = boot_speed; } @@ -2818,25 +2827,49 @@ siocnprobe(cp) * need to set the speed in hardware so that * switching it later is null. */ - cfcr = inb(siocniobase + com_cfcr); - outb(siocniobase + com_cfcr, CFCR_DLAB | cfcr); - outb(siocniobase + com_dlbl, + cfcr = inb(iobase + com_cfcr); + outb(iobase + com_cfcr, CFCR_DLAB | cfcr); + outb(iobase + com_dlbl, COMBRD(comdefaultrate) & 0xff); - outb(siocniobase + com_dlbh, + outb(iobase + com_dlbh, (u_int) COMBRD(comdefaultrate) >> 8); - outb(siocniobase + com_cfcr, cfcr); + outb(iobase + com_cfcr, cfcr); + + siocnopen(&sp, iobase, comdefaultrate); - siocnopen(&sp, siocniobase, comdefaultrate); splx(s); - if (!COM_LLCONSOLE(flags)) { + if (COM_CONSOLE(flags) && !COM_LLCONSOLE(flags)) { cp->cn_dev = makedev(CDEV_MAJOR, unit); cp->cn_pri = COM_FORCECONSOLE(flags) || boothowto & RB_SERIAL ? CN_REMOTE : CN_NORMAL; + printf("sio%d: system console\n", unit); + siocniobase = iobase; + siocnunit = unit; + } + if (COM_DEBUGGER(flags) && !COM_LLCONSOLE(flags)) { + printf("sio%d: gdb debugging port\n", unit); + siogdbiobase = iobase; + siogdbunit = unit; + gdbdev = makedev(CDEV_MAJOR, unit); + gdb_getc = siocngetc; + gdb_putc = siocnputc; } - break; } } + /* + * XXX Ugly Compatability. + * If no gdb port has been specified, set it to be the console + * as some configuration files don't specify the gdb port. + */ + if (gdbdev == -1) { + printf("sio%d: gdb debugging port\n", siocnunit); + siogdbiobase = siocniobase; + siogdbunit = siocnunit; + gdbdev = makedev(CDEV_MAJOR, siocnunit); + gdb_getc = siocngetc; + gdb_putc = siocnputc; + } } #ifdef __alpha__ @@ -2947,7 +2980,10 @@ siocncheckc(dev) int s; struct siocnstate sp; - iobase = siocniobase; + if (minor(dev) == siogdbunit) + iobase = siogdbiobase; + else + iobase = siocniobase; s = spltty(); siocnopen(&sp, iobase, comdefaultrate); if (inb(iobase + com_lsr) & LSR_RXRDY) @@ -2969,7 +3005,10 @@ siocngetc(dev) int s; struct siocnstate sp; - iobase = siocniobase; + if (minor(dev) == siogdbunit) + iobase = siogdbiobase; + else + iobase = siocniobase; s = spltty(); siocnopen(&sp, iobase, comdefaultrate); while (!(inb(iobase + com_lsr) & LSR_RXRDY)) @@ -2987,12 +3026,17 @@ siocnputc(dev, c) { int s; struct siocnstate sp; + Port_t iobase; + if (minor(dev) == siogdbunit) + iobase = siogdbiobase; + else + iobase = siocniobase; s = spltty(); - siocnopen(&sp, siocniobase, comdefaultrate); - siocntxwait(siocniobase); - outb(siocniobase + com_data, c); - siocnclose(&sp, siocniobase); + siocnopen(&sp, iobase, comdefaultrate); + siocntxwait(iobase); + outb(iobase + com_data, c); + siocnclose(&sp, iobase); splx(s); }