ia64/xen-unstable

changeset 1977:c1e2ec69b1db

bitkeeper revision 1.1108.1.42 (4108e6c6q2V_HmGtI-XzIUJWBgppfg)

Merge donkeykong.cl.cam.ac.uk:/auto/groups/xeno/users/ach61/xeno-clone/xeno.bk
into donkeykong.cl.cam.ac.uk:/auto/homes/sos22/xenDb/xeno.bk
author sos22@donkeykong.cl.cam.ac.uk
date Thu Jul 29 12:00:06 2004 +0000 (2004-07-29)
parents 0ad375fd56d9 fc03d5fc3686
children d200c22469e2
files .rootkeys BitKeeper/etc/logging_ok xen/Rules.mk xen/arch/x86/Rules.mk xen/arch/x86/x86_32/xdb_trap.S xen/arch/x86/xdb.c xen/common/domain.c xen/common/kernel.c xen/common/keyhandler.c xen/drivers/char/console.c xen/drivers/char/serial.c
line diff
     1.1 --- a/.rootkeys	Wed Jul 28 18:59:26 2004 +0000
     1.2 +++ b/.rootkeys	Thu Jul 29 12:00:06 2004 +0000
     1.3 @@ -549,10 +549,12 @@ 40f92331jfOlE7MfKwpdkEb1CEf23g xen/arch/
     1.4  3ddb79bcecupHj56ZbTa3B0FxDowMg xen/arch/x86/x86_32/entry.S
     1.5  3ddb79bcHwuCQDjBICDTSis52hWguw xen/arch/x86/x86_32/mm.c
     1.6  3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/x86/x86_32/usercopy.c
     1.7 +4107c15e_NqNYew2EXroXz2mgTAMWQ xen/arch/x86/x86_32/xdb_trap.S
     1.8  3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/x86/x86_32/xen.lds
     1.9  40e96d3aLDI-nViMuYneD7VKYlZrVg xen/arch/x86/x86_64/entry.S
    1.10  40e96d3ahBTZqbTViInnq0lM03vs7A xen/arch/x86/x86_64/usercopy.c
    1.11  40e96d3akN3Hu_J5Bk-WXD8OGscrYQ xen/arch/x86/x86_64/xen.lds
    1.12 +4107c15e-VmEcLsE-7JCXZaabI8C7A xen/arch/x86/xdb.c
    1.13  3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile
    1.14  3e397e66AyyD5fYraAySWuwi9uqSXg xen/common/ac_timer.c
    1.15  4022a73c_BbDFd2YJ_NQYVvKX5Oz7w xen/common/debug-linux.c
     2.1 --- a/BitKeeper/etc/logging_ok	Wed Jul 28 18:59:26 2004 +0000
     2.2 +++ b/BitKeeper/etc/logging_ok	Thu Jul 29 12:00:06 2004 +0000
     2.3 @@ -38,6 +38,7 @@ smh22@boulderdash.cl.cam.ac.uk
     2.4  smh22@labyrinth.cl.cam.ac.uk
     2.5  smh22@tempest.cl.cam.ac.uk
     2.6  smh22@uridium.cl.cam.ac.uk
     2.7 +sos22@donkeykong.cl.cam.ac.uk
     2.8  sos22@labyrinth.cl.cam.ac.uk
     2.9  tlh20@elite.cl.cam.ac.uk
    2.10  tlh20@labyrinth.cl.cam.ac.uk
     3.1 --- a/xen/Rules.mk	Wed Jul 28 18:59:26 2004 +0000
     3.2 +++ b/xen/Rules.mk	Thu Jul 29 12:00:06 2004 +0000
     3.3 @@ -43,7 +43,7 @@ CFLAGS += -DNDEBUG
     3.4  endif
     3.5  
     3.6  ifeq ($(debugger),y)
     3.7 -CFLAGS += -DXEN_DEBUGGER
     3.8 +CFLAGS += -DXEN_DEBUGGER -g
     3.9  endif
    3.10  
    3.11  ifeq ($(perfc),y)
     4.1 --- a/xen/arch/x86/Rules.mk	Wed Jul 28 18:59:26 2004 +0000
     4.2 +++ b/xen/arch/x86/Rules.mk	Thu Jul 29 12:00:06 2004 +0000
     4.3 @@ -4,8 +4,8 @@
     4.4  CC := gcc
     4.5  LD := ld
     4.6  
     4.7 -CFLAGS  := -nostdinc -fno-builtin -fno-common -fno-strict-aliasing -O3
     4.8 -CFLAGS  += -iwithprefix include -Wall -Werror -fomit-frame-pointer -pipe
     4.9 +CFLAGS  := -nostdinc -fno-builtin -fno-common -fno-strict-aliasing
    4.10 +CFLAGS  += -iwithprefix include -Wall -Werror -pipe
    4.11  CFLAGS  += -I$(BASEDIR)/include -Wno-pointer-arith -Wredundant-decls
    4.12  
    4.13  ifeq ($(TARGET_SUBARCH),x86_32)
    4.14 @@ -13,6 +13,12 @@ CFLAGS  += -m32 -march=i686
    4.15  LDFLAGS := --oformat elf32-i386 
    4.16  endif
    4.17  
    4.18 +ifeq ($(debugger),y)
    4.19 +CFLAGS += -O2
    4.20 +else
    4.21 +CFLAGS += -O3 -fomit-frame-pointer
    4.22 +endif
    4.23 +
    4.24  ifeq ($(TARGET_SUBARCH),x86_64)
    4.25  CFLAGS  += -m64 -mno-red-zone -fpic -fno-reorder-blocks
    4.26  CFLAGS  += -fno-asynchronous-unwind-tables
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xen/arch/x86/x86_32/xdb_trap.S	Thu Jul 29 12:00:06 2004 +0000
     5.3 @@ -0,0 +1,35 @@
     5.4 +.global trap_to_xendbg
     5.5 +.extern __trap_to_xendbg
     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_xendbg 
    5.25 +trap_to_xendbg:
    5.26 +	pushw $0
    5.27 +	pushw %ss
    5.28 +	pushl %esp //We'll fix this up later, in __trap_to_xendbg, 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_xendbg
    5.37 +	add $72, %esp
    5.38 +	ret
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xen/arch/x86/xdb.c	Thu Jul 29 12:00:06 2004 +0000
     6.3 @@ -0,0 +1,336 @@
     6.4 +/* Simple hacked-up version of pdb for us in post-mortem debugging of
     6.5 +   Xen and domain 0. This should be a little cleaner, hopefully.  Note
     6.6 +   that we can't share a serial line with PDB. */
     6.7 +#include <xen/lib.h>
     6.8 +#include <asm/uaccess.h>
     6.9 +#include <xen/serial.h>
    6.10 +#include <asm/irq.h>
    6.11 +#include <xen/spinlock.h>
    6.12 +
    6.13 +/* Printk isn't particularly safe just after we've trapped to the
    6.14 +   debugger. so avoid it. */
    6.15 +#define dbg_printk(...)
    6.16 +
    6.17 +struct xendbg_context {
    6.18 +	int serhnd;
    6.19 +	u8 reply_csum;
    6.20 +};
    6.21 +
    6.22 +static void
    6.23 +xendbg_put_char(u8 data, struct xendbg_context *ctx)
    6.24 +{
    6.25 +	ctx->reply_csum += data;
    6.26 +	serial_putc(ctx->serhnd, data);
    6.27 +}
    6.28 +
    6.29 +static u8
    6.30 +xendbg_get_char(struct xendbg_context *ctx)
    6.31 +{
    6.32 +	u8 ch;
    6.33 +	extern unsigned char __serial_getc(int handle);
    6.34 +	ch = __serial_getc(ctx->serhnd);
    6.35 +	return ch;
    6.36 +}
    6.37 +
    6.38 +static int
    6.39 +hex_char_val(unsigned char c)
    6.40 +{
    6.41 +	if (c >= '0' && c <= '9')
    6.42 +		return c - '0';
    6.43 +	else if (c >= 'a' && c <= 'f')
    6.44 +		return c - 'a' + 10;
    6.45 +	else if (c >= 'A' && c <= 'F')
    6.46 +		return c - 'A' + 10;
    6.47 +	else
    6.48 +		BUG();
    6.49 +	return -1;
    6.50 +}
    6.51 +
    6.52 +/* Receive a command.  Returns -1 on csum error, 0 otherwise. */
    6.53 +/* Does not acknowledge. */
    6.54 +static int
    6.55 +attempt_receive_packet(char *recv_buf, struct xendbg_context *ctx)
    6.56 +{
    6.57 +	int count;
    6.58 +	u8 csum;
    6.59 +	u8 received_csum;
    6.60 +	u8 ch;
    6.61 +
    6.62 +	/* Skip over everything up to the first '$' */
    6.63 +	while ((ch = xendbg_get_char(ctx)) != '$')
    6.64 +		;
    6.65 +	csum = 0;
    6.66 +	for (count = 0; count < 4096; count++) {
    6.67 +		ch = xendbg_get_char(ctx);
    6.68 +		if (ch == '#')
    6.69 +			break;
    6.70 +		recv_buf[count] = ch;
    6.71 +		csum += ch;
    6.72 +	}
    6.73 +	if (count == 4096) {
    6.74 +		dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
    6.75 +		return -1;
    6.76 +	}
    6.77 +	recv_buf[count] = 0;
    6.78 +	received_csum = hex_char_val(xendbg_get_char(ctx)) * 16 +
    6.79 +		hex_char_val(xendbg_get_char(ctx));
    6.80 +	if (received_csum == csum) {
    6.81 +		return 0;
    6.82 +	} else {
    6.83 +		return -1;
    6.84 +	}
    6.85 +}
    6.86 +
    6.87 +/* Send a string of bytes to the debugger. */
    6.88 +static void
    6.89 +xendbg_send(const char *buf, int count, struct xendbg_context *ctx)
    6.90 +{
    6.91 +	int x;
    6.92 +	for (x = 0; x < count; x++)
    6.93 +		xendbg_put_char(buf[x], ctx);
    6.94 +}
    6.95 +
    6.96 +/* Receive a command, discarding up to ten packets with csum
    6.97 + * errors.  Acknowledges all received packets. */
    6.98 +static int
    6.99 +receive_command(char *recv_buf, struct xendbg_context *ctx)
   6.100 +{
   6.101 +	int r;
   6.102 +	int count;
   6.103 +
   6.104 +	count = 0;
   6.105 +	do {
   6.106 +		r = attempt_receive_packet(recv_buf, ctx);
   6.107 +		if (r < 0)
   6.108 +			xendbg_put_char('-', ctx);
   6.109 +		else
   6.110 +			xendbg_put_char('+', ctx);
   6.111 +		count++;
   6.112 +	} while (r < 0 && count < 10);
   6.113 +	return r;
   6.114 +}
   6.115 +
   6.116 +static void
   6.117 +xendbg_start_reply(struct xendbg_context *ctx)
   6.118 +{
   6.119 +	xendbg_put_char('$', ctx);
   6.120 +	ctx->reply_csum = 0;
   6.121 +}
   6.122 +
   6.123 +/* Return 0 if the reply was successfully received, !0 otherwise. */
   6.124 +static int
   6.125 +xendbg_finish_reply(struct xendbg_context *ctx)
   6.126 +{
   6.127 +	char ch;
   6.128 +	char buf[3];
   6.129 +
   6.130 +	sprintf(buf, "%.02x\n", ctx->reply_csum);
   6.131 +
   6.132 +	xendbg_put_char('#', ctx);
   6.133 +	xendbg_send(buf, 2, ctx);
   6.134 +
   6.135 +	ch = xendbg_get_char(ctx);
   6.136 +	if (ch == '+')
   6.137 +		return 0;
   6.138 +	else
   6.139 +		return 1;
   6.140 +}
   6.141 +
   6.142 +/* Swap the order of the bytes in a work. */
   6.143 +static inline unsigned
   6.144 +bswab32(unsigned val)
   6.145 +{
   6.146 +	return (((val >> 0) & 0xff) << 24) |
   6.147 +		(((val >> 8) & 0xff) << 16) |
   6.148 +		(((val >> 16) & 0xff) << 8) |
   6.149 +		(((val >> 24) & 0xff) << 0);
   6.150 +}
   6.151 +
   6.152 +static int
   6.153 +handle_memory_read_command(unsigned long addr, unsigned long length,
   6.154 +			   struct xendbg_context *ctx)
   6.155 +{
   6.156 +	int x;
   6.157 +	unsigned char val;
   6.158 +	int r;
   6.159 +	unsigned old_s_limit;
   6.160 +	char buf[2];
   6.161 +
   6.162 +	dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
   6.163 +		   length);
   6.164 +	old_s_limit = current->addr_limit.seg;
   6.165 +	current->addr_limit.seg = ~0;
   6.166 +	xendbg_start_reply(ctx);
   6.167 +	for (x = 0; x < length; x++) {
   6.168 +		r = copy_from_user(&val, (void *)(addr + x), 1);
   6.169 +		if (r != 0) {
   6.170 +			dbg_printk("Error reading from %lx.\n", addr + x);
   6.171 +			break;
   6.172 +		}
   6.173 +		sprintf(buf, "%.02x", val);
   6.174 +		xendbg_send(buf, 2, ctx);
   6.175 +	}
   6.176 +	if (x == 0)
   6.177 +		xendbg_send("E05", 3, ctx);
   6.178 +	dbg_printk("Read done.\n");
   6.179 +	current->addr_limit.seg = old_s_limit;
   6.180 +	return xendbg_finish_reply(ctx);
   6.181 +}
   6.182 +
   6.183 +static int
   6.184 +xendbg_send_reply(const char *buf, struct xendbg_context *ctx)
   6.185 +{
   6.186 +	xendbg_start_reply(ctx);
   6.187 +	xendbg_send(buf, strlen(buf), ctx);
   6.188 +	return xendbg_finish_reply(ctx);
   6.189 +}
   6.190 +
   6.191 +static int
   6.192 +handle_register_read_command(struct pt_regs *regs, struct xendbg_context *ctx)
   6.193 +{
   6.194 +	char buf[121];
   6.195 +
   6.196 +	sprintf(buf,
   6.197 +		"%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x",
   6.198 +		bswab32(regs->eax),
   6.199 +		bswab32(regs->ecx),
   6.200 +		bswab32(regs->edx),
   6.201 +		bswab32(regs->ebx),
   6.202 +		bswab32(regs->esp),
   6.203 +		bswab32(regs->ebp),
   6.204 +		bswab32(regs->esi),
   6.205 +		bswab32(regs->edi),
   6.206 +		bswab32(regs->eip),
   6.207 +		bswab32(regs->eflags),
   6.208 +		bswab32(regs->xcs),
   6.209 +		bswab32(regs->xss),
   6.210 +		bswab32(regs->xes),
   6.211 +		bswab32(regs->xfs),
   6.212 +		bswab32(regs->xgs));
   6.213 +	return xendbg_send_reply(buf, ctx);
   6.214 +}
   6.215 +
   6.216 +static int
   6.217 +process_command(char *received_packet, struct pt_regs *regs,
   6.218 +		struct xendbg_context *ctx)
   6.219 +{
   6.220 +	char *ptr;
   6.221 +	unsigned long addr, length;
   6.222 +	int retry;
   6.223 +	int counter;
   6.224 +	int resume = 0;
   6.225 +
   6.226 +	/* Repeat until gdb acks the reply */
   6.227 +	counter = 0;
   6.228 +	do {
   6.229 +		switch (received_packet[0]) {
   6.230 +		case 'g': /* Read registers */
   6.231 +			retry = handle_register_read_command(regs, ctx);
   6.232 +			break;
   6.233 +		case 'm': /* Read memory */
   6.234 +			addr = simple_strtoul(received_packet + 1, &ptr, 16);
   6.235 +			if (ptr == received_packet + 1 ||
   6.236 +			    ptr[0] != ',') {
   6.237 +				xendbg_send_reply("E03", ctx);
   6.238 +				return 0;
   6.239 +			}
   6.240 +			length = simple_strtoul(ptr + 1, &ptr, 16);
   6.241 +			if (ptr[0] != 0) {
   6.242 +				xendbg_send_reply("E04", ctx);
   6.243 +				return 0;
   6.244 +			}
   6.245 +			retry =
   6.246 +				handle_memory_read_command(addr,
   6.247 +							   length,
   6.248 +							   ctx);
   6.249 +			break;
   6.250 +		case 'G': /* Write registers */
   6.251 +		case 'M': /* Write memory */
   6.252 +			retry = xendbg_send_reply("E02", ctx);
   6.253 +			break;
   6.254 +		case 'D':
   6.255 +			resume = 1;
   6.256 +			retry = xendbg_send_reply("", ctx);
   6.257 +			break;
   6.258 +		case 'c': /* Resume at current address */
   6.259 +		case 's': /* Single step */
   6.260 +		case '?':
   6.261 +			retry = xendbg_send_reply("S01", ctx);
   6.262 +			break;
   6.263 +		default:
   6.264 +			retry = xendbg_send_reply("", ctx);
   6.265 +			break;
   6.266 +		}
   6.267 +		counter++;
   6.268 +	} while (retry == 1 && counter < 10);
   6.269 +	if (retry) {
   6.270 +		dbg_printk("WARNING: gdb disappeared when we were trying to send it a reply.\n");
   6.271 +		return 1;
   6.272 +	}
   6.273 +	return resume;
   6.274 +}
   6.275 +
   6.276 +static struct xendbg_context
   6.277 +xdb_ctx = {
   6.278 +	serhnd : -1
   6.279 +};
   6.280 +
   6.281 +void
   6.282 +__trap_to_xendbg(struct pt_regs *regs)
   6.283 +{
   6.284 +	int resume = 0;
   6.285 +	int r;
   6.286 +	static int xendbg_running;
   6.287 +	static char recv_buf[4096];
   6.288 +	unsigned flags;
   6.289 +
   6.290 +	if (xdb_ctx.serhnd < 0) {
   6.291 +		dbg_printk("Debugger not ready yet.\n");
   6.292 +		return;
   6.293 +	}
   6.294 +	/* We rely on our caller to ensure we're only on one processor
   6.295 +	 * at a time... We should probably panic here, but given that
   6.296 +	 * we're a debugger we should probably be a little tolerant of
   6.297 +	 * things going wrong. */
   6.298 +	if (xendbg_running) {
   6.299 +		dbg_printk("WARNING WARNING WARNING: Avoiding recursive xendbg.\n");
   6.300 +		return;
   6.301 +	}
   6.302 +	xendbg_running = 1;
   6.303 +
   6.304 +	/* Shouldn't really do this, but otherwise we stop for no
   6.305 +	   obvious reason, which is Bad */
   6.306 +	printk("Waiting for GDB to attach to XenDBG\n");
   6.307 +
   6.308 +	/* Try to make things a little more stable by disabling
   6.309 +	   interrupts while we're here. */
   6.310 +	local_irq_save(flags);
   6.311 +
   6.312 +	while (resume == 0) {
   6.313 +		r = receive_command(recv_buf, &xdb_ctx);
   6.314 +		if (r < 0) {
   6.315 +			dbg_printk("GDB disappeared, trying to resume Xen...\n");
   6.316 +			resume = 1;
   6.317 +		} else
   6.318 +			resume = process_command(recv_buf, regs, &xdb_ctx);
   6.319 +	}
   6.320 +	xendbg_running = 0;
   6.321 +	local_irq_restore(flags);
   6.322 +}
   6.323 +
   6.324 +void
   6.325 +initialize_xendbg(void)
   6.326 +{
   6.327 +	extern char opt_xendbg[];
   6.328 +
   6.329 +	if (!strcmp(opt_xendbg, "none"))
   6.330 +		return;
   6.331 +	xdb_ctx.serhnd = parse_serial_handle(opt_xendbg);
   6.332 +	if (xdb_ctx.serhnd == -1)
   6.333 +		panic("Can't parse %s as XDB serial info.\n", opt_xendbg);
   6.334 +
   6.335 +	/* Acknowledge any spurious GDB packets. */
   6.336 +	xendbg_put_char('+', &xdb_ctx);
   6.337 +
   6.338 +	printk("Xendbg initialised.\n");
   6.339 +}
     7.1 --- a/xen/common/domain.c	Wed Jul 28 18:59:26 2004 +0000
     7.2 +++ b/xen/common/domain.c	Thu Jul 29 12:00:06 2004 +0000
     7.3 @@ -164,6 +164,8 @@ void domain_crash(void)
     7.4      BUG();
     7.5  }
     7.6  
     7.7 +extern void trap_to_xendbg(void);
     7.8 +
     7.9  void domain_shutdown(u8 reason)
    7.10  {
    7.11      struct domain *d;
    7.12 @@ -173,6 +175,8 @@ void domain_shutdown(u8 reason)
    7.13          extern void machine_restart(char *);
    7.14          extern void machine_halt(void);
    7.15  
    7.16 +	trap_to_xendbg();
    7.17 +
    7.18          if ( reason == 0 ) 
    7.19          {
    7.20              printk("Domain 0 halted: Our work here is done.\n");
     8.1 --- a/xen/common/kernel.c	Wed Jul 28 18:59:26 2004 +0000
     8.2 +++ b/xen/common/kernel.c	Thu Jul 29 12:00:06 2004 +0000
     8.3 @@ -64,6 +64,8 @@ int opt_ignorebiostables=0;
     8.4  int opt_watchdog=0;
     8.5  /* opt_pdb: Name of serial port for Xen pervasive debugger (and enable pdb) */
     8.6  unsigned char opt_pdb[10] = "none";
     8.7 +/* opt_pdb: Name of serial port for Xen debugger (and enable xendbg) */
     8.8 +unsigned char opt_xendbg[10] = "none";
     8.9  /* opt_tbuf_size: trace buffer size (in pages) */
    8.10  unsigned int opt_tbuf_size = 10;
    8.11  /* opt_sched: scheduler - default to Borrowed Virtual Time */
    8.12 @@ -98,6 +100,7 @@ static struct {
    8.13      { "ignorebiostables",  OPT_BOOL, &opt_ignorebiostables },
    8.14      { "watchdog",          OPT_BOOL, &opt_watchdog },
    8.15      { "pdb",               OPT_STR,  &opt_pdb },
    8.16 +    { "xendbg",            OPT_STR,  &opt_xendbg },
    8.17      { "tbuf_size",         OPT_UINT, &opt_tbuf_size },
    8.18      { "sched",             OPT_STR,  &opt_sched },
    8.19      { "physdev_dom0_hide", OPT_STR,  &opt_physdev_dom0_hide },
    8.20 @@ -108,6 +111,8 @@ static struct {
    8.21  };
    8.22  
    8.23  
    8.24 +void initialize_xendbg(void);
    8.25 +
    8.26  void cmain(multiboot_info_t *mbi)
    8.27  {
    8.28      struct domain *new_dom;
    8.29 @@ -163,6 +168,8 @@ void cmain(multiboot_info_t *mbi)
    8.30  
    8.31      init_console();
    8.32  
    8.33 +    initialize_xendbg();
    8.34 +
    8.35      /* HELLO WORLD --- start-of-day banner text. */
    8.36      printk(XEN_BANNER);
    8.37      printk(" http://www.cl.cam.ac.uk/netos/xen\n");
     9.1 --- a/xen/common/keyhandler.c	Wed Jul 28 18:59:26 2004 +0000
     9.2 +++ b/xen/common/keyhandler.c	Thu Jul 29 12:00:06 2004 +0000
     9.3 @@ -115,6 +115,15 @@ extern void perfc_reset(unsigned char ke
     9.4                          struct pt_regs *regs);
     9.5  #endif
     9.6  
     9.7 +void do_debug_key(unsigned char key, void *dev_id, struct pt_regs *regs)
     9.8 +{
     9.9 +    extern void trap_to_xendbg(void);
    9.10 +    trap_to_xendbg();
    9.11 +    asm volatile ("nop"); /* Prevent the compiler doing tail call
    9.12 +			     optimisation, as that confuses xendbg a
    9.13 +			     bit. */
    9.14 +}
    9.15 +
    9.16  void initialize_keytable(void)
    9.17  {
    9.18      add_key_handler('d', dump_registers, "dump registers"); 
    9.19 @@ -128,4 +137,5 @@ void initialize_keytable(void)
    9.20      add_key_handler('p', perfc_printall, "print performance counters"); 
    9.21      add_key_handler('P', perfc_reset,    "reset performance counters"); 
    9.22  #endif
    9.23 +    add_key_handler('%', do_debug_key,   "Trap to xendbg");
    9.24  }
    10.1 --- a/xen/drivers/char/console.c	Wed Jul 28 18:59:26 2004 +0000
    10.2 +++ b/xen/drivers/char/console.c	Thu Jul 29 12:00:06 2004 +0000
    10.3 @@ -440,6 +440,8 @@ void console_endboot(int disable_vga)
    10.4   * **************************************************************
    10.5   */
    10.6  
    10.7 +extern void trap_to_xendbg(void);
    10.8 +
    10.9  void panic(const char *fmt, ...)
   10.10  {
   10.11      va_list args;
   10.12 @@ -450,7 +452,9 @@ void panic(const char *fmt, ...)
   10.13      va_start(args, fmt);
   10.14      (void)vsnprintf(buf, sizeof(buf), fmt, args);
   10.15      va_end(args);
   10.16 -    
   10.17 +
   10.18 +    trap_to_xendbg();
   10.19 +
   10.20      /* Spit out multiline message in one go. */
   10.21      spin_lock_irqsave(&console_lock, flags);
   10.22      __putstr("\n****************************************\n");
    11.1 --- a/xen/drivers/char/serial.c	Wed Jul 28 18:59:26 2004 +0000
    11.2 +++ b/xen/drivers/char/serial.c	Thu Jul 29 12:00:06 2004 +0000
    11.3 @@ -420,6 +420,30 @@ static int byte_matches(int handle, unsi
    11.4      return 0;
    11.5  }
    11.6  
    11.7 +unsigned char __serial_getc(int handle)
    11.8 +{
    11.9 +    uart_t *uart = &com[handle & SERHND_IDX];
   11.10 +    unsigned char c;
   11.11 +
   11.12 +    /* disable_irq() may have raced execution of uart_rx(). */
   11.13 +    while ( uart->rxbufp != uart->rxbufc )
   11.14 +    {
   11.15 +        c = uart->rxbuf[MASK_RXBUF_IDX(uart->rxbufc++)];
   11.16 +        if ( byte_matches(handle, &c) )
   11.17 +	  return c;
   11.18 +    }
   11.19 +
   11.20 +    /* We now wait for the UART to receive a suitable character. */
   11.21 +    do {
   11.22 +        while ( (inb(uart->io_base + LSR) & LSR_DR) == 0 )
   11.23 +            barrier();
   11.24 +        c = inb(uart->io_base + RBR);
   11.25 +    }
   11.26 +    while ( !byte_matches(handle, &c) );
   11.27 +
   11.28 +    return c;
   11.29 +}
   11.30 +
   11.31  unsigned char serial_getc(int handle)
   11.32  {
   11.33      uart_t *uart = &com[handle & SERHND_IDX];
   11.34 @@ -434,26 +458,11 @@ unsigned char serial_getc(int handle)
   11.35          if ( byte_matches(handle, &c) )
   11.36              goto out;
   11.37      }
   11.38 -    
   11.39 +
   11.40      disable_irq(uart->irq);
   11.41 -    
   11.42 -    /* disable_irq() may have raced execution of uart_rx(). */
   11.43 -    while ( uart->rxbufp != uart->rxbufc )
   11.44 -    {
   11.45 -        c = uart->rxbuf[MASK_RXBUF_IDX(uart->rxbufc++)];
   11.46 -        if ( byte_matches(handle, &c) )
   11.47 -            goto enable_and_out;
   11.48 -    }
   11.49  
   11.50 -    /* We now wait for the UART to receive a suitable character. */
   11.51 -    do {
   11.52 -        while ( (inb(uart->io_base + LSR) & LSR_DR) == 0 )
   11.53 -            barrier();
   11.54 -        c = inb(uart->io_base + RBR);
   11.55 -    }
   11.56 -    while ( !byte_matches(handle, &c) );
   11.57 -    
   11.58 - enable_and_out:
   11.59 +    c = __serial_getc(handle);
   11.60 +
   11.61      enable_irq(uart->irq);
   11.62   out:
   11.63      spin_unlock_irqrestore(&uart->lock, flags);