1 /* 2 * Routines providing a simple monitor for use on the PowerMac. 3 * 4 * Copyright (C) 1996 Paul Mackerras. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 #include <linux/config.h> 12 #include <linux/errno.h> 13 #include <linux/sched.h> 14 #include <linux/smp.h> 15 #include <linux/mm.h> 16 #include <linux/reboot.h> 17 #include <linux/delay.h> 18 #include <linux/kallsyms.h> 19 #include <linux/cpumask.h> 20 #include <linux/module.h> 21 22 #include <asm/ptrace.h> 23 #include <asm/string.h> 24 #include <asm/prom.h> 25 #include <asm/machdep.h> 26 #include <asm/xmon.h> 27 #ifdef CONFIG_PMAC_BACKLIGHT 28 #include <asm/backlight.h> 29 #endif 30 #include <asm/processor.h> 31 #include <asm/pgtable.h> 32 #include <asm/mmu.h> 33 #include <asm/mmu_context.h> 34 #include <asm/cputable.h> 35 #include <asm/rtas.h> 36 #include <asm/sstep.h> 37 #include <asm/bug.h> 38 39 #ifdef CONFIG_PPC64 40 #include <asm/hvcall.h> 41 #include <asm/paca.h> 42 #endif 43 44 #include "nonstdio.h" 45 46 #define scanhex xmon_scanhex 47 #define skipbl xmon_skipbl 48 49 #ifdef CONFIG_SMP 50 cpumask_t cpus_in_xmon = CPU_MASK_NONE; 51 static unsigned long xmon_taken = 1; 52 static int xmon_owner; 53 static int xmon_gate; 54 #endif /* CONFIG_SMP */ 55 56 static unsigned long in_xmon = 0; 57 58 static unsigned long adrs; 59 static int size = 1; 60 #define MAX_DUMP (128 * 1024) 61 static unsigned long ndump = 64; 62 static unsigned long nidump = 16; 63 static unsigned long ncsum = 4096; 64 static int termch; 65 static char tmpstr[128]; 66 67 #define JMP_BUF_LEN 23 68 static long bus_error_jmp[JMP_BUF_LEN]; 69 static int catch_memory_errors; 70 static long *xmon_fault_jmp[NR_CPUS]; 71 #define setjmp xmon_setjmp 72 #define longjmp xmon_longjmp 73 74 /* Breakpoint stuff */ 75 struct bpt { 76 unsigned long address; 77 unsigned int instr[2]; 78 atomic_t ref_count; 79 int enabled; 80 unsigned long pad; 81 }; 82 83 /* Bits in bpt.enabled */ 84 #define BP_IABR_TE 1 /* IABR translation enabled */ 85 #define BP_IABR 2 86 #define BP_TRAP 8 87 #define BP_DABR 0x10 88 89 #define NBPTS 256 90 static struct bpt bpts[NBPTS]; 91 static struct bpt dabr; 92 static struct bpt *iabr; 93 static unsigned bpinstr = 0x7fe00008; /* trap */ 94 95 #define BP_NUM(bp) ((bp) - bpts + 1) 96 97 /* Prototypes */ 98 static int cmds(struct pt_regs *); 99 static int mread(unsigned long, void *, int); 100 static int mwrite(unsigned long, void *, int); 101 static int handle_fault(struct pt_regs *); 102 static void byterev(unsigned char *, int); 103 static void memex(void); 104 static int bsesc(void); 105 static void dump(void); 106 static void prdump(unsigned long, long); 107 static int ppc_inst_dump(unsigned long, long, int); 108 void print_address(unsigned long); 109 static void backtrace(struct pt_regs *); 110 static void excprint(struct pt_regs *); 111 static void prregs(struct pt_regs *); 112 static void memops(int); 113 static void memlocate(void); 114 static void memzcan(void); 115 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned); 116 int skipbl(void); 117 int scanhex(unsigned long *valp); 118 static void scannl(void); 119 static int hexdigit(int); 120 void getstring(char *, int); 121 static void flush_input(void); 122 static int inchar(void); 123 static void take_input(char *); 124 static unsigned long read_spr(int); 125 static void write_spr(int, unsigned long); 126 static void super_regs(void); 127 static void remove_bpts(void); 128 static void insert_bpts(void); 129 static void remove_cpu_bpts(void); 130 static void insert_cpu_bpts(void); 131 static struct bpt *at_breakpoint(unsigned long pc); 132 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp); 133 static int do_step(struct pt_regs *); 134 static void bpt_cmds(void); 135 static void cacheflush(void); 136 static int cpu_cmd(void); 137 static void csum(void); 138 static void bootcmds(void); 139 static void proccall(void); 140 void dump_segments(void); 141 static void symbol_lookup(void); 142 static void xmon_print_symbol(unsigned long address, const char *mid, 143 const char *after); 144 static const char *getvecname(unsigned long vec); 145 146 extern int print_insn_powerpc(unsigned long, unsigned long, int); 147 extern void printf(const char *fmt, ...); 148 extern void xmon_vfprintf(void *f, const char *fmt, va_list ap); 149 extern int xmon_putc(int c, void *f); 150 extern int putchar(int ch); 151 152 extern void xmon_enter(void); 153 extern void xmon_leave(void); 154 155 extern int xmon_read_poll(void); 156 extern long setjmp(long *); 157 extern void longjmp(long *, long); 158 extern void xmon_save_regs(struct pt_regs *); 159 160 #ifdef CONFIG_PPC64 161 #define REG "%.16lx" 162 #define REGS_PER_LINE 4 163 #define LAST_VOLATILE 13 164 #else 165 #define REG "%.8lx" 166 #define REGS_PER_LINE 8 167 #define LAST_VOLATILE 12 168 #endif 169 170 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3]) 171 172 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \ 173 || ('a' <= (c) && (c) <= 'f') \ 174 || ('A' <= (c) && (c) <= 'F')) 175 #define isalnum(c) (('0' <= (c) && (c) <= '9') \ 176 || ('a' <= (c) && (c) <= 'z') \ 177 || ('A' <= (c) && (c) <= 'Z')) 178 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0) 179 180 static char *help_string = "\ 181 Commands:\n\ 182 b show breakpoints\n\ 183 bd set data breakpoint\n\ 184 bi set instruction breakpoint\n\ 185 bc clear breakpoint\n" 186 #ifdef CONFIG_SMP 187 "\ 188 c print cpus stopped in xmon\n\ 189 c# try to switch to cpu number h (in hex)\n" 190 #endif 191 "\ 192 C checksum\n\ 193 d dump bytes\n\ 194 di dump instructions\n\ 195 df dump float values\n\ 196 dd dump double values\n\ 197 e print exception information\n\ 198 f flush cache\n\ 199 la lookup symbol+offset of specified address\n\ 200 ls lookup address of specified symbol\n\ 201 m examine/change memory\n\ 202 mm move a block of memory\n\ 203 ms set a block of memory\n\ 204 md compare two blocks of memory\n\ 205 ml locate a block of memory\n\ 206 mz zero a block of memory\n\ 207 mi show information about memory allocation\n\ 208 p call a procedure\n\ 209 r print registers\n\ 210 s single step\n\ 211 S print special registers\n\ 212 t print backtrace\n\ 213 x exit monitor and recover\n\ 214 X exit monitor and dont recover\n" 215 #ifdef CONFIG_PPC64 216 " u dump segment table or SLB\n" 217 #endif 218 #ifdef CONFIG_PPC_STD_MMU_32 219 " u dump segment registers\n" 220 #endif 221 " ? help\n" 222 " zr reboot\n\ 223 zh halt\n" 224 ; 225 226 static struct pt_regs *xmon_regs; 227 228 static inline void sync(void) 229 { 230 asm volatile("sync; isync"); 231 } 232 233 static inline void store_inst(void *p) 234 { 235 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p)); 236 } 237 238 static inline void cflush(void *p) 239 { 240 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p)); 241 } 242 243 static inline void cinval(void *p) 244 { 245 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p)); 246 } 247 248 /* 249 * Disable surveillance (the service processor watchdog function) 250 * while we are in xmon. 251 * XXX we should re-enable it when we leave. :) 252 */ 253 #define SURVEILLANCE_TOKEN 9000 254 255 static inline void disable_surveillance(void) 256 { 257 #ifdef CONFIG_PPC_PSERIES 258 /* Since this can't be a module, args should end up below 4GB. */ 259 static struct rtas_args args; 260 261 /* 262 * At this point we have got all the cpus we can into 263 * xmon, so there is hopefully no other cpu calling RTAS 264 * at the moment, even though we don't take rtas.lock. 265 * If we did try to take rtas.lock there would be a 266 * real possibility of deadlock. 267 */ 268 args.token = rtas_token("set-indicator"); 269 if (args.token == RTAS_UNKNOWN_SERVICE) 270 return; 271 args.nargs = 3; 272 args.nret = 1; 273 args.rets = &args.args[3]; 274 args.args[0] = SURVEILLANCE_TOKEN; 275 args.args[1] = 0; 276 args.args[2] = 0; 277 enter_rtas(__pa(&args)); 278 #endif /* CONFIG_PPC_PSERIES */ 279 } 280 281 #ifdef CONFIG_SMP 282 static int xmon_speaker; 283 284 static void get_output_lock(void) 285 { 286 int me = smp_processor_id() + 0x100; 287 int last_speaker = 0, prev; 288 long timeout; 289 290 if (xmon_speaker == me) 291 return; 292 for (;;) { 293 if (xmon_speaker == 0) { 294 last_speaker = cmpxchg(&xmon_speaker, 0, me); 295 if (last_speaker == 0) 296 return; 297 } 298 timeout = 10000000; 299 while (xmon_speaker == last_speaker) { 300 if (--timeout > 0) 301 continue; 302 /* hostile takeover */ 303 prev = cmpxchg(&xmon_speaker, last_speaker, me); 304 if (prev == last_speaker) 305 return; 306 break; 307 } 308 } 309 } 310 311 static void release_output_lock(void) 312 { 313 xmon_speaker = 0; 314 } 315 #endif 316 317 int xmon_core(struct pt_regs *regs, int fromipi) 318 { 319 int cmd = 0; 320 unsigned long msr; 321 struct bpt *bp; 322 long recurse_jmp[JMP_BUF_LEN]; 323 unsigned long offset; 324 #ifdef CONFIG_SMP 325 int cpu; 326 int secondary; 327 unsigned long timeout; 328 #endif 329 330 msr = mfmsr(); 331 mtmsr(msr & ~MSR_EE); /* disable interrupts */ 332 333 bp = in_breakpoint_table(regs->nip, &offset); 334 if (bp != NULL) { 335 regs->nip = bp->address + offset; 336 atomic_dec(&bp->ref_count); 337 } 338 339 remove_cpu_bpts(); 340 341 #ifdef CONFIG_SMP 342 cpu = smp_processor_id(); 343 if (cpu_isset(cpu, cpus_in_xmon)) { 344 get_output_lock(); 345 excprint(regs); 346 printf("cpu 0x%x: Exception %lx %s in xmon, " 347 "returning to main loop\n", 348 cpu, regs->trap, getvecname(TRAP(regs))); 349 release_output_lock(); 350 longjmp(xmon_fault_jmp[cpu], 1); 351 } 352 353 if (setjmp(recurse_jmp) != 0) { 354 if (!in_xmon || !xmon_gate) { 355 get_output_lock(); 356 printf("xmon: WARNING: bad recursive fault " 357 "on cpu 0x%x\n", cpu); 358 release_output_lock(); 359 goto waiting; 360 } 361 secondary = !(xmon_taken && cpu == xmon_owner); 362 goto cmdloop; 363 } 364 365 xmon_fault_jmp[cpu] = recurse_jmp; 366 cpu_set(cpu, cpus_in_xmon); 367 368 bp = NULL; 369 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) 370 bp = at_breakpoint(regs->nip); 371 if (bp || (regs->msr & MSR_RI) == 0) 372 fromipi = 0; 373 374 if (!fromipi) { 375 get_output_lock(); 376 excprint(regs); 377 if (bp) { 378 printf("cpu 0x%x stopped at breakpoint 0x%x (", 379 cpu, BP_NUM(bp)); 380 xmon_print_symbol(regs->nip, " ", ")\n"); 381 } 382 if ((regs->msr & MSR_RI) == 0) 383 printf("WARNING: exception is not recoverable, " 384 "can't continue\n"); 385 release_output_lock(); 386 } 387 388 waiting: 389 secondary = 1; 390 while (secondary && !xmon_gate) { 391 if (in_xmon == 0) { 392 if (fromipi) 393 goto leave; 394 secondary = test_and_set_bit(0, &in_xmon); 395 } 396 barrier(); 397 } 398 399 if (!secondary && !xmon_gate) { 400 /* we are the first cpu to come in */ 401 /* interrupt other cpu(s) */ 402 int ncpus = num_online_cpus(); 403 404 xmon_owner = cpu; 405 mb(); 406 if (ncpus > 1) { 407 smp_send_debugger_break(MSG_ALL_BUT_SELF); 408 /* wait for other cpus to come in */ 409 for (timeout = 100000000; timeout != 0; --timeout) { 410 if (cpus_weight(cpus_in_xmon) >= ncpus) 411 break; 412 barrier(); 413 } 414 } 415 remove_bpts(); 416 disable_surveillance(); 417 /* for breakpoint or single step, print the current instr. */ 418 if (bp || TRAP(regs) == 0xd00) 419 ppc_inst_dump(regs->nip, 1, 0); 420 printf("enter ? for help\n"); 421 mb(); 422 xmon_gate = 1; 423 barrier(); 424 } 425 426 cmdloop: 427 while (in_xmon) { 428 if (secondary) { 429 if (cpu == xmon_owner) { 430 if (!test_and_set_bit(0, &xmon_taken)) { 431 secondary = 0; 432 continue; 433 } 434 /* missed it */ 435 while (cpu == xmon_owner) 436 barrier(); 437 } 438 barrier(); 439 } else { 440 cmd = cmds(regs); 441 if (cmd != 0) { 442 /* exiting xmon */ 443 insert_bpts(); 444 xmon_gate = 0; 445 wmb(); 446 in_xmon = 0; 447 break; 448 } 449 /* have switched to some other cpu */ 450 secondary = 1; 451 } 452 } 453 leave: 454 cpu_clear(cpu, cpus_in_xmon); 455 xmon_fault_jmp[cpu] = NULL; 456 457 #else 458 /* UP is simple... */ 459 if (in_xmon) { 460 printf("Exception %lx %s in xmon, returning to main loop\n", 461 regs->trap, getvecname(TRAP(regs))); 462 longjmp(xmon_fault_jmp[0], 1); 463 } 464 if (setjmp(recurse_jmp) == 0) { 465 xmon_fault_jmp[0] = recurse_jmp; 466 in_xmon = 1; 467 468 excprint(regs); 469 bp = at_breakpoint(regs->nip); 470 if (bp) { 471 printf("Stopped at breakpoint %x (", BP_NUM(bp)); 472 xmon_print_symbol(regs->nip, " ", ")\n"); 473 } 474 if ((regs->msr & MSR_RI) == 0) 475 printf("WARNING: exception is not recoverable, " 476 "can't continue\n"); 477 remove_bpts(); 478 disable_surveillance(); 479 /* for breakpoint or single step, print the current instr. */ 480 if (bp || TRAP(regs) == 0xd00) 481 ppc_inst_dump(regs->nip, 1, 0); 482 printf("enter ? for help\n"); 483 } 484 485 cmd = cmds(regs); 486 487 insert_bpts(); 488 in_xmon = 0; 489 #endif 490 491 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) { 492 bp = at_breakpoint(regs->nip); 493 if (bp != NULL) { 494 int stepped = emulate_step(regs, bp->instr[0]); 495 if (stepped == 0) { 496 regs->nip = (unsigned long) &bp->instr[0]; 497 atomic_inc(&bp->ref_count); 498 } else if (stepped < 0) { 499 printf("Couldn't single-step %s instruction\n", 500 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd")); 501 } 502 } 503 } 504 505 insert_cpu_bpts(); 506 507 mtmsr(msr); /* restore interrupt enable */ 508 509 return cmd != 'X'; 510 } 511 512 int xmon(struct pt_regs *excp) 513 { 514 struct pt_regs regs; 515 516 if (excp == NULL) { 517 xmon_save_regs(®s); 518 excp = ®s; 519 } 520 return xmon_core(excp, 0); 521 } 522 EXPORT_SYMBOL(xmon); 523 524 irqreturn_t 525 xmon_irq(int irq, void *d, struct pt_regs *regs) 526 { 527 unsigned long flags; 528 local_irq_save(flags); 529 printf("Keyboard interrupt\n"); 530 xmon(regs); 531 local_irq_restore(flags); 532 return IRQ_HANDLED; 533 } 534 535 int xmon_bpt(struct pt_regs *regs) 536 { 537 struct bpt *bp; 538 unsigned long offset; 539 540 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF)) 541 return 0; 542 543 /* Are we at the trap at bp->instr[1] for some bp? */ 544 bp = in_breakpoint_table(regs->nip, &offset); 545 if (bp != NULL && offset == 4) { 546 regs->nip = bp->address + 4; 547 atomic_dec(&bp->ref_count); 548 return 1; 549 } 550 551 /* Are we at a breakpoint? */ 552 bp = at_breakpoint(regs->nip); 553 if (!bp) 554 return 0; 555 556 xmon_core(regs, 0); 557 558 return 1; 559 } 560 561 int xmon_sstep(struct pt_regs *regs) 562 { 563 if (user_mode(regs)) 564 return 0; 565 xmon_core(regs, 0); 566 return 1; 567 } 568 569 int xmon_dabr_match(struct pt_regs *regs) 570 { 571 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF)) 572 return 0; 573 if (dabr.enabled == 0) 574 return 0; 575 xmon_core(regs, 0); 576 return 1; 577 } 578 579 int xmon_iabr_match(struct pt_regs *regs) 580 { 581 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF)) 582 return 0; 583 if (iabr == 0) 584 return 0; 585 xmon_core(regs, 0); 586 return 1; 587 } 588 589 int xmon_ipi(struct pt_regs *regs) 590 { 591 #ifdef CONFIG_SMP 592 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon)) 593 xmon_core(regs, 1); 594 #endif 595 return 0; 596 } 597 598 int xmon_fault_handler(struct pt_regs *regs) 599 { 600 struct bpt *bp; 601 unsigned long offset; 602 603 if (in_xmon && catch_memory_errors) 604 handle_fault(regs); /* doesn't return */ 605 606 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) { 607 bp = in_breakpoint_table(regs->nip, &offset); 608 if (bp != NULL) { 609 regs->nip = bp->address + offset; 610 atomic_dec(&bp->ref_count); 611 } 612 } 613 614 return 0; 615 } 616 617 static struct bpt *at_breakpoint(unsigned long pc) 618 { 619 int i; 620 struct bpt *bp; 621 622 bp = bpts; 623 for (i = 0; i < NBPTS; ++i, ++bp) 624 if (bp->enabled && pc == bp->address) 625 return bp; 626 return NULL; 627 } 628 629 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp) 630 { 631 unsigned long off; 632 633 off = nip - (unsigned long) bpts; 634 if (off >= sizeof(bpts)) 635 return NULL; 636 off %= sizeof(struct bpt); 637 if (off != offsetof(struct bpt, instr[0]) 638 && off != offsetof(struct bpt, instr[1])) 639 return NULL; 640 *offp = off - offsetof(struct bpt, instr[0]); 641 return (struct bpt *) (nip - off); 642 } 643 644 static struct bpt *new_breakpoint(unsigned long a) 645 { 646 struct bpt *bp; 647 648 a &= ~3UL; 649 bp = at_breakpoint(a); 650 if (bp) 651 return bp; 652 653 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) { 654 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) { 655 bp->address = a; 656 bp->instr[1] = bpinstr; 657 store_inst(&bp->instr[1]); 658 return bp; 659 } 660 } 661 662 printf("Sorry, no free breakpoints. Please clear one first.\n"); 663 return NULL; 664 } 665 666 static void insert_bpts(void) 667 { 668 int i; 669 struct bpt *bp; 670 671 bp = bpts; 672 for (i = 0; i < NBPTS; ++i, ++bp) { 673 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0) 674 continue; 675 if (mread(bp->address, &bp->instr[0], 4) != 4) { 676 printf("Couldn't read instruction at %lx, " 677 "disabling breakpoint there\n", bp->address); 678 bp->enabled = 0; 679 continue; 680 } 681 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) { 682 printf("Breakpoint at %lx is on an mtmsrd or rfid " 683 "instruction, disabling it\n", bp->address); 684 bp->enabled = 0; 685 continue; 686 } 687 store_inst(&bp->instr[0]); 688 if (bp->enabled & BP_IABR) 689 continue; 690 if (mwrite(bp->address, &bpinstr, 4) != 4) { 691 printf("Couldn't write instruction at %lx, " 692 "disabling breakpoint there\n", bp->address); 693 bp->enabled &= ~BP_TRAP; 694 continue; 695 } 696 store_inst((void *)bp->address); 697 } 698 } 699 700 static void insert_cpu_bpts(void) 701 { 702 if (dabr.enabled) 703 set_dabr(dabr.address | (dabr.enabled & 7)); 704 if (iabr && cpu_has_feature(CPU_FTR_IABR)) 705 mtspr(SPRN_IABR, iabr->address 706 | (iabr->enabled & (BP_IABR|BP_IABR_TE))); 707 } 708 709 static void remove_bpts(void) 710 { 711 int i; 712 struct bpt *bp; 713 unsigned instr; 714 715 bp = bpts; 716 for (i = 0; i < NBPTS; ++i, ++bp) { 717 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP) 718 continue; 719 if (mread(bp->address, &instr, 4) == 4 720 && instr == bpinstr 721 && mwrite(bp->address, &bp->instr, 4) != 4) 722 printf("Couldn't remove breakpoint at %lx\n", 723 bp->address); 724 else 725 store_inst((void *)bp->address); 726 } 727 } 728 729 static void remove_cpu_bpts(void) 730 { 731 set_dabr(0); 732 if (cpu_has_feature(CPU_FTR_IABR)) 733 mtspr(SPRN_IABR, 0); 734 } 735 736 /* Command interpreting routine */ 737 static char *last_cmd; 738 739 static int 740 cmds(struct pt_regs *excp) 741 { 742 int cmd = 0; 743 744 last_cmd = NULL; 745 xmon_regs = excp; 746 for(;;) { 747 #ifdef CONFIG_SMP 748 printf("%x:", smp_processor_id()); 749 #endif /* CONFIG_SMP */ 750 printf("mon> "); 751 fflush(stdout); 752 flush_input(); 753 termch = 0; 754 cmd = skipbl(); 755 if( cmd == '\n' ) { 756 if (last_cmd == NULL) 757 continue; 758 take_input(last_cmd); 759 last_cmd = NULL; 760 cmd = inchar(); 761 } 762 switch (cmd) { 763 case 'm': 764 cmd = inchar(); 765 switch (cmd) { 766 case 'm': 767 case 's': 768 case 'd': 769 memops(cmd); 770 break; 771 case 'l': 772 memlocate(); 773 break; 774 case 'z': 775 memzcan(); 776 break; 777 case 'i': 778 show_mem(); 779 break; 780 default: 781 termch = cmd; 782 memex(); 783 } 784 break; 785 case 'd': 786 dump(); 787 break; 788 case 'l': 789 symbol_lookup(); 790 break; 791 case 'r': 792 prregs(excp); /* print regs */ 793 break; 794 case 'e': 795 excprint(excp); 796 break; 797 case 'S': 798 super_regs(); 799 break; 800 case 't': 801 backtrace(excp); 802 break; 803 case 'f': 804 cacheflush(); 805 break; 806 case 's': 807 if (do_step(excp)) 808 return cmd; 809 break; 810 case 'x': 811 case 'X': 812 case EOF: 813 return cmd; 814 case '?': 815 printf(help_string); 816 break; 817 case 'b': 818 bpt_cmds(); 819 break; 820 case 'C': 821 csum(); 822 break; 823 case 'c': 824 if (cpu_cmd()) 825 return 0; 826 break; 827 case 'z': 828 bootcmds(); 829 break; 830 case 'p': 831 proccall(); 832 break; 833 #ifdef CONFIG_PPC_STD_MMU 834 case 'u': 835 dump_segments(); 836 break; 837 #endif 838 default: 839 printf("Unrecognized command: "); 840 do { 841 if (' ' < cmd && cmd <= '~') 842 putchar(cmd); 843 else 844 printf("\\x%x", cmd); 845 cmd = inchar(); 846 } while (cmd != '\n'); 847 printf(" (type ? for help)\n"); 848 break; 849 } 850 } 851 } 852 853 /* 854 * Step a single instruction. 855 * Some instructions we emulate, others we execute with MSR_SE set. 856 */ 857 static int do_step(struct pt_regs *regs) 858 { 859 unsigned int instr; 860 int stepped; 861 862 /* check we are in 64-bit kernel mode, translation enabled */ 863 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) { 864 if (mread(regs->nip, &instr, 4) == 4) { 865 stepped = emulate_step(regs, instr); 866 if (stepped < 0) { 867 printf("Couldn't single-step %s instruction\n", 868 (IS_RFID(instr)? "rfid": "mtmsrd")); 869 return 0; 870 } 871 if (stepped > 0) { 872 regs->trap = 0xd00 | (regs->trap & 1); 873 printf("stepped to "); 874 xmon_print_symbol(regs->nip, " ", "\n"); 875 ppc_inst_dump(regs->nip, 1, 0); 876 return 0; 877 } 878 } 879 } 880 regs->msr |= MSR_SE; 881 return 1; 882 } 883 884 static void bootcmds(void) 885 { 886 int cmd; 887 888 cmd = inchar(); 889 if (cmd == 'r') 890 ppc_md.restart(NULL); 891 else if (cmd == 'h') 892 ppc_md.halt(); 893 else if (cmd == 'p') 894 ppc_md.power_off(); 895 } 896 897 static int cpu_cmd(void) 898 { 899 #ifdef CONFIG_SMP 900 unsigned long cpu; 901 int timeout; 902 int count; 903 904 if (!scanhex(&cpu)) { 905 /* print cpus waiting or in xmon */ 906 printf("cpus stopped:"); 907 count = 0; 908 for (cpu = 0; cpu < NR_CPUS; ++cpu) { 909 if (cpu_isset(cpu, cpus_in_xmon)) { 910 if (count == 0) 911 printf(" %x", cpu); 912 ++count; 913 } else { 914 if (count > 1) 915 printf("-%x", cpu - 1); 916 count = 0; 917 } 918 } 919 if (count > 1) 920 printf("-%x", NR_CPUS - 1); 921 printf("\n"); 922 return 0; 923 } 924 /* try to switch to cpu specified */ 925 if (!cpu_isset(cpu, cpus_in_xmon)) { 926 printf("cpu 0x%x isn't in xmon\n", cpu); 927 return 0; 928 } 929 xmon_taken = 0; 930 mb(); 931 xmon_owner = cpu; 932 timeout = 10000000; 933 while (!xmon_taken) { 934 if (--timeout == 0) { 935 if (test_and_set_bit(0, &xmon_taken)) 936 break; 937 /* take control back */ 938 mb(); 939 xmon_owner = smp_processor_id(); 940 printf("cpu %u didn't take control\n", cpu); 941 return 0; 942 } 943 barrier(); 944 } 945 return 1; 946 #else 947 return 0; 948 #endif /* CONFIG_SMP */ 949 } 950 951 static unsigned short fcstab[256] = { 952 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 953 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 954 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 955 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 956 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 957 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 958 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 959 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 960 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 961 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 962 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 963 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 964 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 965 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 966 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 967 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 968 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 969 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 970 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 971 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 972 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 973 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 974 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 975 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 976 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 977 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 978 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 979 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 980 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 981 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 982 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 983 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 984 }; 985 986 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) 987 988 static void 989 csum(void) 990 { 991 unsigned int i; 992 unsigned short fcs; 993 unsigned char v; 994 995 if (!scanhex(&adrs)) 996 return; 997 if (!scanhex(&ncsum)) 998 return; 999 fcs = 0xffff; 1000 for (i = 0; i < ncsum; ++i) { 1001 if (mread(adrs+i, &v, 1) == 0) { 1002 printf("csum stopped at %x\n", adrs+i); 1003 break; 1004 } 1005 fcs = FCS(fcs, v); 1006 } 1007 printf("%x\n", fcs); 1008 } 1009 1010 /* 1011 * Check if this is a suitable place to put a breakpoint. 1012 */ 1013 static long check_bp_loc(unsigned long addr) 1014 { 1015 unsigned int instr; 1016 1017 addr &= ~3; 1018 if (addr < KERNELBASE) { 1019 printf("Breakpoints may only be placed at kernel addresses\n"); 1020 return 0; 1021 } 1022 if (!mread(addr, &instr, sizeof(instr))) { 1023 printf("Can't read instruction at address %lx\n", addr); 1024 return 0; 1025 } 1026 if (IS_MTMSRD(instr) || IS_RFID(instr)) { 1027 printf("Breakpoints may not be placed on mtmsrd or rfid " 1028 "instructions\n"); 1029 return 0; 1030 } 1031 return 1; 1032 } 1033 1034 static char *breakpoint_help_string = 1035 "Breakpoint command usage:\n" 1036 "b show breakpoints\n" 1037 "b <addr> [cnt] set breakpoint at given instr addr\n" 1038 "bc clear all breakpoints\n" 1039 "bc <n/addr> clear breakpoint number n or at addr\n" 1040 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n" 1041 "bd <addr> [cnt] set hardware data breakpoint\n" 1042 ""; 1043 1044 static void 1045 bpt_cmds(void) 1046 { 1047 int cmd; 1048 unsigned long a; 1049 int mode, i; 1050 struct bpt *bp; 1051 const char badaddr[] = "Only kernel addresses are permitted " 1052 "for breakpoints\n"; 1053 1054 cmd = inchar(); 1055 switch (cmd) { 1056 #ifndef CONFIG_8xx 1057 case 'd': /* bd - hardware data breakpoint */ 1058 mode = 7; 1059 cmd = inchar(); 1060 if (cmd == 'r') 1061 mode = 5; 1062 else if (cmd == 'w') 1063 mode = 6; 1064 else 1065 termch = cmd; 1066 dabr.address = 0; 1067 dabr.enabled = 0; 1068 if (scanhex(&dabr.address)) { 1069 if (dabr.address < KERNELBASE) { 1070 printf(badaddr); 1071 break; 1072 } 1073 dabr.address &= ~7; 1074 dabr.enabled = mode | BP_DABR; 1075 } 1076 break; 1077 1078 case 'i': /* bi - hardware instr breakpoint */ 1079 if (!cpu_has_feature(CPU_FTR_IABR)) { 1080 printf("Hardware instruction breakpoint " 1081 "not supported on this cpu\n"); 1082 break; 1083 } 1084 if (iabr) { 1085 iabr->enabled &= ~(BP_IABR | BP_IABR_TE); 1086 iabr = NULL; 1087 } 1088 if (!scanhex(&a)) 1089 break; 1090 if (!check_bp_loc(a)) 1091 break; 1092 bp = new_breakpoint(a); 1093 if (bp != NULL) { 1094 bp->enabled |= BP_IABR | BP_IABR_TE; 1095 iabr = bp; 1096 } 1097 break; 1098 #endif 1099 1100 case 'c': 1101 if (!scanhex(&a)) { 1102 /* clear all breakpoints */ 1103 for (i = 0; i < NBPTS; ++i) 1104 bpts[i].enabled = 0; 1105 iabr = NULL; 1106 dabr.enabled = 0; 1107 printf("All breakpoints cleared\n"); 1108 break; 1109 } 1110 1111 if (a <= NBPTS && a >= 1) { 1112 /* assume a breakpoint number */ 1113 bp = &bpts[a-1]; /* bp nums are 1 based */ 1114 } else { 1115 /* assume a breakpoint address */ 1116 bp = at_breakpoint(a); 1117 if (bp == 0) { 1118 printf("No breakpoint at %x\n", a); 1119 break; 1120 } 1121 } 1122 1123 printf("Cleared breakpoint %x (", BP_NUM(bp)); 1124 xmon_print_symbol(bp->address, " ", ")\n"); 1125 bp->enabled = 0; 1126 break; 1127 1128 default: 1129 termch = cmd; 1130 cmd = skipbl(); 1131 if (cmd == '?') { 1132 printf(breakpoint_help_string); 1133 break; 1134 } 1135 termch = cmd; 1136 if (!scanhex(&a)) { 1137 /* print all breakpoints */ 1138 printf(" type address\n"); 1139 if (dabr.enabled) { 1140 printf(" data "REG" [", dabr.address); 1141 if (dabr.enabled & 1) 1142 printf("r"); 1143 if (dabr.enabled & 2) 1144 printf("w"); 1145 printf("]\n"); 1146 } 1147 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) { 1148 if (!bp->enabled) 1149 continue; 1150 printf("%2x %s ", BP_NUM(bp), 1151 (bp->enabled & BP_IABR)? "inst": "trap"); 1152 xmon_print_symbol(bp->address, " ", "\n"); 1153 } 1154 break; 1155 } 1156 1157 if (!check_bp_loc(a)) 1158 break; 1159 bp = new_breakpoint(a); 1160 if (bp != NULL) 1161 bp->enabled |= BP_TRAP; 1162 break; 1163 } 1164 } 1165 1166 /* Very cheap human name for vector lookup. */ 1167 static 1168 const char *getvecname(unsigned long vec) 1169 { 1170 char *ret; 1171 1172 switch (vec) { 1173 case 0x100: ret = "(System Reset)"; break; 1174 case 0x200: ret = "(Machine Check)"; break; 1175 case 0x300: ret = "(Data Access)"; break; 1176 case 0x380: ret = "(Data SLB Access)"; break; 1177 case 0x400: ret = "(Instruction Access)"; break; 1178 case 0x480: ret = "(Instruction SLB Access)"; break; 1179 case 0x500: ret = "(Hardware Interrupt)"; break; 1180 case 0x600: ret = "(Alignment)"; break; 1181 case 0x700: ret = "(Program Check)"; break; 1182 case 0x800: ret = "(FPU Unavailable)"; break; 1183 case 0x900: ret = "(Decrementer)"; break; 1184 case 0xc00: ret = "(System Call)"; break; 1185 case 0xd00: ret = "(Single Step)"; break; 1186 case 0xf00: ret = "(Performance Monitor)"; break; 1187 case 0xf20: ret = "(Altivec Unavailable)"; break; 1188 case 0x1300: ret = "(Instruction Breakpoint)"; break; 1189 default: ret = ""; 1190 } 1191 return ret; 1192 } 1193 1194 static void get_function_bounds(unsigned long pc, unsigned long *startp, 1195 unsigned long *endp) 1196 { 1197 unsigned long size, offset; 1198 const char *name; 1199 char *modname; 1200 1201 *startp = *endp = 0; 1202 if (pc == 0) 1203 return; 1204 if (setjmp(bus_error_jmp) == 0) { 1205 catch_memory_errors = 1; 1206 sync(); 1207 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr); 1208 if (name != NULL) { 1209 *startp = pc - offset; 1210 *endp = pc - offset + size; 1211 } 1212 sync(); 1213 } 1214 catch_memory_errors = 0; 1215 } 1216 1217 static int xmon_depth_to_print = 64; 1218 1219 #ifdef CONFIG_PPC64 1220 #define LRSAVE_OFFSET 0x10 1221 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */ 1222 #define MARKER_OFFSET 0x60 1223 #define REGS_OFFSET 0x70 1224 #else 1225 #define LRSAVE_OFFSET 4 1226 #define REG_FRAME_MARKER 0x72656773 1227 #define MARKER_OFFSET 8 1228 #define REGS_OFFSET 16 1229 #endif 1230 1231 static void xmon_show_stack(unsigned long sp, unsigned long lr, 1232 unsigned long pc) 1233 { 1234 unsigned long ip; 1235 unsigned long newsp; 1236 unsigned long marker; 1237 int count = 0; 1238 struct pt_regs regs; 1239 1240 do { 1241 if (sp < PAGE_OFFSET) { 1242 if (sp != 0) 1243 printf("SP (%lx) is in userspace\n", sp); 1244 break; 1245 } 1246 1247 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long)) 1248 || !mread(sp, &newsp, sizeof(unsigned long))) { 1249 printf("Couldn't read stack frame at %lx\n", sp); 1250 break; 1251 } 1252 1253 /* 1254 * For the first stack frame, try to work out if 1255 * LR and/or the saved LR value in the bottommost 1256 * stack frame are valid. 1257 */ 1258 if ((pc | lr) != 0) { 1259 unsigned long fnstart, fnend; 1260 unsigned long nextip; 1261 int printip = 1; 1262 1263 get_function_bounds(pc, &fnstart, &fnend); 1264 nextip = 0; 1265 if (newsp > sp) 1266 mread(newsp + LRSAVE_OFFSET, &nextip, 1267 sizeof(unsigned long)); 1268 if (lr == ip) { 1269 if (lr < PAGE_OFFSET 1270 || (fnstart <= lr && lr < fnend)) 1271 printip = 0; 1272 } else if (lr == nextip) { 1273 printip = 0; 1274 } else if (lr >= PAGE_OFFSET 1275 && !(fnstart <= lr && lr < fnend)) { 1276 printf("[link register ] "); 1277 xmon_print_symbol(lr, " ", "\n"); 1278 } 1279 if (printip) { 1280 printf("["REG"] ", sp); 1281 xmon_print_symbol(ip, " ", " (unreliable)\n"); 1282 } 1283 pc = lr = 0; 1284 1285 } else { 1286 printf("["REG"] ", sp); 1287 xmon_print_symbol(ip, " ", "\n"); 1288 } 1289 1290 /* Look for "regshere" marker to see if this is 1291 an exception frame. */ 1292 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long)) 1293 && marker == REG_FRAME_MARKER) { 1294 if (mread(sp + REGS_OFFSET, ®s, sizeof(regs)) 1295 != sizeof(regs)) { 1296 printf("Couldn't read registers at %lx\n", 1297 sp + REGS_OFFSET); 1298 break; 1299 } 1300 printf("--- Exception: %lx %s at ", regs.trap, 1301 getvecname(TRAP(®s))); 1302 pc = regs.nip; 1303 lr = regs.link; 1304 xmon_print_symbol(pc, " ", "\n"); 1305 } 1306 1307 if (newsp == 0) 1308 break; 1309 1310 sp = newsp; 1311 } while (count++ < xmon_depth_to_print); 1312 } 1313 1314 static void backtrace(struct pt_regs *excp) 1315 { 1316 unsigned long sp; 1317 1318 if (scanhex(&sp)) 1319 xmon_show_stack(sp, 0, 0); 1320 else 1321 xmon_show_stack(excp->gpr[1], excp->link, excp->nip); 1322 scannl(); 1323 } 1324 1325 static void print_bug_trap(struct pt_regs *regs) 1326 { 1327 struct bug_entry *bug; 1328 unsigned long addr; 1329 1330 if (regs->msr & MSR_PR) 1331 return; /* not in kernel */ 1332 addr = regs->nip; /* address of trap instruction */ 1333 if (addr < PAGE_OFFSET) 1334 return; 1335 bug = find_bug(regs->nip); 1336 if (bug == NULL) 1337 return; 1338 if (bug->line & BUG_WARNING_TRAP) 1339 return; 1340 1341 printf("kernel BUG in %s at %s:%d!\n", 1342 bug->function, bug->file, (unsigned int)bug->line); 1343 } 1344 1345 void excprint(struct pt_regs *fp) 1346 { 1347 unsigned long trap; 1348 1349 #ifdef CONFIG_SMP 1350 printf("cpu 0x%x: ", smp_processor_id()); 1351 #endif /* CONFIG_SMP */ 1352 1353 trap = TRAP(fp); 1354 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp); 1355 printf(" pc: "); 1356 xmon_print_symbol(fp->nip, ": ", "\n"); 1357 1358 printf(" lr: ", fp->link); 1359 xmon_print_symbol(fp->link, ": ", "\n"); 1360 1361 printf(" sp: %lx\n", fp->gpr[1]); 1362 printf(" msr: %lx\n", fp->msr); 1363 1364 if (trap == 0x300 || trap == 0x380 || trap == 0x600) { 1365 printf(" dar: %lx\n", fp->dar); 1366 if (trap != 0x380) 1367 printf(" dsisr: %lx\n", fp->dsisr); 1368 } 1369 1370 printf(" current = 0x%lx\n", current); 1371 #ifdef CONFIG_PPC64 1372 printf(" paca = 0x%lx\n", get_paca()); 1373 #endif 1374 if (current) { 1375 printf(" pid = %ld, comm = %s\n", 1376 current->pid, current->comm); 1377 } 1378 1379 if (trap == 0x700) 1380 print_bug_trap(fp); 1381 } 1382 1383 void prregs(struct pt_regs *fp) 1384 { 1385 int n, trap; 1386 unsigned long base; 1387 struct pt_regs regs; 1388 1389 if (scanhex(&base)) { 1390 if (setjmp(bus_error_jmp) == 0) { 1391 catch_memory_errors = 1; 1392 sync(); 1393 regs = *(struct pt_regs *)base; 1394 sync(); 1395 __delay(200); 1396 } else { 1397 catch_memory_errors = 0; 1398 printf("*** Error reading registers from "REG"\n", 1399 base); 1400 return; 1401 } 1402 catch_memory_errors = 0; 1403 fp = ®s; 1404 } 1405 1406 #ifdef CONFIG_PPC64 1407 if (FULL_REGS(fp)) { 1408 for (n = 0; n < 16; ++n) 1409 printf("R%.2ld = "REG" R%.2ld = "REG"\n", 1410 n, fp->gpr[n], n+16, fp->gpr[n+16]); 1411 } else { 1412 for (n = 0; n < 7; ++n) 1413 printf("R%.2ld = "REG" R%.2ld = "REG"\n", 1414 n, fp->gpr[n], n+7, fp->gpr[n+7]); 1415 } 1416 #else 1417 for (n = 0; n < 32; ++n) { 1418 printf("R%.2d = %.8x%s", n, fp->gpr[n], 1419 (n & 3) == 3? "\n": " "); 1420 if (n == 12 && !FULL_REGS(fp)) { 1421 printf("\n"); 1422 break; 1423 } 1424 } 1425 #endif 1426 printf("pc = "); 1427 xmon_print_symbol(fp->nip, " ", "\n"); 1428 printf("lr = "); 1429 xmon_print_symbol(fp->link, " ", "\n"); 1430 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr); 1431 printf("ctr = "REG" xer = "REG" trap = %4lx\n", 1432 fp->ctr, fp->xer, fp->trap); 1433 trap = TRAP(fp); 1434 if (trap == 0x300 || trap == 0x380 || trap == 0x600) 1435 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr); 1436 } 1437 1438 void cacheflush(void) 1439 { 1440 int cmd; 1441 unsigned long nflush; 1442 1443 cmd = inchar(); 1444 if (cmd != 'i') 1445 termch = cmd; 1446 scanhex((void *)&adrs); 1447 if (termch != '\n') 1448 termch = 0; 1449 nflush = 1; 1450 scanhex(&nflush); 1451 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES; 1452 if (setjmp(bus_error_jmp) == 0) { 1453 catch_memory_errors = 1; 1454 sync(); 1455 1456 if (cmd != 'i') { 1457 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES) 1458 cflush((void *) adrs); 1459 } else { 1460 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES) 1461 cinval((void *) adrs); 1462 } 1463 sync(); 1464 /* wait a little while to see if we get a machine check */ 1465 __delay(200); 1466 } 1467 catch_memory_errors = 0; 1468 } 1469 1470 unsigned long 1471 read_spr(int n) 1472 { 1473 unsigned int instrs[2]; 1474 unsigned long (*code)(void); 1475 unsigned long opd[3]; 1476 unsigned long ret = -1UL; 1477 1478 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); 1479 instrs[1] = 0x4e800020; 1480 opd[0] = (unsigned long)instrs; 1481 opd[1] = 0; 1482 opd[2] = 0; 1483 store_inst(instrs); 1484 store_inst(instrs+1); 1485 code = (unsigned long (*)(void)) opd; 1486 1487 if (setjmp(bus_error_jmp) == 0) { 1488 catch_memory_errors = 1; 1489 sync(); 1490 1491 ret = code(); 1492 1493 sync(); 1494 /* wait a little while to see if we get a machine check */ 1495 __delay(200); 1496 n = size; 1497 } 1498 1499 return ret; 1500 } 1501 1502 void 1503 write_spr(int n, unsigned long val) 1504 { 1505 unsigned int instrs[2]; 1506 unsigned long (*code)(unsigned long); 1507 unsigned long opd[3]; 1508 1509 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); 1510 instrs[1] = 0x4e800020; 1511 opd[0] = (unsigned long)instrs; 1512 opd[1] = 0; 1513 opd[2] = 0; 1514 store_inst(instrs); 1515 store_inst(instrs+1); 1516 code = (unsigned long (*)(unsigned long)) opd; 1517 1518 if (setjmp(bus_error_jmp) == 0) { 1519 catch_memory_errors = 1; 1520 sync(); 1521 1522 code(val); 1523 1524 sync(); 1525 /* wait a little while to see if we get a machine check */ 1526 __delay(200); 1527 n = size; 1528 } 1529 } 1530 1531 static unsigned long regno; 1532 extern char exc_prolog; 1533 extern char dec_exc; 1534 1535 void super_regs(void) 1536 { 1537 int cmd; 1538 unsigned long val; 1539 #ifdef CONFIG_PPC_ISERIES 1540 struct paca_struct *ptrPaca = NULL; 1541 struct lppaca *ptrLpPaca = NULL; 1542 struct ItLpRegSave *ptrLpRegSave = NULL; 1543 #endif 1544 1545 cmd = skipbl(); 1546 if (cmd == '\n') { 1547 unsigned long sp, toc; 1548 asm("mr %0,1" : "=r" (sp) :); 1549 asm("mr %0,2" : "=r" (toc) :); 1550 1551 printf("msr = "REG" sprg0= "REG"\n", 1552 mfmsr(), mfspr(SPRN_SPRG0)); 1553 printf("pvr = "REG" sprg1= "REG"\n", 1554 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); 1555 printf("dec = "REG" sprg2= "REG"\n", 1556 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2)); 1557 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); 1558 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR)); 1559 #ifdef CONFIG_PPC_ISERIES 1560 // Dump out relevant Paca data areas. 1561 printf("Paca: \n"); 1562 ptrPaca = get_paca(); 1563 1564 printf(" Local Processor Control Area (LpPaca): \n"); 1565 ptrLpPaca = ptrPaca->lppaca_ptr; 1566 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n", 1567 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1); 1568 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n", 1569 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4); 1570 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5); 1571 1572 printf(" Local Processor Register Save Area (LpRegSave): \n"); 1573 ptrLpRegSave = ptrPaca->reg_save_ptr; 1574 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n", 1575 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0); 1576 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n", 1577 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3); 1578 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n", 1579 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA); 1580 #endif 1581 1582 return; 1583 } 1584 1585 scanhex(®no); 1586 switch (cmd) { 1587 case 'w': 1588 val = read_spr(regno); 1589 scanhex(&val); 1590 write_spr(regno, val); 1591 /* fall through */ 1592 case 'r': 1593 printf("spr %lx = %lx\n", regno, read_spr(regno)); 1594 break; 1595 } 1596 scannl(); 1597 } 1598 1599 /* 1600 * Stuff for reading and writing memory safely 1601 */ 1602 int 1603 mread(unsigned long adrs, void *buf, int size) 1604 { 1605 volatile int n; 1606 char *p, *q; 1607 1608 n = 0; 1609 if (setjmp(bus_error_jmp) == 0) { 1610 catch_memory_errors = 1; 1611 sync(); 1612 p = (char *)adrs; 1613 q = (char *)buf; 1614 switch (size) { 1615 case 2: 1616 *(u16 *)q = *(u16 *)p; 1617 break; 1618 case 4: 1619 *(u32 *)q = *(u32 *)p; 1620 break; 1621 case 8: 1622 *(u64 *)q = *(u64 *)p; 1623 break; 1624 default: 1625 for( ; n < size; ++n) { 1626 *q++ = *p++; 1627 sync(); 1628 } 1629 } 1630 sync(); 1631 /* wait a little while to see if we get a machine check */ 1632 __delay(200); 1633 n = size; 1634 } 1635 catch_memory_errors = 0; 1636 return n; 1637 } 1638 1639 int 1640 mwrite(unsigned long adrs, void *buf, int size) 1641 { 1642 volatile int n; 1643 char *p, *q; 1644 1645 n = 0; 1646 if (setjmp(bus_error_jmp) == 0) { 1647 catch_memory_errors = 1; 1648 sync(); 1649 p = (char *) adrs; 1650 q = (char *) buf; 1651 switch (size) { 1652 case 2: 1653 *(u16 *)p = *(u16 *)q; 1654 break; 1655 case 4: 1656 *(u32 *)p = *(u32 *)q; 1657 break; 1658 case 8: 1659 *(u64 *)p = *(u64 *)q; 1660 break; 1661 default: 1662 for ( ; n < size; ++n) { 1663 *p++ = *q++; 1664 sync(); 1665 } 1666 } 1667 sync(); 1668 /* wait a little while to see if we get a machine check */ 1669 __delay(200); 1670 n = size; 1671 } else { 1672 printf("*** Error writing address %x\n", adrs + n); 1673 } 1674 catch_memory_errors = 0; 1675 return n; 1676 } 1677 1678 static int fault_type; 1679 static int fault_except; 1680 static char *fault_chars[] = { "--", "**", "##" }; 1681 1682 static int handle_fault(struct pt_regs *regs) 1683 { 1684 fault_except = TRAP(regs); 1685 switch (TRAP(regs)) { 1686 case 0x200: 1687 fault_type = 0; 1688 break; 1689 case 0x300: 1690 case 0x380: 1691 fault_type = 1; 1692 break; 1693 default: 1694 fault_type = 2; 1695 } 1696 1697 longjmp(bus_error_jmp, 1); 1698 1699 return 0; 1700 } 1701 1702 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t)) 1703 1704 void 1705 byterev(unsigned char *val, int size) 1706 { 1707 int t; 1708 1709 switch (size) { 1710 case 2: 1711 SWAP(val[0], val[1], t); 1712 break; 1713 case 4: 1714 SWAP(val[0], val[3], t); 1715 SWAP(val[1], val[2], t); 1716 break; 1717 case 8: /* is there really any use for this? */ 1718 SWAP(val[0], val[7], t); 1719 SWAP(val[1], val[6], t); 1720 SWAP(val[2], val[5], t); 1721 SWAP(val[3], val[4], t); 1722 break; 1723 } 1724 } 1725 1726 static int brev; 1727 static int mnoread; 1728 1729 static char *memex_help_string = 1730 "Memory examine command usage:\n" 1731 "m [addr] [flags] examine/change memory\n" 1732 " addr is optional. will start where left off.\n" 1733 " flags may include chars from this set:\n" 1734 " b modify by bytes (default)\n" 1735 " w modify by words (2 byte)\n" 1736 " l modify by longs (4 byte)\n" 1737 " d modify by doubleword (8 byte)\n" 1738 " r toggle reverse byte order mode\n" 1739 " n do not read memory (for i/o spaces)\n" 1740 " . ok to read (default)\n" 1741 "NOTE: flags are saved as defaults\n" 1742 ""; 1743 1744 static char *memex_subcmd_help_string = 1745 "Memory examine subcommands:\n" 1746 " hexval write this val to current location\n" 1747 " 'string' write chars from string to this location\n" 1748 " ' increment address\n" 1749 " ^ decrement address\n" 1750 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n" 1751 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n" 1752 " ` clear no-read flag\n" 1753 " ; stay at this addr\n" 1754 " v change to byte mode\n" 1755 " w change to word (2 byte) mode\n" 1756 " l change to long (4 byte) mode\n" 1757 " u change to doubleword (8 byte) mode\n" 1758 " m addr change current addr\n" 1759 " n toggle no-read flag\n" 1760 " r toggle byte reverse flag\n" 1761 " < count back up count bytes\n" 1762 " > count skip forward count bytes\n" 1763 " x exit this mode\n" 1764 ""; 1765 1766 void 1767 memex(void) 1768 { 1769 int cmd, inc, i, nslash; 1770 unsigned long n; 1771 unsigned char val[16]; 1772 1773 scanhex((void *)&adrs); 1774 cmd = skipbl(); 1775 if (cmd == '?') { 1776 printf(memex_help_string); 1777 return; 1778 } else { 1779 termch = cmd; 1780 } 1781 last_cmd = "m\n"; 1782 while ((cmd = skipbl()) != '\n') { 1783 switch( cmd ){ 1784 case 'b': size = 1; break; 1785 case 'w': size = 2; break; 1786 case 'l': size = 4; break; 1787 case 'd': size = 8; break; 1788 case 'r': brev = !brev; break; 1789 case 'n': mnoread = 1; break; 1790 case '.': mnoread = 0; break; 1791 } 1792 } 1793 if( size <= 0 ) 1794 size = 1; 1795 else if( size > 8 ) 1796 size = 8; 1797 for(;;){ 1798 if (!mnoread) 1799 n = mread(adrs, val, size); 1800 printf("%.16x%c", adrs, brev? 'r': ' '); 1801 if (!mnoread) { 1802 if (brev) 1803 byterev(val, size); 1804 putchar(' '); 1805 for (i = 0; i < n; ++i) 1806 printf("%.2x", val[i]); 1807 for (; i < size; ++i) 1808 printf("%s", fault_chars[fault_type]); 1809 } 1810 putchar(' '); 1811 inc = size; 1812 nslash = 0; 1813 for(;;){ 1814 if( scanhex(&n) ){ 1815 for (i = 0; i < size; ++i) 1816 val[i] = n >> (i * 8); 1817 if (!brev) 1818 byterev(val, size); 1819 mwrite(adrs, val, size); 1820 inc = size; 1821 } 1822 cmd = skipbl(); 1823 if (cmd == '\n') 1824 break; 1825 inc = 0; 1826 switch (cmd) { 1827 case '\'': 1828 for(;;){ 1829 n = inchar(); 1830 if( n == '\\' ) 1831 n = bsesc(); 1832 else if( n == '\'' ) 1833 break; 1834 for (i = 0; i < size; ++i) 1835 val[i] = n >> (i * 8); 1836 if (!brev) 1837 byterev(val, size); 1838 mwrite(adrs, val, size); 1839 adrs += size; 1840 } 1841 adrs -= size; 1842 inc = size; 1843 break; 1844 case ',': 1845 adrs += size; 1846 break; 1847 case '.': 1848 mnoread = 0; 1849 break; 1850 case ';': 1851 break; 1852 case 'x': 1853 case EOF: 1854 scannl(); 1855 return; 1856 case 'b': 1857 case 'v': 1858 size = 1; 1859 break; 1860 case 'w': 1861 size = 2; 1862 break; 1863 case 'l': 1864 size = 4; 1865 break; 1866 case 'u': 1867 size = 8; 1868 break; 1869 case '^': 1870 adrs -= size; 1871 break; 1872 break; 1873 case '/': 1874 if (nslash > 0) 1875 adrs -= 1 << nslash; 1876 else 1877 nslash = 0; 1878 nslash += 4; 1879 adrs += 1 << nslash; 1880 break; 1881 case '\\': 1882 if (nslash < 0) 1883 adrs += 1 << -nslash; 1884 else 1885 nslash = 0; 1886 nslash -= 4; 1887 adrs -= 1 << -nslash; 1888 break; 1889 case 'm': 1890 scanhex((void *)&adrs); 1891 break; 1892 case 'n': 1893 mnoread = 1; 1894 break; 1895 case 'r': 1896 brev = !brev; 1897 break; 1898 case '<': 1899 n = size; 1900 scanhex(&n); 1901 adrs -= n; 1902 break; 1903 case '>': 1904 n = size; 1905 scanhex(&n); 1906 adrs += n; 1907 break; 1908 case '?': 1909 printf(memex_subcmd_help_string); 1910 break; 1911 } 1912 } 1913 adrs += inc; 1914 } 1915 } 1916 1917 int 1918 bsesc(void) 1919 { 1920 int c; 1921 1922 c = inchar(); 1923 switch( c ){ 1924 case 'n': c = '\n'; break; 1925 case 'r': c = '\r'; break; 1926 case 'b': c = '\b'; break; 1927 case 't': c = '\t'; break; 1928 } 1929 return c; 1930 } 1931 1932 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \ 1933 || ('a' <= (c) && (c) <= 'f') \ 1934 || ('A' <= (c) && (c) <= 'F')) 1935 void 1936 dump(void) 1937 { 1938 int c; 1939 1940 c = inchar(); 1941 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') 1942 termch = c; 1943 scanhex((void *)&adrs); 1944 if (termch != '\n') 1945 termch = 0; 1946 if (c == 'i') { 1947 scanhex(&nidump); 1948 if (nidump == 0) 1949 nidump = 16; 1950 else if (nidump > MAX_DUMP) 1951 nidump = MAX_DUMP; 1952 adrs += ppc_inst_dump(adrs, nidump, 1); 1953 last_cmd = "di\n"; 1954 } else { 1955 scanhex(&ndump); 1956 if (ndump == 0) 1957 ndump = 64; 1958 else if (ndump > MAX_DUMP) 1959 ndump = MAX_DUMP; 1960 prdump(adrs, ndump); 1961 adrs += ndump; 1962 last_cmd = "d\n"; 1963 } 1964 } 1965 1966 void 1967 prdump(unsigned long adrs, long ndump) 1968 { 1969 long n, m, c, r, nr; 1970 unsigned char temp[16]; 1971 1972 for (n = ndump; n > 0;) { 1973 printf(REG, adrs); 1974 putchar(' '); 1975 r = n < 16? n: 16; 1976 nr = mread(adrs, temp, r); 1977 adrs += nr; 1978 for (m = 0; m < r; ++m) { 1979 if ((m & 7) == 0 && m > 0) 1980 putchar(' '); 1981 if (m < nr) 1982 printf("%.2x", temp[m]); 1983 else 1984 printf("%s", fault_chars[fault_type]); 1985 } 1986 if (m <= 8) 1987 printf(" "); 1988 for (; m < 16; ++m) 1989 printf(" "); 1990 printf(" |"); 1991 for (m = 0; m < r; ++m) { 1992 if (m < nr) { 1993 c = temp[m]; 1994 putchar(' ' <= c && c <= '~'? c: '.'); 1995 } else 1996 putchar(' '); 1997 } 1998 n -= r; 1999 for (; m < 16; ++m) 2000 putchar(' '); 2001 printf("|\n"); 2002 if (nr < r) 2003 break; 2004 } 2005 } 2006 2007 int 2008 ppc_inst_dump(unsigned long adr, long count, int praddr) 2009 { 2010 int nr, dotted; 2011 unsigned long first_adr; 2012 unsigned long inst, last_inst = 0; 2013 unsigned char val[4]; 2014 2015 dotted = 0; 2016 for (first_adr = adr; count > 0; --count, adr += 4) { 2017 nr = mread(adr, val, 4); 2018 if (nr == 0) { 2019 if (praddr) { 2020 const char *x = fault_chars[fault_type]; 2021 printf(REG" %s%s%s%s\n", adr, x, x, x, x); 2022 } 2023 break; 2024 } 2025 inst = GETWORD(val); 2026 if (adr > first_adr && inst == last_inst) { 2027 if (!dotted) { 2028 printf(" ...\n"); 2029 dotted = 1; 2030 } 2031 continue; 2032 } 2033 dotted = 0; 2034 last_inst = inst; 2035 if (praddr) 2036 printf(REG" %.8x", adr, inst); 2037 printf("\t"); 2038 print_insn_powerpc(inst, adr, 0); /* always returns 4 */ 2039 printf("\n"); 2040 } 2041 return adr - first_adr; 2042 } 2043 2044 void 2045 print_address(unsigned long addr) 2046 { 2047 xmon_print_symbol(addr, "\t# ", ""); 2048 } 2049 2050 2051 /* 2052 * Memory operations - move, set, print differences 2053 */ 2054 static unsigned long mdest; /* destination address */ 2055 static unsigned long msrc; /* source address */ 2056 static unsigned long mval; /* byte value to set memory to */ 2057 static unsigned long mcount; /* # bytes to affect */ 2058 static unsigned long mdiffs; /* max # differences to print */ 2059 2060 void 2061 memops(int cmd) 2062 { 2063 scanhex((void *)&mdest); 2064 if( termch != '\n' ) 2065 termch = 0; 2066 scanhex((void *)(cmd == 's'? &mval: &msrc)); 2067 if( termch != '\n' ) 2068 termch = 0; 2069 scanhex((void *)&mcount); 2070 switch( cmd ){ 2071 case 'm': 2072 memmove((void *)mdest, (void *)msrc, mcount); 2073 break; 2074 case 's': 2075 memset((void *)mdest, mval, mcount); 2076 break; 2077 case 'd': 2078 if( termch != '\n' ) 2079 termch = 0; 2080 scanhex((void *)&mdiffs); 2081 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs); 2082 break; 2083 } 2084 } 2085 2086 void 2087 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr) 2088 { 2089 unsigned n, prt; 2090 2091 prt = 0; 2092 for( n = nb; n > 0; --n ) 2093 if( *p1++ != *p2++ ) 2094 if( ++prt <= maxpr ) 2095 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1, 2096 p1[-1], p2 - 1, p2[-1]); 2097 if( prt > maxpr ) 2098 printf("Total of %d differences\n", prt); 2099 } 2100 2101 static unsigned mend; 2102 static unsigned mask; 2103 2104 void 2105 memlocate(void) 2106 { 2107 unsigned a, n; 2108 unsigned char val[4]; 2109 2110 last_cmd = "ml"; 2111 scanhex((void *)&mdest); 2112 if (termch != '\n') { 2113 termch = 0; 2114 scanhex((void *)&mend); 2115 if (termch != '\n') { 2116 termch = 0; 2117 scanhex((void *)&mval); 2118 mask = ~0; 2119 if (termch != '\n') termch = 0; 2120 scanhex((void *)&mask); 2121 } 2122 } 2123 n = 0; 2124 for (a = mdest; a < mend; a += 4) { 2125 if (mread(a, val, 4) == 4 2126 && ((GETWORD(val) ^ mval) & mask) == 0) { 2127 printf("%.16x: %.16x\n", a, GETWORD(val)); 2128 if (++n >= 10) 2129 break; 2130 } 2131 } 2132 } 2133 2134 static unsigned long mskip = 0x1000; 2135 static unsigned long mlim = 0xffffffff; 2136 2137 void 2138 memzcan(void) 2139 { 2140 unsigned char v; 2141 unsigned a; 2142 int ok, ook; 2143 2144 scanhex(&mdest); 2145 if (termch != '\n') termch = 0; 2146 scanhex(&mskip); 2147 if (termch != '\n') termch = 0; 2148 scanhex(&mlim); 2149 ook = 0; 2150 for (a = mdest; a < mlim; a += mskip) { 2151 ok = mread(a, &v, 1); 2152 if (ok && !ook) { 2153 printf("%.8x .. ", a); 2154 fflush(stdout); 2155 } else if (!ok && ook) 2156 printf("%.8x\n", a - mskip); 2157 ook = ok; 2158 if (a + mskip < a) 2159 break; 2160 } 2161 if (ook) 2162 printf("%.8x\n", a - mskip); 2163 } 2164 2165 void proccall(void) 2166 { 2167 unsigned long args[8]; 2168 unsigned long ret; 2169 int i; 2170 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long, 2171 unsigned long, unsigned long, unsigned long, 2172 unsigned long, unsigned long, unsigned long); 2173 callfunc_t func; 2174 2175 if (!scanhex(&adrs)) 2176 return; 2177 if (termch != '\n') 2178 termch = 0; 2179 for (i = 0; i < 8; ++i) 2180 args[i] = 0; 2181 for (i = 0; i < 8; ++i) { 2182 if (!scanhex(&args[i]) || termch == '\n') 2183 break; 2184 termch = 0; 2185 } 2186 func = (callfunc_t) adrs; 2187 ret = 0; 2188 if (setjmp(bus_error_jmp) == 0) { 2189 catch_memory_errors = 1; 2190 sync(); 2191 ret = func(args[0], args[1], args[2], args[3], 2192 args[4], args[5], args[6], args[7]); 2193 sync(); 2194 printf("return value is %x\n", ret); 2195 } else { 2196 printf("*** %x exception occurred\n", fault_except); 2197 } 2198 catch_memory_errors = 0; 2199 } 2200 2201 /* Input scanning routines */ 2202 int 2203 skipbl(void) 2204 { 2205 int c; 2206 2207 if( termch != 0 ){ 2208 c = termch; 2209 termch = 0; 2210 } else 2211 c = inchar(); 2212 while( c == ' ' || c == '\t' ) 2213 c = inchar(); 2214 return c; 2215 } 2216 2217 #define N_PTREGS 44 2218 static char *regnames[N_PTREGS] = { 2219 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 2220 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 2221 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 2222 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 2223 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", 2224 #ifdef CONFIG_PPC64 2225 "softe", 2226 #else 2227 "mq", 2228 #endif 2229 "trap", "dar", "dsisr", "res" 2230 }; 2231 2232 int 2233 scanhex(unsigned long *vp) 2234 { 2235 int c, d; 2236 unsigned long v; 2237 2238 c = skipbl(); 2239 if (c == '%') { 2240 /* parse register name */ 2241 char regname[8]; 2242 int i; 2243 2244 for (i = 0; i < sizeof(regname) - 1; ++i) { 2245 c = inchar(); 2246 if (!isalnum(c)) { 2247 termch = c; 2248 break; 2249 } 2250 regname[i] = c; 2251 } 2252 regname[i] = 0; 2253 for (i = 0; i < N_PTREGS; ++i) { 2254 if (strcmp(regnames[i], regname) == 0) { 2255 if (xmon_regs == NULL) { 2256 printf("regs not available\n"); 2257 return 0; 2258 } 2259 *vp = ((unsigned long *)xmon_regs)[i]; 2260 return 1; 2261 } 2262 } 2263 printf("invalid register name '%%%s'\n", regname); 2264 return 0; 2265 } 2266 2267 /* skip leading "0x" if any */ 2268 2269 if (c == '0') { 2270 c = inchar(); 2271 if (c == 'x') { 2272 c = inchar(); 2273 } else { 2274 d = hexdigit(c); 2275 if (d == EOF) { 2276 termch = c; 2277 *vp = 0; 2278 return 1; 2279 } 2280 } 2281 } else if (c == '$') { 2282 int i; 2283 for (i=0; i<63; i++) { 2284 c = inchar(); 2285 if (isspace(c)) { 2286 termch = c; 2287 break; 2288 } 2289 tmpstr[i] = c; 2290 } 2291 tmpstr[i++] = 0; 2292 *vp = 0; 2293 if (setjmp(bus_error_jmp) == 0) { 2294 catch_memory_errors = 1; 2295 sync(); 2296 *vp = kallsyms_lookup_name(tmpstr); 2297 sync(); 2298 } 2299 catch_memory_errors = 0; 2300 if (!(*vp)) { 2301 printf("unknown symbol '%s'\n", tmpstr); 2302 return 0; 2303 } 2304 return 1; 2305 } 2306 2307 d = hexdigit(c); 2308 if (d == EOF) { 2309 termch = c; 2310 return 0; 2311 } 2312 v = 0; 2313 do { 2314 v = (v << 4) + d; 2315 c = inchar(); 2316 d = hexdigit(c); 2317 } while (d != EOF); 2318 termch = c; 2319 *vp = v; 2320 return 1; 2321 } 2322 2323 void 2324 scannl(void) 2325 { 2326 int c; 2327 2328 c = termch; 2329 termch = 0; 2330 while( c != '\n' ) 2331 c = inchar(); 2332 } 2333 2334 int hexdigit(int c) 2335 { 2336 if( '0' <= c && c <= '9' ) 2337 return c - '0'; 2338 if( 'A' <= c && c <= 'F' ) 2339 return c - ('A' - 10); 2340 if( 'a' <= c && c <= 'f' ) 2341 return c - ('a' - 10); 2342 return EOF; 2343 } 2344 2345 void 2346 getstring(char *s, int size) 2347 { 2348 int c; 2349 2350 c = skipbl(); 2351 do { 2352 if( size > 1 ){ 2353 *s++ = c; 2354 --size; 2355 } 2356 c = inchar(); 2357 } while( c != ' ' && c != '\t' && c != '\n' ); 2358 termch = c; 2359 *s = 0; 2360 } 2361 2362 static char line[256]; 2363 static char *lineptr; 2364 2365 void 2366 flush_input(void) 2367 { 2368 lineptr = NULL; 2369 } 2370 2371 int 2372 inchar(void) 2373 { 2374 if (lineptr == NULL || *lineptr == 0) { 2375 if (fgets(line, sizeof(line), stdin) == NULL) { 2376 lineptr = NULL; 2377 return EOF; 2378 } 2379 lineptr = line; 2380 } 2381 return *lineptr++; 2382 } 2383 2384 void 2385 take_input(char *str) 2386 { 2387 lineptr = str; 2388 } 2389 2390 2391 static void 2392 symbol_lookup(void) 2393 { 2394 int type = inchar(); 2395 unsigned long addr; 2396 static char tmp[64]; 2397 2398 switch (type) { 2399 case 'a': 2400 if (scanhex(&addr)) 2401 xmon_print_symbol(addr, ": ", "\n"); 2402 termch = 0; 2403 break; 2404 case 's': 2405 getstring(tmp, 64); 2406 if (setjmp(bus_error_jmp) == 0) { 2407 catch_memory_errors = 1; 2408 sync(); 2409 addr = kallsyms_lookup_name(tmp); 2410 if (addr) 2411 printf("%s: %lx\n", tmp, addr); 2412 else 2413 printf("Symbol '%s' not found.\n", tmp); 2414 sync(); 2415 } 2416 catch_memory_errors = 0; 2417 termch = 0; 2418 break; 2419 } 2420 } 2421 2422 2423 /* Print an address in numeric and symbolic form (if possible) */ 2424 static void xmon_print_symbol(unsigned long address, const char *mid, 2425 const char *after) 2426 { 2427 char *modname; 2428 const char *name = NULL; 2429 unsigned long offset, size; 2430 2431 printf(REG, address); 2432 if (setjmp(bus_error_jmp) == 0) { 2433 catch_memory_errors = 1; 2434 sync(); 2435 name = kallsyms_lookup(address, &size, &offset, &modname, 2436 tmpstr); 2437 sync(); 2438 /* wait a little while to see if we get a machine check */ 2439 __delay(200); 2440 } 2441 2442 catch_memory_errors = 0; 2443 2444 if (name) { 2445 printf("%s%s+%#lx/%#lx", mid, name, offset, size); 2446 if (modname) 2447 printf(" [%s]", modname); 2448 } 2449 printf("%s", after); 2450 } 2451 2452 #ifdef CONFIG_PPC64 2453 static void dump_slb(void) 2454 { 2455 int i; 2456 unsigned long tmp; 2457 2458 printf("SLB contents of cpu %x\n", smp_processor_id()); 2459 2460 for (i = 0; i < SLB_NUM_ENTRIES; i++) { 2461 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i)); 2462 printf("%02d %016lx ", i, tmp); 2463 2464 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i)); 2465 printf("%016lx\n", tmp); 2466 } 2467 } 2468 2469 static void dump_stab(void) 2470 { 2471 int i; 2472 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr; 2473 2474 printf("Segment table contents of cpu %x\n", smp_processor_id()); 2475 2476 for (i = 0; i < PAGE_SIZE/16; i++) { 2477 unsigned long a, b; 2478 2479 a = *tmp++; 2480 b = *tmp++; 2481 2482 if (a || b) { 2483 printf("%03d %016lx ", i, a); 2484 printf("%016lx\n", b); 2485 } 2486 } 2487 } 2488 2489 void dump_segments(void) 2490 { 2491 if (cpu_has_feature(CPU_FTR_SLB)) 2492 dump_slb(); 2493 else 2494 dump_stab(); 2495 } 2496 #endif 2497 2498 #ifdef CONFIG_PPC_STD_MMU_32 2499 void dump_segments(void) 2500 { 2501 int i; 2502 2503 printf("sr0-15 ="); 2504 for (i = 0; i < 16; ++i) 2505 printf(" %x", mfsrin(i)); 2506 printf("\n"); 2507 } 2508 #endif 2509 2510 void xmon_init(int enable) 2511 { 2512 if (enable) { 2513 __debugger = xmon; 2514 __debugger_ipi = xmon_ipi; 2515 __debugger_bpt = xmon_bpt; 2516 __debugger_sstep = xmon_sstep; 2517 __debugger_iabr_match = xmon_iabr_match; 2518 __debugger_dabr_match = xmon_dabr_match; 2519 __debugger_fault_handler = xmon_fault_handler; 2520 } else { 2521 __debugger = NULL; 2522 __debugger_ipi = NULL; 2523 __debugger_bpt = NULL; 2524 __debugger_sstep = NULL; 2525 __debugger_iabr_match = NULL; 2526 __debugger_dabr_match = NULL; 2527 __debugger_fault_handler = NULL; 2528 } 2529 } 2530