1 /* 2 * Routines providing a simple monitor for use on the PowerMac. 3 * 4 * Copyright (C) 1996-2005 Paul Mackerras. 5 * Copyright (C) 2001 PPC64 Team, IBM Corp 6 * Copyrignt (C) 2006 Michael Ellerman, IBM Corp 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 11 * 2 of the License, or (at your option) any later version. 12 */ 13 #include <linux/errno.h> 14 #include <linux/sched.h> 15 #include <linux/smp.h> 16 #include <linux/mm.h> 17 #include <linux/reboot.h> 18 #include <linux/delay.h> 19 #include <linux/kallsyms.h> 20 #include <linux/kmsg_dump.h> 21 #include <linux/cpumask.h> 22 #include <linux/export.h> 23 #include <linux/sysrq.h> 24 #include <linux/interrupt.h> 25 #include <linux/irq.h> 26 #include <linux/bug.h> 27 28 #include <asm/ptrace.h> 29 #include <asm/string.h> 30 #include <asm/prom.h> 31 #include <asm/machdep.h> 32 #include <asm/xmon.h> 33 #include <asm/processor.h> 34 #include <asm/pgtable.h> 35 #include <asm/mmu.h> 36 #include <asm/mmu_context.h> 37 #include <asm/cputable.h> 38 #include <asm/rtas.h> 39 #include <asm/sstep.h> 40 #include <asm/irq_regs.h> 41 #include <asm/spu.h> 42 #include <asm/spu_priv1.h> 43 #include <asm/setjmp.h> 44 #include <asm/reg.h> 45 #include <asm/debug.h> 46 47 #ifdef CONFIG_PPC64 48 #include <asm/hvcall.h> 49 #include <asm/paca.h> 50 #endif 51 52 #include "nonstdio.h" 53 #include "dis-asm.h" 54 55 #define scanhex xmon_scanhex 56 #define skipbl xmon_skipbl 57 58 #ifdef CONFIG_SMP 59 static cpumask_t cpus_in_xmon = CPU_MASK_NONE; 60 static unsigned long xmon_taken = 1; 61 static int xmon_owner; 62 static int xmon_gate; 63 #else 64 #define xmon_owner 0 65 #endif /* CONFIG_SMP */ 66 67 static unsigned long in_xmon __read_mostly = 0; 68 69 static unsigned long adrs; 70 static int size = 1; 71 #define MAX_DUMP (128 * 1024) 72 static unsigned long ndump = 64; 73 static unsigned long nidump = 16; 74 static unsigned long ncsum = 4096; 75 static int termch; 76 static char tmpstr[128]; 77 78 static long bus_error_jmp[JMP_BUF_LEN]; 79 static int catch_memory_errors; 80 static long *xmon_fault_jmp[NR_CPUS]; 81 82 /* Breakpoint stuff */ 83 struct bpt { 84 unsigned long address; 85 unsigned int instr[2]; 86 atomic_t ref_count; 87 int enabled; 88 unsigned long pad; 89 }; 90 91 /* Bits in bpt.enabled */ 92 #define BP_IABR_TE 1 /* IABR translation enabled */ 93 #define BP_IABR 2 94 #define BP_TRAP 8 95 #define BP_DABR 0x10 96 97 #define NBPTS 256 98 static struct bpt bpts[NBPTS]; 99 static struct bpt dabr; 100 static struct bpt *iabr; 101 static unsigned bpinstr = 0x7fe00008; /* trap */ 102 103 #define BP_NUM(bp) ((bp) - bpts + 1) 104 105 /* Prototypes */ 106 static int cmds(struct pt_regs *); 107 static int mread(unsigned long, void *, int); 108 static int mwrite(unsigned long, void *, int); 109 static int handle_fault(struct pt_regs *); 110 static void byterev(unsigned char *, int); 111 static void memex(void); 112 static int bsesc(void); 113 static void dump(void); 114 static void prdump(unsigned long, long); 115 static int ppc_inst_dump(unsigned long, long, int); 116 static void dump_log_buf(void); 117 static void backtrace(struct pt_regs *); 118 static void excprint(struct pt_regs *); 119 static void prregs(struct pt_regs *); 120 static void memops(int); 121 static void memlocate(void); 122 static void memzcan(void); 123 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned); 124 int skipbl(void); 125 int scanhex(unsigned long *valp); 126 static void scannl(void); 127 static int hexdigit(int); 128 void getstring(char *, int); 129 static void flush_input(void); 130 static int inchar(void); 131 static void take_input(char *); 132 static unsigned long read_spr(int); 133 static void write_spr(int, unsigned long); 134 static void super_regs(void); 135 static void remove_bpts(void); 136 static void insert_bpts(void); 137 static void remove_cpu_bpts(void); 138 static void insert_cpu_bpts(void); 139 static struct bpt *at_breakpoint(unsigned long pc); 140 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp); 141 static int do_step(struct pt_regs *); 142 static void bpt_cmds(void); 143 static void cacheflush(void); 144 static int cpu_cmd(void); 145 static void csum(void); 146 static void bootcmds(void); 147 static void proccall(void); 148 void dump_segments(void); 149 static void symbol_lookup(void); 150 static void xmon_show_stack(unsigned long sp, unsigned long lr, 151 unsigned long pc); 152 static void xmon_print_symbol(unsigned long address, const char *mid, 153 const char *after); 154 static const char *getvecname(unsigned long vec); 155 156 static int do_spu_cmd(void); 157 158 #ifdef CONFIG_44x 159 static void dump_tlb_44x(void); 160 #endif 161 #ifdef CONFIG_PPC_BOOK3E 162 static void dump_tlb_book3e(void); 163 #endif 164 165 static int xmon_no_auto_backtrace; 166 167 extern void xmon_enter(void); 168 extern void xmon_leave(void); 169 170 #ifdef CONFIG_PPC64 171 #define REG "%.16lx" 172 #define REGS_PER_LINE 4 173 #define LAST_VOLATILE 13 174 #else 175 #define REG "%.8lx" 176 #define REGS_PER_LINE 8 177 #define LAST_VOLATILE 12 178 #endif 179 180 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3]) 181 182 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \ 183 || ('a' <= (c) && (c) <= 'f') \ 184 || ('A' <= (c) && (c) <= 'F')) 185 #define isalnum(c) (('0' <= (c) && (c) <= '9') \ 186 || ('a' <= (c) && (c) <= 'z') \ 187 || ('A' <= (c) && (c) <= 'Z')) 188 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0) 189 190 static char *help_string = "\ 191 Commands:\n\ 192 b show breakpoints\n\ 193 bd set data breakpoint\n\ 194 bi set instruction breakpoint\n\ 195 bc clear breakpoint\n" 196 #ifdef CONFIG_SMP 197 "\ 198 c print cpus stopped in xmon\n\ 199 c# try to switch to cpu number h (in hex)\n" 200 #endif 201 "\ 202 C checksum\n\ 203 d dump bytes\n\ 204 di dump instructions\n\ 205 df dump float values\n\ 206 dd dump double values\n\ 207 dl dump the kernel log buffer\n" 208 #ifdef CONFIG_PPC64 209 "\ 210 dp[#] dump paca for current cpu, or cpu #\n\ 211 dpa dump paca for all possible cpus\n" 212 #endif 213 "\ 214 dr dump stream of raw bytes\n\ 215 e print exception information\n\ 216 f flush cache\n\ 217 la lookup symbol+offset of specified address\n\ 218 ls lookup address of specified symbol\n\ 219 m examine/change memory\n\ 220 mm move a block of memory\n\ 221 ms set a block of memory\n\ 222 md compare two blocks of memory\n\ 223 ml locate a block of memory\n\ 224 mz zero a block of memory\n\ 225 mi show information about memory allocation\n\ 226 p call a procedure\n\ 227 r print registers\n\ 228 s single step\n" 229 #ifdef CONFIG_SPU_BASE 230 " ss stop execution on all spus\n\ 231 sr restore execution on stopped spus\n\ 232 sf # dump spu fields for spu # (in hex)\n\ 233 sd # dump spu local store for spu # (in hex)\n\ 234 sdi # disassemble spu local store for spu # (in hex)\n" 235 #endif 236 " S print special registers\n\ 237 t print backtrace\n\ 238 x exit monitor and recover\n\ 239 X exit monitor and dont recover\n" 240 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E) 241 " u dump segment table or SLB\n" 242 #elif defined(CONFIG_PPC_STD_MMU_32) 243 " u dump segment registers\n" 244 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E) 245 " u dump TLB\n" 246 #endif 247 " ? help\n" 248 " zr reboot\n\ 249 zh halt\n" 250 ; 251 252 static struct pt_regs *xmon_regs; 253 254 static inline void sync(void) 255 { 256 asm volatile("sync; isync"); 257 } 258 259 static inline void store_inst(void *p) 260 { 261 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p)); 262 } 263 264 static inline void cflush(void *p) 265 { 266 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p)); 267 } 268 269 static inline void cinval(void *p) 270 { 271 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p)); 272 } 273 274 /* 275 * Disable surveillance (the service processor watchdog function) 276 * while we are in xmon. 277 * XXX we should re-enable it when we leave. :) 278 */ 279 #define SURVEILLANCE_TOKEN 9000 280 281 static inline void disable_surveillance(void) 282 { 283 #ifdef CONFIG_PPC_PSERIES 284 /* Since this can't be a module, args should end up below 4GB. */ 285 static struct rtas_args args; 286 287 /* 288 * At this point we have got all the cpus we can into 289 * xmon, so there is hopefully no other cpu calling RTAS 290 * at the moment, even though we don't take rtas.lock. 291 * If we did try to take rtas.lock there would be a 292 * real possibility of deadlock. 293 */ 294 args.token = rtas_token("set-indicator"); 295 if (args.token == RTAS_UNKNOWN_SERVICE) 296 return; 297 args.nargs = 3; 298 args.nret = 1; 299 args.rets = &args.args[3]; 300 args.args[0] = SURVEILLANCE_TOKEN; 301 args.args[1] = 0; 302 args.args[2] = 0; 303 enter_rtas(__pa(&args)); 304 #endif /* CONFIG_PPC_PSERIES */ 305 } 306 307 #ifdef CONFIG_SMP 308 static int xmon_speaker; 309 310 static void get_output_lock(void) 311 { 312 int me = smp_processor_id() + 0x100; 313 int last_speaker = 0, prev; 314 long timeout; 315 316 if (xmon_speaker == me) 317 return; 318 for (;;) { 319 if (xmon_speaker == 0) { 320 last_speaker = cmpxchg(&xmon_speaker, 0, me); 321 if (last_speaker == 0) 322 return; 323 } 324 timeout = 10000000; 325 while (xmon_speaker == last_speaker) { 326 if (--timeout > 0) 327 continue; 328 /* hostile takeover */ 329 prev = cmpxchg(&xmon_speaker, last_speaker, me); 330 if (prev == last_speaker) 331 return; 332 break; 333 } 334 } 335 } 336 337 static void release_output_lock(void) 338 { 339 xmon_speaker = 0; 340 } 341 342 int cpus_are_in_xmon(void) 343 { 344 return !cpumask_empty(&cpus_in_xmon); 345 } 346 #endif 347 348 static inline int unrecoverable_excp(struct pt_regs *regs) 349 { 350 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E) 351 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */ 352 return 0; 353 #else 354 return ((regs->msr & MSR_RI) == 0); 355 #endif 356 } 357 358 static int xmon_core(struct pt_regs *regs, int fromipi) 359 { 360 int cmd = 0; 361 struct bpt *bp; 362 long recurse_jmp[JMP_BUF_LEN]; 363 unsigned long offset; 364 unsigned long flags; 365 #ifdef CONFIG_SMP 366 int cpu; 367 int secondary; 368 unsigned long timeout; 369 #endif 370 371 local_irq_save(flags); 372 373 bp = in_breakpoint_table(regs->nip, &offset); 374 if (bp != NULL) { 375 regs->nip = bp->address + offset; 376 atomic_dec(&bp->ref_count); 377 } 378 379 remove_cpu_bpts(); 380 381 #ifdef CONFIG_SMP 382 cpu = smp_processor_id(); 383 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) { 384 get_output_lock(); 385 excprint(regs); 386 printf("cpu 0x%x: Exception %lx %s in xmon, " 387 "returning to main loop\n", 388 cpu, regs->trap, getvecname(TRAP(regs))); 389 release_output_lock(); 390 longjmp(xmon_fault_jmp[cpu], 1); 391 } 392 393 if (setjmp(recurse_jmp) != 0) { 394 if (!in_xmon || !xmon_gate) { 395 get_output_lock(); 396 printf("xmon: WARNING: bad recursive fault " 397 "on cpu 0x%x\n", cpu); 398 release_output_lock(); 399 goto waiting; 400 } 401 secondary = !(xmon_taken && cpu == xmon_owner); 402 goto cmdloop; 403 } 404 405 xmon_fault_jmp[cpu] = recurse_jmp; 406 cpumask_set_cpu(cpu, &cpus_in_xmon); 407 408 bp = NULL; 409 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) 410 bp = at_breakpoint(regs->nip); 411 if (bp || unrecoverable_excp(regs)) 412 fromipi = 0; 413 414 if (!fromipi) { 415 get_output_lock(); 416 excprint(regs); 417 if (bp) { 418 printf("cpu 0x%x stopped at breakpoint 0x%x (", 419 cpu, BP_NUM(bp)); 420 xmon_print_symbol(regs->nip, " ", ")\n"); 421 } 422 if (unrecoverable_excp(regs)) 423 printf("WARNING: exception is not recoverable, " 424 "can't continue\n"); 425 release_output_lock(); 426 } 427 428 waiting: 429 secondary = 1; 430 while (secondary && !xmon_gate) { 431 if (in_xmon == 0) { 432 if (fromipi) 433 goto leave; 434 secondary = test_and_set_bit(0, &in_xmon); 435 } 436 barrier(); 437 } 438 439 if (!secondary && !xmon_gate) { 440 /* we are the first cpu to come in */ 441 /* interrupt other cpu(s) */ 442 int ncpus = num_online_cpus(); 443 444 xmon_owner = cpu; 445 mb(); 446 if (ncpus > 1) { 447 smp_send_debugger_break(); 448 /* wait for other cpus to come in */ 449 for (timeout = 100000000; timeout != 0; --timeout) { 450 if (cpumask_weight(&cpus_in_xmon) >= ncpus) 451 break; 452 barrier(); 453 } 454 } 455 remove_bpts(); 456 disable_surveillance(); 457 /* for breakpoint or single step, print the current instr. */ 458 if (bp || TRAP(regs) == 0xd00) 459 ppc_inst_dump(regs->nip, 1, 0); 460 printf("enter ? for help\n"); 461 mb(); 462 xmon_gate = 1; 463 barrier(); 464 } 465 466 cmdloop: 467 while (in_xmon) { 468 if (secondary) { 469 if (cpu == xmon_owner) { 470 if (!test_and_set_bit(0, &xmon_taken)) { 471 secondary = 0; 472 continue; 473 } 474 /* missed it */ 475 while (cpu == xmon_owner) 476 barrier(); 477 } 478 barrier(); 479 } else { 480 cmd = cmds(regs); 481 if (cmd != 0) { 482 /* exiting xmon */ 483 insert_bpts(); 484 xmon_gate = 0; 485 wmb(); 486 in_xmon = 0; 487 break; 488 } 489 /* have switched to some other cpu */ 490 secondary = 1; 491 } 492 } 493 leave: 494 cpumask_clear_cpu(cpu, &cpus_in_xmon); 495 xmon_fault_jmp[cpu] = NULL; 496 #else 497 /* UP is simple... */ 498 if (in_xmon) { 499 printf("Exception %lx %s in xmon, returning to main loop\n", 500 regs->trap, getvecname(TRAP(regs))); 501 longjmp(xmon_fault_jmp[0], 1); 502 } 503 if (setjmp(recurse_jmp) == 0) { 504 xmon_fault_jmp[0] = recurse_jmp; 505 in_xmon = 1; 506 507 excprint(regs); 508 bp = at_breakpoint(regs->nip); 509 if (bp) { 510 printf("Stopped at breakpoint %x (", BP_NUM(bp)); 511 xmon_print_symbol(regs->nip, " ", ")\n"); 512 } 513 if (unrecoverable_excp(regs)) 514 printf("WARNING: exception is not recoverable, " 515 "can't continue\n"); 516 remove_bpts(); 517 disable_surveillance(); 518 /* for breakpoint or single step, print the current instr. */ 519 if (bp || TRAP(regs) == 0xd00) 520 ppc_inst_dump(regs->nip, 1, 0); 521 printf("enter ? for help\n"); 522 } 523 524 cmd = cmds(regs); 525 526 insert_bpts(); 527 in_xmon = 0; 528 #endif 529 530 #ifdef CONFIG_BOOKE 531 if (regs->msr & MSR_DE) { 532 bp = at_breakpoint(regs->nip); 533 if (bp != NULL) { 534 regs->nip = (unsigned long) &bp->instr[0]; 535 atomic_inc(&bp->ref_count); 536 } 537 } 538 #else 539 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) { 540 bp = at_breakpoint(regs->nip); 541 if (bp != NULL) { 542 int stepped = emulate_step(regs, bp->instr[0]); 543 if (stepped == 0) { 544 regs->nip = (unsigned long) &bp->instr[0]; 545 atomic_inc(&bp->ref_count); 546 } else if (stepped < 0) { 547 printf("Couldn't single-step %s instruction\n", 548 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd")); 549 } 550 } 551 } 552 #endif 553 insert_cpu_bpts(); 554 555 local_irq_restore(flags); 556 557 return cmd != 'X' && cmd != EOF; 558 } 559 560 int xmon(struct pt_regs *excp) 561 { 562 struct pt_regs regs; 563 564 if (excp == NULL) { 565 ppc_save_regs(®s); 566 excp = ®s; 567 } 568 569 return xmon_core(excp, 0); 570 } 571 EXPORT_SYMBOL(xmon); 572 573 irqreturn_t xmon_irq(int irq, void *d) 574 { 575 unsigned long flags; 576 local_irq_save(flags); 577 printf("Keyboard interrupt\n"); 578 xmon(get_irq_regs()); 579 local_irq_restore(flags); 580 return IRQ_HANDLED; 581 } 582 583 static int xmon_bpt(struct pt_regs *regs) 584 { 585 struct bpt *bp; 586 unsigned long offset; 587 588 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT)) 589 return 0; 590 591 /* Are we at the trap at bp->instr[1] for some bp? */ 592 bp = in_breakpoint_table(regs->nip, &offset); 593 if (bp != NULL && offset == 4) { 594 regs->nip = bp->address + 4; 595 atomic_dec(&bp->ref_count); 596 return 1; 597 } 598 599 /* Are we at a breakpoint? */ 600 bp = at_breakpoint(regs->nip); 601 if (!bp) 602 return 0; 603 604 xmon_core(regs, 0); 605 606 return 1; 607 } 608 609 static int xmon_sstep(struct pt_regs *regs) 610 { 611 if (user_mode(regs)) 612 return 0; 613 xmon_core(regs, 0); 614 return 1; 615 } 616 617 static int xmon_dabr_match(struct pt_regs *regs) 618 { 619 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT)) 620 return 0; 621 if (dabr.enabled == 0) 622 return 0; 623 xmon_core(regs, 0); 624 return 1; 625 } 626 627 static int xmon_iabr_match(struct pt_regs *regs) 628 { 629 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT)) 630 return 0; 631 if (iabr == NULL) 632 return 0; 633 xmon_core(regs, 0); 634 return 1; 635 } 636 637 static int xmon_ipi(struct pt_regs *regs) 638 { 639 #ifdef CONFIG_SMP 640 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon)) 641 xmon_core(regs, 1); 642 #endif 643 return 0; 644 } 645 646 static int xmon_fault_handler(struct pt_regs *regs) 647 { 648 struct bpt *bp; 649 unsigned long offset; 650 651 if (in_xmon && catch_memory_errors) 652 handle_fault(regs); /* doesn't return */ 653 654 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) { 655 bp = in_breakpoint_table(regs->nip, &offset); 656 if (bp != NULL) { 657 regs->nip = bp->address + offset; 658 atomic_dec(&bp->ref_count); 659 } 660 } 661 662 return 0; 663 } 664 665 static struct bpt *at_breakpoint(unsigned long pc) 666 { 667 int i; 668 struct bpt *bp; 669 670 bp = bpts; 671 for (i = 0; i < NBPTS; ++i, ++bp) 672 if (bp->enabled && pc == bp->address) 673 return bp; 674 return NULL; 675 } 676 677 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp) 678 { 679 unsigned long off; 680 681 off = nip - (unsigned long) bpts; 682 if (off >= sizeof(bpts)) 683 return NULL; 684 off %= sizeof(struct bpt); 685 if (off != offsetof(struct bpt, instr[0]) 686 && off != offsetof(struct bpt, instr[1])) 687 return NULL; 688 *offp = off - offsetof(struct bpt, instr[0]); 689 return (struct bpt *) (nip - off); 690 } 691 692 static struct bpt *new_breakpoint(unsigned long a) 693 { 694 struct bpt *bp; 695 696 a &= ~3UL; 697 bp = at_breakpoint(a); 698 if (bp) 699 return bp; 700 701 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) { 702 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) { 703 bp->address = a; 704 bp->instr[1] = bpinstr; 705 store_inst(&bp->instr[1]); 706 return bp; 707 } 708 } 709 710 printf("Sorry, no free breakpoints. Please clear one first.\n"); 711 return NULL; 712 } 713 714 static void insert_bpts(void) 715 { 716 int i; 717 struct bpt *bp; 718 719 bp = bpts; 720 for (i = 0; i < NBPTS; ++i, ++bp) { 721 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0) 722 continue; 723 if (mread(bp->address, &bp->instr[0], 4) != 4) { 724 printf("Couldn't read instruction at %lx, " 725 "disabling breakpoint there\n", bp->address); 726 bp->enabled = 0; 727 continue; 728 } 729 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) { 730 printf("Breakpoint at %lx is on an mtmsrd or rfid " 731 "instruction, disabling it\n", bp->address); 732 bp->enabled = 0; 733 continue; 734 } 735 store_inst(&bp->instr[0]); 736 if (bp->enabled & BP_IABR) 737 continue; 738 if (mwrite(bp->address, &bpinstr, 4) != 4) { 739 printf("Couldn't write instruction at %lx, " 740 "disabling breakpoint there\n", bp->address); 741 bp->enabled &= ~BP_TRAP; 742 continue; 743 } 744 store_inst((void *)bp->address); 745 } 746 } 747 748 static void insert_cpu_bpts(void) 749 { 750 if (dabr.enabled) 751 set_dabr(dabr.address | (dabr.enabled & 7), DABRX_ALL); 752 if (iabr && cpu_has_feature(CPU_FTR_IABR)) 753 mtspr(SPRN_IABR, iabr->address 754 | (iabr->enabled & (BP_IABR|BP_IABR_TE))); 755 } 756 757 static void remove_bpts(void) 758 { 759 int i; 760 struct bpt *bp; 761 unsigned instr; 762 763 bp = bpts; 764 for (i = 0; i < NBPTS; ++i, ++bp) { 765 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP) 766 continue; 767 if (mread(bp->address, &instr, 4) == 4 768 && instr == bpinstr 769 && mwrite(bp->address, &bp->instr, 4) != 4) 770 printf("Couldn't remove breakpoint at %lx\n", 771 bp->address); 772 else 773 store_inst((void *)bp->address); 774 } 775 } 776 777 static void remove_cpu_bpts(void) 778 { 779 set_dabr(0, 0); 780 if (cpu_has_feature(CPU_FTR_IABR)) 781 mtspr(SPRN_IABR, 0); 782 } 783 784 /* Command interpreting routine */ 785 static char *last_cmd; 786 787 static int 788 cmds(struct pt_regs *excp) 789 { 790 int cmd = 0; 791 792 last_cmd = NULL; 793 xmon_regs = excp; 794 795 if (!xmon_no_auto_backtrace) { 796 xmon_no_auto_backtrace = 1; 797 xmon_show_stack(excp->gpr[1], excp->link, excp->nip); 798 } 799 800 for(;;) { 801 #ifdef CONFIG_SMP 802 printf("%x:", smp_processor_id()); 803 #endif /* CONFIG_SMP */ 804 printf("mon> "); 805 flush_input(); 806 termch = 0; 807 cmd = skipbl(); 808 if( cmd == '\n' ) { 809 if (last_cmd == NULL) 810 continue; 811 take_input(last_cmd); 812 last_cmd = NULL; 813 cmd = inchar(); 814 } 815 switch (cmd) { 816 case 'm': 817 cmd = inchar(); 818 switch (cmd) { 819 case 'm': 820 case 's': 821 case 'd': 822 memops(cmd); 823 break; 824 case 'l': 825 memlocate(); 826 break; 827 case 'z': 828 memzcan(); 829 break; 830 case 'i': 831 show_mem(0); 832 break; 833 default: 834 termch = cmd; 835 memex(); 836 } 837 break; 838 case 'd': 839 dump(); 840 break; 841 case 'l': 842 symbol_lookup(); 843 break; 844 case 'r': 845 prregs(excp); /* print regs */ 846 break; 847 case 'e': 848 excprint(excp); 849 break; 850 case 'S': 851 super_regs(); 852 break; 853 case 't': 854 backtrace(excp); 855 break; 856 case 'f': 857 cacheflush(); 858 break; 859 case 's': 860 if (do_spu_cmd() == 0) 861 break; 862 if (do_step(excp)) 863 return cmd; 864 break; 865 case 'x': 866 case 'X': 867 return cmd; 868 case EOF: 869 printf(" <no input ...>\n"); 870 mdelay(2000); 871 return cmd; 872 case '?': 873 xmon_puts(help_string); 874 break; 875 case 'b': 876 bpt_cmds(); 877 break; 878 case 'C': 879 csum(); 880 break; 881 case 'c': 882 if (cpu_cmd()) 883 return 0; 884 break; 885 case 'z': 886 bootcmds(); 887 break; 888 case 'p': 889 proccall(); 890 break; 891 #ifdef CONFIG_PPC_STD_MMU 892 case 'u': 893 dump_segments(); 894 break; 895 #elif defined(CONFIG_4xx) 896 case 'u': 897 dump_tlb_44x(); 898 break; 899 #elif defined(CONFIG_PPC_BOOK3E) 900 case 'u': 901 dump_tlb_book3e(); 902 break; 903 #endif 904 default: 905 printf("Unrecognized command: "); 906 do { 907 if (' ' < cmd && cmd <= '~') 908 putchar(cmd); 909 else 910 printf("\\x%x", cmd); 911 cmd = inchar(); 912 } while (cmd != '\n'); 913 printf(" (type ? for help)\n"); 914 break; 915 } 916 } 917 } 918 919 #ifdef CONFIG_BOOKE 920 static int do_step(struct pt_regs *regs) 921 { 922 regs->msr |= MSR_DE; 923 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM); 924 return 1; 925 } 926 #else 927 /* 928 * Step a single instruction. 929 * Some instructions we emulate, others we execute with MSR_SE set. 930 */ 931 static int do_step(struct pt_regs *regs) 932 { 933 unsigned int instr; 934 int stepped; 935 936 /* check we are in 64-bit kernel mode, translation enabled */ 937 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) { 938 if (mread(regs->nip, &instr, 4) == 4) { 939 stepped = emulate_step(regs, instr); 940 if (stepped < 0) { 941 printf("Couldn't single-step %s instruction\n", 942 (IS_RFID(instr)? "rfid": "mtmsrd")); 943 return 0; 944 } 945 if (stepped > 0) { 946 regs->trap = 0xd00 | (regs->trap & 1); 947 printf("stepped to "); 948 xmon_print_symbol(regs->nip, " ", "\n"); 949 ppc_inst_dump(regs->nip, 1, 0); 950 return 0; 951 } 952 } 953 } 954 regs->msr |= MSR_SE; 955 return 1; 956 } 957 #endif 958 959 static void bootcmds(void) 960 { 961 int cmd; 962 963 cmd = inchar(); 964 if (cmd == 'r') 965 ppc_md.restart(NULL); 966 else if (cmd == 'h') 967 ppc_md.halt(); 968 else if (cmd == 'p') 969 ppc_md.power_off(); 970 } 971 972 static int cpu_cmd(void) 973 { 974 #ifdef CONFIG_SMP 975 unsigned long cpu; 976 int timeout; 977 int count; 978 979 if (!scanhex(&cpu)) { 980 /* print cpus waiting or in xmon */ 981 printf("cpus stopped:"); 982 count = 0; 983 for_each_possible_cpu(cpu) { 984 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) { 985 if (count == 0) 986 printf(" %x", cpu); 987 ++count; 988 } else { 989 if (count > 1) 990 printf("-%x", cpu - 1); 991 count = 0; 992 } 993 } 994 if (count > 1) 995 printf("-%x", NR_CPUS - 1); 996 printf("\n"); 997 return 0; 998 } 999 /* try to switch to cpu specified */ 1000 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) { 1001 printf("cpu 0x%x isn't in xmon\n", cpu); 1002 return 0; 1003 } 1004 xmon_taken = 0; 1005 mb(); 1006 xmon_owner = cpu; 1007 timeout = 10000000; 1008 while (!xmon_taken) { 1009 if (--timeout == 0) { 1010 if (test_and_set_bit(0, &xmon_taken)) 1011 break; 1012 /* take control back */ 1013 mb(); 1014 xmon_owner = smp_processor_id(); 1015 printf("cpu %u didn't take control\n", cpu); 1016 return 0; 1017 } 1018 barrier(); 1019 } 1020 return 1; 1021 #else 1022 return 0; 1023 #endif /* CONFIG_SMP */ 1024 } 1025 1026 static unsigned short fcstab[256] = { 1027 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 1028 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 1029 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 1030 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 1031 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 1032 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 1033 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 1034 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 1035 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 1036 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 1037 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 1038 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 1039 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 1040 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 1041 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 1042 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 1043 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 1044 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 1045 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 1046 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 1047 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 1048 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 1049 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 1050 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 1051 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 1052 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 1053 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 1054 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 1055 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 1056 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 1057 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 1058 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 1059 }; 1060 1061 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) 1062 1063 static void 1064 csum(void) 1065 { 1066 unsigned int i; 1067 unsigned short fcs; 1068 unsigned char v; 1069 1070 if (!scanhex(&adrs)) 1071 return; 1072 if (!scanhex(&ncsum)) 1073 return; 1074 fcs = 0xffff; 1075 for (i = 0; i < ncsum; ++i) { 1076 if (mread(adrs+i, &v, 1) == 0) { 1077 printf("csum stopped at %x\n", adrs+i); 1078 break; 1079 } 1080 fcs = FCS(fcs, v); 1081 } 1082 printf("%x\n", fcs); 1083 } 1084 1085 /* 1086 * Check if this is a suitable place to put a breakpoint. 1087 */ 1088 static long check_bp_loc(unsigned long addr) 1089 { 1090 unsigned int instr; 1091 1092 addr &= ~3; 1093 if (!is_kernel_addr(addr)) { 1094 printf("Breakpoints may only be placed at kernel addresses\n"); 1095 return 0; 1096 } 1097 if (!mread(addr, &instr, sizeof(instr))) { 1098 printf("Can't read instruction at address %lx\n", addr); 1099 return 0; 1100 } 1101 if (IS_MTMSRD(instr) || IS_RFID(instr)) { 1102 printf("Breakpoints may not be placed on mtmsrd or rfid " 1103 "instructions\n"); 1104 return 0; 1105 } 1106 return 1; 1107 } 1108 1109 static char *breakpoint_help_string = 1110 "Breakpoint command usage:\n" 1111 "b show breakpoints\n" 1112 "b <addr> [cnt] set breakpoint at given instr addr\n" 1113 "bc clear all breakpoints\n" 1114 "bc <n/addr> clear breakpoint number n or at addr\n" 1115 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n" 1116 "bd <addr> [cnt] set hardware data breakpoint\n" 1117 ""; 1118 1119 static void 1120 bpt_cmds(void) 1121 { 1122 int cmd; 1123 unsigned long a; 1124 int mode, i; 1125 struct bpt *bp; 1126 const char badaddr[] = "Only kernel addresses are permitted " 1127 "for breakpoints\n"; 1128 1129 cmd = inchar(); 1130 switch (cmd) { 1131 #ifndef CONFIG_8xx 1132 case 'd': /* bd - hardware data breakpoint */ 1133 mode = 7; 1134 cmd = inchar(); 1135 if (cmd == 'r') 1136 mode = 5; 1137 else if (cmd == 'w') 1138 mode = 6; 1139 else 1140 termch = cmd; 1141 dabr.address = 0; 1142 dabr.enabled = 0; 1143 if (scanhex(&dabr.address)) { 1144 if (!is_kernel_addr(dabr.address)) { 1145 printf(badaddr); 1146 break; 1147 } 1148 dabr.address &= ~7; 1149 dabr.enabled = mode | BP_DABR; 1150 } 1151 break; 1152 1153 case 'i': /* bi - hardware instr breakpoint */ 1154 if (!cpu_has_feature(CPU_FTR_IABR)) { 1155 printf("Hardware instruction breakpoint " 1156 "not supported on this cpu\n"); 1157 break; 1158 } 1159 if (iabr) { 1160 iabr->enabled &= ~(BP_IABR | BP_IABR_TE); 1161 iabr = NULL; 1162 } 1163 if (!scanhex(&a)) 1164 break; 1165 if (!check_bp_loc(a)) 1166 break; 1167 bp = new_breakpoint(a); 1168 if (bp != NULL) { 1169 bp->enabled |= BP_IABR | BP_IABR_TE; 1170 iabr = bp; 1171 } 1172 break; 1173 #endif 1174 1175 case 'c': 1176 if (!scanhex(&a)) { 1177 /* clear all breakpoints */ 1178 for (i = 0; i < NBPTS; ++i) 1179 bpts[i].enabled = 0; 1180 iabr = NULL; 1181 dabr.enabled = 0; 1182 printf("All breakpoints cleared\n"); 1183 break; 1184 } 1185 1186 if (a <= NBPTS && a >= 1) { 1187 /* assume a breakpoint number */ 1188 bp = &bpts[a-1]; /* bp nums are 1 based */ 1189 } else { 1190 /* assume a breakpoint address */ 1191 bp = at_breakpoint(a); 1192 if (bp == NULL) { 1193 printf("No breakpoint at %x\n", a); 1194 break; 1195 } 1196 } 1197 1198 printf("Cleared breakpoint %x (", BP_NUM(bp)); 1199 xmon_print_symbol(bp->address, " ", ")\n"); 1200 bp->enabled = 0; 1201 break; 1202 1203 default: 1204 termch = cmd; 1205 cmd = skipbl(); 1206 if (cmd == '?') { 1207 printf(breakpoint_help_string); 1208 break; 1209 } 1210 termch = cmd; 1211 if (!scanhex(&a)) { 1212 /* print all breakpoints */ 1213 printf(" type address\n"); 1214 if (dabr.enabled) { 1215 printf(" data "REG" [", dabr.address); 1216 if (dabr.enabled & 1) 1217 printf("r"); 1218 if (dabr.enabled & 2) 1219 printf("w"); 1220 printf("]\n"); 1221 } 1222 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) { 1223 if (!bp->enabled) 1224 continue; 1225 printf("%2x %s ", BP_NUM(bp), 1226 (bp->enabled & BP_IABR)? "inst": "trap"); 1227 xmon_print_symbol(bp->address, " ", "\n"); 1228 } 1229 break; 1230 } 1231 1232 if (!check_bp_loc(a)) 1233 break; 1234 bp = new_breakpoint(a); 1235 if (bp != NULL) 1236 bp->enabled |= BP_TRAP; 1237 break; 1238 } 1239 } 1240 1241 /* Very cheap human name for vector lookup. */ 1242 static 1243 const char *getvecname(unsigned long vec) 1244 { 1245 char *ret; 1246 1247 switch (vec) { 1248 case 0x100: ret = "(System Reset)"; break; 1249 case 0x200: ret = "(Machine Check)"; break; 1250 case 0x300: ret = "(Data Access)"; break; 1251 case 0x380: ret = "(Data SLB Access)"; break; 1252 case 0x400: ret = "(Instruction Access)"; break; 1253 case 0x480: ret = "(Instruction SLB Access)"; break; 1254 case 0x500: ret = "(Hardware Interrupt)"; break; 1255 case 0x600: ret = "(Alignment)"; break; 1256 case 0x700: ret = "(Program Check)"; break; 1257 case 0x800: ret = "(FPU Unavailable)"; break; 1258 case 0x900: ret = "(Decrementer)"; break; 1259 case 0xc00: ret = "(System Call)"; break; 1260 case 0xd00: ret = "(Single Step)"; break; 1261 case 0xf00: ret = "(Performance Monitor)"; break; 1262 case 0xf20: ret = "(Altivec Unavailable)"; break; 1263 case 0x1300: ret = "(Instruction Breakpoint)"; break; 1264 default: ret = ""; 1265 } 1266 return ret; 1267 } 1268 1269 static void get_function_bounds(unsigned long pc, unsigned long *startp, 1270 unsigned long *endp) 1271 { 1272 unsigned long size, offset; 1273 const char *name; 1274 1275 *startp = *endp = 0; 1276 if (pc == 0) 1277 return; 1278 if (setjmp(bus_error_jmp) == 0) { 1279 catch_memory_errors = 1; 1280 sync(); 1281 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr); 1282 if (name != NULL) { 1283 *startp = pc - offset; 1284 *endp = pc - offset + size; 1285 } 1286 sync(); 1287 } 1288 catch_memory_errors = 0; 1289 } 1290 1291 static int xmon_depth_to_print = 64; 1292 1293 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long)) 1294 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long)) 1295 1296 #ifdef __powerpc64__ 1297 #define REGS_OFFSET 0x70 1298 #else 1299 #define REGS_OFFSET 16 1300 #endif 1301 1302 static void xmon_show_stack(unsigned long sp, unsigned long lr, 1303 unsigned long pc) 1304 { 1305 unsigned long ip; 1306 unsigned long newsp; 1307 unsigned long marker; 1308 int count = 0; 1309 struct pt_regs regs; 1310 1311 do { 1312 if (sp < PAGE_OFFSET) { 1313 if (sp != 0) 1314 printf("SP (%lx) is in userspace\n", sp); 1315 break; 1316 } 1317 1318 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long)) 1319 || !mread(sp, &newsp, sizeof(unsigned long))) { 1320 printf("Couldn't read stack frame at %lx\n", sp); 1321 break; 1322 } 1323 1324 /* 1325 * For the first stack frame, try to work out if 1326 * LR and/or the saved LR value in the bottommost 1327 * stack frame are valid. 1328 */ 1329 if ((pc | lr) != 0) { 1330 unsigned long fnstart, fnend; 1331 unsigned long nextip; 1332 int printip = 1; 1333 1334 get_function_bounds(pc, &fnstart, &fnend); 1335 nextip = 0; 1336 if (newsp > sp) 1337 mread(newsp + LRSAVE_OFFSET, &nextip, 1338 sizeof(unsigned long)); 1339 if (lr == ip) { 1340 if (lr < PAGE_OFFSET 1341 || (fnstart <= lr && lr < fnend)) 1342 printip = 0; 1343 } else if (lr == nextip) { 1344 printip = 0; 1345 } else if (lr >= PAGE_OFFSET 1346 && !(fnstart <= lr && lr < fnend)) { 1347 printf("[link register ] "); 1348 xmon_print_symbol(lr, " ", "\n"); 1349 } 1350 if (printip) { 1351 printf("["REG"] ", sp); 1352 xmon_print_symbol(ip, " ", " (unreliable)\n"); 1353 } 1354 pc = lr = 0; 1355 1356 } else { 1357 printf("["REG"] ", sp); 1358 xmon_print_symbol(ip, " ", "\n"); 1359 } 1360 1361 /* Look for "regshere" marker to see if this is 1362 an exception frame. */ 1363 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long)) 1364 && marker == STACK_FRAME_REGS_MARKER) { 1365 if (mread(sp + REGS_OFFSET, ®s, sizeof(regs)) 1366 != sizeof(regs)) { 1367 printf("Couldn't read registers at %lx\n", 1368 sp + REGS_OFFSET); 1369 break; 1370 } 1371 printf("--- Exception: %lx %s at ", regs.trap, 1372 getvecname(TRAP(®s))); 1373 pc = regs.nip; 1374 lr = regs.link; 1375 xmon_print_symbol(pc, " ", "\n"); 1376 } 1377 1378 if (newsp == 0) 1379 break; 1380 1381 sp = newsp; 1382 } while (count++ < xmon_depth_to_print); 1383 } 1384 1385 static void backtrace(struct pt_regs *excp) 1386 { 1387 unsigned long sp; 1388 1389 if (scanhex(&sp)) 1390 xmon_show_stack(sp, 0, 0); 1391 else 1392 xmon_show_stack(excp->gpr[1], excp->link, excp->nip); 1393 scannl(); 1394 } 1395 1396 static void print_bug_trap(struct pt_regs *regs) 1397 { 1398 #ifdef CONFIG_BUG 1399 const struct bug_entry *bug; 1400 unsigned long addr; 1401 1402 if (regs->msr & MSR_PR) 1403 return; /* not in kernel */ 1404 addr = regs->nip; /* address of trap instruction */ 1405 if (addr < PAGE_OFFSET) 1406 return; 1407 bug = find_bug(regs->nip); 1408 if (bug == NULL) 1409 return; 1410 if (is_warning_bug(bug)) 1411 return; 1412 1413 #ifdef CONFIG_DEBUG_BUGVERBOSE 1414 printf("kernel BUG at %s:%u!\n", 1415 bug->file, bug->line); 1416 #else 1417 printf("kernel BUG at %p!\n", (void *)bug->bug_addr); 1418 #endif 1419 #endif /* CONFIG_BUG */ 1420 } 1421 1422 static void excprint(struct pt_regs *fp) 1423 { 1424 unsigned long trap; 1425 1426 #ifdef CONFIG_SMP 1427 printf("cpu 0x%x: ", smp_processor_id()); 1428 #endif /* CONFIG_SMP */ 1429 1430 trap = TRAP(fp); 1431 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp); 1432 printf(" pc: "); 1433 xmon_print_symbol(fp->nip, ": ", "\n"); 1434 1435 printf(" lr: ", fp->link); 1436 xmon_print_symbol(fp->link, ": ", "\n"); 1437 1438 printf(" sp: %lx\n", fp->gpr[1]); 1439 printf(" msr: %lx\n", fp->msr); 1440 1441 if (trap == 0x300 || trap == 0x380 || trap == 0x600) { 1442 printf(" dar: %lx\n", fp->dar); 1443 if (trap != 0x380) 1444 printf(" dsisr: %lx\n", fp->dsisr); 1445 } 1446 1447 printf(" current = 0x%lx\n", current); 1448 #ifdef CONFIG_PPC64 1449 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n", 1450 local_paca, local_paca->soft_enabled, local_paca->irq_happened); 1451 #endif 1452 if (current) { 1453 printf(" pid = %ld, comm = %s\n", 1454 current->pid, current->comm); 1455 } 1456 1457 if (trap == 0x700) 1458 print_bug_trap(fp); 1459 } 1460 1461 static void prregs(struct pt_regs *fp) 1462 { 1463 int n, trap; 1464 unsigned long base; 1465 struct pt_regs regs; 1466 1467 if (scanhex(&base)) { 1468 if (setjmp(bus_error_jmp) == 0) { 1469 catch_memory_errors = 1; 1470 sync(); 1471 regs = *(struct pt_regs *)base; 1472 sync(); 1473 __delay(200); 1474 } else { 1475 catch_memory_errors = 0; 1476 printf("*** Error reading registers from "REG"\n", 1477 base); 1478 return; 1479 } 1480 catch_memory_errors = 0; 1481 fp = ®s; 1482 } 1483 1484 #ifdef CONFIG_PPC64 1485 if (FULL_REGS(fp)) { 1486 for (n = 0; n < 16; ++n) 1487 printf("R%.2ld = "REG" R%.2ld = "REG"\n", 1488 n, fp->gpr[n], n+16, fp->gpr[n+16]); 1489 } else { 1490 for (n = 0; n < 7; ++n) 1491 printf("R%.2ld = "REG" R%.2ld = "REG"\n", 1492 n, fp->gpr[n], n+7, fp->gpr[n+7]); 1493 } 1494 #else 1495 for (n = 0; n < 32; ++n) { 1496 printf("R%.2d = %.8x%s", n, fp->gpr[n], 1497 (n & 3) == 3? "\n": " "); 1498 if (n == 12 && !FULL_REGS(fp)) { 1499 printf("\n"); 1500 break; 1501 } 1502 } 1503 #endif 1504 printf("pc = "); 1505 xmon_print_symbol(fp->nip, " ", "\n"); 1506 if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) { 1507 printf("cfar= "); 1508 xmon_print_symbol(fp->orig_gpr3, " ", "\n"); 1509 } 1510 printf("lr = "); 1511 xmon_print_symbol(fp->link, " ", "\n"); 1512 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr); 1513 printf("ctr = "REG" xer = "REG" trap = %4lx\n", 1514 fp->ctr, fp->xer, fp->trap); 1515 trap = TRAP(fp); 1516 if (trap == 0x300 || trap == 0x380 || trap == 0x600) 1517 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr); 1518 } 1519 1520 static void cacheflush(void) 1521 { 1522 int cmd; 1523 unsigned long nflush; 1524 1525 cmd = inchar(); 1526 if (cmd != 'i') 1527 termch = cmd; 1528 scanhex((void *)&adrs); 1529 if (termch != '\n') 1530 termch = 0; 1531 nflush = 1; 1532 scanhex(&nflush); 1533 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES; 1534 if (setjmp(bus_error_jmp) == 0) { 1535 catch_memory_errors = 1; 1536 sync(); 1537 1538 if (cmd != 'i') { 1539 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES) 1540 cflush((void *) adrs); 1541 } else { 1542 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES) 1543 cinval((void *) adrs); 1544 } 1545 sync(); 1546 /* wait a little while to see if we get a machine check */ 1547 __delay(200); 1548 } 1549 catch_memory_errors = 0; 1550 } 1551 1552 static unsigned long 1553 read_spr(int n) 1554 { 1555 unsigned int instrs[2]; 1556 unsigned long (*code)(void); 1557 unsigned long ret = -1UL; 1558 #ifdef CONFIG_PPC64 1559 unsigned long opd[3]; 1560 1561 opd[0] = (unsigned long)instrs; 1562 opd[1] = 0; 1563 opd[2] = 0; 1564 code = (unsigned long (*)(void)) opd; 1565 #else 1566 code = (unsigned long (*)(void)) instrs; 1567 #endif 1568 1569 /* mfspr r3,n; blr */ 1570 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); 1571 instrs[1] = 0x4e800020; 1572 store_inst(instrs); 1573 store_inst(instrs+1); 1574 1575 if (setjmp(bus_error_jmp) == 0) { 1576 catch_memory_errors = 1; 1577 sync(); 1578 1579 ret = code(); 1580 1581 sync(); 1582 /* wait a little while to see if we get a machine check */ 1583 __delay(200); 1584 n = size; 1585 } 1586 1587 return ret; 1588 } 1589 1590 static void 1591 write_spr(int n, unsigned long val) 1592 { 1593 unsigned int instrs[2]; 1594 unsigned long (*code)(unsigned long); 1595 #ifdef CONFIG_PPC64 1596 unsigned long opd[3]; 1597 1598 opd[0] = (unsigned long)instrs; 1599 opd[1] = 0; 1600 opd[2] = 0; 1601 code = (unsigned long (*)(unsigned long)) opd; 1602 #else 1603 code = (unsigned long (*)(unsigned long)) instrs; 1604 #endif 1605 1606 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); 1607 instrs[1] = 0x4e800020; 1608 store_inst(instrs); 1609 store_inst(instrs+1); 1610 1611 if (setjmp(bus_error_jmp) == 0) { 1612 catch_memory_errors = 1; 1613 sync(); 1614 1615 code(val); 1616 1617 sync(); 1618 /* wait a little while to see if we get a machine check */ 1619 __delay(200); 1620 n = size; 1621 } 1622 } 1623 1624 static unsigned long regno; 1625 extern char exc_prolog; 1626 extern char dec_exc; 1627 1628 static void super_regs(void) 1629 { 1630 int cmd; 1631 unsigned long val; 1632 1633 cmd = skipbl(); 1634 if (cmd == '\n') { 1635 unsigned long sp, toc; 1636 asm("mr %0,1" : "=r" (sp) :); 1637 asm("mr %0,2" : "=r" (toc) :); 1638 1639 printf("msr = "REG" sprg0= "REG"\n", 1640 mfmsr(), mfspr(SPRN_SPRG0)); 1641 printf("pvr = "REG" sprg1= "REG"\n", 1642 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); 1643 printf("dec = "REG" sprg2= "REG"\n", 1644 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2)); 1645 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); 1646 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR)); 1647 1648 return; 1649 } 1650 1651 scanhex(®no); 1652 switch (cmd) { 1653 case 'w': 1654 val = read_spr(regno); 1655 scanhex(&val); 1656 write_spr(regno, val); 1657 /* fall through */ 1658 case 'r': 1659 printf("spr %lx = %lx\n", regno, read_spr(regno)); 1660 break; 1661 } 1662 scannl(); 1663 } 1664 1665 /* 1666 * Stuff for reading and writing memory safely 1667 */ 1668 static int 1669 mread(unsigned long adrs, void *buf, int size) 1670 { 1671 volatile int n; 1672 char *p, *q; 1673 1674 n = 0; 1675 if (setjmp(bus_error_jmp) == 0) { 1676 catch_memory_errors = 1; 1677 sync(); 1678 p = (char *)adrs; 1679 q = (char *)buf; 1680 switch (size) { 1681 case 2: 1682 *(u16 *)q = *(u16 *)p; 1683 break; 1684 case 4: 1685 *(u32 *)q = *(u32 *)p; 1686 break; 1687 case 8: 1688 *(u64 *)q = *(u64 *)p; 1689 break; 1690 default: 1691 for( ; n < size; ++n) { 1692 *q++ = *p++; 1693 sync(); 1694 } 1695 } 1696 sync(); 1697 /* wait a little while to see if we get a machine check */ 1698 __delay(200); 1699 n = size; 1700 } 1701 catch_memory_errors = 0; 1702 return n; 1703 } 1704 1705 static int 1706 mwrite(unsigned long adrs, void *buf, int size) 1707 { 1708 volatile int n; 1709 char *p, *q; 1710 1711 n = 0; 1712 if (setjmp(bus_error_jmp) == 0) { 1713 catch_memory_errors = 1; 1714 sync(); 1715 p = (char *) adrs; 1716 q = (char *) buf; 1717 switch (size) { 1718 case 2: 1719 *(u16 *)p = *(u16 *)q; 1720 break; 1721 case 4: 1722 *(u32 *)p = *(u32 *)q; 1723 break; 1724 case 8: 1725 *(u64 *)p = *(u64 *)q; 1726 break; 1727 default: 1728 for ( ; n < size; ++n) { 1729 *p++ = *q++; 1730 sync(); 1731 } 1732 } 1733 sync(); 1734 /* wait a little while to see if we get a machine check */ 1735 __delay(200); 1736 n = size; 1737 } else { 1738 printf("*** Error writing address %x\n", adrs + n); 1739 } 1740 catch_memory_errors = 0; 1741 return n; 1742 } 1743 1744 static int fault_type; 1745 static int fault_except; 1746 static char *fault_chars[] = { "--", "**", "##" }; 1747 1748 static int handle_fault(struct pt_regs *regs) 1749 { 1750 fault_except = TRAP(regs); 1751 switch (TRAP(regs)) { 1752 case 0x200: 1753 fault_type = 0; 1754 break; 1755 case 0x300: 1756 case 0x380: 1757 fault_type = 1; 1758 break; 1759 default: 1760 fault_type = 2; 1761 } 1762 1763 longjmp(bus_error_jmp, 1); 1764 1765 return 0; 1766 } 1767 1768 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t)) 1769 1770 static void 1771 byterev(unsigned char *val, int size) 1772 { 1773 int t; 1774 1775 switch (size) { 1776 case 2: 1777 SWAP(val[0], val[1], t); 1778 break; 1779 case 4: 1780 SWAP(val[0], val[3], t); 1781 SWAP(val[1], val[2], t); 1782 break; 1783 case 8: /* is there really any use for this? */ 1784 SWAP(val[0], val[7], t); 1785 SWAP(val[1], val[6], t); 1786 SWAP(val[2], val[5], t); 1787 SWAP(val[3], val[4], t); 1788 break; 1789 } 1790 } 1791 1792 static int brev; 1793 static int mnoread; 1794 1795 static char *memex_help_string = 1796 "Memory examine command usage:\n" 1797 "m [addr] [flags] examine/change memory\n" 1798 " addr is optional. will start where left off.\n" 1799 " flags may include chars from this set:\n" 1800 " b modify by bytes (default)\n" 1801 " w modify by words (2 byte)\n" 1802 " l modify by longs (4 byte)\n" 1803 " d modify by doubleword (8 byte)\n" 1804 " r toggle reverse byte order mode\n" 1805 " n do not read memory (for i/o spaces)\n" 1806 " . ok to read (default)\n" 1807 "NOTE: flags are saved as defaults\n" 1808 ""; 1809 1810 static char *memex_subcmd_help_string = 1811 "Memory examine subcommands:\n" 1812 " hexval write this val to current location\n" 1813 " 'string' write chars from string to this location\n" 1814 " ' increment address\n" 1815 " ^ decrement address\n" 1816 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n" 1817 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n" 1818 " ` clear no-read flag\n" 1819 " ; stay at this addr\n" 1820 " v change to byte mode\n" 1821 " w change to word (2 byte) mode\n" 1822 " l change to long (4 byte) mode\n" 1823 " u change to doubleword (8 byte) mode\n" 1824 " m addr change current addr\n" 1825 " n toggle no-read flag\n" 1826 " r toggle byte reverse flag\n" 1827 " < count back up count bytes\n" 1828 " > count skip forward count bytes\n" 1829 " x exit this mode\n" 1830 ""; 1831 1832 static void 1833 memex(void) 1834 { 1835 int cmd, inc, i, nslash; 1836 unsigned long n; 1837 unsigned char val[16]; 1838 1839 scanhex((void *)&adrs); 1840 cmd = skipbl(); 1841 if (cmd == '?') { 1842 printf(memex_help_string); 1843 return; 1844 } else { 1845 termch = cmd; 1846 } 1847 last_cmd = "m\n"; 1848 while ((cmd = skipbl()) != '\n') { 1849 switch( cmd ){ 1850 case 'b': size = 1; break; 1851 case 'w': size = 2; break; 1852 case 'l': size = 4; break; 1853 case 'd': size = 8; break; 1854 case 'r': brev = !brev; break; 1855 case 'n': mnoread = 1; break; 1856 case '.': mnoread = 0; break; 1857 } 1858 } 1859 if( size <= 0 ) 1860 size = 1; 1861 else if( size > 8 ) 1862 size = 8; 1863 for(;;){ 1864 if (!mnoread) 1865 n = mread(adrs, val, size); 1866 printf(REG"%c", adrs, brev? 'r': ' '); 1867 if (!mnoread) { 1868 if (brev) 1869 byterev(val, size); 1870 putchar(' '); 1871 for (i = 0; i < n; ++i) 1872 printf("%.2x", val[i]); 1873 for (; i < size; ++i) 1874 printf("%s", fault_chars[fault_type]); 1875 } 1876 putchar(' '); 1877 inc = size; 1878 nslash = 0; 1879 for(;;){ 1880 if( scanhex(&n) ){ 1881 for (i = 0; i < size; ++i) 1882 val[i] = n >> (i * 8); 1883 if (!brev) 1884 byterev(val, size); 1885 mwrite(adrs, val, size); 1886 inc = size; 1887 } 1888 cmd = skipbl(); 1889 if (cmd == '\n') 1890 break; 1891 inc = 0; 1892 switch (cmd) { 1893 case '\'': 1894 for(;;){ 1895 n = inchar(); 1896 if( n == '\\' ) 1897 n = bsesc(); 1898 else if( n == '\'' ) 1899 break; 1900 for (i = 0; i < size; ++i) 1901 val[i] = n >> (i * 8); 1902 if (!brev) 1903 byterev(val, size); 1904 mwrite(adrs, val, size); 1905 adrs += size; 1906 } 1907 adrs -= size; 1908 inc = size; 1909 break; 1910 case ',': 1911 adrs += size; 1912 break; 1913 case '.': 1914 mnoread = 0; 1915 break; 1916 case ';': 1917 break; 1918 case 'x': 1919 case EOF: 1920 scannl(); 1921 return; 1922 case 'b': 1923 case 'v': 1924 size = 1; 1925 break; 1926 case 'w': 1927 size = 2; 1928 break; 1929 case 'l': 1930 size = 4; 1931 break; 1932 case 'u': 1933 size = 8; 1934 break; 1935 case '^': 1936 adrs -= size; 1937 break; 1938 break; 1939 case '/': 1940 if (nslash > 0) 1941 adrs -= 1 << nslash; 1942 else 1943 nslash = 0; 1944 nslash += 4; 1945 adrs += 1 << nslash; 1946 break; 1947 case '\\': 1948 if (nslash < 0) 1949 adrs += 1 << -nslash; 1950 else 1951 nslash = 0; 1952 nslash -= 4; 1953 adrs -= 1 << -nslash; 1954 break; 1955 case 'm': 1956 scanhex((void *)&adrs); 1957 break; 1958 case 'n': 1959 mnoread = 1; 1960 break; 1961 case 'r': 1962 brev = !brev; 1963 break; 1964 case '<': 1965 n = size; 1966 scanhex(&n); 1967 adrs -= n; 1968 break; 1969 case '>': 1970 n = size; 1971 scanhex(&n); 1972 adrs += n; 1973 break; 1974 case '?': 1975 printf(memex_subcmd_help_string); 1976 break; 1977 } 1978 } 1979 adrs += inc; 1980 } 1981 } 1982 1983 static int 1984 bsesc(void) 1985 { 1986 int c; 1987 1988 c = inchar(); 1989 switch( c ){ 1990 case 'n': c = '\n'; break; 1991 case 'r': c = '\r'; break; 1992 case 'b': c = '\b'; break; 1993 case 't': c = '\t'; break; 1994 } 1995 return c; 1996 } 1997 1998 static void xmon_rawdump (unsigned long adrs, long ndump) 1999 { 2000 long n, m, r, nr; 2001 unsigned char temp[16]; 2002 2003 for (n = ndump; n > 0;) { 2004 r = n < 16? n: 16; 2005 nr = mread(adrs, temp, r); 2006 adrs += nr; 2007 for (m = 0; m < r; ++m) { 2008 if (m < nr) 2009 printf("%.2x", temp[m]); 2010 else 2011 printf("%s", fault_chars[fault_type]); 2012 } 2013 n -= r; 2014 if (nr < r) 2015 break; 2016 } 2017 printf("\n"); 2018 } 2019 2020 #ifdef CONFIG_PPC64 2021 static void dump_one_paca(int cpu) 2022 { 2023 struct paca_struct *p; 2024 2025 if (setjmp(bus_error_jmp) != 0) { 2026 printf("*** Error dumping paca for cpu 0x%x!\n", cpu); 2027 return; 2028 } 2029 2030 catch_memory_errors = 1; 2031 sync(); 2032 2033 p = &paca[cpu]; 2034 2035 printf("paca for cpu 0x%x @ %p:\n", cpu, p); 2036 2037 printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no"); 2038 printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no"); 2039 printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no"); 2040 2041 #define DUMP(paca, name, format) \ 2042 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \ 2043 offsetof(struct paca_struct, name)); 2044 2045 DUMP(p, lock_token, "x"); 2046 DUMP(p, paca_index, "x"); 2047 DUMP(p, kernel_toc, "lx"); 2048 DUMP(p, kernelbase, "lx"); 2049 DUMP(p, kernel_msr, "lx"); 2050 #ifdef CONFIG_PPC_STD_MMU_64 2051 DUMP(p, stab_real, "lx"); 2052 DUMP(p, stab_addr, "lx"); 2053 #endif 2054 DUMP(p, emergency_sp, "p"); 2055 DUMP(p, data_offset, "lx"); 2056 DUMP(p, hw_cpu_id, "x"); 2057 DUMP(p, cpu_start, "x"); 2058 DUMP(p, kexec_state, "x"); 2059 DUMP(p, __current, "p"); 2060 DUMP(p, kstack, "lx"); 2061 DUMP(p, stab_rr, "lx"); 2062 DUMP(p, saved_r1, "lx"); 2063 DUMP(p, trap_save, "x"); 2064 DUMP(p, soft_enabled, "x"); 2065 DUMP(p, irq_happened, "x"); 2066 DUMP(p, io_sync, "x"); 2067 DUMP(p, irq_work_pending, "x"); 2068 DUMP(p, nap_state_lost, "x"); 2069 2070 #undef DUMP 2071 2072 catch_memory_errors = 0; 2073 sync(); 2074 } 2075 2076 static void dump_all_pacas(void) 2077 { 2078 int cpu; 2079 2080 if (num_possible_cpus() == 0) { 2081 printf("No possible cpus, use 'dp #' to dump individual cpus\n"); 2082 return; 2083 } 2084 2085 for_each_possible_cpu(cpu) 2086 dump_one_paca(cpu); 2087 } 2088 2089 static void dump_pacas(void) 2090 { 2091 unsigned long num; 2092 int c; 2093 2094 c = inchar(); 2095 if (c == 'a') { 2096 dump_all_pacas(); 2097 return; 2098 } 2099 2100 termch = c; /* Put c back, it wasn't 'a' */ 2101 2102 if (scanhex(&num)) 2103 dump_one_paca(num); 2104 else 2105 dump_one_paca(xmon_owner); 2106 } 2107 #endif 2108 2109 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \ 2110 || ('a' <= (c) && (c) <= 'f') \ 2111 || ('A' <= (c) && (c) <= 'F')) 2112 static void 2113 dump(void) 2114 { 2115 int c; 2116 2117 c = inchar(); 2118 2119 #ifdef CONFIG_PPC64 2120 if (c == 'p') { 2121 dump_pacas(); 2122 return; 2123 } 2124 #endif 2125 2126 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') 2127 termch = c; 2128 scanhex((void *)&adrs); 2129 if (termch != '\n') 2130 termch = 0; 2131 if (c == 'i') { 2132 scanhex(&nidump); 2133 if (nidump == 0) 2134 nidump = 16; 2135 else if (nidump > MAX_DUMP) 2136 nidump = MAX_DUMP; 2137 adrs += ppc_inst_dump(adrs, nidump, 1); 2138 last_cmd = "di\n"; 2139 } else if (c == 'l') { 2140 dump_log_buf(); 2141 } else if (c == 'r') { 2142 scanhex(&ndump); 2143 if (ndump == 0) 2144 ndump = 64; 2145 xmon_rawdump(adrs, ndump); 2146 adrs += ndump; 2147 last_cmd = "dr\n"; 2148 } else { 2149 scanhex(&ndump); 2150 if (ndump == 0) 2151 ndump = 64; 2152 else if (ndump > MAX_DUMP) 2153 ndump = MAX_DUMP; 2154 prdump(adrs, ndump); 2155 adrs += ndump; 2156 last_cmd = "d\n"; 2157 } 2158 } 2159 2160 static void 2161 prdump(unsigned long adrs, long ndump) 2162 { 2163 long n, m, c, r, nr; 2164 unsigned char temp[16]; 2165 2166 for (n = ndump; n > 0;) { 2167 printf(REG, adrs); 2168 putchar(' '); 2169 r = n < 16? n: 16; 2170 nr = mread(adrs, temp, r); 2171 adrs += nr; 2172 for (m = 0; m < r; ++m) { 2173 if ((m & (sizeof(long) - 1)) == 0 && m > 0) 2174 putchar(' '); 2175 if (m < nr) 2176 printf("%.2x", temp[m]); 2177 else 2178 printf("%s", fault_chars[fault_type]); 2179 } 2180 for (; m < 16; ++m) { 2181 if ((m & (sizeof(long) - 1)) == 0) 2182 putchar(' '); 2183 printf(" "); 2184 } 2185 printf(" |"); 2186 for (m = 0; m < r; ++m) { 2187 if (m < nr) { 2188 c = temp[m]; 2189 putchar(' ' <= c && c <= '~'? c: '.'); 2190 } else 2191 putchar(' '); 2192 } 2193 n -= r; 2194 for (; m < 16; ++m) 2195 putchar(' '); 2196 printf("|\n"); 2197 if (nr < r) 2198 break; 2199 } 2200 } 2201 2202 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr); 2203 2204 static int 2205 generic_inst_dump(unsigned long adr, long count, int praddr, 2206 instruction_dump_func dump_func) 2207 { 2208 int nr, dotted; 2209 unsigned long first_adr; 2210 unsigned long inst, last_inst = 0; 2211 unsigned char val[4]; 2212 2213 dotted = 0; 2214 for (first_adr = adr; count > 0; --count, adr += 4) { 2215 nr = mread(adr, val, 4); 2216 if (nr == 0) { 2217 if (praddr) { 2218 const char *x = fault_chars[fault_type]; 2219 printf(REG" %s%s%s%s\n", adr, x, x, x, x); 2220 } 2221 break; 2222 } 2223 inst = GETWORD(val); 2224 if (adr > first_adr && inst == last_inst) { 2225 if (!dotted) { 2226 printf(" ...\n"); 2227 dotted = 1; 2228 } 2229 continue; 2230 } 2231 dotted = 0; 2232 last_inst = inst; 2233 if (praddr) 2234 printf(REG" %.8x", adr, inst); 2235 printf("\t"); 2236 dump_func(inst, adr); 2237 printf("\n"); 2238 } 2239 return adr - first_adr; 2240 } 2241 2242 static int 2243 ppc_inst_dump(unsigned long adr, long count, int praddr) 2244 { 2245 return generic_inst_dump(adr, count, praddr, print_insn_powerpc); 2246 } 2247 2248 void 2249 print_address(unsigned long addr) 2250 { 2251 xmon_print_symbol(addr, "\t# ", ""); 2252 } 2253 2254 void 2255 dump_log_buf(void) 2256 { 2257 struct kmsg_dumper dumper = { .active = 1 }; 2258 unsigned char buf[128]; 2259 size_t len; 2260 2261 if (setjmp(bus_error_jmp) != 0) { 2262 printf("Error dumping printk buffer!\n"); 2263 return; 2264 } 2265 2266 catch_memory_errors = 1; 2267 sync(); 2268 2269 kmsg_dump_rewind_nolock(&dumper); 2270 while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) { 2271 buf[len] = '\0'; 2272 printf("%s", buf); 2273 } 2274 2275 sync(); 2276 /* wait a little while to see if we get a machine check */ 2277 __delay(200); 2278 catch_memory_errors = 0; 2279 } 2280 2281 /* 2282 * Memory operations - move, set, print differences 2283 */ 2284 static unsigned long mdest; /* destination address */ 2285 static unsigned long msrc; /* source address */ 2286 static unsigned long mval; /* byte value to set memory to */ 2287 static unsigned long mcount; /* # bytes to affect */ 2288 static unsigned long mdiffs; /* max # differences to print */ 2289 2290 static void 2291 memops(int cmd) 2292 { 2293 scanhex((void *)&mdest); 2294 if( termch != '\n' ) 2295 termch = 0; 2296 scanhex((void *)(cmd == 's'? &mval: &msrc)); 2297 if( termch != '\n' ) 2298 termch = 0; 2299 scanhex((void *)&mcount); 2300 switch( cmd ){ 2301 case 'm': 2302 memmove((void *)mdest, (void *)msrc, mcount); 2303 break; 2304 case 's': 2305 memset((void *)mdest, mval, mcount); 2306 break; 2307 case 'd': 2308 if( termch != '\n' ) 2309 termch = 0; 2310 scanhex((void *)&mdiffs); 2311 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs); 2312 break; 2313 } 2314 } 2315 2316 static void 2317 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr) 2318 { 2319 unsigned n, prt; 2320 2321 prt = 0; 2322 for( n = nb; n > 0; --n ) 2323 if( *p1++ != *p2++ ) 2324 if( ++prt <= maxpr ) 2325 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1, 2326 p1[-1], p2 - 1, p2[-1]); 2327 if( prt > maxpr ) 2328 printf("Total of %d differences\n", prt); 2329 } 2330 2331 static unsigned mend; 2332 static unsigned mask; 2333 2334 static void 2335 memlocate(void) 2336 { 2337 unsigned a, n; 2338 unsigned char val[4]; 2339 2340 last_cmd = "ml"; 2341 scanhex((void *)&mdest); 2342 if (termch != '\n') { 2343 termch = 0; 2344 scanhex((void *)&mend); 2345 if (termch != '\n') { 2346 termch = 0; 2347 scanhex((void *)&mval); 2348 mask = ~0; 2349 if (termch != '\n') termch = 0; 2350 scanhex((void *)&mask); 2351 } 2352 } 2353 n = 0; 2354 for (a = mdest; a < mend; a += 4) { 2355 if (mread(a, val, 4) == 4 2356 && ((GETWORD(val) ^ mval) & mask) == 0) { 2357 printf("%.16x: %.16x\n", a, GETWORD(val)); 2358 if (++n >= 10) 2359 break; 2360 } 2361 } 2362 } 2363 2364 static unsigned long mskip = 0x1000; 2365 static unsigned long mlim = 0xffffffff; 2366 2367 static void 2368 memzcan(void) 2369 { 2370 unsigned char v; 2371 unsigned a; 2372 int ok, ook; 2373 2374 scanhex(&mdest); 2375 if (termch != '\n') termch = 0; 2376 scanhex(&mskip); 2377 if (termch != '\n') termch = 0; 2378 scanhex(&mlim); 2379 ook = 0; 2380 for (a = mdest; a < mlim; a += mskip) { 2381 ok = mread(a, &v, 1); 2382 if (ok && !ook) { 2383 printf("%.8x .. ", a); 2384 } else if (!ok && ook) 2385 printf("%.8x\n", a - mskip); 2386 ook = ok; 2387 if (a + mskip < a) 2388 break; 2389 } 2390 if (ook) 2391 printf("%.8x\n", a - mskip); 2392 } 2393 2394 static void proccall(void) 2395 { 2396 unsigned long args[8]; 2397 unsigned long ret; 2398 int i; 2399 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long, 2400 unsigned long, unsigned long, unsigned long, 2401 unsigned long, unsigned long, unsigned long); 2402 callfunc_t func; 2403 2404 if (!scanhex(&adrs)) 2405 return; 2406 if (termch != '\n') 2407 termch = 0; 2408 for (i = 0; i < 8; ++i) 2409 args[i] = 0; 2410 for (i = 0; i < 8; ++i) { 2411 if (!scanhex(&args[i]) || termch == '\n') 2412 break; 2413 termch = 0; 2414 } 2415 func = (callfunc_t) adrs; 2416 ret = 0; 2417 if (setjmp(bus_error_jmp) == 0) { 2418 catch_memory_errors = 1; 2419 sync(); 2420 ret = func(args[0], args[1], args[2], args[3], 2421 args[4], args[5], args[6], args[7]); 2422 sync(); 2423 printf("return value is %x\n", ret); 2424 } else { 2425 printf("*** %x exception occurred\n", fault_except); 2426 } 2427 catch_memory_errors = 0; 2428 } 2429 2430 /* Input scanning routines */ 2431 int 2432 skipbl(void) 2433 { 2434 int c; 2435 2436 if( termch != 0 ){ 2437 c = termch; 2438 termch = 0; 2439 } else 2440 c = inchar(); 2441 while( c == ' ' || c == '\t' ) 2442 c = inchar(); 2443 return c; 2444 } 2445 2446 #define N_PTREGS 44 2447 static char *regnames[N_PTREGS] = { 2448 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 2449 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 2450 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 2451 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 2452 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", 2453 #ifdef CONFIG_PPC64 2454 "softe", 2455 #else 2456 "mq", 2457 #endif 2458 "trap", "dar", "dsisr", "res" 2459 }; 2460 2461 int 2462 scanhex(unsigned long *vp) 2463 { 2464 int c, d; 2465 unsigned long v; 2466 2467 c = skipbl(); 2468 if (c == '%') { 2469 /* parse register name */ 2470 char regname[8]; 2471 int i; 2472 2473 for (i = 0; i < sizeof(regname) - 1; ++i) { 2474 c = inchar(); 2475 if (!isalnum(c)) { 2476 termch = c; 2477 break; 2478 } 2479 regname[i] = c; 2480 } 2481 regname[i] = 0; 2482 for (i = 0; i < N_PTREGS; ++i) { 2483 if (strcmp(regnames[i], regname) == 0) { 2484 if (xmon_regs == NULL) { 2485 printf("regs not available\n"); 2486 return 0; 2487 } 2488 *vp = ((unsigned long *)xmon_regs)[i]; 2489 return 1; 2490 } 2491 } 2492 printf("invalid register name '%%%s'\n", regname); 2493 return 0; 2494 } 2495 2496 /* skip leading "0x" if any */ 2497 2498 if (c == '0') { 2499 c = inchar(); 2500 if (c == 'x') { 2501 c = inchar(); 2502 } else { 2503 d = hexdigit(c); 2504 if (d == EOF) { 2505 termch = c; 2506 *vp = 0; 2507 return 1; 2508 } 2509 } 2510 } else if (c == '$') { 2511 int i; 2512 for (i=0; i<63; i++) { 2513 c = inchar(); 2514 if (isspace(c)) { 2515 termch = c; 2516 break; 2517 } 2518 tmpstr[i] = c; 2519 } 2520 tmpstr[i++] = 0; 2521 *vp = 0; 2522 if (setjmp(bus_error_jmp) == 0) { 2523 catch_memory_errors = 1; 2524 sync(); 2525 *vp = kallsyms_lookup_name(tmpstr); 2526 sync(); 2527 } 2528 catch_memory_errors = 0; 2529 if (!(*vp)) { 2530 printf("unknown symbol '%s'\n", tmpstr); 2531 return 0; 2532 } 2533 return 1; 2534 } 2535 2536 d = hexdigit(c); 2537 if (d == EOF) { 2538 termch = c; 2539 return 0; 2540 } 2541 v = 0; 2542 do { 2543 v = (v << 4) + d; 2544 c = inchar(); 2545 d = hexdigit(c); 2546 } while (d != EOF); 2547 termch = c; 2548 *vp = v; 2549 return 1; 2550 } 2551 2552 static void 2553 scannl(void) 2554 { 2555 int c; 2556 2557 c = termch; 2558 termch = 0; 2559 while( c != '\n' ) 2560 c = inchar(); 2561 } 2562 2563 static int hexdigit(int c) 2564 { 2565 if( '0' <= c && c <= '9' ) 2566 return c - '0'; 2567 if( 'A' <= c && c <= 'F' ) 2568 return c - ('A' - 10); 2569 if( 'a' <= c && c <= 'f' ) 2570 return c - ('a' - 10); 2571 return EOF; 2572 } 2573 2574 void 2575 getstring(char *s, int size) 2576 { 2577 int c; 2578 2579 c = skipbl(); 2580 do { 2581 if( size > 1 ){ 2582 *s++ = c; 2583 --size; 2584 } 2585 c = inchar(); 2586 } while( c != ' ' && c != '\t' && c != '\n' ); 2587 termch = c; 2588 *s = 0; 2589 } 2590 2591 static char line[256]; 2592 static char *lineptr; 2593 2594 static void 2595 flush_input(void) 2596 { 2597 lineptr = NULL; 2598 } 2599 2600 static int 2601 inchar(void) 2602 { 2603 if (lineptr == NULL || *lineptr == 0) { 2604 if (xmon_gets(line, sizeof(line)) == NULL) { 2605 lineptr = NULL; 2606 return EOF; 2607 } 2608 lineptr = line; 2609 } 2610 return *lineptr++; 2611 } 2612 2613 static void 2614 take_input(char *str) 2615 { 2616 lineptr = str; 2617 } 2618 2619 2620 static void 2621 symbol_lookup(void) 2622 { 2623 int type = inchar(); 2624 unsigned long addr; 2625 static char tmp[64]; 2626 2627 switch (type) { 2628 case 'a': 2629 if (scanhex(&addr)) 2630 xmon_print_symbol(addr, ": ", "\n"); 2631 termch = 0; 2632 break; 2633 case 's': 2634 getstring(tmp, 64); 2635 if (setjmp(bus_error_jmp) == 0) { 2636 catch_memory_errors = 1; 2637 sync(); 2638 addr = kallsyms_lookup_name(tmp); 2639 if (addr) 2640 printf("%s: %lx\n", tmp, addr); 2641 else 2642 printf("Symbol '%s' not found.\n", tmp); 2643 sync(); 2644 } 2645 catch_memory_errors = 0; 2646 termch = 0; 2647 break; 2648 } 2649 } 2650 2651 2652 /* Print an address in numeric and symbolic form (if possible) */ 2653 static void xmon_print_symbol(unsigned long address, const char *mid, 2654 const char *after) 2655 { 2656 char *modname; 2657 const char *name = NULL; 2658 unsigned long offset, size; 2659 2660 printf(REG, address); 2661 if (setjmp(bus_error_jmp) == 0) { 2662 catch_memory_errors = 1; 2663 sync(); 2664 name = kallsyms_lookup(address, &size, &offset, &modname, 2665 tmpstr); 2666 sync(); 2667 /* wait a little while to see if we get a machine check */ 2668 __delay(200); 2669 } 2670 2671 catch_memory_errors = 0; 2672 2673 if (name) { 2674 printf("%s%s+%#lx/%#lx", mid, name, offset, size); 2675 if (modname) 2676 printf(" [%s]", modname); 2677 } 2678 printf("%s", after); 2679 } 2680 2681 #ifdef CONFIG_PPC_BOOK3S_64 2682 static void dump_slb(void) 2683 { 2684 int i; 2685 unsigned long esid,vsid,valid; 2686 unsigned long llp; 2687 2688 printf("SLB contents of cpu %x\n", smp_processor_id()); 2689 2690 for (i = 0; i < mmu_slb_size; i++) { 2691 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i)); 2692 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i)); 2693 valid = (esid & SLB_ESID_V); 2694 if (valid | esid | vsid) { 2695 printf("%02d %016lx %016lx", i, esid, vsid); 2696 if (valid) { 2697 llp = vsid & SLB_VSID_LLP; 2698 if (vsid & SLB_VSID_B_1T) { 2699 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n", 2700 GET_ESID_1T(esid), 2701 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T, 2702 llp); 2703 } else { 2704 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n", 2705 GET_ESID(esid), 2706 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT, 2707 llp); 2708 } 2709 } else 2710 printf("\n"); 2711 } 2712 } 2713 } 2714 2715 static void dump_stab(void) 2716 { 2717 int i; 2718 unsigned long *tmp = (unsigned long *)local_paca->stab_addr; 2719 2720 printf("Segment table contents of cpu %x\n", smp_processor_id()); 2721 2722 for (i = 0; i < PAGE_SIZE/16; i++) { 2723 unsigned long a, b; 2724 2725 a = *tmp++; 2726 b = *tmp++; 2727 2728 if (a || b) { 2729 printf("%03d %016lx ", i, a); 2730 printf("%016lx\n", b); 2731 } 2732 } 2733 } 2734 2735 void dump_segments(void) 2736 { 2737 if (mmu_has_feature(MMU_FTR_SLB)) 2738 dump_slb(); 2739 else 2740 dump_stab(); 2741 } 2742 #endif 2743 2744 #ifdef CONFIG_PPC_STD_MMU_32 2745 void dump_segments(void) 2746 { 2747 int i; 2748 2749 printf("sr0-15 ="); 2750 for (i = 0; i < 16; ++i) 2751 printf(" %x", mfsrin(i)); 2752 printf("\n"); 2753 } 2754 #endif 2755 2756 #ifdef CONFIG_44x 2757 static void dump_tlb_44x(void) 2758 { 2759 int i; 2760 2761 for (i = 0; i < PPC44x_TLB_SIZE; i++) { 2762 unsigned long w0,w1,w2; 2763 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i)); 2764 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i)); 2765 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i)); 2766 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2); 2767 if (w0 & PPC44x_TLB_VALID) { 2768 printf("V %08x -> %01x%08x %c%c%c%c%c", 2769 w0 & PPC44x_TLB_EPN_MASK, 2770 w1 & PPC44x_TLB_ERPN_MASK, 2771 w1 & PPC44x_TLB_RPN_MASK, 2772 (w2 & PPC44x_TLB_W) ? 'W' : 'w', 2773 (w2 & PPC44x_TLB_I) ? 'I' : 'i', 2774 (w2 & PPC44x_TLB_M) ? 'M' : 'm', 2775 (w2 & PPC44x_TLB_G) ? 'G' : 'g', 2776 (w2 & PPC44x_TLB_E) ? 'E' : 'e'); 2777 } 2778 printf("\n"); 2779 } 2780 } 2781 #endif /* CONFIG_44x */ 2782 2783 #ifdef CONFIG_PPC_BOOK3E 2784 static void dump_tlb_book3e(void) 2785 { 2786 u32 mmucfg, pidmask, lpidmask; 2787 u64 ramask; 2788 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0; 2789 int mmu_version; 2790 static const char *pgsz_names[] = { 2791 " 1K", 2792 " 2K", 2793 " 4K", 2794 " 8K", 2795 " 16K", 2796 " 32K", 2797 " 64K", 2798 "128K", 2799 "256K", 2800 "512K", 2801 " 1M", 2802 " 2M", 2803 " 4M", 2804 " 8M", 2805 " 16M", 2806 " 32M", 2807 " 64M", 2808 "128M", 2809 "256M", 2810 "512M", 2811 " 1G", 2812 " 2G", 2813 " 4G", 2814 " 8G", 2815 " 16G", 2816 " 32G", 2817 " 64G", 2818 "128G", 2819 "256G", 2820 "512G", 2821 " 1T", 2822 " 2T", 2823 }; 2824 2825 /* Gather some infos about the MMU */ 2826 mmucfg = mfspr(SPRN_MMUCFG); 2827 mmu_version = (mmucfg & 3) + 1; 2828 ntlbs = ((mmucfg >> 2) & 3) + 1; 2829 pidsz = ((mmucfg >> 6) & 0x1f) + 1; 2830 lpidsz = (mmucfg >> 24) & 0xf; 2831 rasz = (mmucfg >> 16) & 0x7f; 2832 if ((mmu_version > 1) && (mmucfg & 0x10000)) 2833 lrat = 1; 2834 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n", 2835 mmu_version, ntlbs, pidsz, lpidsz, rasz); 2836 pidmask = (1ul << pidsz) - 1; 2837 lpidmask = (1ul << lpidsz) - 1; 2838 ramask = (1ull << rasz) - 1; 2839 2840 for (tlb = 0; tlb < ntlbs; tlb++) { 2841 u32 tlbcfg; 2842 int nent, assoc, new_cc = 1; 2843 printf("TLB %d:\n------\n", tlb); 2844 switch(tlb) { 2845 case 0: 2846 tlbcfg = mfspr(SPRN_TLB0CFG); 2847 break; 2848 case 1: 2849 tlbcfg = mfspr(SPRN_TLB1CFG); 2850 break; 2851 case 2: 2852 tlbcfg = mfspr(SPRN_TLB2CFG); 2853 break; 2854 case 3: 2855 tlbcfg = mfspr(SPRN_TLB3CFG); 2856 break; 2857 default: 2858 printf("Unsupported TLB number !\n"); 2859 continue; 2860 } 2861 nent = tlbcfg & 0xfff; 2862 assoc = (tlbcfg >> 24) & 0xff; 2863 for (i = 0; i < nent; i++) { 2864 u32 mas0 = MAS0_TLBSEL(tlb); 2865 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K); 2866 u64 mas2 = 0; 2867 u64 mas7_mas3; 2868 int esel = i, cc = i; 2869 2870 if (assoc != 0) { 2871 cc = i / assoc; 2872 esel = i % assoc; 2873 mas2 = cc * 0x1000; 2874 } 2875 2876 mas0 |= MAS0_ESEL(esel); 2877 mtspr(SPRN_MAS0, mas0); 2878 mtspr(SPRN_MAS1, mas1); 2879 mtspr(SPRN_MAS2, mas2); 2880 asm volatile("tlbre 0,0,0" : : : "memory"); 2881 mas1 = mfspr(SPRN_MAS1); 2882 mas2 = mfspr(SPRN_MAS2); 2883 mas7_mas3 = mfspr(SPRN_MAS7_MAS3); 2884 if (assoc && (i % assoc) == 0) 2885 new_cc = 1; 2886 if (!(mas1 & MAS1_VALID)) 2887 continue; 2888 if (assoc == 0) 2889 printf("%04x- ", i); 2890 else if (new_cc) 2891 printf("%04x-%c", cc, 'A' + esel); 2892 else 2893 printf(" |%c", 'A' + esel); 2894 new_cc = 0; 2895 printf(" %016llx %04x %s %c%c AS%c", 2896 mas2 & ~0x3ffull, 2897 (mas1 >> 16) & 0x3fff, 2898 pgsz_names[(mas1 >> 7) & 0x1f], 2899 mas1 & MAS1_IND ? 'I' : ' ', 2900 mas1 & MAS1_IPROT ? 'P' : ' ', 2901 mas1 & MAS1_TS ? '1' : '0'); 2902 printf(" %c%c%c%c%c%c%c", 2903 mas2 & MAS2_X0 ? 'a' : ' ', 2904 mas2 & MAS2_X1 ? 'v' : ' ', 2905 mas2 & MAS2_W ? 'w' : ' ', 2906 mas2 & MAS2_I ? 'i' : ' ', 2907 mas2 & MAS2_M ? 'm' : ' ', 2908 mas2 & MAS2_G ? 'g' : ' ', 2909 mas2 & MAS2_E ? 'e' : ' '); 2910 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull); 2911 if (mas1 & MAS1_IND) 2912 printf(" %s\n", 2913 pgsz_names[(mas7_mas3 >> 1) & 0x1f]); 2914 else 2915 printf(" U%c%c%c S%c%c%c\n", 2916 mas7_mas3 & MAS3_UX ? 'x' : ' ', 2917 mas7_mas3 & MAS3_UW ? 'w' : ' ', 2918 mas7_mas3 & MAS3_UR ? 'r' : ' ', 2919 mas7_mas3 & MAS3_SX ? 'x' : ' ', 2920 mas7_mas3 & MAS3_SW ? 'w' : ' ', 2921 mas7_mas3 & MAS3_SR ? 'r' : ' '); 2922 } 2923 } 2924 } 2925 #endif /* CONFIG_PPC_BOOK3E */ 2926 2927 static void xmon_init(int enable) 2928 { 2929 if (enable) { 2930 __debugger = xmon; 2931 __debugger_ipi = xmon_ipi; 2932 __debugger_bpt = xmon_bpt; 2933 __debugger_sstep = xmon_sstep; 2934 __debugger_iabr_match = xmon_iabr_match; 2935 __debugger_dabr_match = xmon_dabr_match; 2936 __debugger_fault_handler = xmon_fault_handler; 2937 } else { 2938 __debugger = NULL; 2939 __debugger_ipi = NULL; 2940 __debugger_bpt = NULL; 2941 __debugger_sstep = NULL; 2942 __debugger_iabr_match = NULL; 2943 __debugger_dabr_match = NULL; 2944 __debugger_fault_handler = NULL; 2945 } 2946 xmon_map_scc(); 2947 } 2948 2949 #ifdef CONFIG_MAGIC_SYSRQ 2950 static void sysrq_handle_xmon(int key) 2951 { 2952 /* ensure xmon is enabled */ 2953 xmon_init(1); 2954 debugger(get_irq_regs()); 2955 } 2956 2957 static struct sysrq_key_op sysrq_xmon_op = { 2958 .handler = sysrq_handle_xmon, 2959 .help_msg = "Xmon", 2960 .action_msg = "Entering xmon", 2961 }; 2962 2963 static int __init setup_xmon_sysrq(void) 2964 { 2965 register_sysrq_key('x', &sysrq_xmon_op); 2966 return 0; 2967 } 2968 __initcall(setup_xmon_sysrq); 2969 #endif /* CONFIG_MAGIC_SYSRQ */ 2970 2971 static int __initdata xmon_early, xmon_off; 2972 2973 static int __init early_parse_xmon(char *p) 2974 { 2975 if (!p || strncmp(p, "early", 5) == 0) { 2976 /* just "xmon" is equivalent to "xmon=early" */ 2977 xmon_init(1); 2978 xmon_early = 1; 2979 } else if (strncmp(p, "on", 2) == 0) 2980 xmon_init(1); 2981 else if (strncmp(p, "off", 3) == 0) 2982 xmon_off = 1; 2983 else if (strncmp(p, "nobt", 4) == 0) 2984 xmon_no_auto_backtrace = 1; 2985 else 2986 return 1; 2987 2988 return 0; 2989 } 2990 early_param("xmon", early_parse_xmon); 2991 2992 void __init xmon_setup(void) 2993 { 2994 #ifdef CONFIG_XMON_DEFAULT 2995 if (!xmon_off) 2996 xmon_init(1); 2997 #endif 2998 if (xmon_early) 2999 debugger(NULL); 3000 } 3001 3002 #ifdef CONFIG_SPU_BASE 3003 3004 struct spu_info { 3005 struct spu *spu; 3006 u64 saved_mfc_sr1_RW; 3007 u32 saved_spu_runcntl_RW; 3008 unsigned long dump_addr; 3009 u8 stopped_ok; 3010 }; 3011 3012 #define XMON_NUM_SPUS 16 /* Enough for current hardware */ 3013 3014 static struct spu_info spu_info[XMON_NUM_SPUS]; 3015 3016 void xmon_register_spus(struct list_head *list) 3017 { 3018 struct spu *spu; 3019 3020 list_for_each_entry(spu, list, full_list) { 3021 if (spu->number >= XMON_NUM_SPUS) { 3022 WARN_ON(1); 3023 continue; 3024 } 3025 3026 spu_info[spu->number].spu = spu; 3027 spu_info[spu->number].stopped_ok = 0; 3028 spu_info[spu->number].dump_addr = (unsigned long) 3029 spu_info[spu->number].spu->local_store; 3030 } 3031 } 3032 3033 static void stop_spus(void) 3034 { 3035 struct spu *spu; 3036 int i; 3037 u64 tmp; 3038 3039 for (i = 0; i < XMON_NUM_SPUS; i++) { 3040 if (!spu_info[i].spu) 3041 continue; 3042 3043 if (setjmp(bus_error_jmp) == 0) { 3044 catch_memory_errors = 1; 3045 sync(); 3046 3047 spu = spu_info[i].spu; 3048 3049 spu_info[i].saved_spu_runcntl_RW = 3050 in_be32(&spu->problem->spu_runcntl_RW); 3051 3052 tmp = spu_mfc_sr1_get(spu); 3053 spu_info[i].saved_mfc_sr1_RW = tmp; 3054 3055 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK; 3056 spu_mfc_sr1_set(spu, tmp); 3057 3058 sync(); 3059 __delay(200); 3060 3061 spu_info[i].stopped_ok = 1; 3062 3063 printf("Stopped spu %.2d (was %s)\n", i, 3064 spu_info[i].saved_spu_runcntl_RW ? 3065 "running" : "stopped"); 3066 } else { 3067 catch_memory_errors = 0; 3068 printf("*** Error stopping spu %.2d\n", i); 3069 } 3070 catch_memory_errors = 0; 3071 } 3072 } 3073 3074 static void restart_spus(void) 3075 { 3076 struct spu *spu; 3077 int i; 3078 3079 for (i = 0; i < XMON_NUM_SPUS; i++) { 3080 if (!spu_info[i].spu) 3081 continue; 3082 3083 if (!spu_info[i].stopped_ok) { 3084 printf("*** Error, spu %d was not successfully stopped" 3085 ", not restarting\n", i); 3086 continue; 3087 } 3088 3089 if (setjmp(bus_error_jmp) == 0) { 3090 catch_memory_errors = 1; 3091 sync(); 3092 3093 spu = spu_info[i].spu; 3094 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW); 3095 out_be32(&spu->problem->spu_runcntl_RW, 3096 spu_info[i].saved_spu_runcntl_RW); 3097 3098 sync(); 3099 __delay(200); 3100 3101 printf("Restarted spu %.2d\n", i); 3102 } else { 3103 catch_memory_errors = 0; 3104 printf("*** Error restarting spu %.2d\n", i); 3105 } 3106 catch_memory_errors = 0; 3107 } 3108 } 3109 3110 #define DUMP_WIDTH 23 3111 #define DUMP_VALUE(format, field, value) \ 3112 do { \ 3113 if (setjmp(bus_error_jmp) == 0) { \ 3114 catch_memory_errors = 1; \ 3115 sync(); \ 3116 printf(" %-*s = "format"\n", DUMP_WIDTH, \ 3117 #field, value); \ 3118 sync(); \ 3119 __delay(200); \ 3120 } else { \ 3121 catch_memory_errors = 0; \ 3122 printf(" %-*s = *** Error reading field.\n", \ 3123 DUMP_WIDTH, #field); \ 3124 } \ 3125 catch_memory_errors = 0; \ 3126 } while (0) 3127 3128 #define DUMP_FIELD(obj, format, field) \ 3129 DUMP_VALUE(format, field, obj->field) 3130 3131 static void dump_spu_fields(struct spu *spu) 3132 { 3133 printf("Dumping spu fields at address %p:\n", spu); 3134 3135 DUMP_FIELD(spu, "0x%x", number); 3136 DUMP_FIELD(spu, "%s", name); 3137 DUMP_FIELD(spu, "0x%lx", local_store_phys); 3138 DUMP_FIELD(spu, "0x%p", local_store); 3139 DUMP_FIELD(spu, "0x%lx", ls_size); 3140 DUMP_FIELD(spu, "0x%x", node); 3141 DUMP_FIELD(spu, "0x%lx", flags); 3142 DUMP_FIELD(spu, "%d", class_0_pending); 3143 DUMP_FIELD(spu, "0x%lx", class_0_dar); 3144 DUMP_FIELD(spu, "0x%lx", class_1_dar); 3145 DUMP_FIELD(spu, "0x%lx", class_1_dsisr); 3146 DUMP_FIELD(spu, "0x%lx", irqs[0]); 3147 DUMP_FIELD(spu, "0x%lx", irqs[1]); 3148 DUMP_FIELD(spu, "0x%lx", irqs[2]); 3149 DUMP_FIELD(spu, "0x%x", slb_replace); 3150 DUMP_FIELD(spu, "%d", pid); 3151 DUMP_FIELD(spu, "0x%p", mm); 3152 DUMP_FIELD(spu, "0x%p", ctx); 3153 DUMP_FIELD(spu, "0x%p", rq); 3154 DUMP_FIELD(spu, "0x%p", timestamp); 3155 DUMP_FIELD(spu, "0x%lx", problem_phys); 3156 DUMP_FIELD(spu, "0x%p", problem); 3157 DUMP_VALUE("0x%x", problem->spu_runcntl_RW, 3158 in_be32(&spu->problem->spu_runcntl_RW)); 3159 DUMP_VALUE("0x%x", problem->spu_status_R, 3160 in_be32(&spu->problem->spu_status_R)); 3161 DUMP_VALUE("0x%x", problem->spu_npc_RW, 3162 in_be32(&spu->problem->spu_npc_RW)); 3163 DUMP_FIELD(spu, "0x%p", priv2); 3164 DUMP_FIELD(spu, "0x%p", pdata); 3165 } 3166 3167 int 3168 spu_inst_dump(unsigned long adr, long count, int praddr) 3169 { 3170 return generic_inst_dump(adr, count, praddr, print_insn_spu); 3171 } 3172 3173 static void dump_spu_ls(unsigned long num, int subcmd) 3174 { 3175 unsigned long offset, addr, ls_addr; 3176 3177 if (setjmp(bus_error_jmp) == 0) { 3178 catch_memory_errors = 1; 3179 sync(); 3180 ls_addr = (unsigned long)spu_info[num].spu->local_store; 3181 sync(); 3182 __delay(200); 3183 } else { 3184 catch_memory_errors = 0; 3185 printf("*** Error: accessing spu info for spu %d\n", num); 3186 return; 3187 } 3188 catch_memory_errors = 0; 3189 3190 if (scanhex(&offset)) 3191 addr = ls_addr + offset; 3192 else 3193 addr = spu_info[num].dump_addr; 3194 3195 if (addr >= ls_addr + LS_SIZE) { 3196 printf("*** Error: address outside of local store\n"); 3197 return; 3198 } 3199 3200 switch (subcmd) { 3201 case 'i': 3202 addr += spu_inst_dump(addr, 16, 1); 3203 last_cmd = "sdi\n"; 3204 break; 3205 default: 3206 prdump(addr, 64); 3207 addr += 64; 3208 last_cmd = "sd\n"; 3209 break; 3210 } 3211 3212 spu_info[num].dump_addr = addr; 3213 } 3214 3215 static int do_spu_cmd(void) 3216 { 3217 static unsigned long num = 0; 3218 int cmd, subcmd = 0; 3219 3220 cmd = inchar(); 3221 switch (cmd) { 3222 case 's': 3223 stop_spus(); 3224 break; 3225 case 'r': 3226 restart_spus(); 3227 break; 3228 case 'd': 3229 subcmd = inchar(); 3230 if (isxdigit(subcmd) || subcmd == '\n') 3231 termch = subcmd; 3232 case 'f': 3233 scanhex(&num); 3234 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) { 3235 printf("*** Error: invalid spu number\n"); 3236 return 0; 3237 } 3238 3239 switch (cmd) { 3240 case 'f': 3241 dump_spu_fields(spu_info[num].spu); 3242 break; 3243 default: 3244 dump_spu_ls(num, subcmd); 3245 break; 3246 } 3247 3248 break; 3249 default: 3250 return -1; 3251 } 3252 3253 return 0; 3254 } 3255 #else /* ! CONFIG_SPU_BASE */ 3256 static int do_spu_cmd(void) 3257 { 3258 return -1; 3259 } 3260 #endif 3261