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