ia64/xen-unstable

view tools/debugger/xenitp/xenitp.c @ 16607:dad1f2974d29

[IA64] Fix XenITP build

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author Alex Williamson <alex.williamson@hp.com>
date Thu Dec 13 09:07:55 2007 -0700 (2007-12-13)
parents 1e27eb0c9f22
children 390707dd4c2f
line source
1 /* tools/debugger/xenitp.c - A low-level debugger.
3 Based on xenctxt.c, but heavily modified.
4 Copyright 2007 Tristan Gingold <tgingold@free.fr>
6 Xenitp is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 Xenitp is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
20 #include <time.h>
21 #include <stdlib.h>
22 #include <sys/mman.h>
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <argp.h>
30 #include <signal.h>
31 #include <string.h>
32 #include <getopt.h>
34 #include "xenctrl.h"
35 #include <xen/sys/privcmd.h>
36 #include "dis-asm.h"
38 #ifdef __HYPERVISOR_ia64_debug_op
39 #define HAVE_DEBUG_OP
40 #include <xen/arch-ia64/debug_op.h>
41 #endif
43 static int xc_handle = 0;
44 static int domid = 0;
45 static vcpu_guest_context_t *cur_ctx;
46 static int cur_vcpu;
48 #define PSR_BN (1UL << 44)
49 #define PSR_SS (1UL << 40)
50 #define PSR_DB (1UL << 24)
51 #define PSR_TB (1UL << 26)
52 #define PSR_DD (1UL << 39)
53 #define PSR_ID (1UL << 37)
54 #define PSR_IT (1UL << 36)
55 #define PSR_DT (1UL << 17)
56 #define PSR_RI_SHIFT 41
57 #define CFM_SOF_MASK 0x3f
59 int virt_to_phys (int is_inst, unsigned long vaddr, unsigned long *paddr);
61 static inline unsigned int ctx_slot (vcpu_guest_context_t *ctx)
62 {
63 return (ctx->regs.psr >> PSR_RI_SHIFT) & 3;
64 }
66 unsigned char *
67 target_map_memory (unsigned long paddr)
68 {
69 static unsigned long cur_page = (unsigned long)-1;
70 static unsigned char *cur_map = NULL;
72 if ((paddr >> XC_PAGE_SHIFT) != cur_page) {
73 if (cur_map) {
74 munmap (cur_map, XC_PAGE_SIZE);
75 cur_map = NULL;
76 }
77 cur_page = paddr >> XC_PAGE_SHIFT;
78 cur_map = xc_map_foreign_range (xc_handle, domid, XC_PAGE_SIZE,
79 PROT_READ, cur_page);
80 if (cur_map == NULL) {
81 perror ("cannot map page");
82 cur_page = -1;
83 return NULL;
84 }
85 }
86 return cur_map + (paddr & (XC_PAGE_SIZE - 1));
87 }
89 /* Get LENGTH bytes from info's buffer, at target address memaddr.
90 Transfer them to myaddr. */
91 int
92 target_read_memory (bfd_vma memaddr, bfd_byte *myaddr,
93 unsigned int length, struct disassemble_info *info)
94 {
95 int i;
96 unsigned long paddr;
98 if (cur_ctx->regs.psr & PSR_IT) {
99 if (virt_to_phys (1, memaddr, &paddr) != 0)
100 return EIO;
101 }
102 else {
103 /* Clear UC. */
104 paddr = memaddr & ~(1UL << 63);
105 }
107 for (i = 0; i < length; i++) {
108 unsigned char *p = target_map_memory (paddr + i);
110 if (p == NULL)
111 return EIO;
112 myaddr[i] = *p;
113 }
114 return 0;
115 }
117 /* Print an error message. We can assume that this is in response to
118 an error return from buffer_read_memory. */
119 void
120 perror_memory (int status, bfd_vma memaddr, struct disassemble_info *info)
121 {
122 if (status != EIO)
123 /* Can't happen. */
124 (*info->fprintf_func) (info->stream, "Unknown error %d\n", status);
125 else
126 /* Actually, address between memaddr and memaddr + len was
127 out of bounds. */
128 (*info->fprintf_func) (info->stream,
129 "Address 0x%" PRIx64 " is out of bounds.\n",
130 memaddr);
131 }
133 /* This could be in a separate file, to save miniscule amounts of space
134 in statically linked executables. */
136 /* Just print the address is hex. This is included for completeness even
137 though both GDB and objdump provide their own (to print symbolic
138 addresses). */
140 void
141 generic_print_address (bfd_vma addr, struct disassemble_info *info)
142 {
143 (*info->fprintf_func) (info->stream, "0x%" PRIx64, addr);
144 }
146 /* Just return the given address. */
148 int
149 generic_symbol_at_address (bfd_vma addr, struct disassemble_info * info)
150 {
151 return 1;
152 }
154 bfd_boolean
155 generic_symbol_is_valid (asymbol * sym ATTRIBUTE_UNUSED,
156 struct disassemble_info *info ATTRIBUTE_UNUSED)
157 {
158 return 1;
159 }
161 bfd_vma bfd_getl32 (const bfd_byte *addr)
162 {
163 unsigned long v;
165 v = (unsigned long) addr[0];
166 v |= (unsigned long) addr[1] << 8;
167 v |= (unsigned long) addr[2] << 16;
168 v |= (unsigned long) addr[3] << 24;
170 return (bfd_vma) v;
171 }
173 bfd_vma bfd_getl64 (const bfd_byte *addr)
174 {
175 unsigned long v;
177 v = (unsigned long) addr[0];
178 v |= (unsigned long) addr[1] << 8;
179 v |= (unsigned long) addr[2] << 16;
180 v |= (unsigned long) addr[3] << 24;
181 v |= (unsigned long) addr[4] << 32;
182 v |= (unsigned long) addr[5] << 40;
183 v |= (unsigned long) addr[6] << 48;
184 v |= (unsigned long) addr[7] << 56;
186 return (bfd_vma) v;
187 }
189 bfd_vma bfd_getb32 (const bfd_byte *addr)
190 {
191 unsigned long v;
193 v = (unsigned long) addr[0] << 24;
194 v |= (unsigned long) addr[1] << 16;
195 v |= (unsigned long) addr[2] << 8;
196 v |= (unsigned long) addr[3];
198 return (bfd_vma) v;
199 }
201 bfd_vma bfd_getl16 (const bfd_byte *addr)
202 {
203 unsigned long v;
205 v = (unsigned long) addr[0];
206 v |= (unsigned long) addr[1] << 8;
208 return (bfd_vma) v;
209 }
211 bfd_vma bfd_getb16 (const bfd_byte *addr)
212 {
213 unsigned long v;
215 v = (unsigned long) addr[0] << 24;
216 v |= (unsigned long) addr[1] << 16;
218 return (bfd_vma) v;
219 }
221 void
222 init_disassemble_info (struct disassemble_info *info, void *stream,
223 fprintf_ftype fprintf_func)
224 {
225 memset (info, 0, sizeof (*info));
227 info->flavour = bfd_target_unknown_flavour;
228 info->arch = bfd_arch_unknown;
229 info->endian = BFD_ENDIAN_UNKNOWN;
230 info->octets_per_byte = 1;
231 info->fprintf_func = fprintf_func;
232 info->stream = stream;
233 info->read_memory_func = target_read_memory;
234 info->memory_error_func = perror_memory;
235 info->print_address_func = generic_print_address;
236 info->symbol_at_address_func = generic_symbol_at_address;
237 info->symbol_is_valid = generic_symbol_is_valid;
238 info->display_endian = BFD_ENDIAN_UNKNOWN;
239 }
242 void target_disas (FILE *out, unsigned long code, unsigned long size)
243 {
244 unsigned long pc;
245 int count;
246 struct disassemble_info disasm_info;
248 INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf);
250 disasm_info.read_memory_func = target_read_memory;
251 #if 0
252 disasm_info.buffer = NULL;
253 disasm_info.buffer_vma = (unsigned long)code;
254 disasm_info.buffer_length = size;
255 #endif
257 disasm_info.endian = BFD_ENDIAN_LITTLE;
258 disasm_info.mach = 0; //bfd_mach_ia64;
260 for (pc = code; pc < code + size; pc += count) {
261 int slot = (pc & 0x0f) / 6;
262 fprintf (out, "0x%016lx+%d:%c ", pc & ~0x0fUL, slot,
263 ((pc & ~0x0fUL) == cur_ctx->regs.ip
264 && slot == ctx_slot (cur_ctx)) ? '*' : ' ');
266 count = print_insn_ia64 (pc, &disasm_info);
268 #if 0
269 {
270 int i;
271 uint8_t b;
273 fprintf (out, " {");
274 for (i = 0; i < count; i++) {
275 target_read_memory (pc + i, &b, 1, &disasm_info);
276 fprintf (out, " %02x", b);
277 }
278 fprintf (out, " }");
279 }
280 #endif
281 fprintf (out, "\n");
282 if (count < 0)
283 break;
284 }
285 }
288 #define PTE_ED_SHIFT 52
289 #define PTE_ED_MASK 1
290 #define PTE_PPN_SHIFT 12
291 #define PTE_PPN_MASK 0x3fffffffff
292 #define PTE_AR_SHIFT 9
293 #define PTE_AR_MASK 7
294 #define PTE_PL_SHIFT 7
295 #define PTE_PL_MASK 3
296 #define PTE_D_SHIFT 6
297 #define PTE_D_MASK 1
298 #define PTE_A_SHIFT 5
299 #define PTE_A_MASK 1
300 #define PTE_MA_SHIFT 2
301 #define PTE_MA_MASK 7
302 #define PTE_P_SHIFT 0
303 #define PTE_P_MASK 1
304 #define ITIR_KEY_SHIFT 8
305 #define ITIR_KEY_MASK 0xffffff
306 #define ITIR_PS_SHIFT 2
307 #define ITIR_PS_MASK 0x3f
308 #define ITIR_PS_MIN 12
309 #define ITIR_PS_MAX 28
310 #define RR_RID_SHIFT 8
311 #define RR_RID_MASK 0xffffff
312 #define RR_PS_SHIFT 2
313 #define RR_PS_MASK 0x3f
314 #define RR_VE_MASK 1
316 static const char *get_ps (int ps_val)
317 {
318 static const char ps[][5] = {" 4K", " 8K", " 16K", " ",
319 " 64K", " ", "256K", " ",
320 " 1M", " ", " 4M", " ",
321 " 16M", " ", " 64M", " ",
322 "256M"};
323 return ((ps_val >= ITIR_PS_MIN && ps_val <= ITIR_PS_MAX) ?
324 ps[ps_val - ITIR_PS_MIN] : " ");
326 }
328 static void print_a_tr (int i, const struct ia64_tr_entry *tr)
329 {
330 int ps_val, ma_val;
331 unsigned long pa;
333 static const char ma[][4] = {"WB ", " ", " ", " ",
334 "UC ", "UCE", "WC ", "Nat"};
336 ps_val = tr->itir >> ITIR_PS_SHIFT & ITIR_PS_MASK;
337 ma_val = tr->pte >> PTE_MA_SHIFT & PTE_MA_MASK;
338 pa = (tr->pte >> PTE_PPN_SHIFT & PTE_PPN_MASK) << PTE_PPN_SHIFT;
339 pa = (pa >> ps_val) << ps_val;
340 printf (" [%2d] %ld %06lx %016lx %013lx %02d %s %ld %ld %ld %ld "
341 "%ld %d %s %06lx\n", i,
342 tr->pte >> PTE_P_SHIFT & PTE_P_MASK,
343 tr->rid >> RR_RID_SHIFT & RR_RID_MASK,
344 tr->vadr, pa, ps_val, get_ps (ps_val),
345 tr->pte >> PTE_ED_SHIFT & PTE_ED_MASK,
346 tr->pte >> PTE_PL_SHIFT & PTE_PL_MASK,
347 tr->pte >> PTE_AR_SHIFT & PTE_AR_MASK,
348 tr->pte >> PTE_A_SHIFT & PTE_A_MASK,
349 tr->pte >> PTE_D_SHIFT & PTE_D_MASK,
350 ma_val, ma[ma_val],
351 tr->itir >> ITIR_KEY_SHIFT & ITIR_KEY_MASK);
352 }
354 void print_ctx (vcpu_guest_context_t *ctx)
355 {
356 struct vcpu_guest_context_regs *regs = &ctx->regs;
357 int i;
358 unsigned int rbs_size, cfm_sof;
360 rbs_size = (regs->ar.bsp - regs->ar.bspstore) / 8;
361 cfm_sof = (regs->cfm & CFM_SOF_MASK);
362 printf ("bspstore: %016lx bsp: %016lx rbs_size=%d, sof=%d\n",
363 regs->ar.bspstore, regs->ar.bsp, rbs_size, cfm_sof);
365 for (i = 0; i < cfm_sof; i++) {
366 int off = cfm_sof - i;
367 unsigned int rbs_off =
368 (((62 - ((rbs_size + regs->rbs_voff) % 64) + off)) / 63) + off;
369 if (rbs_off > rbs_size)
370 break;
371 printf (" r%02d: %016lx%s", 32 + i,
372 regs->rbs[rbs_size - rbs_off],
373 (i % 3) != 2 ? " " : "\n");
374 }
375 if ((i % 3) != 0)
376 printf ("\n");
378 printf ("\n");
379 printf (" r1: %016lx ", regs->r[1]);
380 printf (" r2: %016lx ", regs->r[2]);
381 printf (" r3: %016lx\n", regs->r[3]);
382 printf (" r4: %016lx ", regs->r[4]);
383 printf (" r5: %016lx ", regs->r[5]);
384 printf (" r6: %016lx\n", regs->r[6]);
385 printf (" r7: %016lx ", regs->r[7]);
386 printf (" r8: %016lx ", regs->r[8]);
387 printf (" r9: %016lx\n", regs->r[9]);
388 printf (" r10: %016lx ", regs->r[10]);
389 printf (" r11: %016lx ", regs->r[11]);
390 printf (" sp: %016lx\n", regs->r[12]);
391 printf (" tp: %016lx ", regs->r[13]);
392 printf (" r14: %016lx ", regs->r[14]);
393 printf (" r15: %016lx\n", regs->r[15]);
394 printf (" r16: %016lx ", regs->r[16]);
395 printf (" r17: %016lx ", regs->r[17]);
396 printf (" r18: %016lx\n", regs->r[18]);
397 printf (" r19: %016lx ", regs->r[19]);
398 printf (" r20: %016lx ", regs->r[20]);
399 printf (" r21: %016lx\n", regs->r[21]);
400 printf (" r22: %016lx ", regs->r[22]);
401 printf (" r23: %016lx ", regs->r[23]);
402 printf (" r24: %016lx\n", regs->r[24]);
403 printf (" r25: %016lx ", regs->r[25]);
404 printf (" r26: %016lx ", regs->r[26]);
405 printf (" r27: %016lx\n", regs->r[27]);
406 printf (" r28: %016lx ", regs->r[28]);
407 printf (" r29: %016lx ", regs->r[29]);
408 printf (" r30: %016lx\n", regs->r[30]);
409 printf (" r31: %016lx ", regs->r[31]);
410 printf (" ");
411 printf (" b0: %016lx\n", regs->b[0]);
413 printf ("\n");
414 printf (" psr: %016lx ", regs->psr);
415 printf (" cfm: %016lx ", regs->cfm);
416 printf (" pr: %016lx\n", regs->pr);
418 printf ("\n");
419 printf (" ip: %016lx+%d", regs->ip, (int)(regs->psr >> PSR_RI_SHIFT) & 3);
420 printf ("\n");
421 target_disas (stdout, regs->ip, 16);
422 }
424 void print_br (vcpu_guest_context_t *ctx)
425 {
426 struct vcpu_guest_context_regs *regs = &ctx->regs;
428 printf (" b0: %016lx ", regs->b[0]);
429 printf (" b1: %016lx ", regs->b[1]);
430 printf (" b2: %016lx\n", regs->b[2]);
431 printf (" b3: %016lx ", regs->b[3]);
432 printf (" b4: %016lx ", regs->b[4]);
433 printf (" b5: %016lx\n", regs->b[5]);
434 printf (" b6: %016lx ", regs->b[6]);
435 printf (" b7: %016lx\n", regs->b[7]);
436 }
438 void print_regs (vcpu_guest_context_t *ctx)
439 {
440 struct vcpu_guest_context_regs *regs = &ctx->regs;
442 printf (" r1: %016lx ", regs->r[1]);
443 printf (" r2: %016lx ", regs->r[2]);
444 printf (" r3: %016lx\n", regs->r[3]);
445 printf (" r4: %016lx ", regs->r[4]);
446 printf (" r5: %016lx ", regs->r[5]);
447 printf (" r6: %016lx\n", regs->r[6]);
448 printf (" r7: %016lx ", regs->r[7]);
449 printf (" r8: %016lx ", regs->r[8]);
450 printf (" r9: %016lx\n", regs->r[9]);
451 printf (" r10: %016lx ", regs->r[10]);
452 printf (" r11: %016lx ", regs->r[11]);
453 printf (" sp: %016lx\n", regs->r[12]);
454 printf (" tp: %016lx ", regs->r[13]);
455 printf (" r14: %016lx ", regs->r[14]);
456 printf (" r15: %016lx\n", regs->r[15]);
458 printf (" Bank %d (current) Bank %d\n",
459 (regs->psr & PSR_BN) ? 1 : 0, (regs->psr & PSR_BN) ? 0 : 1);
460 printf ("16:%016lx ", regs->r[16]);
461 printf ("17:%016lx ", regs->r[17]);
462 printf ("16:%016lx ", regs->bank[0]);
463 printf ("17:%016lx\n", regs->bank[1]);
464 printf ("18:%016lx ", regs->r[18]);
465 printf ("19:%016lx ", regs->r[19]);
466 printf ("18:%016lx ", regs->bank[2]);
467 printf ("19:%016lx\n", regs->bank[3]);
468 printf ("20:%016lx ", regs->r[20]);
469 printf ("21:%016lx ", regs->r[21]);
470 printf ("20:%016lx ", regs->bank[4]);
471 printf ("21:%016lx\n", regs->bank[5]);
472 printf ("22:%016lx ", regs->r[22]);
473 printf ("23:%016lx ", regs->r[23]);
474 printf ("22:%016lx ", regs->bank[6]);
475 printf ("23:%016lx\n", regs->bank[7]);
476 printf ("24:%016lx ", regs->r[24]);
477 printf ("25:%016lx ", regs->r[25]);
478 printf ("24:%016lx ", regs->bank[8]);
479 printf ("25:%016lx\n", regs->bank[9]);
480 printf ("26:%016lx ", regs->r[26]);
481 printf ("27:%016lx ", regs->r[27]);
482 printf ("26:%016lx ", regs->bank[10]);
483 printf ("27:%016lx\n", regs->bank[11]);
484 printf ("28:%016lx ", regs->r[28]);
485 printf ("29:%016lx ", regs->r[29]);
486 printf ("28:%016lx ", regs->bank[12]);
487 printf ("29:%016lx\n", regs->bank[13]);
488 printf ("30:%016lx ", regs->r[30]);
489 printf ("31:%016lx ", regs->r[31]);
490 printf ("30:%016lx ", regs->bank[14]);
491 printf ("31:%016lx\n", regs->bank[15]);
492 printf ("\n");
493 }
495 void print_cr (vcpu_guest_context_t *ctx)
496 {
497 struct vcpu_guest_context_regs *regs = &ctx->regs;
499 printf (" dcr: %016lx ", regs->cr.dcr);
500 printf (" itm: %016lx ", regs->cr.itm);
501 printf (" iva: %016lx\n", regs->cr.iva);
502 printf (" pta: %016lx ", regs->cr.pta);
503 printf (" ipsr: %016lx ", regs->cr.ipsr);
504 printf (" isr: %016lx\n", regs->cr.isr);
505 printf (" iip: %016lx ", regs->cr.iip);
506 printf (" ifa: %016lx ", regs->cr.ifa);
507 printf (" itir: %016lx\n", regs->cr.itir);
508 printf (" iipa: %016lx ", regs->cr.iipa);
509 printf (" ifs: %016lx ", regs->cr.ifs);
510 printf (" iim: %016lx\n", regs->cr.iim);
511 printf (" iha: %016lx ", regs->cr.iha);
512 printf (" lid: %016lx ", regs->cr.lid);
513 printf (" ivr: %016lx\n", regs->cr.ivr);
514 printf (" tpr: %016lx ", regs->cr.tpr);
515 printf (" eoi: %016lx ", regs->cr.eoi);
516 printf (" irr0: %016lx\n", regs->cr.irr[0]);
517 printf (" irr1: %016lx ", regs->cr.irr[1]);
518 printf (" irr2: %016lx ", regs->cr.irr[2]);
519 printf (" irr3: %016lx\n", regs->cr.irr[3]);
520 printf (" itv: %016lx ", regs->cr.itv);
521 printf (" pmv: %016lx ", regs->cr.pmv);
522 printf (" cmcv: %016lx\n", regs->cr.cmcv);
523 printf (" lrr0: %016lx ", regs->cr.lrr0);
524 printf (" lrr1: %016lx ", regs->cr.lrr1);
525 printf (" ev_cb:%016lx\n", ctx->event_callback_ip);
526 }
528 void print_ar (vcpu_guest_context_t *ctx)
529 {
530 struct vcpu_guest_context_regs *regs = &ctx->regs;
532 printf (" kr0: %016lx ", regs->ar.kr[0]);
533 printf (" kr1: %016lx ", regs->ar.kr[1]);
534 printf (" kr2: %016lx\n", regs->ar.kr[2]);
535 printf (" kr3: %016lx ", regs->ar.kr[3]);
536 printf (" kr4: %016lx ", regs->ar.kr[4]);
537 printf (" kr5: %016lx\n", regs->ar.kr[5]);
538 printf (" kr6: %016lx ", regs->ar.kr[6]);
539 printf (" kr7: %016lx ", regs->ar.kr[7]);
540 printf (" rsc: %016lx\n", regs->ar.rsc);
541 printf (" bsp: %016lx ", regs->ar.bsp);
542 printf (" bsps: %016lx ", regs->ar.bspstore);
543 printf (" rnat: %016lx\n", regs->ar.rnat);
544 printf (" csd: %016lx ", regs->ar.csd);
545 printf (" ccv: %016lx ", regs->ar.ccv);
546 printf (" unat: %016lx\n", regs->ar.unat);
547 printf (" fpsr: %016lx ", regs->ar.fpsr);
548 printf (" itc: %016lx\n", regs->ar.itc);
549 printf (" pfs: %016lx ", regs->ar.pfs);
550 printf (" lc: %016lx ", regs->ar.lc);
551 printf (" ec: %016lx\n", regs->ar.ec);
552 }
554 void print_a_rr (int num, unsigned long rr)
555 {
556 int ps_val = (rr >> RR_PS_SHIFT) & RR_PS_MASK;
558 printf (" [%d] %06lx %02x %s %ld\n",
559 num, (rr >> RR_RID_SHIFT) & RR_RID_MASK,
560 ps_val, get_ps (ps_val), rr & RR_VE_MASK);
561 }
563 void print_rr (vcpu_guest_context_t *ctx)
564 {
565 struct vcpu_guest_context_regs *regs = &ctx->regs;
566 int i;
568 printf (" rr: rid ps ve\n");
569 for (i = 0; i < 8; i++)
570 print_a_rr (i, regs->rr[i]);
571 }
573 void print_db (vcpu_guest_context_t *ctx)
574 {
575 struct vcpu_guest_context_regs *regs = &ctx->regs;
576 int i;
578 for (i = 0; i < 7; i += 2)
579 printf (" ibr[%d]: %016lx ibr[%d]: %016lx\n",
580 i, regs->ibr[i], i + 1, regs->ibr[i + 1]);
581 printf ("\n");
582 for (i = 0; i < 7; i += 2)
583 printf (" dbr[%d]: %016lx dbr[%d]: %016lx\n",
584 i, regs->dbr[i], i + 1, regs->dbr[i + 1]);
585 }
587 struct bit_descr {
588 const char *name;
589 unsigned char sz;
590 };
592 const struct bit_descr psr_bits[] =
593 {
594 {"", 1 }, {"be", 1 }, {"up", 1 }, {"ac", 1 },
595 {"mfl", 1 }, {"mfh", 1 }, {"", 7 },
596 {"ic", 1 }, {"i", 1 }, {"pk", 1 },
597 {"", 1 }, {"dt", 1 }, {"dfl", 1 }, {"dfh", 1 },
598 {"sp", 1 }, {"pp", 1 }, {"di", 1 }, {"si", 1 },
599 {"db", 1 }, {"lp", 1 }, {"tb", 1 }, {"rt", 1 },
600 {"", 4 },
601 {"cpl", 2 }, {"is", 1 }, {"mc", 1 },
602 {"it", 1 }, {"id", 1 }, {"da", 1 }, {"dd", 1 },
603 {"ss", 1 }, {"ri", 2 }, {"ed", 1 },
604 {"bn", 1 }, {"ia", 1 }, {"vm", 1 },
605 {NULL, 0 }
606 };
608 void print_bits (const struct bit_descr *desc, unsigned long val)
609 {
610 const struct bit_descr *d;
611 unsigned int off;
613 /* Reverse order. */
614 for (d = desc, off = 0; d->name; d++)
615 off += d->sz;
617 d--;
619 while (1) {
620 off -= d->sz;
621 if (*d->name) {
622 if (d->sz != 1 || ((val >> off) & 1))
623 printf (" %s", d->name);
624 if (d->sz != 1)
625 printf ("=%lx", (val >> off) & ((1 << d->sz) - 1));
626 }
627 if (d == desc)
628 break;
629 d--;
630 }
631 }
633 void print_tr (vcpu_guest_context_t *ctx)
634 {
635 struct vcpu_tr_regs *tr = &ctx->regs.tr;
636 int i;
638 printf ("\n itr: P rid va pa ps ed pl "
639 "ar a d ma key\n");
641 for (i = 0; i < sizeof (tr->itrs) / sizeof (tr->itrs[0]); i++)
642 print_a_tr (i, &tr->itrs[i]);
644 printf ("\n dtr: P rid va pa ps ed pl "
645 "ar a d ma key\n");
647 for (i = 0; i < sizeof (tr->dtrs) / sizeof (tr->dtrs[0]); i++)
648 print_a_tr (i, &tr->dtrs[i]);
649 }
651 int lock_pages (void *addr, size_t len);
652 void unlock_pages (void *addr, size_t len);
653 int do_xen_hypercall (int xc_handle, privcmd_hypercall_t *hypercall);
655 #ifdef HAVE_DEBUG_OP
656 static int do_ia64_debug_op (int xc_handle,
657 unsigned long cmd, unsigned long domain,
658 xen_ia64_debug_op_t *op)
659 {
660 int ret = -1;
661 privcmd_hypercall_t hypercall;
663 hypercall.op = __HYPERVISOR_ia64_debug_op;
664 hypercall.arg[0] = cmd;
665 hypercall.arg[1] = domain;
666 hypercall.arg[2] = (unsigned long)op;
668 if (lock_pages (op, sizeof (*op)) != 0) {
669 perror ("Could not lock memory for Xen hypercall");
670 goto out1;
671 }
673 ret = do_xen_hypercall (xc_handle, &hypercall);
674 if (ret < 0) {
675 if (errno == EACCES)
676 fprintf (stderr,"domctl operation failed -- need to "
677 "rebuild the user-space tool set?\n");
678 }
680 unlock_pages (op, sizeof (*op));
682 out1:
683 return ret;
684 }
685 #endif
687 static volatile int ctrl_c_hit;
689 void ctrl_c_handler (int sig)
690 {
691 ctrl_c_hit = 1;
692 }
694 int wait_domain (int vcpu, vcpu_guest_context_t *ctx)
695 {
696 struct timespec ts;
697 xc_dominfo_t dominfo;
698 int ret;
699 int cnt = 0;
701 ts.tv_sec = 0;
702 ts.tv_nsec = 10*1000*1000;
704 ret = xc_domain_unpause (xc_handle, domid);
705 if (ret < 0)
706 perror ("xc_domain_unpause");
708 ctrl_c_hit = 0;
710 while (1) {
711 ret = xc_domain_getinfo (xc_handle, domid, 1, &dominfo);
712 if (ret < 0)
713 perror ("xc_domain_getinfo");
715 if (dominfo.paused)
716 break;
718 if (ctrl_c_hit) {
719 fflush (stdout);
720 /* Force pause. */
721 ret = xc_domain_pause (xc_handle, domid);
722 if (ret < 0)
723 perror ("xc_domain_pause");
725 break;
726 }
728 printf ("%c\b", "/-\\|"[(cnt++) % 4]);
729 fflush (stdout);
730 nanosleep (&ts, NULL);
731 }
732 return xc_vcpu_getcontext (xc_handle, domid, vcpu, ctx);
733 }
735 int virt_to_phys (int is_inst, unsigned long vaddr, unsigned long *paddr)
736 {
737 struct vcpu_tr_regs *trs = &cur_ctx->regs.tr;
738 struct ia64_tr_entry *tr;
739 int i;
740 int num;
742 /* Search in tr. */
743 if (is_inst) {
744 tr = trs->itrs;
745 num = sizeof (trs->itrs) / sizeof (trs->itrs[0]);
746 }
747 else {
748 tr = trs->dtrs;
749 num = sizeof (trs->dtrs) / sizeof (trs->dtrs[0]);
750 }
751 for (i = 0; i < num; i++, tr++) {
752 int ps_val = (tr->itir >> ITIR_PS_SHIFT) & ITIR_PS_MASK;
753 unsigned long ps_mask = (-1L) << ps_val;
755 if ((tr->vadr & ps_mask) == (vaddr & ps_mask)) {
756 *paddr = ((tr->pte & (PTE_PPN_MASK << PTE_PPN_SHIFT)) & ps_mask) |
757 (vaddr & ~ps_mask);
758 return 0;
759 }
760 }
761 return -1;
762 }
764 unsigned long *
765 get_reg_addr (const char *name)
766 {
767 if (strcmp (name, "ip") == 0)
768 return &cur_ctx->regs.ip;
769 else if (strcmp (name, "psr") == 0)
770 return &cur_ctx->regs.psr;
771 else if (strcmp (name, "iip") == 0)
772 return &cur_ctx->regs.cr.iip;
773 else if (strcmp (name, "b0") == 0)
774 return &cur_ctx->regs.b[0];
775 else
776 return 0;
777 }
779 enum prio_expr {EXPR_BASE, EXPR_SUM, EXPR_LOGIC, EXPR_PROD};
781 int parse_expr (char **buf, unsigned long *res, enum prio_expr prio);
783 int next_char (char **buf)
784 {
785 char *b;
787 b = *buf;
788 while (isspace ((unsigned char)*b))
789 b++;
790 *buf = b;
791 return *b;
792 }
794 int parse_unary (char **buf, unsigned long *res)
795 {
796 char c;
798 c = next_char (buf);
799 switch (c) {
800 case '0' ... '9':
801 {
802 char *e;
803 *res = strtoul (*buf, &e, 0);
804 if (e == *buf) {
805 printf ("bad literal\n");
806 return -1;
807 }
808 *buf = e;
809 }
810 break;
811 case '+':
812 (*buf)++;
813 return parse_unary (buf, res);
814 case '$':
815 {
816 char *b;
817 char *e;
818 char c;
819 unsigned long *reg;
820 int len;
822 b = *buf;
823 e = b + 1;
825 while ((*e >= 'a' && *e <= 'z') ||
826 (*e >= 'A' && *e <= 'Z') ||
827 (*e >= '0' && *e <= '9') ||
828 (*e == '_' || *e == '.'))
829 e++;
831 if (b == e) {
832 printf ("identifier missing after '$'\n");
833 return -1;
834 }
836 b++;
837 len = e - b;
839 c = b[len];
840 b[len] = 0;
841 reg = get_reg_addr (b);
842 b[len] = c;
844 if (reg != NULL)
845 *res = *reg;
846 else if (strncmp (b, "d2p", len) == 0 ||
847 strncmp (b, "i2p", len) == 0) {
848 unsigned long vaddr;
850 *buf = e;
851 if (parse_unary (buf, &vaddr) != 0)
852 return -1;
853 if (virt_to_phys (*b == 'i', vaddr, res) != 0) {
854 printf ("cannot find vaddr %016lx in tr\n", vaddr);
855 return -1;
856 }
857 return 0;
858 }
859 else {
860 printf ("unknown symbol\n");
861 return -1;
862 }
863 *buf = e;
864 }
865 break;
866 case '(':
867 (*buf)++;
868 if (parse_expr (buf, res, EXPR_BASE) != 0)
869 return -1;
871 if (next_char (buf) != ')') {
872 printf ("missing ')'\n");
873 return -1;
874 }
875 else
876 (*buf)++;
877 break;
878 default:
879 printf ("unknown operand '%c' in expression\n", c);
880 return -1;
881 }
883 return 0;
884 }
886 int parse_expr (char **buf, unsigned long *res, enum prio_expr prio)
887 {
888 unsigned long val = 0;
889 unsigned long val1;
890 char c;
892 if (parse_unary (buf, &val) != 0)
893 return -1;
895 while (1) {
896 c = next_char (buf);
897 switch (c) {
898 case '+':
899 case '-':
900 if (prio > EXPR_SUM)
901 return 0;
902 (*buf)++;
903 if (parse_expr (buf, &val1, EXPR_SUM) < 0)
904 return -1;
905 if (c == '+')
906 val += val1;
907 else
908 val -= val1;
909 break;
910 case '*':
911 if (prio > EXPR_PROD)
912 return 0;
914 (*buf)++;
915 if (parse_expr (buf, &val1, EXPR_SUM) < 0)
916 return -1;
918 val *= val1;
919 break;
920 default:
921 *res = val;
922 return 0;
923 }
924 }
925 }
927 char *parse_arg (char **buf)
928 {
929 char *res;
930 char *b = *buf;
932 /* Eat leading spaces. */
933 while (isspace ((unsigned char)*b))
934 b++;
936 res = b;
937 while (*b && !isspace ((unsigned char)*b))
938 b++;
940 /* Set the NUL terminator. */
941 if (*b)
942 *b++ = 0;
944 *buf = b;
945 return res;
946 }
948 vcpu_guest_context_t vcpu_ctx[MAX_VIRT_CPUS];
950 int vcpu_setcontext (int vcpu)
951 {
952 int ret;
954 ret = xc_vcpu_setcontext (xc_handle, domid, vcpu, &vcpu_ctx[vcpu]);
955 if (ret < 0)
956 perror ("xc_vcpu_setcontext");
958 return ret;
959 }
961 enum cmd_status { CMD_ERROR, CMD_OK, CMD_REPEAT, CMD_QUIT };
963 struct command_desc
964 {
965 const char *name;
966 const char *help;
967 enum cmd_status (*cmd)(char *line);
968 };
970 static enum cmd_status
971 cmd_registers (char *line)
972 {
973 print_ctx (cur_ctx);
974 return CMD_OK;
975 }
977 static enum cmd_status
978 cmd_sstep (char *line)
979 {
980 /* Set psr.dd and psr.id to skip over current breakpoint. */
981 cur_ctx->regs.psr |= PSR_SS | PSR_DD | PSR_ID;
982 cur_ctx->regs.psr &= ~PSR_TB;
983 if (vcpu_setcontext (cur_vcpu) < 0)
984 return CMD_ERROR;
986 if (wait_domain (cur_vcpu, cur_ctx) < 0) {
987 perror ("wait_domain");
988 return CMD_ERROR;
989 }
991 print_ctx (cur_ctx);
993 return CMD_REPEAT;
994 }
996 static enum cmd_status
997 cmd_go (char *line)
998 {
999 unsigned long n = 1;
1001 if (*line != 0) {
1002 if (parse_expr (&line, &n, 0) < 0)
1003 return CMD_ERROR;
1005 while (n > 0) {
1006 /* Set psr.dd and psr.id to skip over current breakpoint. */
1007 if ((cur_ctx->regs.psr & (PSR_SS | PSR_TB | PSR_DB)) != 0) {
1008 cur_ctx->regs.psr &= ~(PSR_SS | PSR_TB);
1009 cur_ctx->regs.psr |= PSR_DD | PSR_ID;
1010 if (vcpu_setcontext (cur_vcpu) < 0)
1011 return CMD_ERROR;
1014 if (wait_domain (cur_vcpu, cur_ctx) < 0) {
1015 perror ("wait_domain");
1016 return CMD_ERROR;
1018 print_ctx (cur_ctx);
1019 n--;
1022 return CMD_REPEAT;
1025 static enum cmd_status
1026 cmd_cb (char *line)
1028 if ((cur_ctx->regs.psr & (PSR_SS | PSR_TB)) != PSR_TB) {
1029 cur_ctx->regs.psr &= ~PSR_SS;
1030 cur_ctx->regs.psr |= PSR_TB;
1031 if (vcpu_setcontext (cur_vcpu) < 0)
1032 return CMD_ERROR;
1035 if (wait_domain (cur_vcpu, cur_ctx) < 0) {
1036 perror ("wait_domain");
1037 return CMD_ERROR;
1040 print_ctx (cur_ctx);
1042 return CMD_REPEAT;
1045 static int quit_paused;
1047 static enum cmd_status
1048 cmd_quit (char *line)
1050 if (!strcmp (line, "paused"))
1051 quit_paused = 1;
1052 return CMD_QUIT;
1055 static enum cmd_status
1056 cmd_echo (char *line)
1058 printf ("%s", line);
1059 return CMD_OK;
1062 static enum cmd_status
1063 cmd_disassemble (char *args)
1065 static unsigned long addr;
1066 unsigned long end_addr = addr + 16;
1068 if (*args != 0) {
1069 if (parse_expr (&args, &addr, 0) < 0)
1070 return CMD_ERROR;
1071 if (*args != 0) {
1072 if (parse_expr (&args, &end_addr, 0) < 0)
1073 return CMD_ERROR;
1075 else
1076 end_addr = addr + 16;
1078 target_disas (stdout, addr, end_addr - addr);
1079 addr = end_addr;
1080 return CMD_REPEAT;
1083 static enum cmd_status
1084 cmd_break (char *args)
1086 unsigned long addr;
1087 int i;
1089 for (i = 0; i < 4; i++)
1090 if (cur_ctx->regs.ibr[2 * i] == 0 && cur_ctx->regs.ibr[2 * i + 1] == 0)
1091 break;
1093 if (i == 4) {
1094 printf ("no availabe break points\n");
1095 return CMD_ERROR;
1098 if (parse_expr (&args, &addr, 0) < 0)
1099 return CMD_ERROR;
1101 cur_ctx->regs.ibr[2 * i] = addr;
1102 cur_ctx->regs.ibr[2 * i + 1] = 0x87fffffffffffff0UL;
1103 cur_ctx->regs.psr |= PSR_DB;
1105 if (vcpu_setcontext (cur_vcpu) < 0)
1106 return CMD_ERROR;
1107 else
1108 return CMD_OK;
1111 static enum cmd_status
1112 cmd_watch (char *args)
1114 unsigned long addr;
1115 unsigned long mask;
1116 int i;
1118 for (i = 0; i < 4; i++)
1119 if (cur_ctx->regs.dbr[2 * i] == 0 && cur_ctx->regs.dbr[2 * i + 1] == 0)
1120 break;
1122 if (i == 4) {
1123 printf ("no availabe watch points\n");
1124 return CMD_ERROR;
1127 if (parse_expr (&args, &addr, 0) < 0)
1128 return CMD_ERROR;
1130 if (*args == 0)
1131 mask = 3;
1132 else if (parse_expr (&args, &mask, 0) < 0)
1133 return CMD_ERROR;
1135 cur_ctx->regs.dbr[2 * i] = addr;
1136 cur_ctx->regs.dbr[2 * i + 1] = ~((1UL << mask) - 1) | (0xc7UL << 56);
1137 cur_ctx->regs.psr |= PSR_DB;
1139 if (vcpu_setcontext (cur_vcpu) < 0)
1140 return CMD_ERROR;
1141 else {
1142 printf ("Watchpoint %d set\n", i);
1143 return CMD_OK;
1147 static enum cmd_status
1148 cmd_delete (char *args)
1150 unsigned long num;
1152 if (parse_expr (&args, &num, 0) < 0)
1153 return CMD_ERROR;
1155 if (num < 4) {
1156 cur_ctx->regs.ibr[2 * num] = 0;
1157 cur_ctx->regs.ibr[2 * num + 1] = 0;
1159 else if (num < 8) {
1160 num -= 4;
1161 cur_ctx->regs.dbr[2 * num] = 0;
1162 cur_ctx->regs.dbr[2 * num + 1] = 0;
1164 else {
1165 printf ("breakpoint out of range\n");
1166 return CMD_ERROR;
1169 cur_ctx->regs.psr |= PSR_DB;
1171 if (vcpu_setcontext (cur_vcpu) < 0)
1172 return CMD_ERROR;
1173 else
1174 return CMD_OK;
1177 static enum cmd_status
1178 cmd_disable (char *args)
1180 unsigned long num;
1182 if (parse_expr (&args, &num, 0) < 0)
1183 return CMD_ERROR;
1185 if (num >= 4) {
1186 printf ("breakpoint out of range\n");
1187 return CMD_ERROR;
1190 cur_ctx->regs.ibr[2 * num + 1] &= ~(1UL << 63);
1192 if (vcpu_setcontext (cur_vcpu) < 0)
1193 return CMD_ERROR;
1194 else
1195 return CMD_OK;
1198 static enum cmd_status
1199 cmd_enable (char *args)
1201 unsigned long num;
1203 if (parse_expr (&args, &num, 0) < 0)
1204 return CMD_ERROR;
1206 if (num >= 4) {
1207 printf ("breakpoint out of range\n");
1208 return CMD_ERROR;
1211 cur_ctx->regs.ibr[2 * num + 1] |= 1UL << 63;
1213 if (vcpu_setcontext (cur_vcpu) < 0)
1214 return CMD_ERROR;
1215 else
1216 return CMD_OK;
1219 static enum cmd_status
1220 cmd_print (char *args)
1222 unsigned long addr;
1224 if (parse_expr (&args, &addr, 0) < 0)
1225 return CMD_ERROR;
1227 printf ("res: 0x%016lx = %ld\n", addr, addr);
1229 return CMD_OK;
1232 struct bit_xlat {
1233 unsigned int bit;
1234 const char *name;
1235 };
1237 static const struct bit_xlat debug_flags[] = {
1238 { XEN_IA64_DEBUG_ON_KERN_SSTEP, "sstep" },
1239 { XEN_IA64_DEBUG_ON_KERN_DEBUG, "debug" },
1240 { XEN_IA64_DEBUG_ON_KERN_TBRANCH, "tbranch" },
1241 { XEN_IA64_DEBUG_ON_EXTINT, "extint" },
1242 { XEN_IA64_DEBUG_ON_EXCEPT, "except" },
1243 { XEN_IA64_DEBUG_ON_EVENT, "event" },
1244 { XEN_IA64_DEBUG_ON_PRIVOP, "privop" },
1245 { XEN_IA64_DEBUG_ON_PAL, "pal" },
1246 { XEN_IA64_DEBUG_ON_SAL, "sal" },
1247 { XEN_IA64_DEBUG_ON_EFI, "efi" },
1248 { XEN_IA64_DEBUG_ON_RFI, "rfi" },
1249 { XEN_IA64_DEBUG_ON_MMU, "mmu" },
1250 { XEN_IA64_DEBUG_ON_BAD_MPA, "mpa" },
1251 { XEN_IA64_DEBUG_FORCE_SS, "ss" },
1252 { XEN_IA64_DEBUG_FORCE_DB, "db" },
1253 { XEN_IA64_DEBUG_ON_TR, "tr" },
1254 { XEN_IA64_DEBUG_ON_TC, "tc" },
1255 #if 0
1256 { XEN_IA64_DEBUG_ON_KEYS, "keys" },
1257 { XEN_IA64_DEBUG_ON_MOV_TO_CR, "mov_to_cr" },
1258 { XEN_IA64_DEBUG_ON_VHPT, "vhpt" },
1259 { XEN_IA64_DEBUG_ON_IOSAPIC, "iosapic" },
1260 #endif
1261 { 0, NULL }
1262 };
1264 static enum cmd_status
1265 cmd_disp (char *arg)
1267 if (strcmp (arg, "br") == 0)
1268 print_br (cur_ctx);
1269 else if (strcmp (arg, "regs") == 0)
1270 print_regs (cur_ctx);
1271 else if (strcmp (arg, "cr") == 0)
1272 print_cr (cur_ctx);
1273 else if (strcmp (arg, "ar") == 0)
1274 print_ar (cur_ctx);
1275 else if (strcmp (arg, "tr") == 0)
1276 print_tr (cur_ctx);
1277 else if (strcmp (arg, "rr") == 0)
1278 print_rr (cur_ctx);
1279 else if (strcmp (arg, "db") == 0)
1280 print_db (cur_ctx);
1281 else if (strcmp (arg, "psr") == 0) {
1282 printf ("psr:");
1283 print_bits (psr_bits, cur_ctx->regs.psr);
1284 printf ("\n");
1286 else if (strcmp (arg, "ipsr") == 0) {
1287 printf ("ipsr:");
1288 print_bits (psr_bits, cur_ctx->regs.cr.ipsr);
1289 printf ("\n");
1291 else if (strcmp (arg, "break") == 0) {
1292 int i;
1294 for (i = 0; i < 4; i++)
1295 if (cur_ctx->regs.ibr[2 * i + 1])
1296 printf ("%d: 0x%016lx %s\n", i, cur_ctx->regs.ibr[2 * i],
1297 (cur_ctx->regs.ibr[2 * i + 1] & (1UL << 63)) ?
1298 "enabled" : "disabled");
1299 for (i = 0; i < 4; i++)
1300 if (cur_ctx->regs.dbr[2 * i + 1])
1301 printf ("%d: 0x%016lx %s\n", i, cur_ctx->regs.dbr[2 * i],
1302 (cur_ctx->regs.dbr[2 * i + 1] & (1UL << 63)) ?
1303 "enabled" : "disabled");
1305 else if (strcmp (arg, "domain") == 0) {
1306 xc_dominfo_t dominfo;
1307 #ifdef HAVE_DEBUG_OP
1308 xen_ia64_debug_op_t debug_op;
1309 int i;
1310 #endif
1311 if (xc_domain_getinfo (xc_handle, domid, 1, &dominfo) < 0) {
1312 perror ("xc_domain_getinfo");
1313 return 0;
1316 printf ("id=%d nr_pages=%lu shared_info_frame=%lu max_mem=%luKB\n",
1317 dominfo.domid, dominfo.nr_pages, dominfo.shared_info_frame,
1318 dominfo.max_memkb);
1319 printf (" nr_online_vcpu=%u max_vcpu_id=%u\n",
1320 dominfo.nr_online_vcpus, dominfo.max_vcpu_id);
1321 printf (" status:");
1322 if (dominfo.dying)
1323 printf (" dying");
1324 if (dominfo.crashed)
1325 printf (" crashed");
1326 if (dominfo.shutdown)
1327 printf (" shutdown(%u)", dominfo.shutdown_reason);
1328 if (dominfo.paused)
1329 printf (" paused");
1330 if (dominfo.blocked)
1331 printf (" blocked");
1332 if (dominfo.running)
1333 printf (" running");
1334 if (dominfo.hvm)
1335 printf (" hvm");
1336 if (dominfo.debugged)
1337 printf (" debug");
1338 printf ("\n");
1340 #ifdef HAVE_DEBUG_OP
1341 if (do_ia64_debug_op (xc_handle, XEN_IA64_DEBUG_OP_GET_FLAGS,
1342 domid, &debug_op) < 0) {
1343 perror ("xc_domain_getinfo");
1344 return 0;
1346 printf ("debug flags: %08lx: ", debug_op.flags);
1347 for (i = 0; debug_flags[i].name; i++)
1348 if (debug_flags[i].bit & debug_op.flags)
1349 printf (" %s", debug_flags[i].name);
1350 printf ("\n");
1351 #endif
1353 else if (*arg == 0)
1354 printf ("choose among br, regs, cr, ar, tr, rr, db\n");
1355 else {
1356 printf ("cannot disp '%s'\n", arg);
1357 return CMD_ERROR;
1359 return CMD_OK;
1362 static enum cmd_status
1363 cmd_bev (char *arg)
1365 xen_ia64_debug_op_t debug_op;
1366 int i;
1368 if (do_ia64_debug_op (xc_handle, XEN_IA64_DEBUG_OP_GET_FLAGS,
1369 domid, &debug_op) < 0) {
1370 perror ("get debug flags");
1371 return CMD_ERROR;
1373 if (arg == NULL || arg[0] == 0) {
1374 printf ("debug flags: %08lx:\n", debug_op.flags);
1375 for (i = 0; debug_flags[i].name; i++)
1376 printf (" %c%s\n",
1377 (debug_flags[i].bit & debug_op.flags) ? '+' : '-',
1378 debug_flags[i].name);
1379 return CMD_OK;
1381 else {
1382 char *p = strtok ((char *)arg, " ");
1384 while (p != NULL) {
1385 unsigned int flag = 0;
1387 for (i = 0; debug_flags[i].name; i++)
1388 if (strcmp (p, debug_flags[i].name) == 0
1389 || ((p[0] == '-' || p[0] == '+')
1390 && strcmp (p + 1, debug_flags[i].name) == 0)) {
1391 flag = debug_flags[i].bit;
1392 break;
1394 if (flag == 0) {
1395 printf ("unknown event %s\n", p);
1396 return CMD_ERROR;
1398 if (p[0] == '-')
1399 debug_op.flags &= ~flag;
1400 else
1401 debug_op.flags |= flag;
1403 p = strtok (NULL, " ");
1405 if (do_ia64_debug_op (xc_handle, XEN_IA64_DEBUG_OP_SET_FLAGS,
1406 domid, &debug_op) < 0) {
1407 perror ("set debug flags");
1408 return CMD_ERROR;
1410 /* Disabling force_SS and force_DB requires setting psr. */
1411 if (vcpu_setcontext (cur_vcpu) < 0)
1412 return CMD_ERROR;
1413 else
1414 return CMD_OK;
1418 static enum cmd_status
1419 cmd_set (char *line)
1421 char *reg;
1422 unsigned long *addr;
1423 unsigned long val;
1425 reg = parse_arg (&line);
1427 addr = get_reg_addr (reg);
1428 if (addr == NULL) {
1429 printf ("unknown register %s\n", reg);
1430 return CMD_ERROR;
1433 if (parse_expr (&line, &val, 0) < 0)
1434 return CMD_ERROR;
1436 *addr = val;
1438 if (vcpu_setcontext (cur_vcpu) < 0)
1439 return CMD_ERROR;
1440 else
1441 return CMD_OK;
1444 const struct command_desc commands[];
1446 static enum cmd_status
1447 cmd_help (char *line)
1449 int i;
1451 for (i = 0; commands[i].name; i++)
1452 printf ("%s -- %s\n", commands[i].name, commands[i].help);
1454 return CMD_OK;
1457 const struct command_desc commands[] = {
1458 { "registers", "display current registers", cmd_registers },
1459 { "sstep", "single step", cmd_sstep },
1460 { "go", "resume execution", cmd_go },
1461 { "quit", "quit debugger", cmd_quit },
1462 { "echo", "display parameters", cmd_echo },
1463 { "disassemble", "disassemble memory", cmd_disassemble },
1464 { "break", "set a break point", cmd_break },
1465 { "watch", "set a watch point", cmd_watch },
1466 { "cb", "resume until branch", cmd_cb },
1467 { "delete", "delete a break point", cmd_delete },
1468 { "disable", "disable a break point", cmd_disable },
1469 { "enable", "enable a break point", cmd_enable },
1470 { "print", "print an expression", cmd_print },
1471 { "disp", "disp br/regs/cr/ar/tr/rr/db/psr/break/domain", cmd_disp},
1472 { "bev", "break on event", cmd_bev},
1473 { "set", "set reg val", cmd_set},
1474 { "help", "disp help", cmd_help },
1475 { NULL, NULL, NULL }
1476 };
1479 enum cmd_status do_command (int vcpu, char *line)
1481 char *cmd;
1482 char *args;
1483 int i;
1484 const struct command_desc *desc;
1485 static const struct command_desc *last_desc;
1486 enum cmd_status status;
1487 int flag_ambiguous;
1489 cur_vcpu = vcpu;
1490 cur_ctx = &vcpu_ctx[vcpu];
1492 /* Handle repeat last-command. */
1493 if (*line == 0) {
1494 if (last_desc != NULL)
1495 return (*last_desc->cmd)("");
1496 else
1497 return CMD_OK;
1499 last_desc = NULL;
1501 cmd = parse_arg (&line);
1502 args = line;
1504 desc = NULL;
1505 flag_ambiguous = 0;
1507 for (i = 0; commands[i].name; i++) {
1508 const char *n = commands[i].name;
1509 char *c = cmd;
1511 while (*n == *c && *n)
1512 n++, c++;
1514 if (*c == 0) {
1515 /* Match. */
1516 if (desc != NULL) {
1517 if (!flag_ambiguous)
1518 printf ("ambiguous command: %s", desc->name);
1519 printf (", %s", commands[i].name);
1520 flag_ambiguous = 1;
1522 else
1523 desc = &commands[i];
1527 if (flag_ambiguous) {
1528 printf ("\n");
1529 return CMD_ERROR;
1531 else if (!desc) {
1532 printf ("command not found, try help\n");
1533 return CMD_ERROR;
1536 status = (*desc->cmd)(args);
1537 if (status == CMD_REPEAT)
1538 last_desc = desc;
1539 return status;
1542 void xenitp (int vcpu)
1544 int ret;
1545 struct sigaction sa;
1547 cur_ctx = &vcpu_ctx[vcpu];
1549 xc_handle = xc_interface_open (); /* for accessing control interface */
1551 if (xc_domain_setdebugging (xc_handle, domid, 1) != 0)
1552 perror ("setdebugging");
1554 ret = xc_domain_pause (xc_handle, domid);
1555 if (ret < 0) {
1556 perror ("xc_domain_pause");
1557 exit (-1);
1560 ret = xc_vcpu_getcontext (xc_handle, domid, vcpu, cur_ctx);
1561 if (ret < 0) {
1562 perror ("xc_vcpu_getcontext");
1563 exit (-1);
1566 print_ctx (cur_ctx);
1568 /* Catch ctrl-c. */
1569 sa.sa_handler = &ctrl_c_handler;
1570 sa.sa_flags = 0;
1571 sigemptyset (&sa.sa_mask);
1572 if (sigaction (SIGINT, &sa, NULL) != 0)
1573 perror ("sigaction");
1575 while (1) {
1576 char buf[128];
1577 int len;
1579 printf ("XenITP> ");
1581 if (fgets (buf, sizeof (buf), stdin) == NULL)
1582 break;
1584 len = strlen ((char *)buf);
1585 if (len >= 1 && buf[len - 1] == '\n')
1586 buf[len - 1] = 0;
1588 ret = do_command (vcpu, buf);
1589 if (ret == CMD_QUIT)
1590 break;
1593 /* Clear debug bits. */
1594 if ((cur_ctx->regs.psr & (PSR_SS | PSR_TB | PSR_DB)) != 0) {
1595 cur_ctx->regs.psr &= ~(PSR_SS | PSR_TB | PSR_DB);
1596 cur_ctx->regs.psr |= PSR_DD | PSR_ID;
1597 vcpu_setcontext (cur_vcpu);
1600 /* Disable debugging. */
1601 if (xc_domain_setdebugging (xc_handle, domid, 0) != 0)
1602 perror ("setdebugging");
1604 if (!quit_paused) {
1605 ret = xc_domain_unpause (xc_handle, domid);
1606 if (ret < 0) {
1607 perror ("xc_domain_unpause");
1608 exit (-1);
1612 xc_interface_close (xc_handle);
1613 if (ret < 0) {
1614 perror ("xc_interface_close");
1615 exit (-1);
1619 static void usage (void)
1621 printf ("usage:\n");
1622 printf (" xenitp <DOMAIN> [VCPU]\n");
1626 int main (int argc, char **argv)
1628 int ch;
1629 static const char *sopts = "h"
1631 static const struct option lopts[] = {
1632 {"help", 0, NULL, 'h'},
1633 {0, 0, 0, 0}
1634 };
1635 int vcpu = 0;
1637 while ((ch = getopt_long (argc, argv, sopts, lopts, NULL)) != -1) {
1638 switch (ch) {
1639 case 'h':
1640 usage ();
1641 exit (-1);
1642 case '?':
1643 fprintf (stderr, "%s --help for more options\n", argv[0]);
1644 exit (-1);
1648 argv += optind;
1649 argc -= optind;
1651 if (argc < 1 || argc > 2) {
1652 usage ();
1653 exit (-1);
1656 domid = atoi (argv[0]);
1657 if (domid == 0) {
1658 fprintf (stderr, "cannot trace dom0\n");
1659 exit (-1);
1662 if (argc == 2)
1663 vcpu = atoi (argv[1]);
1665 xenitp (vcpu);
1667 return 0;
1670 /*
1671 * Local variables:
1672 * mode: C
1673 * c-set-style: "BSD"
1674 * c-basic-offset: 4
1675 * tab-width: 4
1676 * indent-tabs-mode: nil
1677 * End:
1678 */