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