ia64/xen-unstable

view xen/common/gdbstub.c @ 12390:e28beea6d228

[IA64] Fix time services of EFI emulation

This patch serializes the execution of following efi.runtimes.
- GetTime
- SetTime
- GetWakeTime
- SetWakeTime

Linux/ia64 uses similar spinlocks in the EFI RTC driver.

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author awilliam@xenbuild.aw
date Fri Nov 10 12:03:19 2006 -0700 (2006-11-10)
parents d78b31dd07e8
children 79b49fca62e8
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>
46 /* Printk isn't particularly safe just after we've trapped to the
47 debugger. so avoid it. */
48 #define dbg_printk(...)
49 /*#define dbg_printk(...) printk(__VA_ARGS__)*/
51 #define GDB_RETRY_MAX 10
53 static char opt_gdb[30] = "none";
54 string_param("gdb", opt_gdb);
56 static void gdbstub_console_puts(const char *str);
58 /* value <-> char (de)serialzers */
59 char
60 hex2char(unsigned long x)
61 {
62 const char array[] = "0123456789abcdef";
64 return array[x & 15];
65 }
67 int
68 char2hex(unsigned char c)
69 {
70 if ( (c >= '0') && (c <= '9') )
71 return c - '0';
72 else if ( (c >= 'a') && (c <= 'f') )
73 return c - 'a' + 10;
74 else if ( (c >= 'A') && (c <= 'F') )
75 return c - 'A' + 10;
76 else
77 BUG();
78 return -1;
79 }
81 char
82 str2hex(const char *str)
83 {
84 return (char2hex(str[0]) << 4) | char2hex(str[1]);
85 }
87 unsigned long
88 str2ulong(const char *str, unsigned long bytes)
89 {
90 unsigned long x = 0;
91 unsigned long i = 0;
93 while ( *str && (i < (bytes * 2)) )
94 {
95 x <<= 4;
96 x += char2hex(*str);
97 ++str;
98 ++i;
99 }
101 return x;
102 }
104 /* gdb io wrappers */
105 static signed long
106 gdb_io_write(const char *buf, unsigned long len, struct gdb_context *ctx)
107 {
108 int i;
109 for ( i = 0; i < len; i++ )
110 serial_putc(ctx->serhnd, buf[i]);
111 return i;
112 }
114 static int
115 gdb_io_write_char(u8 data, struct gdb_context *ctx)
116 {
117 return gdb_io_write((char*)&data, 1, ctx);
118 }
120 static unsigned char
121 gdb_io_read(struct gdb_context *ctx)
122 {
123 return serial_getc(ctx->serhnd);
124 }
126 /* Receive a command. Returns -1 on csum error, 0 otherwise. */
127 /* Does not acknowledge. */
128 static int
129 attempt_receive_packet(struct gdb_context *ctx)
130 {
131 u8 csum;
132 u8 received_csum;
133 u8 ch;
135 /* Skip over everything up to the first '$' */
136 while ( (ch = gdb_io_read(ctx)) != '$' )
137 continue;
139 csum = 0;
140 for ( ctx->in_bytes = 0;
141 ctx->in_bytes < sizeof(ctx->in_buf);
142 ctx->in_bytes++ )
143 {
144 ch = gdb_io_read(ctx);
145 if ( ch == '#' )
146 break;
147 ctx->in_buf[ctx->in_bytes] = ch;
148 csum += ch;
149 }
151 if ( ctx->in_bytes == sizeof(ctx->in_buf) )
152 {
153 dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
154 return -1;
155 }
157 ctx->in_buf[ctx->in_bytes] = '\0';
158 received_csum = char2hex(gdb_io_read(ctx)) * 16 +
159 char2hex(gdb_io_read(ctx));
161 return (received_csum == csum) ? 0 : -1;
162 }
164 /* Receive a command, discarding up to ten packets with csum
165 * errors. Acknowledges all received packets. */
166 static int
167 receive_command(struct gdb_context *ctx)
168 {
169 int r, count = 0;
171 count = 0;
172 do {
173 r = attempt_receive_packet(ctx);
174 gdb_io_write_char((r < 0) ? '-' : '+', ctx);
175 count++;
176 } while ( (r < 0) && (count < GDB_RETRY_MAX) );
178 return r;
179 }
181 /* routines to send reply packets */
183 static void
184 gdb_start_packet(struct gdb_context *ctx)
185 {
186 ctx->out_buf[0] = '$';
187 ctx->out_offset = 1;
188 ctx->out_csum = 0;
189 }
191 static void
192 gdb_write_to_packet_char(u8 data, struct gdb_context *ctx)
193 {
194 ctx->out_csum += data;
195 ctx->out_buf[ctx->out_offset] = data;
196 ctx->out_offset++;
197 }
199 void
200 gdb_write_to_packet(const char *buf, int count, struct gdb_context *ctx)
201 {
202 int x;
203 for ( x = 0; x < count; x++ )
204 gdb_write_to_packet_char(buf[x], ctx);
205 }
207 void
208 gdb_write_to_packet_str(const char *buf, struct gdb_context *ctx)
209 {
210 gdb_write_to_packet(buf, strlen(buf), ctx);
211 }
213 void
214 gdb_write_to_packet_hex(unsigned long x, int int_size, struct gdb_context *ctx)
215 {
216 char buf[sizeof(unsigned long) * 2 + 1];
217 int i = sizeof(unsigned long) * 2;
218 int width = int_size * 2;
220 buf[sizeof(unsigned long) * 2] = 0;
222 switch ( int_size )
223 {
224 case sizeof(u8):
225 case sizeof(u16):
226 case sizeof(u32):
227 case sizeof(u64):
228 break;
229 default:
230 dbg_printk("WARNING: %s x: 0x%lx int_size: %d\n",
231 __func__, x, int_size);
232 break;
233 }
235 do {
236 buf[--i] = hex2char(x & 15);
237 x >>= 4;
238 } while ( x );
240 while ( (i + width) > (sizeof(unsigned long) * 2) )
241 buf[--i] = '0';
243 gdb_write_to_packet(&buf[i], width, ctx);
244 }
246 static int
247 gdb_check_ack(struct gdb_context *ctx)
248 {
249 u8 c = gdb_io_read(ctx);
251 switch ( c )
252 {
253 case '+':
254 return 1;
255 case '-':
256 return 0;
257 default:
258 printk("Bad ack: %c\n", c);
259 return 0;
260 }
261 }
263 /* Return 0 if the reply was successfully received, !0 otherwise. */
264 void
265 gdb_send_packet(struct gdb_context *ctx)
266 {
267 char buf[3];
268 int count;
270 sprintf(buf, "%.02x\n", ctx->out_csum);
272 gdb_write_to_packet_char('#', ctx);
273 gdb_write_to_packet(buf, 2, ctx);
275 count = 0;
276 do {
277 gdb_io_write(ctx->out_buf, ctx->out_offset, ctx);
278 } while ( !gdb_check_ack(ctx) && (count++ < GDB_RETRY_MAX) );
280 if ( count == GDB_RETRY_MAX )
281 dbg_printk("WARNING: %s reached max retry %d\n",
282 __func__, GDB_RETRY_MAX);
283 }
285 void
286 gdb_send_reply(const char *buf, struct gdb_context *ctx)
287 {
288 gdb_start_packet(ctx);
289 gdb_write_to_packet_str(buf, ctx);
290 gdb_send_packet(ctx);
291 }
293 /* arch neutral command handlers */
295 static void
296 gdb_cmd_signum(struct gdb_context *ctx)
297 {
298 gdb_write_to_packet_char('S', ctx);
299 gdb_write_to_packet_hex(ctx->signum, sizeof(ctx->signum), ctx);
300 gdb_send_packet(ctx);
301 }
303 static void
304 gdb_cmd_read_mem(unsigned long addr, unsigned long length,
305 struct gdb_context *ctx)
306 {
307 int x, r;
308 unsigned char val;
310 dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
311 length);
313 for ( x = 0; x < length; x++ )
314 {
315 r = gdb_arch_copy_from_user(&val, (void *)(addr + x), 1);
316 if ( r != 0 )
317 {
318 dbg_printk("Error reading from %lx.\n", addr + x);
319 break;
320 }
321 gdb_write_to_packet_hex(val, sizeof(val), ctx);
322 }
324 if ( x == 0 )
325 gdb_write_to_packet_str("E05", ctx);
327 dbg_printk("Read done.\n");
329 gdb_send_packet(ctx);
330 }
332 static void
333 gdb_cmd_write_mem(unsigned long addr, unsigned long length,
334 const char *buf, struct gdb_context *ctx)
335 {
336 int x, r;
337 unsigned char val;
339 dbg_printk("Memory write starting at %lx, length %lx.\n", addr, length);
341 for ( x = 0; x < length; x++, addr++, buf += 2 )
342 {
343 val = str2ulong(buf, sizeof(val));
344 r = gdb_arch_copy_to_user((void*)addr, (void*)&val, 1);
345 if ( r != 0 )
346 {
347 dbg_printk("Error writing to %lx.\n", addr);
348 break;
349 }
350 }
352 if (x == length)
353 gdb_write_to_packet_str("OK", ctx);
354 else
355 gdb_write_to_packet_str("E11", ctx);
357 dbg_printk("Write done.\n");
359 gdb_send_packet(ctx);
360 }
362 static void
363 gdbstub_attach(struct gdb_context *ctx)
364 {
365 if ( ctx->currently_attached )
366 return;
367 ctx->currently_attached = 1;
368 ctx->console_steal_id = console_steal(ctx->serhnd, gdbstub_console_puts);
369 }
371 static void
372 gdbstub_detach(struct gdb_context *ctx)
373 {
374 if ( !ctx->currently_attached )
375 return;
376 ctx->currently_attached = 0;
377 console_giveback(ctx->console_steal_id);
378 }
380 /* command dispatcher */
381 static int
382 process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
383 {
384 char *ptr;
385 unsigned long addr, length;
386 int resume = 0;
388 /* XXX check ctx->in_bytes >= 2 or similar. */
390 gdb_start_packet(ctx);
391 switch ( ctx->in_buf[0] )
392 {
393 case '?': /* query signal number */
394 gdb_cmd_signum(ctx);
395 break;
396 case 'H': /* thread operations */
397 gdb_send_reply("OK", ctx);
398 break;
399 case 'g': /* Read registers */
400 gdb_arch_read_reg_array(regs, ctx);
401 break;
402 case 'G': /* Write registers */
403 gdb_arch_write_reg_array(regs, ctx->in_buf + 1, ctx);
404 break;
405 case 'm': /* Read memory */
406 addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
407 if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
408 {
409 gdb_send_reply("E03", ctx);
410 return 0;
411 }
412 length = simple_strtoul(ptr + 1, &ptr, 16);
413 if ( ptr[0] != 0 )
414 {
415 gdb_send_reply("E04", ctx);
416 return 0;
417 }
418 gdb_cmd_read_mem(addr, length, ctx);
419 break;
420 case 'M': /* Write memory */
421 addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
422 if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
423 {
424 gdb_send_reply("E03", ctx);
425 return 0;
426 }
427 length = simple_strtoul(ptr + 1, &ptr, 16);
428 if ( ptr[0] != ':')
429 {
430 gdb_send_reply("E04", ctx);
431 return 0;
432 }
433 gdb_cmd_write_mem(addr, length, ptr + 1, ctx);
434 break;
435 case 'p': /* read register */
436 addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
437 if ( ptr == (ctx->in_buf + 1) )
438 {
439 gdb_send_reply("E03", ctx);
440 return 0;
441 }
442 if ( ptr[0] != 0 )
443 {
444 gdb_send_reply("E04", ctx);
445 return 0;
446 }
447 gdb_arch_read_reg(addr, regs, ctx);
448 break;
449 case 'D':
450 gdbstub_detach(ctx);
451 gdb_send_reply("OK", ctx);
452 /* fall through */
453 case 'k':
454 ctx->connected = 0;
455 /* fall through */
456 case 's': /* Single step */
457 case 'c': /* Resume at current address */
458 {
459 unsigned long addr = ~((unsigned long)0);
460 unsigned long type = GDB_CONTINUE;
461 if ( ctx->in_buf[0] == 's' )
462 type = GDB_STEP;
463 if ( ((ctx->in_buf[0] == 's') || (ctx->in_buf[0] == 'c')) &&
464 ctx->in_buf[1] )
465 addr = str2ulong(&ctx->in_buf[1], sizeof(unsigned long));
466 if ( ctx->in_buf[0] != 'D' )
467 gdbstub_attach(ctx);
468 resume = 1;
469 gdb_arch_resume(regs, addr, type, ctx);
470 break;
471 }
473 default:
474 gdb_send_reply("", ctx);
475 break;
476 }
477 return resume;
478 }
480 static struct gdb_context
481 __gdb_ctx = {
482 .serhnd = -1,
483 .running = ATOMIC_INIT(1),
484 .signum = 1
485 };
486 static struct gdb_context *gdb_ctx = &__gdb_ctx;
488 static void
489 gdbstub_console_puts(const char *str)
490 {
491 const char *p;
493 gdb_start_packet(gdb_ctx);
494 gdb_write_to_packet_char('O', gdb_ctx);
496 for ( p = str; *p != '\0'; p++ )
497 {
498 gdb_write_to_packet_char(hex2char((*p>>4) & 0x0f), gdb_ctx );
499 gdb_write_to_packet_char(hex2char((*p) & 0x0f), gdb_ctx );
500 }
502 gdb_send_packet(gdb_ctx);
503 }
505 /* trap handler: main entry point */
506 int
507 __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
508 {
509 int rc = 0;
510 unsigned long flags;
512 if ( gdb_ctx->serhnd < 0 )
513 {
514 dbg_printk("Debugger not ready yet.\n");
515 return -EBUSY;
516 }
518 /* We rely on our caller to ensure we're only on one processor
519 * at a time... We should probably panic here, but given that
520 * we're a debugger we should probably be a little tolerant of
521 * things going wrong. */
522 /* We don't want to use a spin lock here, because we're doing
523 two distinct things:
525 1 -- we don't want to run on more than one processor at a time,
526 and
527 2 -- we want to do something sensible if we re-enter ourselves.
529 Spin locks are good for 1, but useless for 2. */
530 if ( !atomic_dec_and_test(&gdb_ctx->running) )
531 {
532 printk("WARNING WARNING WARNING: Avoiding recursive gdb.\n");
533 atomic_inc(&gdb_ctx->running);
534 return -EBUSY;
535 }
537 if ( !gdb_ctx->connected )
538 {
539 printk("GDB connection activated.\n");
540 gdb_arch_print_state(regs);
541 gdb_ctx->connected = 1;
542 }
544 smp_send_stop();
546 /* Try to make things a little more stable by disabling
547 interrupts while we're here. */
548 local_irq_save(flags);
550 watchdog_disable();
551 console_start_sync();
553 /* Shouldn't really do this, but otherwise we stop for no
554 obvious reason, which is Bad */
555 printk("Waiting for GDB to attach...\n");
557 gdb_arch_enter(regs);
558 gdb_ctx->signum = gdb_arch_signal_num(regs, cookie);
560 /* If gdb is already attached, tell it we've stopped again. */
561 if ( gdb_ctx->currently_attached )
562 {
563 gdb_start_packet(gdb_ctx);
564 gdb_cmd_signum(gdb_ctx);
565 }
567 do {
568 if ( receive_command(gdb_ctx) < 0 )
569 {
570 dbg_printk("Error in GDB session...\n");
571 rc = -EIO;
572 break;
573 }
574 } while ( process_command(regs, gdb_ctx) == 0 );
576 gdb_arch_exit(regs);
577 console_end_sync();
578 watchdog_enable();
579 atomic_inc(&gdb_ctx->running);
581 local_irq_restore(flags);
583 return rc;
584 }
586 void
587 initialise_gdb(void)
588 {
589 gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
590 if ( gdb_ctx->serhnd != -1 )
591 printk("GDB stub initialised.\n");
592 serial_start_sync(gdb_ctx->serhnd);
593 }
595 /*
596 * Local variables:
597 * mode: C
598 * c-set-style: "BSD"
599 * c-basic-offset: 4
600 * tab-width: 4
601 * End:
602 */