[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Use GDB 'O' packets for console output if the serial line is shared
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 19b126974c1f0bd4f075562931356bd84d11a372 # Parent 828c0c89d8309427f65d5293173f24487c5dd7d4 Use GDB 'O' packets for console output if the serial line is shared and GDB is attached. It may be necessary for gdb and the console to share a serial port. This patch utilises the GDB protocol to encode console output. Based on a patch from Tony Breeds <tony@xxxxxxxxxxxxxxxxxx> Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/common/gdbstub.c | 52 ++++++++++++++++++++++++++++++++++++--------- xen/drivers/char/console.c | 36 +++++++++++++++++++++++++++---- xen/include/xen/console.h | 9 +++++++ xen/include/xen/gdbstub.h | 3 +- 4 files changed, 85 insertions(+), 15 deletions(-) diff -r 828c0c89d830 -r 19b126974c1f xen/common/gdbstub.c --- a/xen/common/gdbstub.c Sat Sep 23 14:07:41 2006 +0100 +++ b/xen/common/gdbstub.c Sat Sep 23 14:47:00 2006 +0100 @@ -357,6 +357,25 @@ gdb_cmd_write_mem(unsigned long addr, un gdb_send_packet(ctx); } +static void +gdbstub_attach(struct gdb_context *ctx) +{ + static void gdbstub_console_puts(const char *str); + if ( ctx->currently_attached ) + return; + ctx->currently_attached = 1; + ctx->console_steal_id = console_steal(ctx->serhnd, gdbstub_console_puts); +} + +static void +gdbstub_detach(struct gdb_context *ctx) +{ + if ( !ctx->currently_attached ) + return; + ctx->currently_attached = 0; + console_giveback(ctx->console_steal_id); +} + /* command dispatcher */ static int process_command(struct cpu_user_regs *regs, struct gdb_context *ctx) @@ -427,7 +446,7 @@ process_command(struct cpu_user_regs *re gdb_arch_read_reg(addr, regs, ctx); break; case 'D': - ctx->currently_attached = 0; + gdbstub_detach(ctx); gdb_send_reply("OK", ctx); /* fall through */ case 'k': @@ -444,7 +463,7 @@ process_command(struct cpu_user_regs *re ctx->in_buf[1] ) addr = str2ulong(&ctx->in_buf[1], sizeof(unsigned long)); if ( ctx->in_buf[0] != 'D' ) - ctx->currently_attached = 1; + gdbstub_attach(ctx); resume = 1; gdb_arch_resume(regs, addr, type, ctx); break; @@ -459,16 +478,28 @@ process_command(struct cpu_user_regs *re static struct gdb_context __gdb_ctx = { - .serhnd = -1, - .currently_attached = 0, - .running = ATOMIC_INIT(1), - .connected = 0, - .signum = 1, - .in_bytes = 0, - .out_offset = 0, - .out_csum = 0, + .serhnd = -1, + .running = ATOMIC_INIT(1), + .signum = 1 }; static struct gdb_context *gdb_ctx = &__gdb_ctx; + +static void +gdbstub_console_puts(const char *str) +{ + const char *p; + + gdb_start_packet(gdb_ctx); + gdb_write_to_packet_char('O', gdb_ctx); + + for ( p = str; *p != '\0'; 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); +} /* trap handler: main entry point */ int @@ -525,6 +556,7 @@ __trap_to_gdb(struct cpu_user_regs *regs gdb_arch_enter(regs); gdb_ctx->signum = gdb_arch_signal_num(regs, cookie); + /* If gdb is already attached, tell it we've stopped again. */ if ( gdb_ctx->currently_attached ) { diff -r 828c0c89d830 -r 19b126974c1f xen/drivers/char/console.c --- a/xen/drivers/char/console.c Sat Sep 23 14:07:41 2006 +0100 +++ b/xen/drivers/char/console.c Sat Sep 23 14:47:00 2006 +0100 @@ -116,6 +116,34 @@ static char serial_rx_ring[SERIAL_RX_SIZ static char serial_rx_ring[SERIAL_RX_SIZE]; static unsigned int serial_rx_cons, serial_rx_prod; +static void (*serial_steal_fn)(const char *); + +int console_steal(int handle, void (*fn)(const char *)) +{ + if ( (handle == -1) || (handle != sercon_handle) ) + return 0; + + if ( serial_steal_fn == NULL ) + return -EBUSY; + + serial_steal_fn = fn; + return 1; +} + +void console_giveback(int id) +{ + if ( id == 1 ) + serial_steal_fn = NULL; +} + +static void sercon_puts(const char *s) +{ + if ( serial_steal_fn != NULL ) + (*serial_steal_fn)(s); + else + serial_puts(sercon_handle, s); +} + /* CTRL-<switch_char> switches input direction between Xen and DOM0. */ #define SWITCH_CODE (opt_conswitch[0]-'a'+1) static int xen_rx = 1; /* FALSE => serial input passed to domain 0. */ @@ -191,7 +219,7 @@ static long guest_console_write(XEN_GUES return -EFAULT; kbuf[kcount] = '\0'; - serial_puts(sercon_handle, kbuf); + sercon_puts(kbuf); for ( kptr = kbuf; *kptr != '\0'; kptr++ ) vga_putchar(*kptr); @@ -257,7 +285,7 @@ static inline void __putstr(const char * { int c; - serial_puts(sercon_handle, str); + sercon_puts(str); while ( (c = *str++) != '\0' ) { @@ -448,11 +476,11 @@ static void debugtrace_dump_worker(void) /* Print oldest portion of the ring. */ ASSERT(debugtrace_buf[debugtrace_bytes - 1] == 0); - serial_puts(sercon_handle, &debugtrace_buf[debugtrace_prd]); + sercon_puts(&debugtrace_buf[debugtrace_prd]); /* Print youngest portion of the ring. */ debugtrace_buf[debugtrace_prd] = '\0'; - serial_puts(sercon_handle, &debugtrace_buf[0]); + sercon_puts(&debugtrace_buf[0]); memset(debugtrace_buf, '\0', debugtrace_bytes); diff -r 828c0c89d830 -r 19b126974c1f xen/include/xen/console.h --- a/xen/include/xen/console.h Sat Sep 23 14:07:41 2006 +0100 +++ b/xen/include/xen/console.h Sat Sep 23 14:47:00 2006 +0100 @@ -26,4 +26,13 @@ void console_start_sync(void); void console_start_sync(void); void console_end_sync(void); +/* + * Steal output from the console. Returns +ve identifier, else -ve error. + * Takes the handle of the serial line to steal, and steal callback function. + */ +int console_steal(int handle, void (*fn)(const char *)); + +/* Give back stolen console. Takes the identifier returned by console_steal. */ +void console_giveback(int id); + #endif /* __CONSOLE_H__ */ diff -r 828c0c89d830 -r 19b126974c1f xen/include/xen/gdbstub.h --- a/xen/include/xen/gdbstub.h Sat Sep 23 14:07:41 2006 +0100 +++ b/xen/include/xen/gdbstub.h Sat Sep 23 14:47:00 2006 +0100 @@ -33,7 +33,8 @@ unsigned long str2ulong(const char *str, unsigned long str2ulong(const char *str, unsigned long bytes); struct gdb_context { - int serhnd; + int serhnd; /* handle on our serial line */ + int console_steal_id; /* handle on stolen console */ int currently_attached:1; atomic_t running; unsigned long connected; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |