ia64/xen-unstable

changeset 3763:415d774d6ee7

bitkeeper revision 1.1162 (420b71f6yarVsHEUH8wBvGFgIVSTBQ)

Re-sanify after merge.
author sos22@douglas.cl.cam.ac.uk
date Thu Feb 10 14:38:46 2005 +0000 (2005-02-10)
parents 0a4b76b6b5a0
children 3cb679ee7d62
files .rootkeys xen/Rules.mk xen/arch/x86/Makefile xen/arch/x86/cdb.c xen/arch/x86/x86_32/cdb_trap.S xen/arch/x86/x86_32/xdb_trap.S xen/arch/x86/xdb.c xen/common/domain.c xen/common/keyhandler.c xen/drivers/char/console.c xen/include/asm-x86/debugger.h
line diff
     1.1 --- a/.rootkeys	Thu Feb 10 13:17:10 2005 +0000
     1.2 +++ b/.rootkeys	Thu Feb 10 14:38:46 2005 +0000
     1.3 @@ -881,6 +881,7 @@ 3ddb79bcsjinG9k1KcvbVBuas1R2dA xen/arch/
     1.4  3ddb79c4yGZ7_22QAFFwPzqP4NSHwA xen/arch/x86/boot/mkelf32.c
     1.5  3ddb79bcSC_LvnmFlX-T5iTgaR0SKg xen/arch/x86/boot/x86_32.S
     1.6  40e42bdbNu4MjI750THP_8J1S-Sa0g xen/arch/x86/boot/x86_64.S
     1.7 +4107c15e-VmEcLsE-7JCXZaabI8C7A xen/arch/x86/cdb.c
     1.8  3ddb79bcUrk2EIaM5VsT6wUudH1kkg xen/arch/x86/delay.c
     1.9  40e34414WiQO4h2m3tcpaCPn7SyYyg xen/arch/x86/dom0_ops.c
    1.10  3ddb79bc1_2bAt67x9MFCP4AZrQnvQ xen/arch/x86/domain.c
    1.11 @@ -921,6 +922,7 @@ 41c0c411ODt8uEmV-yUxpQLpqimE5Q xen/arch/
    1.12  41f97ef5139vN42cOYHfX_Ac8WOOjA xen/arch/x86/vmx_platform.c
    1.13  41c0c4128URE0dxcO15JME_MuKBPfg xen/arch/x86/vmx_vmcs.c
    1.14  419cbedeQDg8IrO3izo3o5rQNlo0kQ xen/arch/x86/x86_32/asm-offsets.c
    1.15 +4107c15e_NqNYew2EXroXz2mgTAMWQ xen/arch/x86/x86_32/cdb_trap.S
    1.16  4202391dkvdTZ8GhWXe3Gqf9EOgWXg xen/arch/x86/x86_32/domain_build.c
    1.17  3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen/arch/x86/x86_32/domain_page.c
    1.18  3ddb79bcecupHj56ZbTa3B0FxDowMg xen/arch/x86/x86_32/entry.S
    1.19 @@ -928,7 +930,6 @@ 3ddb79bcHwuCQDjBICDTSis52hWguw xen/arch/
    1.20  40f92331jfOlE7MfKwpdkEb1CEf23g xen/arch/x86/x86_32/seg_fixup.c
    1.21  42000d3ckiFc1qxa4AWqsd0t3lxuyw xen/arch/x86/x86_32/traps.c
    1.22  3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/x86/x86_32/usercopy.c
    1.23 -4107c15e_NqNYew2EXroXz2mgTAMWQ xen/arch/x86/x86_32/xdb_trap.S
    1.24  3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/x86/x86_32/xen.lds
    1.25  41bf1717Ty3hwN3E9swdu8QfnvGqww xen/arch/x86/x86_64/asm-offsets.c
    1.26  4202391dA91ZovYX9d_5zJi9yGvLoQ xen/arch/x86/x86_64/domain_build.c
    1.27 @@ -937,7 +938,6 @@ 41bf1717XhPz_dNT5OKSjgmbFuWBuA xen/arch/
    1.28  42000d3cMb8o1WuFBXC07c8i3lPZBw xen/arch/x86/x86_64/traps.c
    1.29  40e96d3ahBTZqbTViInnq0lM03vs7A xen/arch/x86/x86_64/usercopy.c
    1.30  40e96d3akN3Hu_J5Bk-WXD8OGscrYQ xen/arch/x86/x86_64/xen.lds
    1.31 -4107c15e-VmEcLsE-7JCXZaabI8C7A xen/arch/x86/xdb.c
    1.32  3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile
    1.33  3e397e66AyyD5fYraAySWuwi9uqSXg xen/common/ac_timer.c
    1.34  3ddb79bdLX_P6iB7ILiblRLWvebapg xen/common/dom0_ops.c
     2.1 --- a/xen/Rules.mk	Thu Feb 10 13:17:10 2005 +0000
     2.2 +++ b/xen/Rules.mk	Thu Feb 10 14:38:46 2005 +0000
     2.3 @@ -5,6 +5,7 @@ debugger    ?= n
     2.4  perfc       ?= n
     2.5  trace       ?= n
     2.6  optimize    ?= y
     2.7 +crash_debug ?= n
     2.8  
     2.9  # Currently supported architectures: x86_32, x86_64
    2.10  COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
    2.11 @@ -54,8 +55,11 @@ else
    2.12  CFLAGS += -DVERBOSE
    2.13  endif
    2.14  
    2.15 -ifeq ($(gdb_stub),y)
    2.16 -CFLAGS += -g
    2.17 +ifeq ($(crash_debug),y)
    2.18 +CFLAGS += -g -DCRASH_DEBUG
    2.19 +ifeq ($(debugger),y)
    2.20 +error Crash debugger conflicts with PDB
    2.21 +endif
    2.22  endif
    2.23  
    2.24  ifeq ($(perfc),y)
     3.1 --- a/xen/arch/x86/Makefile	Thu Feb 10 13:17:10 2005 +0000
     3.2 +++ b/xen/arch/x86/Makefile	Thu Feb 10 14:38:46 2005 +0000
     3.3 @@ -11,6 +11,10 @@ ifneq ($(TARGET_SUBARCH),x86_32)
     3.4  OBJS := $(patsubst vmx%.o,,$(OBJS))
     3.5  endif
     3.6  
     3.7 +ifneq ($(crash_debug),y)
     3.8 +OBJS := $(subst cdb%.o,,$(OBJS))
     3.9 +endif
    3.10 +
    3.11  default: $(TARGET)
    3.12  
    3.13  $(TARGET): $(TARGET)-syms boot/mkelf32
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/arch/x86/cdb.c	Thu Feb 10 14:38:46 2005 +0000
     4.3 @@ -0,0 +1,357 @@
     4.4 +/* Simple hacked-up version of pdb for use in post-mortem debugging of
     4.5 +   Xen and domain 0. This should be a little cleaner, hopefully.  Note
     4.6 +   that we can't share a serial line with PDB. */
     4.7 +/* We try to avoid assuming much about what the rest of the system is
     4.8 +   doing.  In particular, dynamic memory allocation is out of the
     4.9 +   question. */
    4.10 +#include <xen/lib.h>
    4.11 +#include <asm/uaccess.h>
    4.12 +#include <xen/serial.h>
    4.13 +#include <asm/irq.h>
    4.14 +#include <xen/spinlock.h>
    4.15 +#include <asm/debugger.h>
    4.16 +
    4.17 +/* Printk isn't particularly safe just after we've trapped to the
    4.18 +   debugger. so avoid it. */
    4.19 +#define dbg_printk(...)
    4.20 +
    4.21 +static unsigned char opt_cdb[30] = "none";
    4.22 +string_param("cdb", opt_cdb);
    4.23 +
    4.24 +struct xendbg_context {
    4.25 +	int serhnd;
    4.26 +	u8 reply_csum;
    4.27 +	int currently_attached:1;
    4.28 +};
    4.29 +
    4.30 +static void
    4.31 +xendbg_put_char(u8 data, struct xendbg_context *ctx)
    4.32 +{
    4.33 +	ctx->reply_csum += data;
    4.34 +	serial_putc(ctx->serhnd, data);
    4.35 +}
    4.36 +
    4.37 +static int
    4.38 +hex_char_val(unsigned char c)
    4.39 +{
    4.40 +	if (c >= '0' && c <= '9')
    4.41 +		return c - '0';
    4.42 +	else if (c >= 'a' && c <= 'f')
    4.43 +		return c - 'a' + 10;
    4.44 +	else if (c >= 'A' && c <= 'F')
    4.45 +		return c - 'A' + 10;
    4.46 +	else
    4.47 +		BUG();
    4.48 +	return -1;
    4.49 +}
    4.50 +
    4.51 +/* Receive a command.  Returns -1 on csum error, 0 otherwise. */
    4.52 +/* Does not acknowledge. */
    4.53 +static int
    4.54 +attempt_receive_packet(char *recv_buf, struct xendbg_context *ctx)
    4.55 +{
    4.56 +	int count;
    4.57 +	u8 csum;
    4.58 +	u8 received_csum;
    4.59 +	u8 ch;
    4.60 +
    4.61 +	/* Skip over everything up to the first '$' */
    4.62 +	while ((ch = irq_serial_getc(ctx->serhnd)) != '$')
    4.63 +		;
    4.64 +	csum = 0;
    4.65 +	for (count = 0; count < 4096; count++) {
    4.66 +		ch = irq_serial_getc(ctx->serhnd);
    4.67 +		if (ch == '#')
    4.68 +			break;
    4.69 +		recv_buf[count] = ch;
    4.70 +		csum += ch;
    4.71 +	}
    4.72 +	if (count == 4096) {
    4.73 +		dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
    4.74 +		return -1;
    4.75 +	}
    4.76 +	recv_buf[count] = 0;
    4.77 +	received_csum = hex_char_val(irq_serial_getc(ctx->serhnd)) * 16 +
    4.78 +		hex_char_val(irq_serial_getc(ctx->serhnd));
    4.79 +	if (received_csum == csum) {
    4.80 +		return 0;
    4.81 +	} else {
    4.82 +		return -1;
    4.83 +	}
    4.84 +}
    4.85 +
    4.86 +/* Send a string of bytes to the debugger. */
    4.87 +static void
    4.88 +xendbg_send(const char *buf, int count, struct xendbg_context *ctx)
    4.89 +{
    4.90 +	int x;
    4.91 +	for (x = 0; x < count; x++)
    4.92 +		xendbg_put_char(buf[x], ctx);
    4.93 +}
    4.94 +
    4.95 +/* Receive a command, discarding up to ten packets with csum
    4.96 + * errors.  Acknowledges all received packets. */
    4.97 +static int
    4.98 +receive_command(char *recv_buf, struct xendbg_context *ctx)
    4.99 +{
   4.100 +	int r;
   4.101 +	int count;
   4.102 +
   4.103 +	count = 0;
   4.104 +	do {
   4.105 +		r = attempt_receive_packet(recv_buf, ctx);
   4.106 +		if (r < 0)
   4.107 +			xendbg_put_char('-', ctx);
   4.108 +		else
   4.109 +			xendbg_put_char('+', ctx);
   4.110 +		count++;
   4.111 +	} while (r < 0 && count < 10);
   4.112 +	return r;
   4.113 +}
   4.114 +
   4.115 +static void
   4.116 +xendbg_start_reply(struct xendbg_context *ctx)
   4.117 +{
   4.118 +	xendbg_put_char('$', ctx);
   4.119 +	ctx->reply_csum = 0;
   4.120 +}
   4.121 +
   4.122 +/* Return 0 if the reply was successfully received, !0 otherwise. */
   4.123 +static int
   4.124 +xendbg_finish_reply(struct xendbg_context *ctx)
   4.125 +{
   4.126 +	char ch;
   4.127 +	char buf[3];
   4.128 +
   4.129 +	sprintf(buf, "%.02x\n", ctx->reply_csum);
   4.130 +
   4.131 +	xendbg_put_char('#', ctx);
   4.132 +	xendbg_send(buf, 2, ctx);
   4.133 +
   4.134 +	ch = irq_serial_getc(ctx->serhnd);
   4.135 +	if (ch == '+')
   4.136 +		return 0;
   4.137 +	else
   4.138 +		return 1;
   4.139 +}
   4.140 +
   4.141 +/* Swap the order of the bytes in a work. */
   4.142 +static inline unsigned
   4.143 +bswab32(unsigned val)
   4.144 +{
   4.145 +	return (((val >> 0) & 0xff) << 24) |
   4.146 +		(((val >> 8) & 0xff) << 16) |
   4.147 +		(((val >> 16) & 0xff) << 8) |
   4.148 +		(((val >> 24) & 0xff) << 0);
   4.149 +}
   4.150 +
   4.151 +static int
   4.152 +handle_memory_read_command(unsigned long addr, unsigned long length,
   4.153 +			   struct xendbg_context *ctx)
   4.154 +{
   4.155 +	int x;
   4.156 +	unsigned char val;
   4.157 +	int r;
   4.158 +	char buf[2];
   4.159 +
   4.160 +	dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
   4.161 +		   length);
   4.162 +	xendbg_start_reply(ctx);
   4.163 +	for (x = 0; x < length; x++) {
   4.164 +		r = __copy_from_user(&val, (void *)(addr + x), 1);
   4.165 +		if (r != 0) {
   4.166 +			dbg_printk("Error reading from %lx.\n", addr + x);
   4.167 +			break;
   4.168 +		}
   4.169 +		sprintf(buf, "%.02x", val);
   4.170 +		xendbg_send(buf, 2, ctx);
   4.171 +	}
   4.172 +	if (x == 0)
   4.173 +		xendbg_send("E05", 3, ctx);
   4.174 +	dbg_printk("Read done.\n");
   4.175 +	return xendbg_finish_reply(ctx);
   4.176 +}
   4.177 +
   4.178 +static int
   4.179 +xendbg_send_reply(const char *buf, struct xendbg_context *ctx)
   4.180 +{
   4.181 +	xendbg_start_reply(ctx);
   4.182 +	xendbg_send(buf, strlen(buf), ctx);
   4.183 +	return xendbg_finish_reply(ctx);
   4.184 +}
   4.185 +
   4.186 +static int
   4.187 +handle_register_read_command(struct xen_regs *regs, struct xendbg_context *ctx)
   4.188 +{
   4.189 +	char buf[121];
   4.190 +
   4.191 +	sprintf(buf,
   4.192 +		"%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x",
   4.193 +		bswab32(regs->eax),
   4.194 +		bswab32(regs->ecx),
   4.195 +		bswab32(regs->edx),
   4.196 +		bswab32(regs->ebx),
   4.197 +		bswab32(regs->esp),
   4.198 +		bswab32(regs->ebp),
   4.199 +		bswab32(regs->esi),
   4.200 +		bswab32(regs->edi),
   4.201 +		bswab32(regs->eip),
   4.202 +		bswab32(regs->eflags),
   4.203 +		bswab32(regs->cs),
   4.204 +		bswab32(regs->ss),
   4.205 +		bswab32(regs->es),
   4.206 +		bswab32(regs->fs),
   4.207 +		bswab32(regs->gs));
   4.208 +	return xendbg_send_reply(buf, ctx);
   4.209 +}
   4.210 +
   4.211 +static int
   4.212 +process_command(char *received_packet, struct xen_regs *regs,
   4.213 +		struct xendbg_context *ctx)
   4.214 +{
   4.215 +	char *ptr;
   4.216 +	unsigned long addr, length;
   4.217 +	int retry;
   4.218 +	int counter;
   4.219 +	int resume = 0;
   4.220 +
   4.221 +	/* Repeat until gdb acks the reply */
   4.222 +	counter = 0;
   4.223 +	do {
   4.224 +		switch (received_packet[0]) {
   4.225 +		case 'g': /* Read registers */
   4.226 +			retry = handle_register_read_command(regs, ctx);
   4.227 +			break;
   4.228 +		case 'm': /* Read memory */
   4.229 +			addr = simple_strtoul(received_packet + 1, &ptr, 16);
   4.230 +			if (ptr == received_packet + 1 ||
   4.231 +			    ptr[0] != ',') {
   4.232 +				xendbg_send_reply("E03", ctx);
   4.233 +				return 0;
   4.234 +			}
   4.235 +			length = simple_strtoul(ptr + 1, &ptr, 16);
   4.236 +			if (ptr[0] != 0) {
   4.237 +				xendbg_send_reply("E04", ctx);
   4.238 +				return 0;
   4.239 +			}
   4.240 +			retry =
   4.241 +				handle_memory_read_command(addr,
   4.242 +							   length,
   4.243 +							   ctx);
   4.244 +			break;
   4.245 +		case 'G': /* Write registers */
   4.246 +		case 'M': /* Write memory */
   4.247 +			retry = xendbg_send_reply("E02", ctx);
   4.248 +			break;
   4.249 +		case 'D':
   4.250 +			resume = 1;
   4.251 +			ctx->currently_attached = 0;
   4.252 +			retry = xendbg_send_reply("", ctx);
   4.253 +			break;
   4.254 +		case 'c': /* Resume at current address */
   4.255 +			ctx->currently_attached = 1;
   4.256 +			resume = 1;
   4.257 +			retry = 0;
   4.258 +			break;
   4.259 +		case 'Z': /* We need to claim to support these or gdb
   4.260 +			     won't let you continue the process. */
   4.261 +		case 'z':
   4.262 +			retry = xendbg_send_reply("OK", ctx);
   4.263 +			break;
   4.264 +
   4.265 +		case 's': /* Single step */
   4.266 +		case '?':
   4.267 +			retry = xendbg_send_reply("S01", ctx);
   4.268 +			break;
   4.269 +		default:
   4.270 +			retry = xendbg_send_reply("", ctx);
   4.271 +			break;
   4.272 +		}
   4.273 +		counter++;
   4.274 +	} while (retry == 1 && counter < 10);
   4.275 +	if (retry) {
   4.276 +		dbg_printk("WARNING: gdb disappeared when we were trying to send it a reply.\n");
   4.277 +		return 1;
   4.278 +	}
   4.279 +	return resume;
   4.280 +}
   4.281 +
   4.282 +static struct xendbg_context
   4.283 +xdb_ctx = {
   4.284 +	serhnd : -1
   4.285 +};
   4.286 +
   4.287 +void
   4.288 +__trap_to_cdb(struct xen_regs *regs)
   4.289 +{
   4.290 +	int resume = 0;
   4.291 +	int r;
   4.292 +	static atomic_t xendbg_running = ATOMIC_INIT(1);
   4.293 +	static char recv_buf[4096];
   4.294 +	unsigned flags;
   4.295 +
   4.296 +	if (xdb_ctx.serhnd < 0) {
   4.297 +		dbg_printk("Debugger not ready yet.\n");
   4.298 +		return;
   4.299 +	}
   4.300 +
   4.301 +	/* Try to make things a little more stable by disabling
   4.302 +	   interrupts while we're here. */
   4.303 +	local_irq_save(flags);
   4.304 +
   4.305 +	/* We rely on our caller to ensure we're only on one processor
   4.306 +	 * at a time... We should probably panic here, but given that
   4.307 +	 * we're a debugger we should probably be a little tolerant of
   4.308 +	 * things going wrong. */
   4.309 +	/* We don't want to use a spin lock here, because we're doing
   4.310 +	   two distinct things:
   4.311 +
   4.312 +	   1 -- we don't want to run on more than one processor at a time,
   4.313 +	        and
   4.314 +	   2 -- we want to do something sensible if we re-enter ourselves.
   4.315 +
   4.316 +	   Spin locks are good for 1, but useless for 2. */
   4.317 +	if (!atomic_dec_and_test(&xendbg_running)) {
   4.318 +		printk("WARNING WARNING WARNING: Avoiding recursive xendbg.\n");
   4.319 +		atomic_inc(&xendbg_running);
   4.320 +		local_irq_restore(flags);
   4.321 +		return;
   4.322 +	}
   4.323 +
   4.324 +	/* Shouldn't really do this, but otherwise we stop for no
   4.325 +	   obvious reason, which is Bad */
   4.326 +	printk("Waiting for GDB to attach to XenDBG\n");
   4.327 +
   4.328 +	/* If gdb is already attached, tell it we've stopped again. */
   4.329 +	if (xdb_ctx.currently_attached) {
   4.330 +		do {
   4.331 +			r = xendbg_send_reply("S01", &xdb_ctx);
   4.332 +		} while (r != 0);
   4.333 +	}
   4.334 +
   4.335 +	while (resume == 0) {
   4.336 +		r = receive_command(recv_buf, &xdb_ctx);
   4.337 +		if (r < 0) {
   4.338 +			dbg_printk("GDB disappeared, trying to resume Xen...\n");
   4.339 +			resume = 1;
   4.340 +		} else
   4.341 +			resume = process_command(recv_buf, regs, &xdb_ctx);
   4.342 +	}
   4.343 +	atomic_inc(&xendbg_running);
   4.344 +	local_irq_restore(flags);
   4.345 +}
   4.346 +
   4.347 +void
   4.348 +initialize_xendbg(void)
   4.349 +{
   4.350 +	if (!strcmp(opt_cdb, "none"))
   4.351 +		return;
   4.352 +	xdb_ctx.serhnd = parse_serial_handle(opt_cdb);
   4.353 +	if (xdb_ctx.serhnd == -1)
   4.354 +		panic("Can't parse %s as CDB serial info.\n", opt_cdb);
   4.355 +
   4.356 +	/* Acknowledge any spurious GDB packets. */
   4.357 +	xendbg_put_char('+', &xdb_ctx);
   4.358 +
   4.359 +	printk("Xendbg initialised.\n");
   4.360 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xen/arch/x86/x86_32/cdb_trap.S	Thu Feb 10 14:38:46 2005 +0000
     5.3 @@ -0,0 +1,36 @@
     5.4 +.global cdb_trap
     5.5 +.extern __trap_to_cdb
     5.6 +	
     5.7 +#define SAVE_ALL_NOSEGREGS \
     5.8 +	pushw $0;  \
     5.9 +        pushw %gs; \
    5.10 +	pushw $0;  \
    5.11 +        pushw %fs; \
    5.12 +	pushw $0;  \
    5.13 +        pushw %es; \
    5.14 +	pushw $0;  \
    5.15 +        pushw %ds; \
    5.16 +        pushl %eax; \
    5.17 +        pushl %ebp; \
    5.18 +        pushl %edi; \
    5.19 +        pushl %esi; \
    5.20 +        pushl %edx; \
    5.21 +        pushl %ecx; \
    5.22 +        pushl %ebx;
    5.23 +
    5.24 +	// Save the register state and call __trap_to_cdb
    5.25 +cdb_trap:
    5.26 +	pushw $0
    5.27 +	pushw %ss
    5.28 +	pushl %esp //We'll fix this up later, in __trap_to_cdb, by adding 8
    5.29 +	pushf
    5.30 +	pushw $0
    5.31 +	pushw %cs
    5.32 +	pushl 16(%esp)
    5.33 +1:	pushl $0 		// Orig_eax
    5.34 +	SAVE_ALL_NOSEGREGS
    5.35 +	pushl %esp
    5.36 +	call __trap_to_cdb
    5.37 +	add $72, %esp
    5.38 +	xorl %eax, %eax
    5.39 +	ret
     6.1 --- a/xen/arch/x86/x86_32/xdb_trap.S	Thu Feb 10 13:17:10 2005 +0000
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,35 +0,0 @@
     6.4 -.global trap_to_xendbg
     6.5 -.extern __trap_to_xendbg
     6.6 -	
     6.7 -#define SAVE_ALL_NOSEGREGS \
     6.8 -	pushw $0;  \
     6.9 -        pushw %gs; \
    6.10 -	pushw $0;  \
    6.11 -        pushw %fs; \
    6.12 -	pushw $0;  \
    6.13 -        pushw %es; \
    6.14 -	pushw $0;  \
    6.15 -        pushw %ds; \
    6.16 -        pushl %eax; \
    6.17 -        pushl %ebp; \
    6.18 -        pushl %edi; \
    6.19 -        pushl %esi; \
    6.20 -        pushl %edx; \
    6.21 -        pushl %ecx; \
    6.22 -        pushl %ebx;
    6.23 -
    6.24 -	// Save the register state and call __trap_to_xendbg 
    6.25 -trap_to_xendbg:
    6.26 -	pushw $0
    6.27 -	pushw %ss
    6.28 -	pushl %esp //We'll fix this up later, in __trap_to_xendbg, by adding 8
    6.29 -	pushf
    6.30 -	pushw $0
    6.31 -	pushw %cs
    6.32 -	pushl 16(%esp)
    6.33 -1:	pushl $0 		// Orig_eax
    6.34 -	SAVE_ALL_NOSEGREGS
    6.35 -	pushl %esp
    6.36 -	call __trap_to_xendbg
    6.37 -	add $72, %esp
    6.38 -	ret
     7.1 --- a/xen/arch/x86/xdb.c	Thu Feb 10 13:17:10 2005 +0000
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,355 +0,0 @@
     7.4 -/* Simple hacked-up version of pdb for us in post-mortem debugging of
     7.5 -   Xen and domain 0. This should be a little cleaner, hopefully.  Note
     7.6 -   that we can't share a serial line with PDB. */
     7.7 -#include <xen/lib.h>
     7.8 -#include <asm/uaccess.h>
     7.9 -#include <xen/serial.h>
    7.10 -#include <asm/irq.h>
    7.11 -#include <xen/spinlock.h>
    7.12 -
    7.13 -/* Printk isn't particularly safe just after we've trapped to the
    7.14 -   debugger. so avoid it. */
    7.15 -#define dbg_printk(...)
    7.16 -
    7.17 -struct xendbg_context {
    7.18 -	int serhnd;
    7.19 -	u8 reply_csum;
    7.20 -	int currently_attached:1;
    7.21 -};
    7.22 -
    7.23 -static void
    7.24 -xendbg_put_char(u8 data, struct xendbg_context *ctx)
    7.25 -{
    7.26 -	ctx->reply_csum += data;
    7.27 -	serial_putc(ctx->serhnd, data);
    7.28 -}
    7.29 -
    7.30 -static u8
    7.31 -xendbg_get_char(struct xendbg_context *ctx)
    7.32 -{
    7.33 -	u8 ch;
    7.34 -	extern unsigned char __serial_getc(int handle);
    7.35 -	ch = __serial_getc(ctx->serhnd);
    7.36 -	return ch;
    7.37 -}
    7.38 -
    7.39 -static int
    7.40 -hex_char_val(unsigned char c)
    7.41 -{
    7.42 -	if (c >= '0' && c <= '9')
    7.43 -		return c - '0';
    7.44 -	else if (c >= 'a' && c <= 'f')
    7.45 -		return c - 'a' + 10;
    7.46 -	else if (c >= 'A' && c <= 'F')
    7.47 -		return c - 'A' + 10;
    7.48 -	else
    7.49 -		BUG();
    7.50 -	return -1;
    7.51 -}
    7.52 -
    7.53 -/* Receive a command.  Returns -1 on csum error, 0 otherwise. */
    7.54 -/* Does not acknowledge. */
    7.55 -static int
    7.56 -attempt_receive_packet(char *recv_buf, struct xendbg_context *ctx)
    7.57 -{
    7.58 -	int count;
    7.59 -	u8 csum;
    7.60 -	u8 received_csum;
    7.61 -	u8 ch;
    7.62 -
    7.63 -	/* Skip over everything up to the first '$' */
    7.64 -	while ((ch = xendbg_get_char(ctx)) != '$')
    7.65 -		;
    7.66 -	csum = 0;
    7.67 -	for (count = 0; count < 4096; count++) {
    7.68 -		ch = xendbg_get_char(ctx);
    7.69 -		if (ch == '#')
    7.70 -			break;
    7.71 -		recv_buf[count] = ch;
    7.72 -		csum += ch;
    7.73 -	}
    7.74 -	if (count == 4096) {
    7.75 -		dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
    7.76 -		return -1;
    7.77 -	}
    7.78 -	recv_buf[count] = 0;
    7.79 -	received_csum = hex_char_val(xendbg_get_char(ctx)) * 16 +
    7.80 -		hex_char_val(xendbg_get_char(ctx));
    7.81 -	if (received_csum == csum) {
    7.82 -		return 0;
    7.83 -	} else {
    7.84 -		return -1;
    7.85 -	}
    7.86 -}
    7.87 -
    7.88 -/* Send a string of bytes to the debugger. */
    7.89 -static void
    7.90 -xendbg_send(const char *buf, int count, struct xendbg_context *ctx)
    7.91 -{
    7.92 -	int x;
    7.93 -	for (x = 0; x < count; x++)
    7.94 -		xendbg_put_char(buf[x], ctx);
    7.95 -}
    7.96 -
    7.97 -/* Receive a command, discarding up to ten packets with csum
    7.98 - * errors.  Acknowledges all received packets. */
    7.99 -static int
   7.100 -receive_command(char *recv_buf, struct xendbg_context *ctx)
   7.101 -{
   7.102 -	int r;
   7.103 -	int count;
   7.104 -
   7.105 -	count = 0;
   7.106 -	do {
   7.107 -		r = attempt_receive_packet(recv_buf, ctx);
   7.108 -		if (r < 0)
   7.109 -			xendbg_put_char('-', ctx);
   7.110 -		else
   7.111 -			xendbg_put_char('+', ctx);
   7.112 -		count++;
   7.113 -	} while (r < 0 && count < 10);
   7.114 -	return r;
   7.115 -}
   7.116 -
   7.117 -static void
   7.118 -xendbg_start_reply(struct xendbg_context *ctx)
   7.119 -{
   7.120 -	xendbg_put_char('$', ctx);
   7.121 -	ctx->reply_csum = 0;
   7.122 -}
   7.123 -
   7.124 -/* Return 0 if the reply was successfully received, !0 otherwise. */
   7.125 -static int
   7.126 -xendbg_finish_reply(struct xendbg_context *ctx)
   7.127 -{
   7.128 -	char ch;
   7.129 -	char buf[3];
   7.130 -
   7.131 -	sprintf(buf, "%.02x\n", ctx->reply_csum);
   7.132 -
   7.133 -	xendbg_put_char('#', ctx);
   7.134 -	xendbg_send(buf, 2, ctx);
   7.135 -
   7.136 -	ch = xendbg_get_char(ctx);
   7.137 -	if (ch == '+')
   7.138 -		return 0;
   7.139 -	else
   7.140 -		return 1;
   7.141 -}
   7.142 -
   7.143 -/* Swap the order of the bytes in a work. */
   7.144 -static inline unsigned
   7.145 -bswab32(unsigned val)
   7.146 -{
   7.147 -	return (((val >> 0) & 0xff) << 24) |
   7.148 -		(((val >> 8) & 0xff) << 16) |
   7.149 -		(((val >> 16) & 0xff) << 8) |
   7.150 -		(((val >> 24) & 0xff) << 0);
   7.151 -}
   7.152 -
   7.153 -static int
   7.154 -handle_memory_read_command(unsigned long addr, unsigned long length,
   7.155 -			   struct xendbg_context *ctx)
   7.156 -{
   7.157 -	int x;
   7.158 -	unsigned char val;
   7.159 -	int r;
   7.160 -	unsigned old_s_limit;
   7.161 -	char buf[2];
   7.162 -
   7.163 -	dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
   7.164 -		   length);
   7.165 -	old_s_limit = current->addr_limit.seg;
   7.166 -	current->addr_limit.seg = ~0;
   7.167 -	xendbg_start_reply(ctx);
   7.168 -	for (x = 0; x < length; x++) {
   7.169 -		r = copy_from_user(&val, (void *)(addr + x), 1);
   7.170 -		if (r != 0) {
   7.171 -			dbg_printk("Error reading from %lx.\n", addr + x);
   7.172 -			break;
   7.173 -		}
   7.174 -		sprintf(buf, "%.02x", val);
   7.175 -		xendbg_send(buf, 2, ctx);
   7.176 -	}
   7.177 -	if (x == 0)
   7.178 -		xendbg_send("E05", 3, ctx);
   7.179 -	dbg_printk("Read done.\n");
   7.180 -	current->addr_limit.seg = old_s_limit;
   7.181 -	return xendbg_finish_reply(ctx);
   7.182 -}
   7.183 -
   7.184 -static int
   7.185 -xendbg_send_reply(const char *buf, struct xendbg_context *ctx)
   7.186 -{
   7.187 -	xendbg_start_reply(ctx);
   7.188 -	xendbg_send(buf, strlen(buf), ctx);
   7.189 -	return xendbg_finish_reply(ctx);
   7.190 -}
   7.191 -
   7.192 -static int
   7.193 -handle_register_read_command(struct pt_regs *regs, struct xendbg_context *ctx)
   7.194 -{
   7.195 -	char buf[121];
   7.196 -
   7.197 -	sprintf(buf,
   7.198 -		"%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x",
   7.199 -		bswab32(regs->eax),
   7.200 -		bswab32(regs->ecx),
   7.201 -		bswab32(regs->edx),
   7.202 -		bswab32(regs->ebx),
   7.203 -		bswab32(regs->esp),
   7.204 -		bswab32(regs->ebp),
   7.205 -		bswab32(regs->esi),
   7.206 -		bswab32(regs->edi),
   7.207 -		bswab32(regs->eip),
   7.208 -		bswab32(regs->eflags),
   7.209 -		bswab32(regs->xcs),
   7.210 -		bswab32(regs->xss),
   7.211 -		bswab32(regs->xes),
   7.212 -		bswab32(regs->xfs),
   7.213 -		bswab32(regs->xgs));
   7.214 -	return xendbg_send_reply(buf, ctx);
   7.215 -}
   7.216 -
   7.217 -static int
   7.218 -process_command(char *received_packet, struct pt_regs *regs,
   7.219 -		struct xendbg_context *ctx)
   7.220 -{
   7.221 -	char *ptr;
   7.222 -	unsigned long addr, length;
   7.223 -	int retry;
   7.224 -	int counter;
   7.225 -	int resume = 0;
   7.226 -
   7.227 -	/* Repeat until gdb acks the reply */
   7.228 -	counter = 0;
   7.229 -	do {
   7.230 -		switch (received_packet[0]) {
   7.231 -		case 'g': /* Read registers */
   7.232 -			retry = handle_register_read_command(regs, ctx);
   7.233 -			break;
   7.234 -		case 'm': /* Read memory */
   7.235 -			addr = simple_strtoul(received_packet + 1, &ptr, 16);
   7.236 -			if (ptr == received_packet + 1 ||
   7.237 -			    ptr[0] != ',') {
   7.238 -				xendbg_send_reply("E03", ctx);
   7.239 -				return 0;
   7.240 -			}
   7.241 -			length = simple_strtoul(ptr + 1, &ptr, 16);
   7.242 -			if (ptr[0] != 0) {
   7.243 -				xendbg_send_reply("E04", ctx);
   7.244 -				return 0;
   7.245 -			}
   7.246 -			retry =
   7.247 -				handle_memory_read_command(addr,
   7.248 -							   length,
   7.249 -							   ctx);
   7.250 -			break;
   7.251 -		case 'G': /* Write registers */
   7.252 -		case 'M': /* Write memory */
   7.253 -			retry = xendbg_send_reply("E02", ctx);
   7.254 -			break;
   7.255 -		case 'D':
   7.256 -			resume = 1;
   7.257 -			ctx->currently_attached = 0;
   7.258 -			retry = xendbg_send_reply("", ctx);
   7.259 -			break;
   7.260 -		case 'c': /* Resume at current address */
   7.261 -			ctx->currently_attached = 1;
   7.262 -			resume = 1;
   7.263 -			retry = 0;
   7.264 -			break;
   7.265 -		case 'Z': /* We need to claim to support these or gdb
   7.266 -			     won't let you continue the process. */
   7.267 -		case 'z':
   7.268 -			retry = xendbg_send_reply("OK", ctx);
   7.269 -			break;
   7.270 -
   7.271 -		case 's': /* Single step */
   7.272 -		case '?':
   7.273 -			retry = xendbg_send_reply("S01", ctx);
   7.274 -			break;
   7.275 -		default:
   7.276 -			retry = xendbg_send_reply("", ctx);
   7.277 -			break;
   7.278 -		}
   7.279 -		counter++;
   7.280 -	} while (retry == 1 && counter < 10);
   7.281 -	if (retry) {
   7.282 -		dbg_printk("WARNING: gdb disappeared when we were trying to send it a reply.\n");
   7.283 -		return 1;
   7.284 -	}
   7.285 -	return resume;
   7.286 -}
   7.287 -
   7.288 -static struct xendbg_context
   7.289 -xdb_ctx = {
   7.290 -	serhnd : -1
   7.291 -};
   7.292 -
   7.293 -void
   7.294 -__trap_to_xendbg(struct pt_regs *regs)
   7.295 -{
   7.296 -	int resume = 0;
   7.297 -	int r;
   7.298 -	static int xendbg_running;
   7.299 -	static char recv_buf[4096];
   7.300 -	unsigned flags;
   7.301 -
   7.302 -	if (xdb_ctx.serhnd < 0) {
   7.303 -		dbg_printk("Debugger not ready yet.\n");
   7.304 -		return;
   7.305 -	}
   7.306 -	/* We rely on our caller to ensure we're only on one processor
   7.307 -	 * at a time... We should probably panic here, but given that
   7.308 -	 * we're a debugger we should probably be a little tolerant of
   7.309 -	 * things going wrong. */
   7.310 -	if (xendbg_running) {
   7.311 -		dbg_printk("WARNING WARNING WARNING: Avoiding recursive xendbg.\n");
   7.312 -		return;
   7.313 -	}
   7.314 -	xendbg_running = 1;
   7.315 -
   7.316 -	/* Shouldn't really do this, but otherwise we stop for no
   7.317 -	   obvious reason, which is Bad */
   7.318 -	printk("Waiting for GDB to attach to XenDBG\n");
   7.319 -
   7.320 -	/* Try to make things a little more stable by disabling
   7.321 -	   interrupts while we're here. */
   7.322 -	local_irq_save(flags);
   7.323 -
   7.324 -	/* If gdb is already attached, tell it we've stopped again. */
   7.325 -	if (xdb_ctx.currently_attached) {
   7.326 -		do {
   7.327 -			r = xendbg_send_reply("S01", &xdb_ctx);
   7.328 -		} while (r != 0);
   7.329 -	}
   7.330 -
   7.331 -	while (resume == 0) {
   7.332 -		r = receive_command(recv_buf, &xdb_ctx);
   7.333 -		if (r < 0) {
   7.334 -			dbg_printk("GDB disappeared, trying to resume Xen...\n");
   7.335 -			resume = 1;
   7.336 -		} else
   7.337 -			resume = process_command(recv_buf, regs, &xdb_ctx);
   7.338 -	}
   7.339 -	xendbg_running = 0;
   7.340 -	local_irq_restore(flags);
   7.341 -}
   7.342 -
   7.343 -void
   7.344 -initialize_xendbg(void)
   7.345 -{
   7.346 -	extern char opt_xendbg[];
   7.347 -
   7.348 -	if (!strcmp(opt_xendbg, "none"))
   7.349 -		return;
   7.350 -	xdb_ctx.serhnd = parse_serial_handle(opt_xendbg);
   7.351 -	if (xdb_ctx.serhnd == -1)
   7.352 -		panic("Can't parse %s as XDB serial info.\n", opt_xendbg);
   7.353 -
   7.354 -	/* Acknowledge any spurious GDB packets. */
   7.355 -	xendbg_put_char('+', &xdb_ctx);
   7.356 -
   7.357 -	printk("Xendbg initialised.\n");
   7.358 -}
     8.1 --- a/xen/common/domain.c	Thu Feb 10 13:17:10 2005 +0000
     8.2 +++ b/xen/common/domain.c	Thu Feb 10 14:38:46 2005 +0000
     8.3 @@ -18,6 +18,7 @@
     8.4  #include <asm/shadow.h>
     8.5  #include <public/dom0_ops.h>
     8.6  #include <asm/domain_page.h>
     8.7 +#include <asm/debugger.h>
     8.8  
     8.9  /* Both these structures are protected by the domlist_lock. */
    8.10  rwlock_t domlist_lock = RW_LOCK_UNLOCKED;
    8.11 @@ -172,7 +173,7 @@ void domain_shutdown(u8 reason)
    8.12          extern void machine_restart(char *);
    8.13          extern void machine_halt(void);
    8.14  
    8.15 -	trap_to_xendbg();
    8.16 +        debugger_trap_immediate();
    8.17  
    8.18          if ( reason == 0 ) 
    8.19          {
     9.1 --- a/xen/common/keyhandler.c	Thu Feb 10 13:17:10 2005 +0000
     9.2 +++ b/xen/common/keyhandler.c	Thu Feb 10 14:38:46 2005 +0000
     9.3 @@ -10,6 +10,7 @@
     9.4  #include <xen/serial.h>
     9.5  #include <xen/sched.h>
     9.6  #include <xen/softirq.h>
     9.7 +#include <asm/debugger.h>
     9.8  
     9.9  #define KEY_MAX 256
    9.10  #define STR_MAX  64
    9.11 @@ -146,13 +147,12 @@ extern void perfc_printall(unsigned char
    9.12  extern void perfc_reset(unsigned char key);
    9.13  #endif
    9.14  
    9.15 -void do_debug_key(unsigned char key, void *dev_id, struct pt_regs *regs)
    9.16 +void do_debug_key(unsigned char key, struct xen_regs *regs)
    9.17  {
    9.18 -    extern void trap_to_xendbg(void);
    9.19 -    trap_to_xendbg();
    9.20 +    debugger_trap_fatal(0xf001, regs);
    9.21      asm volatile ("nop"); /* Prevent the compiler doing tail call
    9.22 -			     optimisation, as that confuses xendbg a
    9.23 -			     bit. */
    9.24 +                             optimisation, as that confuses xendbg a
    9.25 +                             bit. */
    9.26  }
    9.27  
    9.28  void initialize_keytable(void)
    9.29 @@ -185,5 +185,5 @@ void initialize_keytable(void)
    9.30      register_keyhandler(
    9.31          'P', perfc_reset,    "reset performance counters"); 
    9.32  #endif
    9.33 -    add_key_handler('%', do_debug_key,   "Trap to xendbg");
    9.34 +    register_irq_keyhandler('%', do_debug_key,   "Trap to xendbg");
    9.35  }
    10.1 --- a/xen/drivers/char/console.c	Thu Feb 10 13:17:10 2005 +0000
    10.2 +++ b/xen/drivers/char/console.c	Thu Feb 10 14:38:46 2005 +0000
    10.3 @@ -20,6 +20,7 @@
    10.4  #include <xen/keyhandler.h>
    10.5  #include <asm/uaccess.h>
    10.6  #include <asm/mm.h>
    10.7 +#include <asm/debugger.h>
    10.8  
    10.9  /* opt_console: comma-separated list of console outputs. */
   10.10  static unsigned char opt_console[30] = OPT_CONSOLE_STR;
   10.11 @@ -497,7 +498,7 @@ void panic(const char *fmt, ...)
   10.12      (void)vsnprintf(buf, sizeof(buf), fmt, args);
   10.13      va_end(args);
   10.14  
   10.15 -    trap_to_xendbg();
   10.16 +    debugger_trap_immediate();
   10.17  
   10.18      /* Spit out multiline message in one go. */
   10.19      spin_lock_irqsave(&console_lock, flags);
    11.1 --- a/xen/include/asm-x86/debugger.h	Thu Feb 10 13:17:10 2005 +0000
    11.2 +++ b/xen/include/asm-x86/debugger.h	Thu Feb 10 14:38:46 2005 +0000
    11.3 @@ -93,6 +93,16 @@ static inline int debugger_trap_fatal(
    11.4      return ret;
    11.5  }
    11.6  
    11.7 +#define debugger_trap_immediate() ()
    11.8 +
    11.9 +#elif defined(CRASH_DEBUG)
   11.10 +
   11.11 +extern void cdb_trap(void);
   11.12 +extern void __trap_to_cdb(struct xen_regs *);
   11.13 +#define debugger_trap_entry(_v, _r) (0)
   11.14 +#define debugger_trap_fatal(_v, _r) (__trap_to_cdb(_r), 0)
   11.15 +#define debugger_trap_immediate() (cdb_trap())
   11.16 +
   11.17  #elif 0
   11.18  
   11.19  extern int kdb_trap(int, int, struct xen_regs *);
   11.20 @@ -113,6 +123,7 @@ static inline int debugger_trap_fatal(
   11.21  
   11.22  #define debugger_trap_entry(_v, _r) (0)
   11.23  #define debugger_trap_fatal(_v, _r) (0)
   11.24 +#define debugger_trap_immediate() ()
   11.25  
   11.26  #endif
   11.27