[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC] Use GDB 'O' packets for console output
Hello All, The remote serial protocol for GDB supports echoing program output. This patch adds a new SERHND flag and hooks into serial_puts() to allow this to happen. All XEN prtintk()s and dom0 console output will get send to a remote GDB if it's attached and the serial console shares the same port. Feedback greatly appreciated. --- common/gdbstub.c | 28 +++++++++++++++++++++++++++- drivers/char/console.c | 11 +++++++++++ drivers/char/serial.c | 5 +++++ include/asm-powerpc/debugger.h | 3 +++ include/xen/gdbstub.h | 2 ++ include/xen/serial.h | 5 +++++ 6 files changed, 53 insertions(+), 1 deletion(-) --- diff -r 9c4858991254 xen/common/gdbstub.c --- a/xen/common/gdbstub.c Tue Aug 29 07:07:57 2006 -0400 +++ b/xen/common/gdbstub.c Fri Sep 01 13:40:19 2006 +1000 @@ -470,6 +470,30 @@ __gdb_ctx = { }; static struct gdb_context *gdb_ctx = &__gdb_ctx; +/* FIXME: does this need to be protected by a lock? + * Can it clobber another packet? */ +void +debugger_puts(const char *str) +{ + char *p; + + gdb_start_packet(gdb_ctx); + gdb_write_to_packet_char('O', gdb_ctx); + + for(p=(char *)str; *p != '\x0'; p++) { + gdb_write_to_packet_char(hex2char((*p>>4) & 0x0f), gdb_ctx ); + gdb_write_to_packet_char(hex2char((*p) & 0x0f), gdb_ctx ); + } + + gdb_send_packet(gdb_ctx); +} + +int +in_debugger(void) +{ + return gdb_ctx->currently_attached; +} + /* trap handler: main entry point */ int __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie) @@ -560,8 +584,10 @@ initialise_gdb(void) initialise_gdb(void) { gdb_ctx->serhnd = serial_parse_handle(opt_gdb); - if ( gdb_ctx->serhnd != -1 ) + if ( gdb_ctx->serhnd != -1 ) { + serial_maybe_add_flags(gdb_ctx->serhnd, SERHND_DEBUGGER); printk("GDB stub initialised.\n"); + } serial_start_sync(gdb_ctx->serhnd); } diff -r 9c4858991254 xen/drivers/char/console.c --- a/xen/drivers/char/console.c Tue Aug 29 07:07:57 2006 -0400 +++ b/xen/drivers/char/console.c Fri Sep 01 13:40:19 2006 +1000 @@ -115,6 +115,17 @@ long read_console_ring(XEN_GUEST_HANDLE( #define SERIAL_RX_MASK(_i) ((_i)&(SERIAL_RX_SIZE-1)) static char serial_rx_ring[SERIAL_RX_SIZE]; static unsigned int serial_rx_cons, serial_rx_prod; + +/* Enable debugger output on the serial console if it's the same + * port as the debugger */ +void serial_maybe_add_flags(int debugger_handle, int flags) +{ + /* If the debugger and the serial console differ only in + * whether SERHND_DEBUGGER is enabled, enable it for the console */ + if ( (debugger_handle != -1 ) && + (debugger_handle & ~flags) == sercon_handle ) + sercon_handle |= flags; +} /* CTRL-<switch_char> switches input direction between Xen and DOM0. */ #define SWITCH_CODE (opt_conswitch[0]-'a'+1) diff -r 9c4858991254 xen/drivers/char/serial.c --- a/xen/drivers/char/serial.c Tue Aug 29 07:07:57 2006 -0400 +++ b/xen/drivers/char/serial.c Fri Sep 01 13:40:19 2006 +1000 @@ -14,6 +14,7 @@ #include <xen/sched.h> #include <xen/mm.h> #include <xen/serial.h> +#include <asm/debugger.h> /* in_debugger() and debugger_puts() */ static struct serial_port com[2] = { { .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED }, @@ -153,6 +154,10 @@ void serial_puts(int handle, const char if ( (handle == -1) || !port->driver || !port->driver->putc ) return; + if ( (handle & SERHND_DEBUGGER) && in_debugger() ) { + debugger_puts(s); + return; + } spin_lock_irqsave(&port->tx_lock, flags); diff -r 9c4858991254 xen/include/asm-powerpc/debugger.h --- a/xen/include/asm-powerpc/debugger.h Tue Aug 29 07:07:57 2006 -0400 +++ b/xen/include/asm-powerpc/debugger.h Fri Sep 01 13:40:19 2006 +1000 @@ -39,6 +39,9 @@ static inline int debugger_trap_fatal( #define debugger_trap_fatal(_v, _r) (0) #define debugger_trap_immediate() ((void)0) +#define debugger_puts(str) ((void)0) +#define in_debugger() (0) + #endif /* CRASH_DEBUG */ #endif diff -r 9c4858991254 xen/include/xen/gdbstub.h --- a/xen/include/xen/gdbstub.h Tue Aug 29 07:07:57 2006 -0400 +++ b/xen/include/xen/gdbstub.h Fri Sep 01 13:40:19 2006 +1000 @@ -90,6 +90,8 @@ void gdb_arch_exit(struct cpu_user_regs #define SIGTERM 15 void initialise_gdb(void); +void debugger_puts(const char *str); +int in_debugger(void); #else diff -r 9c4858991254 xen/include/xen/serial.h --- a/xen/include/xen/serial.h Tue Aug 29 07:07:57 2006 -0400 +++ b/xen/include/xen/serial.h Fri Sep 01 13:40:19 2006 +1000 @@ -66,6 +66,7 @@ struct uart_driver { #define SERHND_HI (1<<1) /* Mux/demux each transferred char by MSB. */ #define SERHND_LO (1<<2) /* Ditto, except that the MSB is cleared. */ #define SERHND_COOKED (1<<3) /* Newline/carriage-return translation? */ +#define SERHND_DEBUGGER (1<<4) /* Translate console messages for the debugger */ /* Two-stage initialisation (before/after IRQ-subsystem initialisation). */ void serial_init_preirq(void); @@ -132,6 +133,10 @@ void ns16550_init(int index, struct ns16 /* Baud rate was pre-configured before invoking the UART driver. */ #define BAUD_AUTO (-1) +/* Enable debuggger output if the serial console and debugger are on the same + * port */ +void serial_maybe_add_flags(int debugger_handle, int flags); + #endif /* __XEN_SERIAL_H__ */ /* Yours Tony linux.conf.au http://linux.conf.au/ || http://lca2007.linux.org.au/ Jan 15-20 2007 The Australian Linux Technical Conference! _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |