direct-io.hg

view xen/common/gdbstub.c @ 12980:79b49fca62e8

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