ia64/xen-unstable

annotate xen/common/gdbstub.c @ 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
children ec7802acc8c9
rev   line source
kaf24@8607 1 /*
kaf24@8607 2 * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
kaf24@8607 3 * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
kaf24@8607 4 * VA Linux Systems Japan. K.K.
kaf24@8607 5 *
kaf24@8607 6 * gdbstub arch neutral part
kaf24@8607 7 * Based on x86 cdb (xen/arch/x86/cdb.c) and ppc gdbstub(xen/common/gdbstub.c)
kaf24@8607 8 * But extensively modified.
kaf24@8607 9 *
kaf24@8607 10 * This program is free software; you can redistribute it and/or modify
kaf24@8607 11 * it under the terms of the GNU General Public License as published by
kaf24@8607 12 * the Free Software Foundation; either version 2 of the License, or
kaf24@8607 13 * (at your option) any later version.
kaf24@8607 14 *
kaf24@8607 15 * This program is distributed in the hope that it will be useful,
kaf24@8607 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
kaf24@8607 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kaf24@8607 18 * GNU General Public License for more details.
kaf24@8607 19 *
kaf24@8607 20 * You should have received a copy of the GNU General Public License
kaf24@8607 21 * along with this program; if not, write to the Free Software
kaf24@8607 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
kaf24@8607 23 */
kaf24@8607 24
kaf24@8607 25 /*
kaf24@8607 26 * gdbstub: implements the architecture independant parts of the
kaf24@8607 27 * gdb remote protocol.
kaf24@8607 28 */
kaf24@8607 29
kaf24@8607 30 /* We try to avoid assuming much about what the rest of the system is
kaf24@8607 31 doing. In particular, dynamic memory allocation is out of the
kaf24@8607 32 question. */
kaf24@8607 33
kaf24@8607 34 /* Resuming after we've stopped used to work, but more through luck
kaf24@8607 35 than any actual intention. It doesn't at the moment. */
kaf24@8607 36
kaf24@8607 37 #include <xen/lib.h>
kaf24@8607 38 #include <asm/uaccess.h>
kaf24@8607 39 #include <xen/spinlock.h>
kaf24@8607 40 #include <xen/serial.h>
kaf24@8607 41 #include <xen/irq.h>
kaf24@8607 42 #include <asm/debugger.h>
kaf24@8607 43 #include <xen/init.h>
kaf24@8607 44 #include <xen/smp.h>
kaf24@8607 45 #include <xen/console.h>
kaf24@8607 46
kaf24@8607 47 /* Printk isn't particularly safe just after we've trapped to the
kaf24@8607 48 debugger. so avoid it. */
kaf24@8607 49 #define dbg_printk(...)
kaf24@8607 50 /*#define dbg_printk(...) printk(__VA_ARGS__)*/
kaf24@8607 51
kaf24@8607 52 #define GDB_RETRY_MAX 10
kaf24@8607 53
kaf24@8607 54 static char opt_gdb[30] = "none";
kaf24@8607 55 string_param("gdb", opt_gdb);
kaf24@8607 56
kaf24@8607 57 /* value <-> char (de)serialzers */
kaf24@8607 58 char
kaf24@8607 59 hex2char(unsigned long x)
kaf24@8607 60 {
kaf24@8607 61 const char array[] = "0123456789abcdef";
kaf24@8607 62
kaf24@8607 63 return array[x & 15];
kaf24@8607 64 }
kaf24@8607 65
kaf24@8607 66 int
kaf24@8607 67 char2hex(unsigned char c)
kaf24@8607 68 {
kaf24@8607 69 if ( (c >= '0') && (c <= '9') )
kaf24@8607 70 return c - '0';
kaf24@8607 71 else if ( (c >= 'a') && (c <= 'f') )
kaf24@8607 72 return c - 'a' + 10;
kaf24@8607 73 else if ( (c >= 'A') && (c <= 'F') )
kaf24@8607 74 return c - 'A' + 10;
kaf24@8607 75 else
kaf24@8607 76 BUG();
kaf24@8607 77 return -1;
kaf24@8607 78 }
kaf24@8607 79
kaf24@8607 80 char
kaf24@8607 81 str2hex(const char *str)
kaf24@8607 82 {
kaf24@8607 83 return (char2hex(str[0]) << 4) | char2hex(str[1]);
kaf24@8607 84 }
kaf24@8607 85
kaf24@8607 86 unsigned long
kaf24@8607 87 str2ulong(const char *str, unsigned long bytes)
kaf24@8607 88 {
kaf24@8607 89 unsigned long x = 0;
kaf24@8607 90 unsigned long i = 0;
kaf24@8607 91
kaf24@8607 92 while ( *str && (i < (bytes * 2)) )
kaf24@8607 93 {
kaf24@8607 94 x <<= 4;
kaf24@8607 95 x += char2hex(*str);
kaf24@8607 96 ++str;
kaf24@8607 97 ++i;
kaf24@8607 98 }
kaf24@8607 99
kaf24@8607 100 return x;
kaf24@8607 101 }
kaf24@8607 102
kaf24@8607 103 /* gdb io wrappers */
kaf24@8607 104 static signed long
kaf24@8607 105 gdb_io_write(const char *buf, unsigned long len, struct gdb_context *ctx)
kaf24@8607 106 {
kaf24@8607 107 int i;
kaf24@8607 108 for ( i = 0; i < len; i++ )
kaf24@8607 109 serial_putc(ctx->serhnd, buf[i]);
kaf24@8607 110 return i;
kaf24@8607 111 }
kaf24@8607 112
kaf24@8607 113 static int
kaf24@8607 114 gdb_io_write_char(u8 data, struct gdb_context *ctx)
kaf24@8607 115 {
kaf24@8607 116 return gdb_io_write((char*)&data, 1, ctx);
kaf24@8607 117 }
kaf24@8607 118
kaf24@8607 119 static unsigned char
kaf24@8607 120 gdb_io_read(struct gdb_context *ctx)
kaf24@8607 121 {
kaf24@8607 122 return serial_getc(ctx->serhnd);
kaf24@8607 123 }
kaf24@8607 124
kaf24@8607 125 /* Receive a command. Returns -1 on csum error, 0 otherwise. */
kaf24@8607 126 /* Does not acknowledge. */
kaf24@8607 127 static int
kaf24@8607 128 attempt_receive_packet(struct gdb_context *ctx)
kaf24@8607 129 {
kaf24@8607 130 u8 csum;
kaf24@8607 131 u8 received_csum;
kaf24@8607 132 u8 ch;
kaf24@8607 133
kaf24@8607 134 /* Skip over everything up to the first '$' */
kaf24@8607 135 while ( (ch = gdb_io_read(ctx)) != '$' )
kaf24@8607 136 continue;
kaf24@8607 137
kaf24@8607 138 csum = 0;
kaf24@8607 139 for ( ctx->in_bytes = 0;
kaf24@8607 140 ctx->in_bytes < sizeof(ctx->in_buf);
kaf24@8607 141 ctx->in_bytes++ )
kaf24@8607 142 {
kaf24@8607 143 ch = gdb_io_read(ctx);
kaf24@8607 144 if ( ch == '#' )
kaf24@8607 145 break;
kaf24@8607 146 ctx->in_buf[ctx->in_bytes] = ch;
kaf24@8607 147 csum += ch;
kaf24@8607 148 }
kaf24@8607 149
kaf24@8607 150 if ( ctx->in_bytes == sizeof(ctx->in_buf) )
kaf24@8607 151 {
kaf24@8607 152 dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
kaf24@8607 153 return -1;
kaf24@8607 154 }
kaf24@8607 155
kaf24@8607 156 ctx->in_buf[ctx->in_bytes] = '\0';
kaf24@8607 157 received_csum = char2hex(gdb_io_read(ctx)) * 16 +
kaf24@8607 158 char2hex(gdb_io_read(ctx));
kaf24@8607 159
kaf24@8607 160 return (received_csum == csum) ? 0 : -1;
kaf24@8607 161 }
kaf24@8607 162
kaf24@8607 163 /* Receive a command, discarding up to ten packets with csum
kaf24@8607 164 * errors. Acknowledges all received packets. */
kaf24@8607 165 static int
kaf24@8607 166 receive_command(struct gdb_context *ctx)
kaf24@8607 167 {
kaf24@8607 168 int r, count = 0;
kaf24@8607 169
kaf24@8607 170 count = 0;
kaf24@8607 171 do {
kaf24@8607 172 r = attempt_receive_packet(ctx);
kaf24@8607 173 gdb_io_write_char((r < 0) ? '-' : '+', ctx);
kaf24@8607 174 count++;
kaf24@8607 175 } while ( (r < 0) && (count < GDB_RETRY_MAX) );
kaf24@8607 176
kaf24@8607 177 return r;
kaf24@8607 178 }
kaf24@8607 179
kaf24@8607 180 /* routines to send reply packets */
kaf24@8607 181
kaf24@8607 182 static void
kaf24@8607 183 gdb_start_packet(struct gdb_context *ctx)
kaf24@8607 184 {
kaf24@8607 185 ctx->out_buf[0] = '$';
kaf24@8607 186 ctx->out_offset = 1;
kaf24@8607 187 ctx->out_csum = 0;
kaf24@8607 188 }
kaf24@8607 189
kaf24@8607 190 static void
kaf24@8607 191 gdb_write_to_packet_char(u8 data, struct gdb_context *ctx)
kaf24@8607 192 {
kaf24@8607 193 ctx->out_csum += data;
kaf24@8607 194 ctx->out_buf[ctx->out_offset] = data;
kaf24@8607 195 ctx->out_offset++;
kaf24@8607 196 }
kaf24@8607 197
kaf24@8607 198 void
kaf24@8607 199 gdb_write_to_packet(const char *buf, int count, struct gdb_context *ctx)
kaf24@8607 200 {
kaf24@8607 201 int x;
kaf24@8607 202 for ( x = 0; x < count; x++ )
kaf24@8607 203 gdb_write_to_packet_char(buf[x], ctx);
kaf24@8607 204 }
kaf24@8607 205
kaf24@8607 206 void
kaf24@8607 207 gdb_write_to_packet_str(const char *buf, struct gdb_context *ctx)
kaf24@8607 208 {
kaf24@8607 209 gdb_write_to_packet(buf, strlen(buf), ctx);
kaf24@8607 210 }
kaf24@8607 211
kaf24@8607 212 void
kaf24@8607 213 gdb_write_to_packet_hex(unsigned long x, int int_size, struct gdb_context *ctx)
kaf24@8607 214 {
kaf24@8607 215 char buf[sizeof(unsigned long) * 2 + 1];
kaf24@8607 216 int i = sizeof(unsigned long) * 2;
kaf24@8607 217 int width = int_size * 2;
kaf24@8607 218
kaf24@8607 219 buf[sizeof(unsigned long) * 2] = 0;
kaf24@8607 220
kaf24@8607 221 switch ( int_size )
kaf24@8607 222 {
kaf24@8607 223 case sizeof(u8):
kaf24@8607 224 case sizeof(u16):
kaf24@8607 225 case sizeof(u32):
kaf24@8607 226 case sizeof(u64):
kaf24@8607 227 break;
kaf24@8607 228 default:
kaf24@8607 229 dbg_printk("WARNING: %s x: 0x%lx int_size: %d\n",
kaf24@8607 230 __func__, x, int_size);
kaf24@8607 231 break;
kaf24@8607 232 }
kaf24@8607 233
kaf24@8607 234 do {
kaf24@8607 235 buf[--i] = hex2char(x & 15);
kaf24@8607 236 x >>= 4;
kaf24@8607 237 } while ( x );
kaf24@8607 238
kaf24@8607 239 while ( (i + width) > (sizeof(unsigned long) * 2) )
kaf24@8607 240 buf[--i] = '0';
kaf24@8607 241
kaf24@8607 242 gdb_write_to_packet(&buf[i], width, ctx);
kaf24@8607 243 }
kaf24@8607 244
kaf24@8607 245 static int
kaf24@8607 246 gdb_check_ack(struct gdb_context *ctx)
kaf24@8607 247 {
kaf24@8607 248 u8 c = gdb_io_read(ctx);
kaf24@8607 249
kaf24@8607 250 switch ( c )
kaf24@8607 251 {
kaf24@8607 252 case '+':
kaf24@8607 253 return 1;
kaf24@8607 254 case '-':
kaf24@8607 255 return 0;
kaf24@8607 256 default:
kaf24@8607 257 printk("Bad ack: %c\n", c);
kaf24@8607 258 return 0;
kaf24@8607 259 }
kaf24@8607 260 }
kaf24@8607 261
kaf24@8607 262 /* Return 0 if the reply was successfully received, !0 otherwise. */
kaf24@8607 263 void
kaf24@8607 264 gdb_send_packet(struct gdb_context *ctx)
kaf24@8607 265 {
kaf24@8607 266 char buf[3];
kaf24@8607 267 int count;
kaf24@8607 268
kaf24@8607 269 sprintf(buf, "%.02x\n", ctx->out_csum);
kaf24@8607 270
kaf24@8607 271 gdb_write_to_packet_char('#', ctx);
kaf24@8607 272 gdb_write_to_packet(buf, 2, ctx);
kaf24@8607 273
kaf24@8607 274 count = 0;
kaf24@8607 275 do {
kaf24@8607 276 gdb_io_write(ctx->out_buf, ctx->out_offset, ctx);
kaf24@8607 277 } while ( !gdb_check_ack(ctx) && (count++ < GDB_RETRY_MAX) );
kaf24@8607 278
kaf24@8607 279 if ( count == GDB_RETRY_MAX )
kaf24@8607 280 dbg_printk("WARNING: %s reached max retry %d\n",
kaf24@8607 281 __func__, GDB_RETRY_MAX);
kaf24@8607 282 }
kaf24@8607 283
kaf24@8607 284 void
kaf24@8607 285 gdb_send_reply(const char *buf, struct gdb_context *ctx)
kaf24@8607 286 {
kaf24@8607 287 gdb_start_packet(ctx);
kaf24@8607 288 gdb_write_to_packet_str(buf, ctx);
kaf24@8607 289 gdb_send_packet(ctx);
kaf24@8607 290 }
kaf24@8607 291
kaf24@8607 292 /* arch neutral command handlers */
kaf24@8607 293
kaf24@8607 294 static void
kaf24@8607 295 gdb_cmd_signum(struct gdb_context *ctx)
kaf24@8607 296 {
kaf24@8607 297 gdb_write_to_packet_char('S', ctx);
kaf24@8607 298 gdb_write_to_packet_hex(ctx->signum, sizeof(ctx->signum), ctx);
kaf24@8607 299 gdb_send_packet(ctx);
kaf24@8607 300 }
kaf24@8607 301
kaf24@8607 302 static void
kaf24@8607 303 gdb_cmd_read_mem(unsigned long addr, unsigned long length,
kaf24@8607 304 struct gdb_context *ctx)
kaf24@8607 305 {
kaf24@8607 306 int x, r;
kaf24@8607 307 unsigned char val;
kaf24@8607 308
kaf24@8607 309 dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
kaf24@8607 310 length);
kaf24@8607 311
kaf24@8607 312 for ( x = 0; x < length; x++ )
kaf24@8607 313 {
kaf24@8607 314 r = gdb_arch_copy_from_user(&val, (void *)(addr + x), 1);
kaf24@8607 315 if ( r != 0 )
kaf24@8607 316 {
kaf24@8607 317 dbg_printk("Error reading from %lx.\n", addr + x);
kaf24@8607 318 break;
kaf24@8607 319 }
kaf24@8607 320 gdb_write_to_packet_hex(val, sizeof(val), ctx);
kaf24@8607 321 }
kaf24@8607 322
kaf24@8607 323 if ( x == 0 )
kaf24@8607 324 gdb_write_to_packet_str("E05", ctx);
kaf24@8607 325
kaf24@8607 326 dbg_printk("Read done.\n");
kaf24@8607 327
kaf24@8607 328 gdb_send_packet(ctx);
kaf24@8607 329 }
kaf24@8607 330
kaf24@8607 331 static void
kaf24@8607 332 gdb_cmd_write_mem(unsigned long addr, unsigned long length,
kaf24@8607 333 const char *buf, struct gdb_context *ctx)
kaf24@8607 334 {
kaf24@8607 335 int x, r;
kaf24@8607 336 unsigned char val;
kaf24@8607 337
kaf24@8607 338 dbg_printk("Memory write starting at %lx, length %lx.\n", addr, length);
kaf24@8607 339
kaf24@8607 340 for ( x = 0; x < length; x++, addr++, buf += 2 )
kaf24@8607 341 {
kaf24@8607 342 val = str2ulong(buf, sizeof(val));
kaf24@8607 343 r = gdb_arch_copy_to_user((void*)addr, (void*)&val, 1);
kaf24@8607 344 if ( r != 0 )
kaf24@8607 345 {
kaf24@8607 346 dbg_printk("Error writing to %lx.\n", addr);
kaf24@8607 347 break;
kaf24@8607 348 }
kaf24@8607 349 }
kaf24@8607 350
kaf24@8607 351 gdb_write_to_packet_str((x != length) ? "OK" : "E11", ctx);
kaf24@8607 352
kaf24@8607 353 dbg_printk("Write done.\n");
kaf24@8607 354
kaf24@8607 355 gdb_send_packet(ctx);
kaf24@8607 356 }
kaf24@8607 357
kaf24@8607 358 /* command dispatcher */
kaf24@8607 359 static int
kaf24@8607 360 process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
kaf24@8607 361 {
kaf24@8607 362 char *ptr;
kaf24@8607 363 unsigned long addr, length;
kaf24@8607 364 int resume = 0;
kaf24@8607 365
kaf24@8607 366 /* XXX check ctx->in_bytes >= 2 or similar. */
kaf24@8607 367
kaf24@8607 368 gdb_start_packet(ctx);
kaf24@8607 369 switch ( ctx->in_buf[0] )
kaf24@8607 370 {
kaf24@8607 371 case '?': /* query signal number */
kaf24@8607 372 gdb_cmd_signum(ctx);
kaf24@8607 373 break;
kaf24@8607 374 case 'H': /* thread operations */
kaf24@8607 375 gdb_send_reply("OK", ctx);
kaf24@8607 376 break;
kaf24@8607 377 case 'g': /* Read registers */
kaf24@8607 378 gdb_arch_read_reg_array(regs, ctx);
kaf24@8607 379 ASSERT(!local_irq_is_enabled());
kaf24@8607 380 break;
kaf24@8607 381 case 'G': /* Write registers */
kaf24@8607 382 gdb_arch_write_reg_array(regs, ctx->in_buf + 1, ctx);
kaf24@8607 383 break;
kaf24@8607 384 case 'm': /* Read memory */
kaf24@8607 385 addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
kaf24@8607 386 if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
kaf24@8607 387 {
kaf24@8607 388 gdb_send_reply("E03", ctx);
kaf24@8607 389 return 0;
kaf24@8607 390 }
kaf24@8607 391 length = simple_strtoul(ptr + 1, &ptr, 16);
kaf24@8607 392 if ( ptr[0] != 0 )
kaf24@8607 393 {
kaf24@8607 394 gdb_send_reply("E04", ctx);
kaf24@8607 395 return 0;
kaf24@8607 396 }
kaf24@8607 397 gdb_cmd_read_mem(addr, length, ctx);
kaf24@8607 398 ASSERT(!local_irq_is_enabled());
kaf24@8607 399 break;
kaf24@8607 400 case 'M': /* Write memory */
kaf24@8607 401 addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
kaf24@8607 402 if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ':') )
kaf24@8607 403 {
kaf24@8607 404 gdb_send_reply("E03", ctx);
kaf24@8607 405 return 0;
kaf24@8607 406 }
kaf24@8607 407 length = simple_strtoul(ptr + 1, &ptr, 16);
kaf24@8607 408 gdb_cmd_write_mem(addr, length, ptr, ctx);
kaf24@8607 409 break;
kaf24@8607 410 case 'p': /* read register */
kaf24@8607 411 addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
kaf24@8607 412 if ( ptr == (ctx->in_buf + 1) )
kaf24@8607 413 {
kaf24@8607 414 gdb_send_reply("E03", ctx);
kaf24@8607 415 return 0;
kaf24@8607 416 }
kaf24@8607 417 if ( ptr[0] != 0 )
kaf24@8607 418 {
kaf24@8607 419 gdb_send_reply("E04", ctx);
kaf24@8607 420 return 0;
kaf24@8607 421 }
kaf24@8607 422 gdb_arch_read_reg(addr, regs, ctx);
kaf24@8607 423 break;
kaf24@8607 424 case 'Z': /* We need to claim to support these or gdb
kaf24@8607 425 won't let you continue the process. */
kaf24@8607 426 case 'z':
kaf24@8607 427 gdb_send_reply("OK", ctx);
kaf24@8607 428 break;
kaf24@8607 429
kaf24@8607 430 case 'D':
kaf24@8607 431 ctx->currently_attached = 0;
kaf24@8607 432 gdb_send_reply("OK", ctx);
kaf24@8607 433 /* fall through */
kaf24@8607 434 case 'k':
kaf24@8607 435 ctx->connected = 0;
kaf24@8607 436 /* fall through */
kaf24@8607 437 case 's': /* Single step */
kaf24@8607 438 case 'c': /* Resume at current address */
kaf24@8607 439 {
kaf24@8607 440 unsigned long addr = ~((unsigned long)0);
kaf24@8607 441 unsigned long type = GDB_CONTINUE;
kaf24@8607 442 if ( ctx->in_buf[0] == 's' )
kaf24@8607 443 type = GDB_STEP;
kaf24@8607 444 if ( ((ctx->in_buf[0] == 's') || (ctx->in_buf[0] == 'c')) &&
kaf24@8607 445 ctx->in_buf[1] )
kaf24@8607 446 addr = str2ulong(&ctx->in_buf[1], sizeof(unsigned long));
kaf24@8607 447 if ( ctx->in_buf[0] != 'D' )
kaf24@8607 448 ctx->currently_attached = 1;
kaf24@8607 449 resume = 1;
kaf24@8607 450 gdb_arch_resume(regs, addr, type, ctx);
kaf24@8607 451 break;
kaf24@8607 452 }
kaf24@8607 453
kaf24@8607 454 default:
kaf24@8607 455 gdb_send_reply("", ctx);
kaf24@8607 456 break;
kaf24@8607 457 }
kaf24@8607 458 return resume;
kaf24@8607 459 }
kaf24@8607 460
kaf24@8607 461 static struct gdb_context
kaf24@8607 462 __gdb_ctx = {
kaf24@8607 463 .serhnd = -1,
kaf24@8607 464 .currently_attached = 0,
kaf24@8607 465 .running = ATOMIC_INIT(1),
kaf24@8607 466 .connected = 0,
kaf24@8607 467 .signum = 1,
kaf24@8607 468 .in_bytes = 0,
kaf24@8607 469 .out_offset = 0,
kaf24@8607 470 .out_csum = 0,
kaf24@8607 471 };
kaf24@8607 472 static struct gdb_context *gdb_ctx = &__gdb_ctx;
kaf24@8607 473
kaf24@8607 474 /* trap handler: main entry point */
kaf24@8607 475 int
kaf24@8607 476 __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
kaf24@8607 477 {
kaf24@8607 478 int resume = 0;
kaf24@8607 479 int r;
kaf24@8607 480 unsigned flags;
kaf24@8607 481
kaf24@8607 482 if ( gdb_ctx->serhnd < 0 )
kaf24@8607 483 {
kaf24@8607 484 dbg_printk("Debugger not ready yet.\n");
kaf24@8607 485 return 0;
kaf24@8607 486 }
kaf24@8607 487
kaf24@8607 488 /* We rely on our caller to ensure we're only on one processor
kaf24@8607 489 * at a time... We should probably panic here, but given that
kaf24@8607 490 * we're a debugger we should probably be a little tolerant of
kaf24@8607 491 * things going wrong. */
kaf24@8607 492 /* We don't want to use a spin lock here, because we're doing
kaf24@8607 493 two distinct things:
kaf24@8607 494
kaf24@8607 495 1 -- we don't want to run on more than one processor at a time,
kaf24@8607 496 and
kaf24@8607 497 2 -- we want to do something sensible if we re-enter ourselves.
kaf24@8607 498
kaf24@8607 499 Spin locks are good for 1, but useless for 2. */
kaf24@8607 500 if ( !atomic_dec_and_test(&gdb_ctx->running) )
kaf24@8607 501 {
kaf24@8607 502 printk("WARNING WARNING WARNING: Avoiding recursive gdb.\n");
kaf24@8607 503 atomic_inc(&gdb_ctx->running);
kaf24@8607 504 return 0;
kaf24@8607 505 }
kaf24@8607 506
kaf24@8607 507 if ( !gdb_ctx->connected )
kaf24@8607 508 {
kaf24@8607 509 printk("GDB connection activated\n");
kaf24@8607 510 gdb_arch_print_state(regs);
kaf24@8607 511 gdb_ctx->connected = 1;
kaf24@8607 512 }
kaf24@8607 513
kaf24@8607 514 smp_send_stop();
kaf24@8607 515
kaf24@8607 516 /* Try to make things a little more stable by disabling
kaf24@8607 517 interrupts while we're here. */
kaf24@8607 518 local_irq_save(flags);
kaf24@8607 519
kaf24@8607 520 watchdog_disable();
kaf24@8607 521 console_start_sync();
kaf24@8607 522
kaf24@8607 523 /* Shouldn't really do this, but otherwise we stop for no
kaf24@8607 524 obvious reason, which is Bad */
kaf24@8607 525 printk("Waiting for GDB to attach to Gdb\n");
kaf24@8607 526
kaf24@8607 527 gdb_arch_enter(regs);
kaf24@8607 528 gdb_ctx->signum = gdb_arch_signal_num(regs, cookie);
kaf24@8607 529 /* If gdb is already attached, tell it we've stopped again. */
kaf24@8607 530 if ( gdb_ctx->currently_attached )
kaf24@8607 531 {
kaf24@8607 532 gdb_start_packet(gdb_ctx);
kaf24@8607 533 gdb_cmd_signum(gdb_ctx);
kaf24@8607 534 }
kaf24@8607 535
kaf24@8607 536 while ( resume == 0 )
kaf24@8607 537 {
kaf24@8607 538 ASSERT(!local_irq_is_enabled());
kaf24@8607 539 r = receive_command(gdb_ctx);
kaf24@8607 540 ASSERT(!local_irq_is_enabled());
kaf24@8607 541 if ( r < 0 )
kaf24@8607 542 {
kaf24@8607 543 dbg_printk("GDB disappeared, trying to resume Xen...\n");
kaf24@8607 544 resume = 1;
kaf24@8607 545 }
kaf24@8607 546 else
kaf24@8607 547 {
kaf24@8607 548 ASSERT(!local_irq_is_enabled());
kaf24@8607 549 resume = process_command(regs, gdb_ctx);
kaf24@8607 550 ASSERT(!local_irq_is_enabled());
kaf24@8607 551 }
kaf24@8607 552 }
kaf24@8607 553
kaf24@8607 554 gdb_arch_exit(regs);
kaf24@8607 555 console_end_sync();
kaf24@8607 556 watchdog_enable();
kaf24@8607 557 atomic_inc(&gdb_ctx->running);
kaf24@8607 558
kaf24@8607 559 local_irq_restore(flags);
kaf24@8607 560
kaf24@8607 561 return 0;
kaf24@8607 562 }
kaf24@8607 563
kaf24@8607 564 /*
kaf24@8607 565 * initialization
kaf24@8607 566 * XXX TODO
kaf24@8607 567 * This should be an explicit call from architecture code.
kaf24@8607 568 * initcall is far too late for some early debugging, and only the
kaf24@8607 569 * architecture code knows when this call can be made.
kaf24@8607 570 */
kaf24@8607 571 static int
kaf24@8607 572 initialize_gdb(void)
kaf24@8607 573 {
kaf24@8607 574 if ( !strcmp(opt_gdb, "none") )
kaf24@8607 575 return 0;
kaf24@8607 576 gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
kaf24@8607 577 if ( gdb_ctx->serhnd == -1 )
kaf24@8607 578 panic("Can't parse %s as GDB serial info.\n", opt_gdb);
kaf24@8607 579
kaf24@8607 580 printk("Gdb initialised.\n");
kaf24@8607 581 return 0;
kaf24@8607 582 }
kaf24@8607 583
kaf24@8607 584 __initcall(initialize_gdb);
kaf24@8607 585
kaf24@8607 586 /*
kaf24@8607 587 * Local variables:
kaf24@8607 588 * mode: C
kaf24@8607 589 * c-set-style: "BSD"
kaf24@8607 590 * c-basic-offset: 4
kaf24@8607 591 * tab-width: 4
kaf24@8607 592 * End:
kaf24@8607 593 */