I don't particularly like "serial_maybe_add_flags", but I think this is
worth posting to xen-devel to get Keir's feedback.
--
Hollis Blanchard
IBM Linux Technology Center
On Fri, 2006-09-01 at 13:54 +1000, Tony Breeds wrote:
> Okay Take 2.
>
> This patch is a little more invasive than my original approach. It adds
> a new SERHND flag for debugger output. With this version any data
> written to the console of dom0 or xen will get sent to the attached GDB
> process. When gdb detaches console output goes back to the serial
> console.
>
> Feedback most welcome.
> ---
> 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-ppc-devel mailing list
> Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
> http://lists.xensource.com/xen-ppc-devel
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel
|