ia64/xen-unstable

changeset 8607:1b839e1b1de1

Rename cdb to gdbstub and split it into arch dependent/neutral part.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Sat Jan 14 16:58:54 2006 +0100 (2006-01-14)
parents ef88c2db00ad
children d8415ebc8c87
files xen/arch/x86/Makefile xen/arch/x86/gdbstub.c xen/common/Makefile xen/common/gdbstub.c xen/include/asm-x86/debugger.h xen/include/xen/gdbstub.h
line diff
     1.1 --- a/xen/arch/x86/Makefile	Sat Jan 14 10:36:40 2006 +0100
     1.2 +++ b/xen/arch/x86/Makefile	Sat Jan 14 16:58:54 2006 +0100
     1.3 @@ -32,7 +32,7 @@ OBJS := $(subst $(TARGET_SUBARCH)/asm-of
     1.4  OBJS := $(subst $(TARGET_SUBARCH)/xen.lds.o,,$(OBJS))
     1.5  
     1.6  ifneq ($(crash_debug),y)
     1.7 -OBJS := $(patsubst cdb%.o,,$(OBJS))
     1.8 +OBJS := $(patsubst gdbstub%.o,,$(OBJS))
     1.9  endif
    1.10  
    1.11  default: $(TARGET)
     2.1 --- a/xen/arch/x86/cdb.c	Sat Jan 14 10:36:40 2006 +0100
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,414 +0,0 @@
     2.4 -/* Simple hacked-up version of pdb for use in post-mortem debugging of
     2.5 -   Xen and domain 0. This should be a little cleaner, hopefully.  Note
     2.6 -   that we can't share a serial line with PDB. */
     2.7 -/* We try to avoid assuming much about what the rest of the system is
     2.8 -   doing.  In particular, dynamic memory allocation is out of the
     2.9 -   question. */
    2.10 -/* Resuming after we've stopped used to work, but more through luck
    2.11 -   than any actual intention.  It doesn't at the moment. */
    2.12 -#include <xen/lib.h>
    2.13 -#include <asm/uaccess.h>
    2.14 -#include <xen/spinlock.h>
    2.15 -#include <xen/serial.h>
    2.16 -#include <xen/irq.h>
    2.17 -#include <asm/debugger.h>
    2.18 -#include <xen/init.h>
    2.19 -#include <xen/smp.h>
    2.20 -#include <xen/console.h>
    2.21 -#include <asm/apic.h>
    2.22 -
    2.23 -/* Printk isn't particularly safe just after we've trapped to the
    2.24 -   debugger. so avoid it. */
    2.25 -#define dbg_printk(...)
    2.26 -
    2.27 -static char opt_cdb[30] = "none";
    2.28 -string_param("cdb", opt_cdb);
    2.29 -
    2.30 -struct xendbg_context {
    2.31 -	int serhnd;
    2.32 -	u8 reply_csum;
    2.33 -	int currently_attached:1;
    2.34 -};
    2.35 -
    2.36 -/* Like copy_from_user, but safe to call with interrupts disabled.
    2.37 -
    2.38 -   Trust me, and don't look behind the curtain. */
    2.39 -static unsigned
    2.40 -dbg_copy_from_user(void *dest, const void *src, unsigned len)
    2.41 -{
    2.42 -	int __d0, __d1, __d2;
    2.43 -	ASSERT(!local_irq_is_enabled());
    2.44 -	__asm__ __volatile__(
    2.45 -		"1:	rep; movsb\n"
    2.46 -		"2:\n"
    2.47 -		".section .fixup,\"ax\"\n"
    2.48 -		"3:     addl $4, %%esp\n"
    2.49 -		"       jmp 2b\n"
    2.50 -		".previous\n"
    2.51 -		".section __pre_ex_table,\"a\"\n"
    2.52 -		"	.align 4\n"
    2.53 -		"	.long 1b,3b\n"
    2.54 -		".previous\n"
    2.55 -		".section __ex_table,\"a\"\n"
    2.56 -		"	.align 4\n"
    2.57 -		"	.long 1b,2b\n"
    2.58 -		".previous\n"
    2.59 -		: "=c"(__d2), "=D" (__d0), "=S" (__d1)
    2.60 -		: "0"(len), "1"(dest), "2"(src)
    2.61 -		: "memory");
    2.62 -	ASSERT(!local_irq_is_enabled());
    2.63 -	return __d2;
    2.64 -}
    2.65 -
    2.66 -static void
    2.67 -xendbg_put_char(u8 data, struct xendbg_context *ctx)
    2.68 -{
    2.69 -	ctx->reply_csum += data;
    2.70 -	serial_putc(ctx->serhnd, data);
    2.71 -}
    2.72 -
    2.73 -static int
    2.74 -hex_char_val(unsigned char c)
    2.75 -{
    2.76 -	if (c >= '0' && c <= '9')
    2.77 -		return c - '0';
    2.78 -	else if (c >= 'a' && c <= 'f')
    2.79 -		return c - 'a' + 10;
    2.80 -	else if (c >= 'A' && c <= 'F')
    2.81 -		return c - 'A' + 10;
    2.82 -	else
    2.83 -		BUG();
    2.84 -	return -1;
    2.85 -}
    2.86 -
    2.87 -/* Receive a command.  Returns -1 on csum error, 0 otherwise. */
    2.88 -/* Does not acknowledge. */
    2.89 -static int
    2.90 -attempt_receive_packet(char *recv_buf, struct xendbg_context *ctx)
    2.91 -{
    2.92 -	int count;
    2.93 -	u8 csum;
    2.94 -	u8 received_csum;
    2.95 -	u8 ch;
    2.96 -
    2.97 -	/* Skip over everything up to the first '$' */
    2.98 -	while ((ch = serial_getc(ctx->serhnd)) != '$')
    2.99 -		;
   2.100 -	csum = 0;
   2.101 -	for (count = 0; count < 4096; count++) {
   2.102 -		ch = serial_getc(ctx->serhnd);
   2.103 -		if (ch == '#')
   2.104 -			break;
   2.105 -		recv_buf[count] = ch;
   2.106 -		csum += ch;
   2.107 -	}
   2.108 -	if (count == 4096) {
   2.109 -		dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
   2.110 -		return -1;
   2.111 -	}
   2.112 -	recv_buf[count] = 0;
   2.113 -	received_csum = hex_char_val(serial_getc(ctx->serhnd)) * 16 +
   2.114 -		hex_char_val(serial_getc(ctx->serhnd));
   2.115 -	if (received_csum == csum) {
   2.116 -		return 0;
   2.117 -	} else {
   2.118 -		return -1;
   2.119 -	}
   2.120 -}
   2.121 -
   2.122 -/* Send a string of bytes to the debugger. */
   2.123 -static void
   2.124 -xendbg_send(const char *buf, int count, struct xendbg_context *ctx)
   2.125 -{
   2.126 -	int x;
   2.127 -	for (x = 0; x < count; x++)
   2.128 -		xendbg_put_char(buf[x], ctx);
   2.129 -}
   2.130 -
   2.131 -/* Receive a command, discarding up to ten packets with csum
   2.132 - * errors.  Acknowledges all received packets. */
   2.133 -static int
   2.134 -receive_command(char *recv_buf, struct xendbg_context *ctx)
   2.135 -{
   2.136 -	int r;
   2.137 -	int count;
   2.138 -
   2.139 -	count = 0;
   2.140 -	do {
   2.141 -		r = attempt_receive_packet(recv_buf, ctx);
   2.142 -		if (r < 0)
   2.143 -			xendbg_put_char('-', ctx);
   2.144 -		else
   2.145 -			xendbg_put_char('+', ctx);
   2.146 -		count++;
   2.147 -	} while (r < 0 && count < 10);
   2.148 -	return r;
   2.149 -}
   2.150 -
   2.151 -static void
   2.152 -xendbg_start_reply(struct xendbg_context *ctx)
   2.153 -{
   2.154 -	xendbg_put_char('$', ctx);
   2.155 -	ctx->reply_csum = 0;
   2.156 -}
   2.157 -
   2.158 -/* Return 0 if the reply was successfully received, !0 otherwise. */
   2.159 -static int
   2.160 -xendbg_finish_reply(struct xendbg_context *ctx)
   2.161 -{
   2.162 -	char ch;
   2.163 -	char buf[3];
   2.164 -
   2.165 -	sprintf(buf, "%.02x\n", ctx->reply_csum);
   2.166 -
   2.167 -	xendbg_put_char('#', ctx);
   2.168 -	xendbg_send(buf, 2, ctx);
   2.169 -
   2.170 -	ch = serial_getc(ctx->serhnd);
   2.171 -	if (ch == '+')
   2.172 -		return 0;
   2.173 -	else
   2.174 -		return 1;
   2.175 -}
   2.176 -
   2.177 -/* Swap the order of the bytes in a work. */
   2.178 -static inline unsigned
   2.179 -bswab32(unsigned val)
   2.180 -{
   2.181 -	return (((val >> 0) & 0xff) << 24) |
   2.182 -		(((val >> 8) & 0xff) << 16) |
   2.183 -		(((val >> 16) & 0xff) << 8) |
   2.184 -		(((val >> 24) & 0xff) << 0);
   2.185 -}
   2.186 -
   2.187 -static int
   2.188 -handle_memory_read_command(unsigned long addr, unsigned long length,
   2.189 -			   struct xendbg_context *ctx)
   2.190 -{
   2.191 -	int x;
   2.192 -	unsigned char val;
   2.193 -	int r;
   2.194 -	char buf[2];
   2.195 -
   2.196 -	dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
   2.197 -		   length);
   2.198 -	xendbg_start_reply(ctx);
   2.199 -	for (x = 0; x < length; x++) {
   2.200 -		r = dbg_copy_from_user(&val, (void *)(addr + x), 1);
   2.201 -		if (r != 0) {
   2.202 -			dbg_printk("Error reading from %lx.\n", addr + x);
   2.203 -			break;
   2.204 -		}
   2.205 -		sprintf(buf, "%.02x", val);
   2.206 -		xendbg_send(buf, 2, ctx);
   2.207 -	}
   2.208 -	if (x == 0)
   2.209 -		xendbg_send("E05", 3, ctx);
   2.210 -	dbg_printk("Read done.\n");
   2.211 -	return xendbg_finish_reply(ctx);
   2.212 -}
   2.213 -
   2.214 -static int
   2.215 -xendbg_send_reply(const char *buf, struct xendbg_context *ctx)
   2.216 -{
   2.217 -	xendbg_start_reply(ctx);
   2.218 -	xendbg_send(buf, strlen(buf), ctx);
   2.219 -	return xendbg_finish_reply(ctx);
   2.220 -}
   2.221 -
   2.222 -static int
   2.223 -handle_register_read_command(struct cpu_user_regs *regs, struct xendbg_context *ctx)
   2.224 -{
   2.225 -	char buf[121];
   2.226 -
   2.227 -	sprintf(buf,
   2.228 -		"%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x",
   2.229 -		bswab32(regs->eax),
   2.230 -		bswab32(regs->ecx),
   2.231 -		bswab32(regs->edx),
   2.232 -		bswab32(regs->ebx),
   2.233 -		bswab32(regs->esp),
   2.234 -		bswab32(regs->ebp),
   2.235 -		bswab32(regs->esi),
   2.236 -		bswab32(regs->edi),
   2.237 -		bswab32(regs->eip),
   2.238 -		bswab32(regs->eflags),
   2.239 -		bswab32(regs->cs),
   2.240 -		bswab32(regs->ss),
   2.241 -		bswab32(regs->ds),
   2.242 -		bswab32(regs->es),
   2.243 -		bswab32(regs->fs),
   2.244 -		bswab32(regs->gs));
   2.245 -	return xendbg_send_reply(buf, ctx);
   2.246 -}
   2.247 -
   2.248 -static int
   2.249 -process_command(char *received_packet, struct cpu_user_regs *regs,
   2.250 -		struct xendbg_context *ctx)
   2.251 -{
   2.252 -	char *ptr;
   2.253 -	unsigned long addr, length;
   2.254 -	int retry;
   2.255 -	int counter;
   2.256 -	int resume = 0;
   2.257 -
   2.258 -	/* Repeat until gdb acks the reply */
   2.259 -	counter = 0;
   2.260 -	do {
   2.261 -		switch (received_packet[0]) {
   2.262 -		case 'g': /* Read registers */
   2.263 -			retry = handle_register_read_command(regs, ctx);
   2.264 -			ASSERT(!local_irq_is_enabled());
   2.265 -			break;
   2.266 -		case 'm': /* Read memory */
   2.267 -			addr = simple_strtoul(received_packet + 1, &ptr, 16);
   2.268 -			if (ptr == received_packet + 1 ||
   2.269 -			    ptr[0] != ',') {
   2.270 -				xendbg_send_reply("E03", ctx);
   2.271 -				return 0;
   2.272 -			}
   2.273 -			length = simple_strtoul(ptr + 1, &ptr, 16);
   2.274 -			if (ptr[0] != 0) {
   2.275 -				xendbg_send_reply("E04", ctx);
   2.276 -				return 0;
   2.277 -			}
   2.278 -			retry =
   2.279 -				handle_memory_read_command(addr,
   2.280 -							   length,
   2.281 -							   ctx);
   2.282 -			ASSERT(!local_irq_is_enabled());
   2.283 -			break;
   2.284 -		case 'G': /* Write registers */
   2.285 -		case 'M': /* Write memory */
   2.286 -			retry = xendbg_send_reply("E02", ctx);
   2.287 -			break;
   2.288 -		case 'D':
   2.289 -			resume = 1;
   2.290 -			ctx->currently_attached = 0;
   2.291 -			retry = xendbg_send_reply("", ctx);
   2.292 -			break;
   2.293 -		case 'c': /* Resume at current address */
   2.294 -			ctx->currently_attached = 1;
   2.295 -			resume = 1;
   2.296 -			retry = 0;
   2.297 -			break;
   2.298 -		case 'Z': /* We need to claim to support these or gdb
   2.299 -			     won't let you continue the process. */
   2.300 -		case 'z':
   2.301 -			retry = xendbg_send_reply("OK", ctx);
   2.302 -			break;
   2.303 -
   2.304 -		case 's': /* Single step */
   2.305 -		case '?':
   2.306 -			retry = xendbg_send_reply("S01", ctx);
   2.307 -			break;
   2.308 -		default:
   2.309 -			retry = xendbg_send_reply("", ctx);
   2.310 -			break;
   2.311 -		}
   2.312 -		counter++;
   2.313 -	} while (retry == 1 && counter < 10);
   2.314 -	if (retry) {
   2.315 -		dbg_printk("WARNING: gdb disappeared when we were trying to send it a reply.\n");
   2.316 -		return 1;
   2.317 -	}
   2.318 -	return resume;
   2.319 -}
   2.320 -
   2.321 -static struct xendbg_context
   2.322 -xdb_ctx = {
   2.323 -	serhnd : -1
   2.324 -};
   2.325 -
   2.326 -int
   2.327 -__trap_to_cdb(struct cpu_user_regs *regs)
   2.328 -{
   2.329 -	int resume = 0;
   2.330 -	int r;
   2.331 -	static atomic_t xendbg_running = ATOMIC_INIT(1);
   2.332 -	static char recv_buf[4096];
   2.333 -	unsigned flags;
   2.334 -
   2.335 -	if (xdb_ctx.serhnd < 0) {
   2.336 -		dbg_printk("Debugger not ready yet.\n");
   2.337 -		return 0;
   2.338 -	}
   2.339 -
   2.340 -	/* We rely on our caller to ensure we're only on one processor
   2.341 -	 * at a time... We should probably panic here, but given that
   2.342 -	 * we're a debugger we should probably be a little tolerant of
   2.343 -	 * things going wrong. */
   2.344 -	/* We don't want to use a spin lock here, because we're doing
   2.345 -	   two distinct things:
   2.346 -
   2.347 -	   1 -- we don't want to run on more than one processor at a time,
   2.348 -	        and
   2.349 -	   2 -- we want to do something sensible if we re-enter ourselves.
   2.350 -
   2.351 -	   Spin locks are good for 1, but useless for 2. */
   2.352 -	if (!atomic_dec_and_test(&xendbg_running)) {
   2.353 -		printk("WARNING WARNING WARNING: Avoiding recursive xendbg.\n");
   2.354 -		atomic_inc(&xendbg_running);
   2.355 -		return 0;
   2.356 -	}
   2.357 -
   2.358 -	smp_send_stop();
   2.359 -
   2.360 -	/* Try to make things a little more stable by disabling
   2.361 -	   interrupts while we're here. */
   2.362 -	local_irq_save(flags);
   2.363 -
   2.364 -	watchdog_disable();
   2.365 -	console_start_sync();
   2.366 -
   2.367 -	/* Shouldn't really do this, but otherwise we stop for no
   2.368 -	   obvious reason, which is Bad */
   2.369 -	printk("Waiting for GDB to attach to XenDBG\n");
   2.370 -
   2.371 -	/* If gdb is already attached, tell it we've stopped again. */
   2.372 -	if (xdb_ctx.currently_attached) {
   2.373 -		do {
   2.374 -			r = xendbg_send_reply("S01", &xdb_ctx);
   2.375 -		} while (r != 0);
   2.376 -	}
   2.377 -
   2.378 -	while (resume == 0) {
   2.379 -		ASSERT(!local_irq_is_enabled());
   2.380 -		r = receive_command(recv_buf, &xdb_ctx);
   2.381 -		ASSERT(!local_irq_is_enabled());
   2.382 -		if (r < 0) {
   2.383 -			dbg_printk("GDB disappeared, trying to resume Xen...\n");
   2.384 -			resume = 1;
   2.385 -		} else {
   2.386 -			ASSERT(!local_irq_is_enabled());
   2.387 -			resume = process_command(recv_buf, regs, &xdb_ctx);
   2.388 -			ASSERT(!local_irq_is_enabled());
   2.389 -		}
   2.390 -	}
   2.391 -
   2.392 -	console_end_sync();
   2.393 -	watchdog_enable();
   2.394 -	atomic_inc(&xendbg_running);
   2.395 -
   2.396 -	local_irq_restore(flags);
   2.397 -
   2.398 -	return 0;
   2.399 -}
   2.400 -
   2.401 -static int
   2.402 -initialize_xendbg(void)
   2.403 -{
   2.404 -	if (!strcmp(opt_cdb, "none"))
   2.405 -		return 0;
   2.406 -	xdb_ctx.serhnd = serial_parse_handle(opt_cdb);
   2.407 -	if (xdb_ctx.serhnd == -1)
   2.408 -		panic("Can't parse %s as CDB serial info.\n", opt_cdb);
   2.409 -
   2.410 -	/* Acknowledge any spurious GDB packets. */
   2.411 -	xendbg_put_char('+', &xdb_ctx);
   2.412 -
   2.413 -	printk("Xendbg initialised.\n");
   2.414 -	return 0;
   2.415 -}
   2.416 -
   2.417 -__initcall(initialize_xendbg);
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/arch/x86/gdbstub.c	Sat Jan 14 16:58:54 2006 +0100
     3.3 @@ -0,0 +1,146 @@
     3.4 +/*
     3.5 + * x86-specific gdb stub routines
     3.6 + * based on x86 cdb(xen/arch/x86/cdb.c), but Extensively modified.
     3.7 + * 
     3.8 + * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
     3.9 + *                    VA Linux Systems Japan. K.K.
    3.10 + *
    3.11 + * This program is free software; you can redistribute it and/or modify
    3.12 + * it under the terms of the GNU General Public License as published by
    3.13 + * the Free Software Foundation; either version 2 of the License, or
    3.14 + * (at your option) any later version.
    3.15 + * 
    3.16 + * This program is distributed in the hope that it will be useful,
    3.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.19 + * GNU General Public License for more details.
    3.20 + * 
    3.21 + * You should have received a copy of the GNU General Public License
    3.22 + * along with this program; if not, write to the Free Software
    3.23 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    3.24 + */
    3.25 +#include <asm/debugger.h>
    3.26 +
    3.27 +u16
    3.28 +gdb_arch_signal_num(struct cpu_user_regs *regs, unsigned long cookie)
    3.29 +{
    3.30 +    /* XXX */
    3.31 +    return 1;
    3.32 +}
    3.33 +
    3.34 +void 
    3.35 +gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
    3.36 +{
    3.37 +#define GDB_REG(r) gdb_write_to_packet_hex(r, sizeof(r), ctx);
    3.38 +    GDB_REG(regs->eax);
    3.39 +    GDB_REG(regs->ecx);
    3.40 +    GDB_REG(regs->edx);
    3.41 +    GDB_REG(regs->ebx);
    3.42 +    GDB_REG(regs->esp);
    3.43 +    GDB_REG(regs->ebp);
    3.44 +    GDB_REG(regs->esi);
    3.45 +    GDB_REG(regs->edi);
    3.46 +    GDB_REG(regs->eip);
    3.47 +    GDB_REG(regs->eflags);
    3.48 +#undef GDB_REG
    3.49 +#define GDB_SEG_REG(s)  gdb_write_to_packet_hex(s, sizeof(u32), ctx);
    3.50 +    /* sizeof(segment) = 16bit */
    3.51 +    /* but gdb requires its return value as 32bit value */
    3.52 +    GDB_SEG_REG(regs->cs);
    3.53 +    GDB_SEG_REG(regs->ss);
    3.54 +    GDB_SEG_REG(regs->ds);
    3.55 +    GDB_SEG_REG(regs->es);
    3.56 +    GDB_SEG_REG(regs->fs);
    3.57 +    GDB_SEG_REG(regs->gs);
    3.58 +#undef GDB_SEG_REG
    3.59 +    gdb_send_packet(ctx);
    3.60 +}
    3.61 +
    3.62 +void 
    3.63 +gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
    3.64 +                         struct gdb_context *ctx)
    3.65 +{
    3.66 +    /* XXX TODO */
    3.67 +    gdb_send_reply("E02", ctx);
    3.68 +}
    3.69 +
    3.70 +void 
    3.71 +gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
    3.72 +                  struct gdb_context *ctx)
    3.73 +{
    3.74 +    gdb_send_reply("", ctx);
    3.75 +}
    3.76 +
    3.77 +/* Like copy_from_user, but safe to call with interrupts disabled.
    3.78 +   Trust me, and don't look behind the curtain. */
    3.79 +unsigned 
    3.80 +gdb_arch_copy_from_user(void *dest, const void *src, unsigned len)
    3.81 +{
    3.82 +    int __d0, __d1, __d2;
    3.83 +    ASSERT(!local_irq_is_enabled());
    3.84 +    __asm__ __volatile__(
    3.85 +        "1: rep; movsb\n"
    3.86 +        "2:\n"
    3.87 +        ".section .fixup,\"ax\"\n"
    3.88 +        "3:     addl $4, %%esp\n"
    3.89 +        "       jmp 2b\n"
    3.90 +        ".previous\n"
    3.91 +        ".section __pre_ex_table,\"a\"\n"
    3.92 +        "   .align 4\n"
    3.93 +        "   .long 1b,3b\n"
    3.94 +        ".previous\n"
    3.95 +        ".section __ex_table,\"a\"\n"
    3.96 +        "   .align 4\n"
    3.97 +        "   .long 1b,2b\n"
    3.98 +        ".previous\n"
    3.99 +        : "=c"(__d2), "=D" (__d0), "=S" (__d1)
   3.100 +        : "0"(len), "1"(dest), "2"(src)
   3.101 +        : "memory");
   3.102 +    ASSERT(!local_irq_is_enabled());
   3.103 +    return __d2;
   3.104 +}
   3.105 +
   3.106 +unsigned int 
   3.107 +gdb_arch_copy_to_user(void *dest, const void *src, unsigned len)
   3.108 +{
   3.109 +    /* XXX  */
   3.110 +    return len;
   3.111 +}
   3.112 +
   3.113 +void 
   3.114 +gdb_arch_resume(struct cpu_user_regs *regs,
   3.115 +                unsigned long addr, unsigned long type,
   3.116 +                struct gdb_context *ctx)
   3.117 +{
   3.118 +    /* XXX */
   3.119 +    if (type == GDB_STEP) {
   3.120 +        gdb_send_reply("S01", ctx);
   3.121 +    }
   3.122 +}
   3.123 +
   3.124 +void
   3.125 +gdb_arch_print_state(struct cpu_user_regs *regs)
   3.126 +{
   3.127 +    /* XXX */
   3.128 +}
   3.129 +
   3.130 +void
   3.131 +gdb_arch_enter(struct cpu_user_regs *regs)
   3.132 +{
   3.133 +    /* nothing */
   3.134 +}
   3.135 +
   3.136 +void
   3.137 +gdb_arch_exit(struct cpu_user_regs *regs)
   3.138 +{
   3.139 +    /* nothing */
   3.140 +}
   3.141 +
   3.142 +/*
   3.143 + * Local variables:
   3.144 + * mode: C
   3.145 + * c-set-style: "BSD"
   3.146 + * c-basic-offset: 4
   3.147 + * tab-width: 4
   3.148 + * End:
   3.149 + */
     4.1 --- a/xen/common/Makefile	Sat Jan 14 10:36:40 2006 +0100
     4.2 +++ b/xen/common/Makefile	Sat Jan 14 16:58:54 2006 +0100
     4.3 @@ -4,6 +4,9 @@ include $(BASEDIR)/Rules.mk
     4.4  ifneq ($(perfc),y)
     4.5  OBJS := $(subst perfc.o,,$(OBJS))
     4.6  endif
     4.7 +ifneq ($(crash_debug),y)
     4.8 +OBJS := $(patsubst gdbstub.o,,$(OBJS))
     4.9 +endif
    4.10  
    4.11  default: common.o
    4.12  common.o: $(OBJS)
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xen/common/gdbstub.c	Sat Jan 14 16:58:54 2006 +0100
     5.3 @@ -0,0 +1,593 @@
     5.4 +/*
     5.5 + * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
     5.6 + * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
     5.7 + *                    VA Linux Systems Japan. K.K.
     5.8 + * 
     5.9 + * gdbstub arch neutral part
    5.10 + * Based on x86 cdb (xen/arch/x86/cdb.c) and ppc gdbstub(xen/common/gdbstub.c)
    5.11 + * But extensively modified.
    5.12 + *
    5.13 + * This program is free software; you can redistribute it and/or modify
    5.14 + * it under the terms of the GNU General Public License as published by
    5.15 + * the Free Software Foundation; either version 2 of the License, or
    5.16 + * (at your option) any later version.
    5.17 + * 
    5.18 + * This program is distributed in the hope that it will be useful,
    5.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.21 + * GNU General Public License for more details.
    5.22 + * 
    5.23 + * You should have received a copy of the GNU General Public License
    5.24 + * along with this program; if not, write to the Free Software
    5.25 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    5.26 + */
    5.27 +
    5.28 +/*
    5.29 + * gdbstub: implements the architecture independant parts of the
    5.30 + * gdb remote protocol.
    5.31 + */
    5.32 +
    5.33 +/* We try to avoid assuming much about what the rest of the system is
    5.34 +   doing.  In particular, dynamic memory allocation is out of the
    5.35 +   question. */
    5.36 +
    5.37 +/* Resuming after we've stopped used to work, but more through luck
    5.38 +   than any actual intention.  It doesn't at the moment. */
    5.39 +
    5.40 +#include <xen/lib.h>
    5.41 +#include <asm/uaccess.h>
    5.42 +#include <xen/spinlock.h>
    5.43 +#include <xen/serial.h>
    5.44 +#include <xen/irq.h>
    5.45 +#include <asm/debugger.h>
    5.46 +#include <xen/init.h>
    5.47 +#include <xen/smp.h>
    5.48 +#include <xen/console.h>
    5.49 +
    5.50 +/* Printk isn't particularly safe just after we've trapped to the
    5.51 +   debugger. so avoid it. */
    5.52 +#define dbg_printk(...)
    5.53 +/*#define dbg_printk(...)   printk(__VA_ARGS__)*/
    5.54 +
    5.55 +#define GDB_RETRY_MAX   10
    5.56 +
    5.57 +static char opt_gdb[30] = "none";
    5.58 +string_param("gdb", opt_gdb);
    5.59 +
    5.60 +/* value <-> char (de)serialzers */
    5.61 +char
    5.62 +hex2char(unsigned long x)
    5.63 +{
    5.64 +    const char array[] = "0123456789abcdef";
    5.65 +
    5.66 +    return array[x & 15];
    5.67 +}
    5.68 +
    5.69 +int
    5.70 +char2hex(unsigned char c)
    5.71 +{
    5.72 +    if ( (c >= '0') && (c <= '9') )
    5.73 +        return c - '0';
    5.74 +    else if ( (c >= 'a') && (c <= 'f') )
    5.75 +        return c - 'a' + 10;
    5.76 +    else if ( (c >= 'A') && (c <= 'F') )
    5.77 +        return c - 'A' + 10;
    5.78 +    else
    5.79 +        BUG();
    5.80 +    return -1;
    5.81 +}
    5.82 +
    5.83 +char
    5.84 +str2hex(const char *str)
    5.85 +{
    5.86 +    return (char2hex(str[0]) << 4) | char2hex(str[1]);
    5.87 +}
    5.88 +
    5.89 +unsigned long
    5.90 +str2ulong(const char *str, unsigned long bytes)
    5.91 +{
    5.92 +    unsigned long x = 0;
    5.93 +    unsigned long i = 0;
    5.94 +
    5.95 +    while ( *str && (i < (bytes * 2)) )
    5.96 +    {
    5.97 +        x <<= 4;
    5.98 +        x += char2hex(*str);
    5.99 +        ++str;
   5.100 +        ++i;
   5.101 +    }
   5.102 +
   5.103 +    return x;
   5.104 +}
   5.105 +
   5.106 +/* gdb io wrappers */
   5.107 +static signed long
   5.108 +gdb_io_write(const char *buf, unsigned long len, struct gdb_context *ctx)
   5.109 +{
   5.110 +    int i;
   5.111 +    for ( i = 0; i < len; i++ )
   5.112 +        serial_putc(ctx->serhnd, buf[i]);
   5.113 +    return i;
   5.114 +}
   5.115 +
   5.116 +static int
   5.117 +gdb_io_write_char(u8 data, struct gdb_context *ctx)
   5.118 +{
   5.119 +    return gdb_io_write((char*)&data, 1, ctx);
   5.120 +}
   5.121 +
   5.122 +static unsigned char
   5.123 +gdb_io_read(struct gdb_context *ctx)
   5.124 +{
   5.125 +    return serial_getc(ctx->serhnd);
   5.126 +}
   5.127 +
   5.128 +/* Receive a command.  Returns -1 on csum error, 0 otherwise. */
   5.129 +/* Does not acknowledge. */
   5.130 +static int 
   5.131 +attempt_receive_packet(struct gdb_context *ctx)
   5.132 +{
   5.133 +    u8 csum;
   5.134 +    u8 received_csum;
   5.135 +    u8 ch;
   5.136 +
   5.137 +    /* Skip over everything up to the first '$' */
   5.138 +    while ( (ch = gdb_io_read(ctx)) != '$' )
   5.139 +        continue;
   5.140 +
   5.141 +    csum = 0;
   5.142 +    for ( ctx->in_bytes = 0;
   5.143 +          ctx->in_bytes < sizeof(ctx->in_buf);
   5.144 +          ctx->in_bytes++ )
   5.145 +    {
   5.146 +        ch = gdb_io_read(ctx);
   5.147 +        if ( ch == '#' )
   5.148 +            break;
   5.149 +        ctx->in_buf[ctx->in_bytes] = ch;
   5.150 +        csum += ch;
   5.151 +    }
   5.152 +
   5.153 +    if ( ctx->in_bytes == sizeof(ctx->in_buf) )
   5.154 +    {
   5.155 +        dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
   5.156 +        return -1;
   5.157 +    }
   5.158 +
   5.159 +    ctx->in_buf[ctx->in_bytes] = '\0';
   5.160 +    received_csum = char2hex(gdb_io_read(ctx)) * 16 +
   5.161 +        char2hex(gdb_io_read(ctx));
   5.162 +
   5.163 +    return (received_csum == csum) ? 0 : -1;
   5.164 +}
   5.165 +
   5.166 +/* Receive a command, discarding up to ten packets with csum
   5.167 + * errors.  Acknowledges all received packets. */
   5.168 +static int 
   5.169 +receive_command(struct gdb_context *ctx)
   5.170 +{
   5.171 +    int r, count = 0;
   5.172 +
   5.173 +    count = 0;
   5.174 +    do {
   5.175 +        r = attempt_receive_packet(ctx);
   5.176 +        gdb_io_write_char((r < 0) ? '-' : '+', ctx);
   5.177 +        count++;
   5.178 +    } while ( (r < 0) && (count < GDB_RETRY_MAX) );
   5.179 +
   5.180 +    return r;
   5.181 +}
   5.182 +
   5.183 +/* routines to send reply packets */
   5.184 +
   5.185 +static void 
   5.186 +gdb_start_packet(struct gdb_context *ctx)
   5.187 +{
   5.188 +    ctx->out_buf[0] = '$';
   5.189 +    ctx->out_offset = 1;
   5.190 +    ctx->out_csum = 0;
   5.191 +}
   5.192 +
   5.193 +static void 
   5.194 +gdb_write_to_packet_char(u8 data, struct gdb_context *ctx)
   5.195 +{
   5.196 +    ctx->out_csum += data;
   5.197 +    ctx->out_buf[ctx->out_offset] = data;
   5.198 +    ctx->out_offset++;
   5.199 +}
   5.200 +
   5.201 +void 
   5.202 +gdb_write_to_packet(const char *buf, int count, struct gdb_context *ctx)
   5.203 +{
   5.204 +    int x;
   5.205 +    for ( x = 0; x < count; x++ )
   5.206 +        gdb_write_to_packet_char(buf[x], ctx);
   5.207 +}
   5.208 +
   5.209 +void 
   5.210 +gdb_write_to_packet_str(const char *buf, struct gdb_context *ctx)
   5.211 +{
   5.212 +    gdb_write_to_packet(buf, strlen(buf), ctx);
   5.213 +}
   5.214 +
   5.215 +void
   5.216 +gdb_write_to_packet_hex(unsigned long x, int int_size, struct gdb_context *ctx)
   5.217 +{
   5.218 +    char buf[sizeof(unsigned long) * 2 + 1];
   5.219 +    int i = sizeof(unsigned long) * 2;
   5.220 +    int width = int_size * 2;
   5.221 +
   5.222 +    buf[sizeof(unsigned long) * 2] = 0;
   5.223 +
   5.224 +    switch ( int_size )
   5.225 +    {
   5.226 +    case sizeof(u8):
   5.227 +    case sizeof(u16):
   5.228 +    case sizeof(u32):
   5.229 +    case sizeof(u64):
   5.230 +        break;
   5.231 +    default:
   5.232 +        dbg_printk("WARNING: %s x: 0x%lx int_size: %d\n",
   5.233 +                   __func__, x, int_size);
   5.234 +        break;
   5.235 +    }
   5.236 +
   5.237 +    do {
   5.238 +        buf[--i] = hex2char(x & 15);
   5.239 +        x >>= 4;
   5.240 +    } while ( x );
   5.241 +
   5.242 +    while ( (i + width) > (sizeof(unsigned long) * 2) )
   5.243 +        buf[--i] = '0';
   5.244 +
   5.245 +    gdb_write_to_packet(&buf[i], width, ctx);
   5.246 +}
   5.247 +
   5.248 +static int
   5.249 +gdb_check_ack(struct gdb_context *ctx)
   5.250 +{
   5.251 +    u8 c = gdb_io_read(ctx);
   5.252 +
   5.253 +    switch ( c )
   5.254 +    {
   5.255 +    case '+':
   5.256 +        return 1;
   5.257 +    case '-':
   5.258 +        return 0;
   5.259 +    default:
   5.260 +        printk("Bad ack: %c\n", c);
   5.261 +        return 0;
   5.262 +    }
   5.263 +}
   5.264 +
   5.265 +/* Return 0 if the reply was successfully received, !0 otherwise. */
   5.266 +void 
   5.267 +gdb_send_packet(struct gdb_context *ctx)
   5.268 +{
   5.269 +    char buf[3];
   5.270 +    int count;
   5.271 +
   5.272 +    sprintf(buf, "%.02x\n", ctx->out_csum);
   5.273 +
   5.274 +    gdb_write_to_packet_char('#', ctx);
   5.275 +    gdb_write_to_packet(buf, 2, ctx);
   5.276 +
   5.277 +    count = 0;
   5.278 +    do {
   5.279 +        gdb_io_write(ctx->out_buf, ctx->out_offset, ctx);
   5.280 +    } while ( !gdb_check_ack(ctx) && (count++ < GDB_RETRY_MAX) );
   5.281 +
   5.282 +    if ( count == GDB_RETRY_MAX )
   5.283 +        dbg_printk("WARNING: %s reached max retry %d\n",
   5.284 +                   __func__, GDB_RETRY_MAX);
   5.285 +}
   5.286 +
   5.287 +void 
   5.288 +gdb_send_reply(const char *buf, struct gdb_context *ctx)
   5.289 +{
   5.290 +    gdb_start_packet(ctx);
   5.291 +    gdb_write_to_packet_str(buf, ctx);
   5.292 +    gdb_send_packet(ctx);
   5.293 +}
   5.294 +
   5.295 +/* arch neutral command handlers */
   5.296 +
   5.297 +static void 
   5.298 +gdb_cmd_signum(struct gdb_context *ctx)
   5.299 +{
   5.300 +    gdb_write_to_packet_char('S', ctx);
   5.301 +    gdb_write_to_packet_hex(ctx->signum, sizeof(ctx->signum), ctx);
   5.302 +    gdb_send_packet(ctx);
   5.303 +}
   5.304 +
   5.305 +static void 
   5.306 +gdb_cmd_read_mem(unsigned long addr, unsigned long length,
   5.307 +                 struct gdb_context *ctx)
   5.308 +{
   5.309 +    int x, r;
   5.310 +    unsigned char val;
   5.311 +
   5.312 +    dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
   5.313 +               length);
   5.314 +
   5.315 +    for ( x = 0; x < length; x++ )
   5.316 +    {
   5.317 +        r = gdb_arch_copy_from_user(&val, (void *)(addr + x), 1);
   5.318 +        if ( r != 0 )
   5.319 +        {
   5.320 +            dbg_printk("Error reading from %lx.\n", addr + x);
   5.321 +            break;
   5.322 +        }
   5.323 +        gdb_write_to_packet_hex(val, sizeof(val), ctx);
   5.324 +    }
   5.325 +
   5.326 +    if ( x == 0 )
   5.327 +        gdb_write_to_packet_str("E05", ctx);
   5.328 +
   5.329 +    dbg_printk("Read done.\n");
   5.330 +
   5.331 +    gdb_send_packet(ctx);
   5.332 +}
   5.333 +
   5.334 +static void 
   5.335 +gdb_cmd_write_mem(unsigned long addr, unsigned long length,
   5.336 +                  const char *buf, struct gdb_context *ctx)
   5.337 +{
   5.338 +    int x, r;
   5.339 +    unsigned char val;
   5.340 +
   5.341 +    dbg_printk("Memory write starting at %lx, length %lx.\n", addr, length);
   5.342 +
   5.343 +    for ( x = 0; x < length; x++, addr++, buf += 2 )
   5.344 +    {
   5.345 +        val = str2ulong(buf, sizeof(val));
   5.346 +        r = gdb_arch_copy_to_user((void*)addr, (void*)&val, 1);
   5.347 +        if ( r != 0 )
   5.348 +        {
   5.349 +            dbg_printk("Error writing to %lx.\n", addr);
   5.350 +            break;
   5.351 +        }
   5.352 +    }
   5.353 +
   5.354 +    gdb_write_to_packet_str((x != length) ? "OK" : "E11", ctx);
   5.355 +
   5.356 +    dbg_printk("Write done.\n");
   5.357 +
   5.358 +    gdb_send_packet(ctx);
   5.359 +}
   5.360 +
   5.361 +/* command dispatcher */
   5.362 +static int 
   5.363 +process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
   5.364 +{
   5.365 +    char *ptr;
   5.366 +    unsigned long addr, length;
   5.367 +    int resume = 0;
   5.368 +
   5.369 +    /* XXX check ctx->in_bytes >= 2 or similar. */
   5.370 +
   5.371 +    gdb_start_packet(ctx);
   5.372 +    switch ( ctx->in_buf[0] )
   5.373 +    {
   5.374 +    case '?':    /* query signal number */
   5.375 +        gdb_cmd_signum(ctx);
   5.376 +        break;
   5.377 +    case 'H':    /* thread operations */
   5.378 +        gdb_send_reply("OK", ctx);
   5.379 +        break;
   5.380 +    case 'g': /* Read registers */
   5.381 +        gdb_arch_read_reg_array(regs, ctx);
   5.382 +        ASSERT(!local_irq_is_enabled());
   5.383 +        break;
   5.384 +    case 'G': /* Write registers */
   5.385 +        gdb_arch_write_reg_array(regs, ctx->in_buf + 1, ctx);
   5.386 +        break;
   5.387 +    case 'm': /* Read memory */
   5.388 +        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
   5.389 +        if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
   5.390 +        {
   5.391 +            gdb_send_reply("E03", ctx);
   5.392 +            return 0;
   5.393 +        }
   5.394 +        length = simple_strtoul(ptr + 1, &ptr, 16);
   5.395 +        if ( ptr[0] != 0 )
   5.396 +        {
   5.397 +            gdb_send_reply("E04", ctx);
   5.398 +            return 0;
   5.399 +        }
   5.400 +        gdb_cmd_read_mem(addr, length, ctx);
   5.401 +        ASSERT(!local_irq_is_enabled());
   5.402 +        break;
   5.403 +    case 'M': /* Write memory */
   5.404 +        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
   5.405 +        if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ':') )
   5.406 +        {
   5.407 +            gdb_send_reply("E03", ctx);
   5.408 +            return 0;
   5.409 +        }
   5.410 +        length = simple_strtoul(ptr + 1, &ptr, 16);
   5.411 +        gdb_cmd_write_mem(addr, length, ptr, ctx);
   5.412 +        break;
   5.413 +    case 'p': /* read register */
   5.414 +        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
   5.415 +        if ( ptr == (ctx->in_buf + 1) )
   5.416 +        {
   5.417 +            gdb_send_reply("E03", ctx);
   5.418 +            return 0;
   5.419 +        }
   5.420 +        if ( ptr[0] != 0 )
   5.421 +        {
   5.422 +            gdb_send_reply("E04", ctx);
   5.423 +            return 0;
   5.424 +        }
   5.425 +        gdb_arch_read_reg(addr, regs, ctx);
   5.426 +        break;
   5.427 +    case 'Z': /* We need to claim to support these or gdb
   5.428 +                 won't let you continue the process. */
   5.429 +    case 'z':
   5.430 +        gdb_send_reply("OK", ctx);
   5.431 +        break;
   5.432 +
   5.433 +    case 'D':
   5.434 +        ctx->currently_attached = 0;
   5.435 +        gdb_send_reply("OK", ctx);
   5.436 +        /* fall through */
   5.437 +    case 'k':
   5.438 +        ctx->connected = 0;
   5.439 +        /* fall through */
   5.440 +    case 's': /* Single step */
   5.441 +    case 'c': /* Resume at current address */
   5.442 +    {
   5.443 +        unsigned long addr = ~((unsigned long)0);
   5.444 +        unsigned long type = GDB_CONTINUE;
   5.445 +        if ( ctx->in_buf[0] == 's' )
   5.446 +            type = GDB_STEP;
   5.447 +        if ( ((ctx->in_buf[0] == 's') || (ctx->in_buf[0] == 'c')) &&
   5.448 +             ctx->in_buf[1] )
   5.449 +            addr = str2ulong(&ctx->in_buf[1], sizeof(unsigned long));
   5.450 +        if ( ctx->in_buf[0] != 'D' )
   5.451 +            ctx->currently_attached = 1;
   5.452 +        resume = 1;
   5.453 +        gdb_arch_resume(regs, addr, type, ctx);
   5.454 +        break;
   5.455 +    }
   5.456 +
   5.457 +    default:
   5.458 +        gdb_send_reply("", ctx);
   5.459 +        break;
   5.460 +    }
   5.461 +    return resume;
   5.462 +}
   5.463 +
   5.464 +static struct gdb_context
   5.465 +__gdb_ctx = {
   5.466 +    .serhnd             = -1,
   5.467 +    .currently_attached = 0,
   5.468 +    .running            = ATOMIC_INIT(1),
   5.469 +    .connected          = 0,
   5.470 +    .signum             = 1,
   5.471 +    .in_bytes           = 0,
   5.472 +    .out_offset         = 0,
   5.473 +    .out_csum           = 0,
   5.474 +};
   5.475 +static struct gdb_context *gdb_ctx = &__gdb_ctx;
   5.476 +
   5.477 +/* trap handler: main entry point */
   5.478 +int 
   5.479 +__trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
   5.480 +{
   5.481 +    int resume = 0;
   5.482 +    int r;
   5.483 +    unsigned flags;
   5.484 +
   5.485 +    if ( gdb_ctx->serhnd < 0 )
   5.486 +    {
   5.487 +        dbg_printk("Debugger not ready yet.\n");
   5.488 +        return 0;
   5.489 +    }
   5.490 +
   5.491 +    /* We rely on our caller to ensure we're only on one processor
   5.492 +     * at a time... We should probably panic here, but given that
   5.493 +     * we're a debugger we should probably be a little tolerant of
   5.494 +     * things going wrong. */
   5.495 +    /* We don't want to use a spin lock here, because we're doing
   5.496 +       two distinct things:
   5.497 +
   5.498 +       1 -- we don't want to run on more than one processor at a time,
   5.499 +            and
   5.500 +       2 -- we want to do something sensible if we re-enter ourselves.
   5.501 +
   5.502 +       Spin locks are good for 1, but useless for 2. */
   5.503 +    if ( !atomic_dec_and_test(&gdb_ctx->running) )
   5.504 +    {
   5.505 +        printk("WARNING WARNING WARNING: Avoiding recursive gdb.\n");
   5.506 +        atomic_inc(&gdb_ctx->running);
   5.507 +        return 0;
   5.508 +    }
   5.509 +
   5.510 +    if ( !gdb_ctx->connected )
   5.511 +    {
   5.512 +        printk("GDB connection activated\n");
   5.513 +        gdb_arch_print_state(regs);
   5.514 +        gdb_ctx->connected = 1;
   5.515 +    }
   5.516 +
   5.517 +    smp_send_stop();
   5.518 +
   5.519 +    /* Try to make things a little more stable by disabling
   5.520 +       interrupts while we're here. */
   5.521 +    local_irq_save(flags);
   5.522 +
   5.523 +    watchdog_disable();
   5.524 +    console_start_sync();
   5.525 +
   5.526 +    /* Shouldn't really do this, but otherwise we stop for no
   5.527 +       obvious reason, which is Bad */
   5.528 +    printk("Waiting for GDB to attach to Gdb\n");
   5.529 +
   5.530 +    gdb_arch_enter(regs);
   5.531 +    gdb_ctx->signum = gdb_arch_signal_num(regs, cookie);
   5.532 +    /* If gdb is already attached, tell it we've stopped again. */
   5.533 +    if ( gdb_ctx->currently_attached )
   5.534 +    {
   5.535 +        gdb_start_packet(gdb_ctx);
   5.536 +        gdb_cmd_signum(gdb_ctx);
   5.537 +    }
   5.538 +
   5.539 +    while ( resume == 0 )
   5.540 +    {
   5.541 +        ASSERT(!local_irq_is_enabled());
   5.542 +        r = receive_command(gdb_ctx);
   5.543 +        ASSERT(!local_irq_is_enabled());
   5.544 +        if ( r < 0 )
   5.545 +        {
   5.546 +            dbg_printk("GDB disappeared, trying to resume Xen...\n");
   5.547 +            resume = 1;
   5.548 +        }
   5.549 +        else
   5.550 +        {
   5.551 +            ASSERT(!local_irq_is_enabled());
   5.552 +            resume = process_command(regs, gdb_ctx);
   5.553 +            ASSERT(!local_irq_is_enabled());
   5.554 +        }
   5.555 +    }
   5.556 +
   5.557 +    gdb_arch_exit(regs);
   5.558 +    console_end_sync();
   5.559 +    watchdog_enable();
   5.560 +    atomic_inc(&gdb_ctx->running);
   5.561 +
   5.562 +    local_irq_restore(flags);
   5.563 +
   5.564 +    return 0;
   5.565 +}
   5.566 +
   5.567 +/*
   5.568 + * initialization
   5.569 + * XXX TODO
   5.570 + *     This should be an explicit call from architecture code.               
   5.571 + *     initcall is far too late for some early debugging, and only the 
   5.572 + *     architecture code knows when this call can be made.          
   5.573 + */
   5.574 +static int
   5.575 +initialize_gdb(void)
   5.576 +{
   5.577 +    if ( !strcmp(opt_gdb, "none") )
   5.578 +        return 0;
   5.579 +    gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
   5.580 +    if ( gdb_ctx->serhnd == -1 )
   5.581 +        panic("Can't parse %s as GDB serial info.\n", opt_gdb);
   5.582 +
   5.583 +    printk("Gdb initialised.\n");
   5.584 +    return 0;
   5.585 +}
   5.586 +
   5.587 +__initcall(initialize_gdb);
   5.588 +
   5.589 +/*
   5.590 + * Local variables:
   5.591 + * mode: C
   5.592 + * c-set-style: "BSD"
   5.593 + * c-basic-offset: 4
   5.594 + * tab-width: 4
   5.595 + * End:
   5.596 + */
     6.1 --- a/xen/include/asm-x86/debugger.h	Sat Jan 14 10:36:40 2006 +0100
     6.2 +++ b/xen/include/asm-x86/debugger.h	Sat Jan 14 16:58:54 2006 +0100
     6.3 @@ -42,19 +42,19 @@
     6.4  
     6.5  #if defined(CRASH_DEBUG)
     6.6  
     6.7 -extern int __trap_to_cdb(struct cpu_user_regs *r);
     6.8 +#include <xen/gdbstub.h>
     6.9  
    6.10  #define __debugger_trap_entry(_v, _r) (0)
    6.11  
    6.12  static inline int __debugger_trap_fatal(
    6.13      unsigned int vector, struct cpu_user_regs *regs)
    6.14  {
    6.15 -    (void)__trap_to_cdb(regs);
    6.16 +    (void)__trap_to_gdb(regs, vector);
    6.17      return (vector == TRAP_int3); /* int3 is harmless */
    6.18  }
    6.19  
    6.20  /* Int3 is a trivial way to gather cpu_user_regs context. */
    6.21 -#define __debugger_trap_immediate() __asm__ __volatile__ ( "int3" );
    6.22 +#define debugger_trap_immediate() __asm__ __volatile__ ( "int3" );
    6.23  
    6.24  #elif 0
    6.25  
    6.26 @@ -73,7 +73,7 @@ static inline int __debugger_trap_fatal(
    6.27  }
    6.28  
    6.29  /* Int3 is a trivial way to gather cpu_user_regs context. */
    6.30 -#define __debugger_trap_immediate() __asm__ __volatile__ ( "int3" )
    6.31 +#define debugger_trap_immediate() __asm__ __volatile__ ( "int3" )
    6.32  
    6.33  #else
    6.34  
    6.35 @@ -100,6 +100,8 @@ static inline int debugger_trap_entry(
    6.36  }
    6.37  
    6.38  #define debugger_trap_fatal(v, r) (__debugger_trap_fatal(v, r))
    6.39 +#ifndef debugger_trap_immediate
    6.40  #define debugger_trap_immediate() (__debugger_trap_immediate())
    6.41 +#endif
    6.42  
    6.43  #endif /* __X86_DEBUGGER_H__ */
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/xen/include/xen/gdbstub.h	Sat Jan 14 16:58:54 2006 +0100
     7.3 @@ -0,0 +1,96 @@
     7.4 +/*
     7.5 + * Copyright (C) 2005 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation
     7.6 + * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
     7.7 + *                    VA Linux Systems Japan. K.K.
     7.8 + *
     7.9 + * This program is free software; you can redistribute it and/or modify
    7.10 + * it under the terms of the GNU General Public License as published by
    7.11 + * the Free Software Foundation; either version 2 of the License, or
    7.12 + * (at your option) any later version.
    7.13 + * 
    7.14 + * This program is distributed in the hope that it will be useful,
    7.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.17 + * GNU General Public License for more details.
    7.18 + * 
    7.19 + * You should have received a copy of the GNU General Public License
    7.20 + * along with this program; if not, write to the Free Software
    7.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    7.22 + */
    7.23 +
    7.24 +#ifndef __XEN_GDBSTUB_H__
    7.25 +#define __XEN_GDBSTUB_H__
    7.26 +
    7.27 +/* value <-> char (de)serialzers for arch specific gdb backends */
    7.28 +char hex2char(unsigned long x); 
    7.29 +int char2hex(unsigned char c); 
    7.30 +char str2hex(const char *str); 
    7.31 +unsigned long str2ulong(const char *str, unsigned long bytes); 
    7.32 +
    7.33 +struct gdb_context {
    7.34 +    int                 serhnd;
    7.35 +    int                 currently_attached:1;
    7.36 +    atomic_t            running;
    7.37 +    unsigned long       connected;
    7.38 +    u8                  signum;
    7.39 +
    7.40 +    char                in_buf[PAGE_SIZE];
    7.41 +    unsigned long       in_bytes;
    7.42 +
    7.43 +    char                out_buf[PAGE_SIZE];
    7.44 +    unsigned long       out_offset;
    7.45 +    u8                  out_csum;
    7.46 +};
    7.47 +
    7.48 +/* interface to arch specific routines */
    7.49 +void gdb_write_to_packet(
    7.50 +    const char *buf, int count, struct gdb_context *ctx);
    7.51 +void gdb_write_to_packet_hex(
    7.52 +    unsigned long x, int int_size, struct gdb_context *ctx);
    7.53 +void gdb_send_packet(struct gdb_context *ctx); 
    7.54 +void gdb_send_reply(const char *buf, struct gdb_context *ctx);
    7.55 +
    7.56 +/* gdb stub trap handler: entry point */
    7.57 +int __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie);
    7.58 +
    7.59 +/* arch specific routines */
    7.60 +u16 gdb_arch_signal_num(
    7.61 +    struct cpu_user_regs *regs, unsigned long cookie);
    7.62 +void gdb_arch_read_reg_array(
    7.63 +    struct cpu_user_regs *regs, struct gdb_context *ctx);
    7.64 +void gdb_arch_write_reg_array(
    7.65 +    struct cpu_user_regs *regs, const char* buf, struct gdb_context *ctx);
    7.66 +void gdb_arch_read_reg(
    7.67 +    unsigned long regnum, struct cpu_user_regs *regs, struct gdb_context *ctx);
    7.68 +unsigned int gdb_arch_copy_from_user(
    7.69 +    void *dest, const void *src, unsigned len);
    7.70 +unsigned int gdb_arch_copy_to_user(
    7.71 +    void *dest, const void *src, unsigned len);
    7.72 +void gdb_arch_resume(
    7.73 +    struct cpu_user_regs *regs, unsigned long addr,
    7.74 +    unsigned long type, struct gdb_context *ctx);
    7.75 +void gdb_arch_print_state(struct cpu_user_regs *regs);
    7.76 +void gdb_arch_enter(struct cpu_user_regs *regs);
    7.77 +void gdb_arch_exit(struct cpu_user_regs *regs);
    7.78 +
    7.79 +#define GDB_CONTINUE     0
    7.80 +#define GDB_STEP         1
    7.81 +
    7.82 +#define SIGILL           4
    7.83 +#define SIGTRAP          5
    7.84 +#define SIGBUS           7
    7.85 +#define SIGFPE           8
    7.86 +#define SIGSEGV         11
    7.87 +#define SIGALRM         14
    7.88 +#define SIGTERM         15
    7.89 +
    7.90 +#endif /* __XEN_GDBSTUB_H__ */
    7.91 +
    7.92 +/*
    7.93 + * Local variables:
    7.94 + * mode: C
    7.95 + * c-set-style: "BSD"
    7.96 + * c-basic-offset: 4
    7.97 + * tab-width: 4
    7.98 + * End:
    7.99 + */