ia64/xen-unstable

annotate xen/common/gdbstub.c @ 19835:edfdeb150f27

Fix buildsystem to detect udev > version 124

udev removed the udevinfo symlink from versions higher than 123 and
xen's build-system could not detect if udev is in place and has the
required version.

Signed-off-by: Marc-A. Dahlhaus <mad@wol.de>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 25 13:02:37 2009 +0100 (2009-06-25)
parents 7dfc0a20fa59
children
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 <xen/spinlock.h>
kaf24@8607 39 #include <xen/serial.h>
kaf24@8607 40 #include <xen/irq.h>
kaf24@8607 41 #include <asm/debugger.h>
kaf24@8607 42 #include <xen/init.h>
kaf24@8607 43 #include <xen/smp.h>
kaf24@8607 44 #include <xen/console.h>
hollisb@12983 45 #include <xen/errno.h>
keir@16667 46 #include <xen/delay.h>
keir@16599 47 #include <asm/byteorder.h>
kaf24@8607 48
kaf24@8607 49 /* Printk isn't particularly safe just after we've trapped to the
kaf24@8607 50 debugger. so avoid it. */
kaf24@8607 51 #define dbg_printk(...)
kaf24@8607 52 /*#define dbg_printk(...) printk(__VA_ARGS__)*/
kaf24@8607 53
kaf24@8607 54 #define GDB_RETRY_MAX 10
kaf24@8607 55
keir@16667 56 struct gdb_cpu_info
keir@16667 57 {
keir@16667 58 atomic_t paused;
keir@16667 59 atomic_t ack;
keir@16667 60 };
keir@16667 61
keir@16667 62 static struct gdb_cpu_info gdb_cpu[NR_CPUS];
keir@16667 63 static atomic_t gdb_smp_paused_count;
keir@16667 64
keir@16667 65 static void gdb_smp_pause(void);
keir@16667 66 static void gdb_smp_resume(void);
keir@16667 67
keir@18487 68 static char opt_gdb[30];
kaf24@8607 69 string_param("gdb", opt_gdb);
kaf24@8607 70
kaf24@11627 71 static void gdbstub_console_puts(const char *str);
kaf24@11627 72
kaf24@8607 73 /* value <-> char (de)serialzers */
kaf24@8607 74 char
kaf24@8607 75 hex2char(unsigned long x)
kaf24@8607 76 {
kaf24@8607 77 const char array[] = "0123456789abcdef";
kaf24@8607 78
kaf24@8607 79 return array[x & 15];
kaf24@8607 80 }
kaf24@8607 81
kaf24@8607 82 int
kaf24@8607 83 char2hex(unsigned char c)
kaf24@8607 84 {
kaf24@8607 85 if ( (c >= '0') && (c <= '9') )
kaf24@8607 86 return c - '0';
kaf24@8607 87 else if ( (c >= 'a') && (c <= 'f') )
kaf24@8607 88 return c - 'a' + 10;
kaf24@8607 89 else if ( (c >= 'A') && (c <= 'F') )
kaf24@8607 90 return c - 'A' + 10;
kaf24@8607 91 else
kaf24@8607 92 BUG();
kaf24@8607 93 return -1;
kaf24@8607 94 }
kaf24@8607 95
kaf24@8607 96 char
kaf24@8607 97 str2hex(const char *str)
kaf24@8607 98 {
kaf24@8607 99 return (char2hex(str[0]) << 4) | char2hex(str[1]);
kaf24@8607 100 }
kaf24@8607 101
kaf24@8607 102 unsigned long
kaf24@8607 103 str2ulong(const char *str, unsigned long bytes)
kaf24@8607 104 {
kaf24@8607 105 unsigned long x = 0;
kaf24@8607 106 unsigned long i = 0;
kaf24@8607 107
kaf24@8607 108 while ( *str && (i < (bytes * 2)) )
kaf24@8607 109 {
kaf24@8607 110 x <<= 4;
kaf24@8607 111 x += char2hex(*str);
kaf24@8607 112 ++str;
kaf24@8607 113 ++i;
kaf24@8607 114 }
kaf24@8607 115
kaf24@8607 116 return x;
kaf24@8607 117 }
kaf24@8607 118
kaf24@8607 119 /* gdb io wrappers */
kaf24@8607 120 static signed long
kaf24@8607 121 gdb_io_write(const char *buf, unsigned long len, struct gdb_context *ctx)
kaf24@8607 122 {
kaf24@8607 123 int i;
kaf24@8607 124 for ( i = 0; i < len; i++ )
kaf24@8607 125 serial_putc(ctx->serhnd, buf[i]);
kaf24@8607 126 return i;
kaf24@8607 127 }
kaf24@8607 128
kaf24@8607 129 static int
kaf24@8607 130 gdb_io_write_char(u8 data, struct gdb_context *ctx)
kaf24@8607 131 {
kaf24@8607 132 return gdb_io_write((char*)&data, 1, ctx);
kaf24@8607 133 }
kaf24@8607 134
kaf24@8607 135 static unsigned char
kaf24@8607 136 gdb_io_read(struct gdb_context *ctx)
kaf24@8607 137 {
kaf24@8607 138 return serial_getc(ctx->serhnd);
kaf24@8607 139 }
kaf24@8607 140
kaf24@8607 141 /* Receive a command. Returns -1 on csum error, 0 otherwise. */
kaf24@8607 142 /* Does not acknowledge. */
kaf24@8607 143 static int
kaf24@8607 144 attempt_receive_packet(struct gdb_context *ctx)
kaf24@8607 145 {
kaf24@8607 146 u8 csum;
kaf24@8607 147 u8 received_csum;
kaf24@8607 148 u8 ch;
kaf24@8607 149
kaf24@8607 150 /* Skip over everything up to the first '$' */
kaf24@8607 151 while ( (ch = gdb_io_read(ctx)) != '$' )
kaf24@8607 152 continue;
kaf24@8607 153
kaf24@8607 154 csum = 0;
kaf24@8607 155 for ( ctx->in_bytes = 0;
kaf24@8607 156 ctx->in_bytes < sizeof(ctx->in_buf);
kaf24@8607 157 ctx->in_bytes++ )
kaf24@8607 158 {
kaf24@8607 159 ch = gdb_io_read(ctx);
kaf24@8607 160 if ( ch == '#' )
kaf24@8607 161 break;
kaf24@8607 162 ctx->in_buf[ctx->in_bytes] = ch;
kaf24@8607 163 csum += ch;
kaf24@8607 164 }
kaf24@8607 165
kaf24@8607 166 if ( ctx->in_bytes == sizeof(ctx->in_buf) )
kaf24@8607 167 {
kaf24@8607 168 dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
kaf24@8607 169 return -1;
kaf24@8607 170 }
kaf24@8607 171
kaf24@8607 172 ctx->in_buf[ctx->in_bytes] = '\0';
kaf24@8607 173 received_csum = char2hex(gdb_io_read(ctx)) * 16 +
kaf24@8607 174 char2hex(gdb_io_read(ctx));
kaf24@8607 175
kaf24@8607 176 return (received_csum == csum) ? 0 : -1;
kaf24@8607 177 }
kaf24@8607 178
kaf24@8607 179 /* Receive a command, discarding up to ten packets with csum
kaf24@8607 180 * errors. Acknowledges all received packets. */
kaf24@8607 181 static int
kaf24@8607 182 receive_command(struct gdb_context *ctx)
kaf24@8607 183 {
kaf24@8607 184 int r, count = 0;
kaf24@8607 185
kaf24@8607 186 count = 0;
kaf24@8607 187 do {
kaf24@8607 188 r = attempt_receive_packet(ctx);
kaf24@8607 189 gdb_io_write_char((r < 0) ? '-' : '+', ctx);
kaf24@8607 190 count++;
kaf24@8607 191 } while ( (r < 0) && (count < GDB_RETRY_MAX) );
kaf24@8607 192
kaf24@8607 193 return r;
kaf24@8607 194 }
kaf24@8607 195
kaf24@8607 196 /* routines to send reply packets */
kaf24@8607 197
kaf24@8607 198 static void
kaf24@8607 199 gdb_start_packet(struct gdb_context *ctx)
kaf24@8607 200 {
kaf24@8607 201 ctx->out_buf[0] = '$';
kaf24@8607 202 ctx->out_offset = 1;
kaf24@8607 203 ctx->out_csum = 0;
kaf24@8607 204 }
kaf24@8607 205
kaf24@8607 206 static void
kaf24@8607 207 gdb_write_to_packet_char(u8 data, struct gdb_context *ctx)
kaf24@8607 208 {
kaf24@8607 209 ctx->out_csum += data;
kaf24@8607 210 ctx->out_buf[ctx->out_offset] = data;
kaf24@8607 211 ctx->out_offset++;
kaf24@8607 212 }
kaf24@8607 213
kaf24@8607 214 void
kaf24@8607 215 gdb_write_to_packet(const char *buf, int count, struct gdb_context *ctx)
kaf24@8607 216 {
kaf24@8607 217 int x;
kaf24@8607 218 for ( x = 0; x < count; x++ )
kaf24@8607 219 gdb_write_to_packet_char(buf[x], ctx);
kaf24@8607 220 }
kaf24@8607 221
kaf24@8607 222 void
kaf24@8607 223 gdb_write_to_packet_str(const char *buf, struct gdb_context *ctx)
kaf24@8607 224 {
kaf24@8607 225 gdb_write_to_packet(buf, strlen(buf), ctx);
kaf24@8607 226 }
kaf24@8607 227
kaf24@8607 228 void
kaf24@8607 229 gdb_write_to_packet_hex(unsigned long x, int int_size, struct gdb_context *ctx)
kaf24@8607 230 {
kaf24@8607 231 char buf[sizeof(unsigned long) * 2 + 1];
keir@16599 232 int i, width = int_size * 2;
kaf24@8607 233
kaf24@8607 234 buf[sizeof(unsigned long) * 2] = 0;
kaf24@8607 235
kaf24@8607 236 switch ( int_size )
kaf24@8607 237 {
kaf24@8607 238 case sizeof(u8):
kaf24@8607 239 case sizeof(u16):
kaf24@8607 240 case sizeof(u32):
kaf24@8607 241 case sizeof(u64):
kaf24@8607 242 break;
kaf24@8607 243 default:
kaf24@8607 244 dbg_printk("WARNING: %s x: 0x%lx int_size: %d\n",
kaf24@8607 245 __func__, x, int_size);
kaf24@8607 246 break;
kaf24@8607 247 }
kaf24@8607 248
keir@16599 249 #ifdef __BIG_ENDIAN
keir@16667 250 i = sizeof(unsigned long) * 2
kaf24@8607 251 do {
kaf24@8607 252 buf[--i] = hex2char(x & 15);
kaf24@8607 253 x >>= 4;
kaf24@8607 254 } while ( x );
kaf24@8607 255
kaf24@8607 256 while ( (i + width) > (sizeof(unsigned long) * 2) )
kaf24@8607 257 buf[--i] = '0';
kaf24@8607 258
kaf24@8607 259 gdb_write_to_packet(&buf[i], width, ctx);
keir@16599 260 #elif defined(__LITTLE_ENDIAN)
keir@16667 261 i = 0;
keir@16667 262 while ( i < width )
keir@16667 263 {
keir@16667 264 buf[i++] = hex2char(x>>4);
keir@16667 265 buf[i++] = hex2char(x);
keir@16667 266 x >>= 8;
keir@16667 267 }
keir@16667 268 gdb_write_to_packet(buf, width, ctx);
keir@16599 269 #else
keir@16599 270 # error unknown endian
keir@16599 271 #endif
kaf24@8607 272 }
kaf24@8607 273
kaf24@8607 274 static int
kaf24@8607 275 gdb_check_ack(struct gdb_context *ctx)
kaf24@8607 276 {
kaf24@8607 277 u8 c = gdb_io_read(ctx);
kaf24@8607 278
kaf24@8607 279 switch ( c )
kaf24@8607 280 {
kaf24@8607 281 case '+':
kaf24@8607 282 return 1;
kaf24@8607 283 case '-':
kaf24@8607 284 return 0;
kaf24@8607 285 default:
kaf24@8607 286 printk("Bad ack: %c\n", c);
kaf24@8607 287 return 0;
kaf24@8607 288 }
kaf24@8607 289 }
kaf24@8607 290
kaf24@8607 291 /* Return 0 if the reply was successfully received, !0 otherwise. */
kaf24@8607 292 void
kaf24@8607 293 gdb_send_packet(struct gdb_context *ctx)
kaf24@8607 294 {
kaf24@8607 295 char buf[3];
kaf24@8607 296 int count;
kaf24@8607 297
kfraser@13685 298 snprintf(buf, sizeof(buf), "%.02x\n", ctx->out_csum);
kaf24@8607 299
kaf24@8607 300 gdb_write_to_packet_char('#', ctx);
kaf24@8607 301 gdb_write_to_packet(buf, 2, ctx);
kaf24@8607 302
kaf24@8607 303 count = 0;
kaf24@8607 304 do {
kaf24@8607 305 gdb_io_write(ctx->out_buf, ctx->out_offset, ctx);
kaf24@8607 306 } while ( !gdb_check_ack(ctx) && (count++ < GDB_RETRY_MAX) );
kaf24@8607 307
kaf24@8607 308 if ( count == GDB_RETRY_MAX )
kaf24@8607 309 dbg_printk("WARNING: %s reached max retry %d\n",
kaf24@8607 310 __func__, GDB_RETRY_MAX);
kaf24@8607 311 }
kaf24@8607 312
kaf24@8607 313 void
kaf24@8607 314 gdb_send_reply(const char *buf, struct gdb_context *ctx)
kaf24@8607 315 {
kaf24@8607 316 gdb_start_packet(ctx);
kaf24@8607 317 gdb_write_to_packet_str(buf, ctx);
kaf24@8607 318 gdb_send_packet(ctx);
kaf24@8607 319 }
kaf24@8607 320
kaf24@8607 321 /* arch neutral command handlers */
kaf24@8607 322
kaf24@8607 323 static void
kaf24@8607 324 gdb_cmd_signum(struct gdb_context *ctx)
kaf24@8607 325 {
kaf24@8607 326 gdb_write_to_packet_char('S', ctx);
kaf24@8607 327 gdb_write_to_packet_hex(ctx->signum, sizeof(ctx->signum), ctx);
kaf24@8607 328 gdb_send_packet(ctx);
kaf24@8607 329 }
kaf24@8607 330
kaf24@8607 331 static void
kaf24@8607 332 gdb_cmd_read_mem(unsigned long addr, unsigned long length,
kaf24@8607 333 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 read starting at %lx, length %lx.\n", addr,
kaf24@8607 339 length);
kaf24@8607 340
kaf24@8607 341 for ( x = 0; x < length; x++ )
kaf24@8607 342 {
kaf24@8607 343 r = gdb_arch_copy_from_user(&val, (void *)(addr + x), 1);
kaf24@8607 344 if ( r != 0 )
kaf24@8607 345 {
kaf24@8607 346 dbg_printk("Error reading from %lx.\n", addr + x);
kaf24@8607 347 break;
kaf24@8607 348 }
kaf24@8607 349 gdb_write_to_packet_hex(val, sizeof(val), ctx);
kaf24@8607 350 }
kaf24@8607 351
kaf24@8607 352 if ( x == 0 )
kaf24@8607 353 gdb_write_to_packet_str("E05", ctx);
kaf24@8607 354
kaf24@8607 355 dbg_printk("Read done.\n");
kaf24@8607 356
kaf24@8607 357 gdb_send_packet(ctx);
kaf24@8607 358 }
kaf24@8607 359
kaf24@8607 360 static void
kaf24@8607 361 gdb_cmd_write_mem(unsigned long addr, unsigned long length,
kaf24@8607 362 const char *buf, struct gdb_context *ctx)
kaf24@8607 363 {
kaf24@8607 364 int x, r;
kaf24@8607 365 unsigned char val;
kaf24@8607 366
kaf24@8607 367 dbg_printk("Memory write starting at %lx, length %lx.\n", addr, length);
kaf24@8607 368
kaf24@8607 369 for ( x = 0; x < length; x++, addr++, buf += 2 )
kaf24@8607 370 {
kaf24@8607 371 val = str2ulong(buf, sizeof(val));
kaf24@8607 372 r = gdb_arch_copy_to_user((void*)addr, (void*)&val, 1);
kaf24@8607 373 if ( r != 0 )
kaf24@8607 374 {
kaf24@8607 375 dbg_printk("Error writing to %lx.\n", addr);
kaf24@8607 376 break;
kaf24@8607 377 }
kaf24@8607 378 }
kaf24@8607 379
kaf24@9179 380 if (x == length)
kaf24@9179 381 gdb_write_to_packet_str("OK", ctx);
kaf24@9179 382 else
kaf24@9179 383 gdb_write_to_packet_str("E11", ctx);
kaf24@8607 384
kaf24@8607 385 dbg_printk("Write done.\n");
kaf24@8607 386
kaf24@8607 387 gdb_send_packet(ctx);
kaf24@8607 388 }
kaf24@8607 389
kfraser@11602 390 static void
kfraser@11602 391 gdbstub_attach(struct gdb_context *ctx)
kfraser@11602 392 {
kfraser@11602 393 if ( ctx->currently_attached )
kfraser@11602 394 return;
kfraser@11602 395 ctx->currently_attached = 1;
kfraser@11602 396 ctx->console_steal_id = console_steal(ctx->serhnd, gdbstub_console_puts);
kfraser@11602 397 }
kfraser@11602 398
kfraser@11602 399 static void
kfraser@11602 400 gdbstub_detach(struct gdb_context *ctx)
kfraser@11602 401 {
kfraser@11602 402 if ( !ctx->currently_attached )
kfraser@11602 403 return;
kfraser@11602 404 ctx->currently_attached = 0;
kfraser@11602 405 console_giveback(ctx->console_steal_id);
kfraser@11602 406 }
kfraser@11602 407
kaf24@8607 408 /* command dispatcher */
kaf24@8607 409 static int
kaf24@8607 410 process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
kaf24@8607 411 {
kaf24@13172 412 const char *ptr;
keir@16667 413 unsigned long addr, length, val;
kaf24@8607 414 int resume = 0;
keir@16667 415 unsigned long type = GDB_CONTINUE;
kaf24@8607 416
kaf24@8607 417 /* XXX check ctx->in_bytes >= 2 or similar. */
kaf24@8607 418
kaf24@8607 419 gdb_start_packet(ctx);
kaf24@8607 420 switch ( ctx->in_buf[0] )
kaf24@8607 421 {
kaf24@8607 422 case '?': /* query signal number */
kaf24@8607 423 gdb_cmd_signum(ctx);
kaf24@8607 424 break;
kaf24@8607 425 case 'H': /* thread operations */
kaf24@8607 426 gdb_send_reply("OK", ctx);
kaf24@8607 427 break;
kaf24@8607 428 case 'g': /* Read registers */
kaf24@8607 429 gdb_arch_read_reg_array(regs, ctx);
kaf24@8607 430 break;
kaf24@8607 431 case 'G': /* Write registers */
kaf24@8607 432 gdb_arch_write_reg_array(regs, ctx->in_buf + 1, ctx);
kaf24@8607 433 break;
kaf24@8607 434 case 'm': /* Read memory */
kaf24@8607 435 addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
kaf24@8607 436 if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
kaf24@8607 437 {
kaf24@8607 438 gdb_send_reply("E03", ctx);
kaf24@8607 439 return 0;
kaf24@8607 440 }
kaf24@8607 441 length = simple_strtoul(ptr + 1, &ptr, 16);
kaf24@8607 442 if ( ptr[0] != 0 )
kaf24@8607 443 {
kaf24@8607 444 gdb_send_reply("E04", ctx);
kaf24@8607 445 return 0;
kaf24@8607 446 }
kaf24@8607 447 gdb_cmd_read_mem(addr, length, ctx);
kaf24@8607 448 break;
kaf24@8607 449 case 'M': /* Write memory */
kaf24@8607 450 addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
kaf24@9179 451 if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
kaf24@8607 452 {
kaf24@8607 453 gdb_send_reply("E03", ctx);
kaf24@8607 454 return 0;
kaf24@8607 455 }
kaf24@8607 456 length = simple_strtoul(ptr + 1, &ptr, 16);
kaf24@9179 457 if ( ptr[0] != ':')
kaf24@9179 458 {
kaf24@9179 459 gdb_send_reply("E04", ctx);
kaf24@9179 460 return 0;
kaf24@9179 461 }
kaf24@9179 462 gdb_cmd_write_mem(addr, length, ptr + 1, ctx);
kaf24@8607 463 break;
kaf24@8607 464 case 'p': /* read register */
kaf24@8607 465 addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
kaf24@8607 466 if ( ptr == (ctx->in_buf + 1) )
kaf24@8607 467 {
kaf24@8607 468 gdb_send_reply("E03", ctx);
kaf24@8607 469 return 0;
kaf24@8607 470 }
kaf24@8607 471 if ( ptr[0] != 0 )
kaf24@8607 472 {
kaf24@8607 473 gdb_send_reply("E04", ctx);
kaf24@8607 474 return 0;
kaf24@8607 475 }
kaf24@8607 476 gdb_arch_read_reg(addr, regs, ctx);
kaf24@8607 477 break;
keir@16667 478 case 'P': /* write register */
keir@16667 479 addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
keir@16667 480 if ( ptr == (ctx->in_buf + 1) )
keir@16667 481 {
keir@16667 482 gdb_send_reply("E03", ctx);
keir@16667 483 return 0;
keir@16667 484 }
keir@16667 485 if ( ptr[0] != '=' )
keir@16667 486 {
keir@16667 487 gdb_send_reply("E04", ctx);
keir@16667 488 return 0;
keir@16667 489 }
keir@16667 490 ptr++;
keir@16667 491 val = str2ulong(ptr, sizeof(unsigned long));
keir@16667 492 gdb_arch_write_reg(addr, val, regs, ctx);
keir@16667 493 break;
kaf24@8607 494 case 'D':
keir@16667 495 case 'k':
kfraser@11602 496 gdbstub_detach(ctx);
kaf24@8607 497 gdb_send_reply("OK", ctx);
kaf24@8607 498 ctx->connected = 0;
keir@16667 499 resume = 1;
keir@16667 500 break;
kaf24@8607 501 case 's': /* Single step */
keir@16667 502 type = GDB_STEP;
kaf24@8607 503 case 'c': /* Resume at current address */
keir@16667 504 addr = ~((unsigned long)0);
keir@16667 505
keir@16667 506 if ( ctx->in_buf[1] )
kaf24@8607 507 addr = str2ulong(&ctx->in_buf[1], sizeof(unsigned long));
keir@16667 508 gdbstub_attach(ctx);
kaf24@8607 509 resume = 1;
kaf24@8607 510 gdb_arch_resume(regs, addr, type, ctx);
kaf24@8607 511 break;
kaf24@8607 512 default:
kaf24@8607 513 gdb_send_reply("", ctx);
kaf24@8607 514 break;
kaf24@8607 515 }
kaf24@8607 516 return resume;
kaf24@8607 517 }
kaf24@8607 518
kaf24@8607 519 static struct gdb_context
kaf24@8607 520 __gdb_ctx = {
kfraser@11602 521 .serhnd = -1,
kfraser@11602 522 .running = ATOMIC_INIT(1),
kfraser@11602 523 .signum = 1
kaf24@8607 524 };
kaf24@8607 525 static struct gdb_context *gdb_ctx = &__gdb_ctx;
kaf24@8607 526
kfraser@11602 527 static void
kfraser@11602 528 gdbstub_console_puts(const char *str)
kfraser@11602 529 {
kfraser@11602 530 const char *p;
kfraser@11602 531
kfraser@11602 532 gdb_start_packet(gdb_ctx);
kfraser@11602 533 gdb_write_to_packet_char('O', gdb_ctx);
kfraser@11602 534
kfraser@11602 535 for ( p = str; *p != '\0'; p++ )
kfraser@11602 536 {
kfraser@11602 537 gdb_write_to_packet_char(hex2char((*p>>4) & 0x0f), gdb_ctx );
kfraser@11602 538 gdb_write_to_packet_char(hex2char((*p) & 0x0f), gdb_ctx );
kfraser@11602 539 }
kfraser@11602 540
kfraser@11602 541 gdb_send_packet(gdb_ctx);
kfraser@11602 542 }
kfraser@11602 543
kaf24@8607 544 /* trap handler: main entry point */
kaf24@8607 545 int
kaf24@8607 546 __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
kaf24@8607 547 {
kfraser@11649 548 int rc = 0;
kaf24@9117 549 unsigned long flags;
kaf24@8607 550
kaf24@8607 551 if ( gdb_ctx->serhnd < 0 )
kaf24@8607 552 {
keir@16599 553 printk("Debugging connection not set up.\n");
kfraser@11649 554 return -EBUSY;
kaf24@8607 555 }
kaf24@8607 556
kaf24@8607 557 /* We rely on our caller to ensure we're only on one processor
kaf24@8607 558 * at a time... We should probably panic here, but given that
kaf24@8607 559 * we're a debugger we should probably be a little tolerant of
kaf24@8607 560 * things going wrong. */
kaf24@8607 561 /* We don't want to use a spin lock here, because we're doing
kaf24@8607 562 two distinct things:
kaf24@8607 563
kaf24@8607 564 1 -- we don't want to run on more than one processor at a time,
kaf24@8607 565 and
kaf24@8607 566 2 -- we want to do something sensible if we re-enter ourselves.
kaf24@8607 567
kaf24@8607 568 Spin locks are good for 1, but useless for 2. */
kaf24@8607 569 if ( !atomic_dec_and_test(&gdb_ctx->running) )
kaf24@8607 570 {
kaf24@8607 571 printk("WARNING WARNING WARNING: Avoiding recursive gdb.\n");
kaf24@8607 572 atomic_inc(&gdb_ctx->running);
kfraser@11649 573 return -EBUSY;
kaf24@8607 574 }
kaf24@8607 575
kaf24@8607 576 if ( !gdb_ctx->connected )
kaf24@8607 577 {
kaf24@9117 578 printk("GDB connection activated.\n");
kaf24@8607 579 gdb_arch_print_state(regs);
kaf24@8607 580 gdb_ctx->connected = 1;
kaf24@8607 581 }
kaf24@8607 582
keir@16667 583 gdb_smp_pause();
kaf24@8607 584
kaf24@8607 585 local_irq_save(flags);
kaf24@8607 586
kaf24@8607 587 watchdog_disable();
kaf24@8607 588 console_start_sync();
kaf24@8607 589
kaf24@8607 590 /* Shouldn't really do this, but otherwise we stop for no
kaf24@8607 591 obvious reason, which is Bad */
kaf24@9117 592 printk("Waiting for GDB to attach...\n");
kaf24@8607 593
kaf24@8607 594 gdb_arch_enter(regs);
kaf24@8607 595 gdb_ctx->signum = gdb_arch_signal_num(regs, cookie);
kfraser@11602 596
kaf24@8607 597 /* If gdb is already attached, tell it we've stopped again. */
kaf24@8607 598 if ( gdb_ctx->currently_attached )
kaf24@8607 599 {
kaf24@8607 600 gdb_start_packet(gdb_ctx);
kaf24@8607 601 gdb_cmd_signum(gdb_ctx);
kaf24@8607 602 }
kaf24@8607 603
kfraser@11649 604 do {
kfraser@11649 605 if ( receive_command(gdb_ctx) < 0 )
kaf24@8607 606 {
kfraser@11649 607 dbg_printk("Error in GDB session...\n");
kfraser@11649 608 rc = -EIO;
kfraser@11649 609 break;
kaf24@8607 610 }
kfraser@11649 611 } while ( process_command(regs, gdb_ctx) == 0 );
kaf24@8607 612
keir@16667 613 gdb_smp_resume();
keir@16667 614
kaf24@8607 615 gdb_arch_exit(regs);
kaf24@8607 616 console_end_sync();
kaf24@8607 617 watchdog_enable();
kaf24@8607 618 atomic_inc(&gdb_ctx->running);
kaf24@8607 619
kaf24@8607 620 local_irq_restore(flags);
kaf24@8607 621
kfraser@11649 622 return rc;
kaf24@8607 623 }
kaf24@8607 624
keir@15082 625 void __init
kaf24@9117 626 initialise_gdb(void)
kaf24@8607 627 {
keir@18487 628 if ( *opt_gdb == '\0' )
keir@18487 629 return;
keir@18487 630
kaf24@8607 631 gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
keir@18487 632 if ( gdb_ctx->serhnd == -1 )
keir@18487 633 {
keir@18487 634 printk("Bad gdb= option '%s'\n", opt_gdb);
keir@18487 635 return;
keir@18487 636 }
keir@18487 637
kaf24@9437 638 serial_start_sync(gdb_ctx->serhnd);
keir@18487 639
keir@18487 640 printk("GDB stub initialised.\n");
kaf24@8607 641 }
kaf24@8607 642
keir@16667 643 static void gdb_pause_this_cpu(void *unused)
keir@16667 644 {
keir@16667 645 unsigned long flags;
keir@16667 646
keir@16667 647 local_irq_save(flags);
keir@16667 648
keir@16667 649 atomic_set(&gdb_cpu[smp_processor_id()].ack, 1);
keir@16667 650 atomic_inc(&gdb_smp_paused_count);
keir@16667 651
keir@16667 652 while ( atomic_read(&gdb_cpu[smp_processor_id()].paused) )
keir@16667 653 mdelay(1);
keir@16667 654
keir@16667 655 atomic_dec(&gdb_smp_paused_count);
keir@16667 656 atomic_set(&gdb_cpu[smp_processor_id()].ack, 0);
keir@16667 657
keir@16667 658 /* Restore interrupts */
keir@16667 659 local_irq_restore(flags);
keir@16667 660 }
keir@16667 661
keir@16667 662 static void gdb_smp_pause(void)
keir@16667 663 {
keir@16667 664 int timeout = 100;
keir@16667 665 int cpu;
keir@16667 666
keir@16667 667 for_each_online_cpu(cpu)
keir@16667 668 {
keir@16667 669 atomic_set(&gdb_cpu[cpu].ack, 0);
keir@16667 670 atomic_set(&gdb_cpu[cpu].paused, 1);
keir@16667 671 }
keir@16667 672
keir@16667 673 atomic_set(&gdb_smp_paused_count, 0);
keir@16667 674
keir@19652 675 smp_call_function(gdb_pause_this_cpu, NULL, /* dont wait! */0);
keir@16667 676
keir@16667 677 /* Wait 100ms for all other CPUs to enter pause loop */
keir@16667 678 while ( (atomic_read(&gdb_smp_paused_count) < (num_online_cpus() - 1))
keir@16667 679 && (timeout-- > 0) )
keir@16667 680 mdelay(1);
keir@16667 681
keir@16667 682 if ( atomic_read(&gdb_smp_paused_count) < (num_online_cpus() - 1) )
keir@16667 683 {
keir@16667 684 printk("GDB: Not all CPUs have paused, missing CPUs ");
keir@16667 685 for_each_online_cpu(cpu)
keir@16667 686 {
keir@16667 687 if ( (cpu != smp_processor_id()) &&
keir@16667 688 !atomic_read(&gdb_cpu[cpu].ack) )
keir@16667 689 printk("%d ", cpu);
keir@16667 690 }
keir@16667 691 printk("\n");
keir@16667 692 }
keir@16667 693 }
keir@16667 694
keir@16667 695 static void gdb_smp_resume(void)
keir@16667 696 {
keir@16667 697 int cpu;
keir@16667 698 int timeout = 100;
keir@16667 699
keir@16667 700 for_each_online_cpu(cpu)
keir@16667 701 atomic_set(&gdb_cpu[cpu].paused, 0);
keir@16667 702
keir@16667 703 /* Make sure all CPUs resume */
keir@16667 704 while ( (atomic_read(&gdb_smp_paused_count) > 0)
keir@16667 705 && (timeout-- > 0) )
keir@16667 706 mdelay(1);
keir@16667 707
keir@16667 708 if ( atomic_read(&gdb_smp_paused_count) > 0 )
keir@16667 709 {
keir@16667 710 printk("GDB: Not all CPUs have resumed execution, missing CPUs ");
keir@16667 711 for_each_online_cpu(cpu)
keir@16667 712 {
keir@16667 713 if ( (cpu != smp_processor_id()) &&
keir@16667 714 atomic_read(&gdb_cpu[cpu].ack) )
keir@16667 715 printk("%d ", cpu);
keir@16667 716 }
keir@16667 717 printk("\n");
keir@16667 718 }
keir@16667 719 }
keir@16667 720
kaf24@8607 721 /*
kaf24@8607 722 * Local variables:
kaf24@8607 723 * mode: C
kaf24@8607 724 * c-set-style: "BSD"
kaf24@8607 725 * c-basic-offset: 4
kaf24@8607 726 * tab-width: 4
kaf24@8607 727 * End:
kaf24@8607 728 */