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/module.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 !cpus_empty(cpus_in_xmon); 338 } 339 #endif 340 341 static inline int unrecoverable_excp(struct pt_regs *regs) 342 { 343 #ifdef CONFIG_4xx 344 /* We have no MSR_RI bit on 4xx, 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 (cpu_isset(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 cpu_set(cpu, cpus_in_xmon); 400 401 bp = NULL; 402 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) 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(MSG_ALL_BUT_SELF); 441 /* wait for other cpus to come in */ 442 for (timeout = 100000000; timeout != 0; --timeout) { 443 if (cpus_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 cpu_clear(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_SF)) == (MSR_IR|MSR_SF)) { 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_SF)) != (MSR_IR|MSR_SF)) 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_SF)) != (MSR_IR|MSR_SF)) 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_SF)) != (MSR_IR|MSR_SF)) 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 && !cpu_isset(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_SF)) == (MSR_IR|MSR_SF)) { 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(); 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_SF|MSR_PR|MSR_IR)) == (MSR_SF|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 (cpu_isset(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 (!cpu_isset(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 printf("lr = "); 1501 xmon_print_symbol(fp->link, " ", "\n"); 1502 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr); 1503 printf("ctr = "REG" xer = "REG" trap = %4lx\n", 1504 fp->ctr, fp->xer, fp->trap); 1505 trap = TRAP(fp); 1506 if (trap == 0x300 || trap == 0x380 || trap == 0x600) 1507 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr); 1508 } 1509 1510 static void cacheflush(void) 1511 { 1512 int cmd; 1513 unsigned long nflush; 1514 1515 cmd = inchar(); 1516 if (cmd != 'i') 1517 termch = cmd; 1518 scanhex((void *)&adrs); 1519 if (termch != '\n') 1520 termch = 0; 1521 nflush = 1; 1522 scanhex(&nflush); 1523 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES; 1524 if (setjmp(bus_error_jmp) == 0) { 1525 catch_memory_errors = 1; 1526 sync(); 1527 1528 if (cmd != 'i') { 1529 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES) 1530 cflush((void *) adrs); 1531 } else { 1532 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES) 1533 cinval((void *) adrs); 1534 } 1535 sync(); 1536 /* wait a little while to see if we get a machine check */ 1537 __delay(200); 1538 } 1539 catch_memory_errors = 0; 1540 } 1541 1542 static unsigned long 1543 read_spr(int n) 1544 { 1545 unsigned int instrs[2]; 1546 unsigned long (*code)(void); 1547 unsigned long ret = -1UL; 1548 #ifdef CONFIG_PPC64 1549 unsigned long opd[3]; 1550 1551 opd[0] = (unsigned long)instrs; 1552 opd[1] = 0; 1553 opd[2] = 0; 1554 code = (unsigned long (*)(void)) opd; 1555 #else 1556 code = (unsigned long (*)(void)) instrs; 1557 #endif 1558 1559 /* mfspr r3,n; blr */ 1560 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); 1561 instrs[1] = 0x4e800020; 1562 store_inst(instrs); 1563 store_inst(instrs+1); 1564 1565 if (setjmp(bus_error_jmp) == 0) { 1566 catch_memory_errors = 1; 1567 sync(); 1568 1569 ret = code(); 1570 1571 sync(); 1572 /* wait a little while to see if we get a machine check */ 1573 __delay(200); 1574 n = size; 1575 } 1576 1577 return ret; 1578 } 1579 1580 static void 1581 write_spr(int n, unsigned long val) 1582 { 1583 unsigned int instrs[2]; 1584 unsigned long (*code)(unsigned long); 1585 #ifdef CONFIG_PPC64 1586 unsigned long opd[3]; 1587 1588 opd[0] = (unsigned long)instrs; 1589 opd[1] = 0; 1590 opd[2] = 0; 1591 code = (unsigned long (*)(unsigned long)) opd; 1592 #else 1593 code = (unsigned long (*)(unsigned long)) instrs; 1594 #endif 1595 1596 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); 1597 instrs[1] = 0x4e800020; 1598 store_inst(instrs); 1599 store_inst(instrs+1); 1600 1601 if (setjmp(bus_error_jmp) == 0) { 1602 catch_memory_errors = 1; 1603 sync(); 1604 1605 code(val); 1606 1607 sync(); 1608 /* wait a little while to see if we get a machine check */ 1609 __delay(200); 1610 n = size; 1611 } 1612 } 1613 1614 static unsigned long regno; 1615 extern char exc_prolog; 1616 extern char dec_exc; 1617 1618 static void super_regs(void) 1619 { 1620 int cmd; 1621 unsigned long val; 1622 1623 cmd = skipbl(); 1624 if (cmd == '\n') { 1625 unsigned long sp, toc; 1626 asm("mr %0,1" : "=r" (sp) :); 1627 asm("mr %0,2" : "=r" (toc) :); 1628 1629 printf("msr = "REG" sprg0= "REG"\n", 1630 mfmsr(), mfspr(SPRN_SPRG0)); 1631 printf("pvr = "REG" sprg1= "REG"\n", 1632 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); 1633 printf("dec = "REG" sprg2= "REG"\n", 1634 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2)); 1635 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); 1636 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR)); 1637 #ifdef CONFIG_PPC_ISERIES 1638 if (firmware_has_feature(FW_FEATURE_ISERIES)) { 1639 struct paca_struct *ptrPaca; 1640 struct lppaca *ptrLpPaca; 1641 1642 /* Dump out relevant Paca data areas. */ 1643 printf("Paca: \n"); 1644 ptrPaca = get_paca(); 1645 1646 printf(" Local Processor Control Area (LpPaca): \n"); 1647 ptrLpPaca = ptrPaca->lppaca_ptr; 1648 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n", 1649 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1); 1650 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n", 1651 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4); 1652 printf(" Saved Gpr5=%.16lx \n", 1653 ptrLpPaca->gpr5_dword.saved_gpr5); 1654 } 1655 #endif 1656 1657 return; 1658 } 1659 1660 scanhex(®no); 1661 switch (cmd) { 1662 case 'w': 1663 val = read_spr(regno); 1664 scanhex(&val); 1665 write_spr(regno, val); 1666 /* fall through */ 1667 case 'r': 1668 printf("spr %lx = %lx\n", regno, read_spr(regno)); 1669 break; 1670 } 1671 scannl(); 1672 } 1673 1674 /* 1675 * Stuff for reading and writing memory safely 1676 */ 1677 static int 1678 mread(unsigned long adrs, void *buf, int size) 1679 { 1680 volatile int n; 1681 char *p, *q; 1682 1683 n = 0; 1684 if (setjmp(bus_error_jmp) == 0) { 1685 catch_memory_errors = 1; 1686 sync(); 1687 p = (char *)adrs; 1688 q = (char *)buf; 1689 switch (size) { 1690 case 2: 1691 *(u16 *)q = *(u16 *)p; 1692 break; 1693 case 4: 1694 *(u32 *)q = *(u32 *)p; 1695 break; 1696 case 8: 1697 *(u64 *)q = *(u64 *)p; 1698 break; 1699 default: 1700 for( ; n < size; ++n) { 1701 *q++ = *p++; 1702 sync(); 1703 } 1704 } 1705 sync(); 1706 /* wait a little while to see if we get a machine check */ 1707 __delay(200); 1708 n = size; 1709 } 1710 catch_memory_errors = 0; 1711 return n; 1712 } 1713 1714 static int 1715 mwrite(unsigned long adrs, void *buf, int size) 1716 { 1717 volatile int n; 1718 char *p, *q; 1719 1720 n = 0; 1721 if (setjmp(bus_error_jmp) == 0) { 1722 catch_memory_errors = 1; 1723 sync(); 1724 p = (char *) adrs; 1725 q = (char *) buf; 1726 switch (size) { 1727 case 2: 1728 *(u16 *)p = *(u16 *)q; 1729 break; 1730 case 4: 1731 *(u32 *)p = *(u32 *)q; 1732 break; 1733 case 8: 1734 *(u64 *)p = *(u64 *)q; 1735 break; 1736 default: 1737 for ( ; n < size; ++n) { 1738 *p++ = *q++; 1739 sync(); 1740 } 1741 } 1742 sync(); 1743 /* wait a little while to see if we get a machine check */ 1744 __delay(200); 1745 n = size; 1746 } else { 1747 printf("*** Error writing address %x\n", adrs + n); 1748 } 1749 catch_memory_errors = 0; 1750 return n; 1751 } 1752 1753 static int fault_type; 1754 static int fault_except; 1755 static char *fault_chars[] = { "--", "**", "##" }; 1756 1757 static int handle_fault(struct pt_regs *regs) 1758 { 1759 fault_except = TRAP(regs); 1760 switch (TRAP(regs)) { 1761 case 0x200: 1762 fault_type = 0; 1763 break; 1764 case 0x300: 1765 case 0x380: 1766 fault_type = 1; 1767 break; 1768 default: 1769 fault_type = 2; 1770 } 1771 1772 longjmp(bus_error_jmp, 1); 1773 1774 return 0; 1775 } 1776 1777 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t)) 1778 1779 static void 1780 byterev(unsigned char *val, int size) 1781 { 1782 int t; 1783 1784 switch (size) { 1785 case 2: 1786 SWAP(val[0], val[1], t); 1787 break; 1788 case 4: 1789 SWAP(val[0], val[3], t); 1790 SWAP(val[1], val[2], t); 1791 break; 1792 case 8: /* is there really any use for this? */ 1793 SWAP(val[0], val[7], t); 1794 SWAP(val[1], val[6], t); 1795 SWAP(val[2], val[5], t); 1796 SWAP(val[3], val[4], t); 1797 break; 1798 } 1799 } 1800 1801 static int brev; 1802 static int mnoread; 1803 1804 static char *memex_help_string = 1805 "Memory examine command usage:\n" 1806 "m [addr] [flags] examine/change memory\n" 1807 " addr is optional. will start where left off.\n" 1808 " flags may include chars from this set:\n" 1809 " b modify by bytes (default)\n" 1810 " w modify by words (2 byte)\n" 1811 " l modify by longs (4 byte)\n" 1812 " d modify by doubleword (8 byte)\n" 1813 " r toggle reverse byte order mode\n" 1814 " n do not read memory (for i/o spaces)\n" 1815 " . ok to read (default)\n" 1816 "NOTE: flags are saved as defaults\n" 1817 ""; 1818 1819 static char *memex_subcmd_help_string = 1820 "Memory examine subcommands:\n" 1821 " hexval write this val to current location\n" 1822 " 'string' write chars from string to this location\n" 1823 " ' increment address\n" 1824 " ^ decrement address\n" 1825 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n" 1826 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n" 1827 " ` clear no-read flag\n" 1828 " ; stay at this addr\n" 1829 " v change to byte mode\n" 1830 " w change to word (2 byte) mode\n" 1831 " l change to long (4 byte) mode\n" 1832 " u change to doubleword (8 byte) mode\n" 1833 " m addr change current addr\n" 1834 " n toggle no-read flag\n" 1835 " r toggle byte reverse flag\n" 1836 " < count back up count bytes\n" 1837 " > count skip forward count bytes\n" 1838 " x exit this mode\n" 1839 ""; 1840 1841 static void 1842 memex(void) 1843 { 1844 int cmd, inc, i, nslash; 1845 unsigned long n; 1846 unsigned char val[16]; 1847 1848 scanhex((void *)&adrs); 1849 cmd = skipbl(); 1850 if (cmd == '?') { 1851 printf(memex_help_string); 1852 return; 1853 } else { 1854 termch = cmd; 1855 } 1856 last_cmd = "m\n"; 1857 while ((cmd = skipbl()) != '\n') { 1858 switch( cmd ){ 1859 case 'b': size = 1; break; 1860 case 'w': size = 2; break; 1861 case 'l': size = 4; break; 1862 case 'd': size = 8; break; 1863 case 'r': brev = !brev; break; 1864 case 'n': mnoread = 1; break; 1865 case '.': mnoread = 0; break; 1866 } 1867 } 1868 if( size <= 0 ) 1869 size = 1; 1870 else if( size > 8 ) 1871 size = 8; 1872 for(;;){ 1873 if (!mnoread) 1874 n = mread(adrs, val, size); 1875 printf(REG"%c", adrs, brev? 'r': ' '); 1876 if (!mnoread) { 1877 if (brev) 1878 byterev(val, size); 1879 putchar(' '); 1880 for (i = 0; i < n; ++i) 1881 printf("%.2x", val[i]); 1882 for (; i < size; ++i) 1883 printf("%s", fault_chars[fault_type]); 1884 } 1885 putchar(' '); 1886 inc = size; 1887 nslash = 0; 1888 for(;;){ 1889 if( scanhex(&n) ){ 1890 for (i = 0; i < size; ++i) 1891 val[i] = n >> (i * 8); 1892 if (!brev) 1893 byterev(val, size); 1894 mwrite(adrs, val, size); 1895 inc = size; 1896 } 1897 cmd = skipbl(); 1898 if (cmd == '\n') 1899 break; 1900 inc = 0; 1901 switch (cmd) { 1902 case '\'': 1903 for(;;){ 1904 n = inchar(); 1905 if( n == '\\' ) 1906 n = bsesc(); 1907 else if( n == '\'' ) 1908 break; 1909 for (i = 0; i < size; ++i) 1910 val[i] = n >> (i * 8); 1911 if (!brev) 1912 byterev(val, size); 1913 mwrite(adrs, val, size); 1914 adrs += size; 1915 } 1916 adrs -= size; 1917 inc = size; 1918 break; 1919 case ',': 1920 adrs += size; 1921 break; 1922 case '.': 1923 mnoread = 0; 1924 break; 1925 case ';': 1926 break; 1927 case 'x': 1928 case EOF: 1929 scannl(); 1930 return; 1931 case 'b': 1932 case 'v': 1933 size = 1; 1934 break; 1935 case 'w': 1936 size = 2; 1937 break; 1938 case 'l': 1939 size = 4; 1940 break; 1941 case 'u': 1942 size = 8; 1943 break; 1944 case '^': 1945 adrs -= size; 1946 break; 1947 break; 1948 case '/': 1949 if (nslash > 0) 1950 adrs -= 1 << nslash; 1951 else 1952 nslash = 0; 1953 nslash += 4; 1954 adrs += 1 << nslash; 1955 break; 1956 case '\\': 1957 if (nslash < 0) 1958 adrs += 1 << -nslash; 1959 else 1960 nslash = 0; 1961 nslash -= 4; 1962 adrs -= 1 << -nslash; 1963 break; 1964 case 'm': 1965 scanhex((void *)&adrs); 1966 break; 1967 case 'n': 1968 mnoread = 1; 1969 break; 1970 case 'r': 1971 brev = !brev; 1972 break; 1973 case '<': 1974 n = size; 1975 scanhex(&n); 1976 adrs -= n; 1977 break; 1978 case '>': 1979 n = size; 1980 scanhex(&n); 1981 adrs += n; 1982 break; 1983 case '?': 1984 printf(memex_subcmd_help_string); 1985 break; 1986 } 1987 } 1988 adrs += inc; 1989 } 1990 } 1991 1992 static int 1993 bsesc(void) 1994 { 1995 int c; 1996 1997 c = inchar(); 1998 switch( c ){ 1999 case 'n': c = '\n'; break; 2000 case 'r': c = '\r'; break; 2001 case 'b': c = '\b'; break; 2002 case 't': c = '\t'; break; 2003 } 2004 return c; 2005 } 2006 2007 static void xmon_rawdump (unsigned long adrs, long ndump) 2008 { 2009 long n, m, r, nr; 2010 unsigned char temp[16]; 2011 2012 for (n = ndump; n > 0;) { 2013 r = n < 16? n: 16; 2014 nr = mread(adrs, temp, r); 2015 adrs += nr; 2016 for (m = 0; m < r; ++m) { 2017 if (m < nr) 2018 printf("%.2x", temp[m]); 2019 else 2020 printf("%s", fault_chars[fault_type]); 2021 } 2022 n -= r; 2023 if (nr < r) 2024 break; 2025 } 2026 printf("\n"); 2027 } 2028 2029 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \ 2030 || ('a' <= (c) && (c) <= 'f') \ 2031 || ('A' <= (c) && (c) <= 'F')) 2032 static void 2033 dump(void) 2034 { 2035 int c; 2036 2037 c = inchar(); 2038 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') 2039 termch = c; 2040 scanhex((void *)&adrs); 2041 if (termch != '\n') 2042 termch = 0; 2043 if (c == 'i') { 2044 scanhex(&nidump); 2045 if (nidump == 0) 2046 nidump = 16; 2047 else if (nidump > MAX_DUMP) 2048 nidump = MAX_DUMP; 2049 adrs += ppc_inst_dump(adrs, nidump, 1); 2050 last_cmd = "di\n"; 2051 } else if (c == 'l') { 2052 dump_log_buf(); 2053 } else if (c == 'r') { 2054 scanhex(&ndump); 2055 if (ndump == 0) 2056 ndump = 64; 2057 xmon_rawdump(adrs, ndump); 2058 adrs += ndump; 2059 last_cmd = "dr\n"; 2060 } else { 2061 scanhex(&ndump); 2062 if (ndump == 0) 2063 ndump = 64; 2064 else if (ndump > MAX_DUMP) 2065 ndump = MAX_DUMP; 2066 prdump(adrs, ndump); 2067 adrs += ndump; 2068 last_cmd = "d\n"; 2069 } 2070 } 2071 2072 static void 2073 prdump(unsigned long adrs, long ndump) 2074 { 2075 long n, m, c, r, nr; 2076 unsigned char temp[16]; 2077 2078 for (n = ndump; n > 0;) { 2079 printf(REG, adrs); 2080 putchar(' '); 2081 r = n < 16? n: 16; 2082 nr = mread(adrs, temp, r); 2083 adrs += nr; 2084 for (m = 0; m < r; ++m) { 2085 if ((m & (sizeof(long) - 1)) == 0 && m > 0) 2086 putchar(' '); 2087 if (m < nr) 2088 printf("%.2x", temp[m]); 2089 else 2090 printf("%s", fault_chars[fault_type]); 2091 } 2092 for (; m < 16; ++m) { 2093 if ((m & (sizeof(long) - 1)) == 0) 2094 putchar(' '); 2095 printf(" "); 2096 } 2097 printf(" |"); 2098 for (m = 0; m < r; ++m) { 2099 if (m < nr) { 2100 c = temp[m]; 2101 putchar(' ' <= c && c <= '~'? c: '.'); 2102 } else 2103 putchar(' '); 2104 } 2105 n -= r; 2106 for (; m < 16; ++m) 2107 putchar(' '); 2108 printf("|\n"); 2109 if (nr < r) 2110 break; 2111 } 2112 } 2113 2114 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr); 2115 2116 static int 2117 generic_inst_dump(unsigned long adr, long count, int praddr, 2118 instruction_dump_func dump_func) 2119 { 2120 int nr, dotted; 2121 unsigned long first_adr; 2122 unsigned long inst, last_inst = 0; 2123 unsigned char val[4]; 2124 2125 dotted = 0; 2126 for (first_adr = adr; count > 0; --count, adr += 4) { 2127 nr = mread(adr, val, 4); 2128 if (nr == 0) { 2129 if (praddr) { 2130 const char *x = fault_chars[fault_type]; 2131 printf(REG" %s%s%s%s\n", adr, x, x, x, x); 2132 } 2133 break; 2134 } 2135 inst = GETWORD(val); 2136 if (adr > first_adr && inst == last_inst) { 2137 if (!dotted) { 2138 printf(" ...\n"); 2139 dotted = 1; 2140 } 2141 continue; 2142 } 2143 dotted = 0; 2144 last_inst = inst; 2145 if (praddr) 2146 printf(REG" %.8x", adr, inst); 2147 printf("\t"); 2148 dump_func(inst, adr); 2149 printf("\n"); 2150 } 2151 return adr - first_adr; 2152 } 2153 2154 static int 2155 ppc_inst_dump(unsigned long adr, long count, int praddr) 2156 { 2157 return generic_inst_dump(adr, count, praddr, print_insn_powerpc); 2158 } 2159 2160 void 2161 print_address(unsigned long addr) 2162 { 2163 xmon_print_symbol(addr, "\t# ", ""); 2164 } 2165 2166 void 2167 dump_log_buf(void) 2168 { 2169 const unsigned long size = 128; 2170 unsigned long end, addr; 2171 unsigned char buf[size + 1]; 2172 2173 addr = 0; 2174 buf[size] = '\0'; 2175 2176 if (setjmp(bus_error_jmp) != 0) { 2177 printf("Unable to lookup symbol __log_buf!\n"); 2178 return; 2179 } 2180 2181 catch_memory_errors = 1; 2182 sync(); 2183 addr = kallsyms_lookup_name("__log_buf"); 2184 2185 if (! addr) 2186 printf("Symbol __log_buf not found!\n"); 2187 else { 2188 end = addr + (1 << CONFIG_LOG_BUF_SHIFT); 2189 while (addr < end) { 2190 if (! mread(addr, buf, size)) { 2191 printf("Can't read memory at address 0x%lx\n", addr); 2192 break; 2193 } 2194 2195 printf("%s", buf); 2196 2197 if (strlen(buf) < size) 2198 break; 2199 2200 addr += size; 2201 } 2202 } 2203 2204 sync(); 2205 /* wait a little while to see if we get a machine check */ 2206 __delay(200); 2207 catch_memory_errors = 0; 2208 } 2209 2210 /* 2211 * Memory operations - move, set, print differences 2212 */ 2213 static unsigned long mdest; /* destination address */ 2214 static unsigned long msrc; /* source address */ 2215 static unsigned long mval; /* byte value to set memory to */ 2216 static unsigned long mcount; /* # bytes to affect */ 2217 static unsigned long mdiffs; /* max # differences to print */ 2218 2219 static void 2220 memops(int cmd) 2221 { 2222 scanhex((void *)&mdest); 2223 if( termch != '\n' ) 2224 termch = 0; 2225 scanhex((void *)(cmd == 's'? &mval: &msrc)); 2226 if( termch != '\n' ) 2227 termch = 0; 2228 scanhex((void *)&mcount); 2229 switch( cmd ){ 2230 case 'm': 2231 memmove((void *)mdest, (void *)msrc, mcount); 2232 break; 2233 case 's': 2234 memset((void *)mdest, mval, mcount); 2235 break; 2236 case 'd': 2237 if( termch != '\n' ) 2238 termch = 0; 2239 scanhex((void *)&mdiffs); 2240 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs); 2241 break; 2242 } 2243 } 2244 2245 static void 2246 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr) 2247 { 2248 unsigned n, prt; 2249 2250 prt = 0; 2251 for( n = nb; n > 0; --n ) 2252 if( *p1++ != *p2++ ) 2253 if( ++prt <= maxpr ) 2254 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1, 2255 p1[-1], p2 - 1, p2[-1]); 2256 if( prt > maxpr ) 2257 printf("Total of %d differences\n", prt); 2258 } 2259 2260 static unsigned mend; 2261 static unsigned mask; 2262 2263 static void 2264 memlocate(void) 2265 { 2266 unsigned a, n; 2267 unsigned char val[4]; 2268 2269 last_cmd = "ml"; 2270 scanhex((void *)&mdest); 2271 if (termch != '\n') { 2272 termch = 0; 2273 scanhex((void *)&mend); 2274 if (termch != '\n') { 2275 termch = 0; 2276 scanhex((void *)&mval); 2277 mask = ~0; 2278 if (termch != '\n') termch = 0; 2279 scanhex((void *)&mask); 2280 } 2281 } 2282 n = 0; 2283 for (a = mdest; a < mend; a += 4) { 2284 if (mread(a, val, 4) == 4 2285 && ((GETWORD(val) ^ mval) & mask) == 0) { 2286 printf("%.16x: %.16x\n", a, GETWORD(val)); 2287 if (++n >= 10) 2288 break; 2289 } 2290 } 2291 } 2292 2293 static unsigned long mskip = 0x1000; 2294 static unsigned long mlim = 0xffffffff; 2295 2296 static void 2297 memzcan(void) 2298 { 2299 unsigned char v; 2300 unsigned a; 2301 int ok, ook; 2302 2303 scanhex(&mdest); 2304 if (termch != '\n') termch = 0; 2305 scanhex(&mskip); 2306 if (termch != '\n') termch = 0; 2307 scanhex(&mlim); 2308 ook = 0; 2309 for (a = mdest; a < mlim; a += mskip) { 2310 ok = mread(a, &v, 1); 2311 if (ok && !ook) { 2312 printf("%.8x .. ", a); 2313 } else if (!ok && ook) 2314 printf("%.8x\n", a - mskip); 2315 ook = ok; 2316 if (a + mskip < a) 2317 break; 2318 } 2319 if (ook) 2320 printf("%.8x\n", a - mskip); 2321 } 2322 2323 static void proccall(void) 2324 { 2325 unsigned long args[8]; 2326 unsigned long ret; 2327 int i; 2328 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long, 2329 unsigned long, unsigned long, unsigned long, 2330 unsigned long, unsigned long, unsigned long); 2331 callfunc_t func; 2332 2333 if (!scanhex(&adrs)) 2334 return; 2335 if (termch != '\n') 2336 termch = 0; 2337 for (i = 0; i < 8; ++i) 2338 args[i] = 0; 2339 for (i = 0; i < 8; ++i) { 2340 if (!scanhex(&args[i]) || termch == '\n') 2341 break; 2342 termch = 0; 2343 } 2344 func = (callfunc_t) adrs; 2345 ret = 0; 2346 if (setjmp(bus_error_jmp) == 0) { 2347 catch_memory_errors = 1; 2348 sync(); 2349 ret = func(args[0], args[1], args[2], args[3], 2350 args[4], args[5], args[6], args[7]); 2351 sync(); 2352 printf("return value is %x\n", ret); 2353 } else { 2354 printf("*** %x exception occurred\n", fault_except); 2355 } 2356 catch_memory_errors = 0; 2357 } 2358 2359 /* Input scanning routines */ 2360 int 2361 skipbl(void) 2362 { 2363 int c; 2364 2365 if( termch != 0 ){ 2366 c = termch; 2367 termch = 0; 2368 } else 2369 c = inchar(); 2370 while( c == ' ' || c == '\t' ) 2371 c = inchar(); 2372 return c; 2373 } 2374 2375 #define N_PTREGS 44 2376 static char *regnames[N_PTREGS] = { 2377 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 2378 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 2379 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 2380 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 2381 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", 2382 #ifdef CONFIG_PPC64 2383 "softe", 2384 #else 2385 "mq", 2386 #endif 2387 "trap", "dar", "dsisr", "res" 2388 }; 2389 2390 int 2391 scanhex(unsigned long *vp) 2392 { 2393 int c, d; 2394 unsigned long v; 2395 2396 c = skipbl(); 2397 if (c == '%') { 2398 /* parse register name */ 2399 char regname[8]; 2400 int i; 2401 2402 for (i = 0; i < sizeof(regname) - 1; ++i) { 2403 c = inchar(); 2404 if (!isalnum(c)) { 2405 termch = c; 2406 break; 2407 } 2408 regname[i] = c; 2409 } 2410 regname[i] = 0; 2411 for (i = 0; i < N_PTREGS; ++i) { 2412 if (strcmp(regnames[i], regname) == 0) { 2413 if (xmon_regs == NULL) { 2414 printf("regs not available\n"); 2415 return 0; 2416 } 2417 *vp = ((unsigned long *)xmon_regs)[i]; 2418 return 1; 2419 } 2420 } 2421 printf("invalid register name '%%%s'\n", regname); 2422 return 0; 2423 } 2424 2425 /* skip leading "0x" if any */ 2426 2427 if (c == '0') { 2428 c = inchar(); 2429 if (c == 'x') { 2430 c = inchar(); 2431 } else { 2432 d = hexdigit(c); 2433 if (d == EOF) { 2434 termch = c; 2435 *vp = 0; 2436 return 1; 2437 } 2438 } 2439 } else if (c == '$') { 2440 int i; 2441 for (i=0; i<63; i++) { 2442 c = inchar(); 2443 if (isspace(c)) { 2444 termch = c; 2445 break; 2446 } 2447 tmpstr[i] = c; 2448 } 2449 tmpstr[i++] = 0; 2450 *vp = 0; 2451 if (setjmp(bus_error_jmp) == 0) { 2452 catch_memory_errors = 1; 2453 sync(); 2454 *vp = kallsyms_lookup_name(tmpstr); 2455 sync(); 2456 } 2457 catch_memory_errors = 0; 2458 if (!(*vp)) { 2459 printf("unknown symbol '%s'\n", tmpstr); 2460 return 0; 2461 } 2462 return 1; 2463 } 2464 2465 d = hexdigit(c); 2466 if (d == EOF) { 2467 termch = c; 2468 return 0; 2469 } 2470 v = 0; 2471 do { 2472 v = (v << 4) + d; 2473 c = inchar(); 2474 d = hexdigit(c); 2475 } while (d != EOF); 2476 termch = c; 2477 *vp = v; 2478 return 1; 2479 } 2480 2481 static void 2482 scannl(void) 2483 { 2484 int c; 2485 2486 c = termch; 2487 termch = 0; 2488 while( c != '\n' ) 2489 c = inchar(); 2490 } 2491 2492 static int hexdigit(int c) 2493 { 2494 if( '0' <= c && c <= '9' ) 2495 return c - '0'; 2496 if( 'A' <= c && c <= 'F' ) 2497 return c - ('A' - 10); 2498 if( 'a' <= c && c <= 'f' ) 2499 return c - ('a' - 10); 2500 return EOF; 2501 } 2502 2503 void 2504 getstring(char *s, int size) 2505 { 2506 int c; 2507 2508 c = skipbl(); 2509 do { 2510 if( size > 1 ){ 2511 *s++ = c; 2512 --size; 2513 } 2514 c = inchar(); 2515 } while( c != ' ' && c != '\t' && c != '\n' ); 2516 termch = c; 2517 *s = 0; 2518 } 2519 2520 static char line[256]; 2521 static char *lineptr; 2522 2523 static void 2524 flush_input(void) 2525 { 2526 lineptr = NULL; 2527 } 2528 2529 static int 2530 inchar(void) 2531 { 2532 if (lineptr == NULL || *lineptr == 0) { 2533 if (xmon_gets(line, sizeof(line)) == NULL) { 2534 lineptr = NULL; 2535 return EOF; 2536 } 2537 lineptr = line; 2538 } 2539 return *lineptr++; 2540 } 2541 2542 static void 2543 take_input(char *str) 2544 { 2545 lineptr = str; 2546 } 2547 2548 2549 static void 2550 symbol_lookup(void) 2551 { 2552 int type = inchar(); 2553 unsigned long addr; 2554 static char tmp[64]; 2555 2556 switch (type) { 2557 case 'a': 2558 if (scanhex(&addr)) 2559 xmon_print_symbol(addr, ": ", "\n"); 2560 termch = 0; 2561 break; 2562 case 's': 2563 getstring(tmp, 64); 2564 if (setjmp(bus_error_jmp) == 0) { 2565 catch_memory_errors = 1; 2566 sync(); 2567 addr = kallsyms_lookup_name(tmp); 2568 if (addr) 2569 printf("%s: %lx\n", tmp, addr); 2570 else 2571 printf("Symbol '%s' not found.\n", tmp); 2572 sync(); 2573 } 2574 catch_memory_errors = 0; 2575 termch = 0; 2576 break; 2577 } 2578 } 2579 2580 2581 /* Print an address in numeric and symbolic form (if possible) */ 2582 static void xmon_print_symbol(unsigned long address, const char *mid, 2583 const char *after) 2584 { 2585 char *modname; 2586 const char *name = NULL; 2587 unsigned long offset, size; 2588 2589 printf(REG, address); 2590 if (setjmp(bus_error_jmp) == 0) { 2591 catch_memory_errors = 1; 2592 sync(); 2593 name = kallsyms_lookup(address, &size, &offset, &modname, 2594 tmpstr); 2595 sync(); 2596 /* wait a little while to see if we get a machine check */ 2597 __delay(200); 2598 } 2599 2600 catch_memory_errors = 0; 2601 2602 if (name) { 2603 printf("%s%s+%#lx/%#lx", mid, name, offset, size); 2604 if (modname) 2605 printf(" [%s]", modname); 2606 } 2607 printf("%s", after); 2608 } 2609 2610 #ifdef CONFIG_PPC_BOOK3S_64 2611 static void dump_slb(void) 2612 { 2613 int i; 2614 unsigned long esid,vsid,valid; 2615 unsigned long llp; 2616 2617 printf("SLB contents of cpu %x\n", smp_processor_id()); 2618 2619 for (i = 0; i < mmu_slb_size; i++) { 2620 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i)); 2621 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i)); 2622 valid = (esid & SLB_ESID_V); 2623 if (valid | esid | vsid) { 2624 printf("%02d %016lx %016lx", i, esid, vsid); 2625 if (valid) { 2626 llp = vsid & SLB_VSID_LLP; 2627 if (vsid & SLB_VSID_B_1T) { 2628 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n", 2629 GET_ESID_1T(esid), 2630 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T, 2631 llp); 2632 } else { 2633 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n", 2634 GET_ESID(esid), 2635 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT, 2636 llp); 2637 } 2638 } else 2639 printf("\n"); 2640 } 2641 } 2642 } 2643 2644 static void dump_stab(void) 2645 { 2646 int i; 2647 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr; 2648 2649 printf("Segment table contents of cpu %x\n", smp_processor_id()); 2650 2651 for (i = 0; i < PAGE_SIZE/16; i++) { 2652 unsigned long a, b; 2653 2654 a = *tmp++; 2655 b = *tmp++; 2656 2657 if (a || b) { 2658 printf("%03d %016lx ", i, a); 2659 printf("%016lx\n", b); 2660 } 2661 } 2662 } 2663 2664 void dump_segments(void) 2665 { 2666 if (cpu_has_feature(CPU_FTR_SLB)) 2667 dump_slb(); 2668 else 2669 dump_stab(); 2670 } 2671 #endif 2672 2673 #ifdef CONFIG_PPC_STD_MMU_32 2674 void dump_segments(void) 2675 { 2676 int i; 2677 2678 printf("sr0-15 ="); 2679 for (i = 0; i < 16; ++i) 2680 printf(" %x", mfsrin(i)); 2681 printf("\n"); 2682 } 2683 #endif 2684 2685 #ifdef CONFIG_44x 2686 static void dump_tlb_44x(void) 2687 { 2688 int i; 2689 2690 for (i = 0; i < PPC44x_TLB_SIZE; i++) { 2691 unsigned long w0,w1,w2; 2692 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i)); 2693 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i)); 2694 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i)); 2695 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2); 2696 if (w0 & PPC44x_TLB_VALID) { 2697 printf("V %08x -> %01x%08x %c%c%c%c%c", 2698 w0 & PPC44x_TLB_EPN_MASK, 2699 w1 & PPC44x_TLB_ERPN_MASK, 2700 w1 & PPC44x_TLB_RPN_MASK, 2701 (w2 & PPC44x_TLB_W) ? 'W' : 'w', 2702 (w2 & PPC44x_TLB_I) ? 'I' : 'i', 2703 (w2 & PPC44x_TLB_M) ? 'M' : 'm', 2704 (w2 & PPC44x_TLB_G) ? 'G' : 'g', 2705 (w2 & PPC44x_TLB_E) ? 'E' : 'e'); 2706 } 2707 printf("\n"); 2708 } 2709 } 2710 #endif /* CONFIG_44x */ 2711 2712 #ifdef CONFIG_PPC_BOOK3E 2713 static void dump_tlb_book3e(void) 2714 { 2715 u32 mmucfg, pidmask, lpidmask; 2716 u64 ramask; 2717 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0; 2718 int mmu_version; 2719 static const char *pgsz_names[] = { 2720 " 1K", 2721 " 2K", 2722 " 4K", 2723 " 8K", 2724 " 16K", 2725 " 32K", 2726 " 64K", 2727 "128K", 2728 "256K", 2729 "512K", 2730 " 1M", 2731 " 2M", 2732 " 4M", 2733 " 8M", 2734 " 16M", 2735 " 32M", 2736 " 64M", 2737 "128M", 2738 "256M", 2739 "512M", 2740 " 1G", 2741 " 2G", 2742 " 4G", 2743 " 8G", 2744 " 16G", 2745 " 32G", 2746 " 64G", 2747 "128G", 2748 "256G", 2749 "512G", 2750 " 1T", 2751 " 2T", 2752 }; 2753 2754 /* Gather some infos about the MMU */ 2755 mmucfg = mfspr(SPRN_MMUCFG); 2756 mmu_version = (mmucfg & 3) + 1; 2757 ntlbs = ((mmucfg >> 2) & 3) + 1; 2758 pidsz = ((mmucfg >> 6) & 0x1f) + 1; 2759 lpidsz = (mmucfg >> 24) & 0xf; 2760 rasz = (mmucfg >> 16) & 0x7f; 2761 if ((mmu_version > 1) && (mmucfg & 0x10000)) 2762 lrat = 1; 2763 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n", 2764 mmu_version, ntlbs, pidsz, lpidsz, rasz); 2765 pidmask = (1ul << pidsz) - 1; 2766 lpidmask = (1ul << lpidsz) - 1; 2767 ramask = (1ull << rasz) - 1; 2768 2769 for (tlb = 0; tlb < ntlbs; tlb++) { 2770 u32 tlbcfg; 2771 int nent, assoc, new_cc = 1; 2772 printf("TLB %d:\n------\n", tlb); 2773 switch(tlb) { 2774 case 0: 2775 tlbcfg = mfspr(SPRN_TLB0CFG); 2776 break; 2777 case 1: 2778 tlbcfg = mfspr(SPRN_TLB1CFG); 2779 break; 2780 case 2: 2781 tlbcfg = mfspr(SPRN_TLB2CFG); 2782 break; 2783 case 3: 2784 tlbcfg = mfspr(SPRN_TLB3CFG); 2785 break; 2786 default: 2787 printf("Unsupported TLB number !\n"); 2788 continue; 2789 } 2790 nent = tlbcfg & 0xfff; 2791 assoc = (tlbcfg >> 24) & 0xff; 2792 for (i = 0; i < nent; i++) { 2793 u32 mas0 = MAS0_TLBSEL(tlb); 2794 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K); 2795 u64 mas2 = 0; 2796 u64 mas7_mas3; 2797 int esel = i, cc = i; 2798 2799 if (assoc != 0) { 2800 cc = i / assoc; 2801 esel = i % assoc; 2802 mas2 = cc * 0x1000; 2803 } 2804 2805 mas0 |= MAS0_ESEL(esel); 2806 mtspr(SPRN_MAS0, mas0); 2807 mtspr(SPRN_MAS1, mas1); 2808 mtspr(SPRN_MAS2, mas2); 2809 asm volatile("tlbre 0,0,0" : : : "memory"); 2810 mas1 = mfspr(SPRN_MAS1); 2811 mas2 = mfspr(SPRN_MAS2); 2812 mas7_mas3 = mfspr(SPRN_MAS7_MAS3); 2813 if (assoc && (i % assoc) == 0) 2814 new_cc = 1; 2815 if (!(mas1 & MAS1_VALID)) 2816 continue; 2817 if (assoc == 0) 2818 printf("%04x- ", i); 2819 else if (new_cc) 2820 printf("%04x-%c", cc, 'A' + esel); 2821 else 2822 printf(" |%c", 'A' + esel); 2823 new_cc = 0; 2824 printf(" %016llx %04x %s %c%c AS%c", 2825 mas2 & ~0x3ffull, 2826 (mas1 >> 16) & 0x3fff, 2827 pgsz_names[(mas1 >> 7) & 0x1f], 2828 mas1 & MAS1_IND ? 'I' : ' ', 2829 mas1 & MAS1_IPROT ? 'P' : ' ', 2830 mas1 & MAS1_TS ? '1' : '0'); 2831 printf(" %c%c%c%c%c%c%c", 2832 mas2 & MAS2_X0 ? 'a' : ' ', 2833 mas2 & MAS2_X1 ? 'v' : ' ', 2834 mas2 & MAS2_W ? 'w' : ' ', 2835 mas2 & MAS2_I ? 'i' : ' ', 2836 mas2 & MAS2_M ? 'm' : ' ', 2837 mas2 & MAS2_G ? 'g' : ' ', 2838 mas2 & MAS2_E ? 'e' : ' '); 2839 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull); 2840 if (mas1 & MAS1_IND) 2841 printf(" %s\n", 2842 pgsz_names[(mas7_mas3 >> 1) & 0x1f]); 2843 else 2844 printf(" U%c%c%c S%c%c%c\n", 2845 mas7_mas3 & MAS3_UX ? 'x' : ' ', 2846 mas7_mas3 & MAS3_UW ? 'w' : ' ', 2847 mas7_mas3 & MAS3_UR ? 'r' : ' ', 2848 mas7_mas3 & MAS3_SX ? 'x' : ' ', 2849 mas7_mas3 & MAS3_SW ? 'w' : ' ', 2850 mas7_mas3 & MAS3_SR ? 'r' : ' '); 2851 } 2852 } 2853 } 2854 #endif /* CONFIG_PPC_BOOK3E */ 2855 2856 static void xmon_init(int enable) 2857 { 2858 #ifdef CONFIG_PPC_ISERIES 2859 if (firmware_has_feature(FW_FEATURE_ISERIES)) 2860 return; 2861 #endif 2862 if (enable) { 2863 __debugger = xmon; 2864 __debugger_ipi = xmon_ipi; 2865 __debugger_bpt = xmon_bpt; 2866 __debugger_sstep = xmon_sstep; 2867 __debugger_iabr_match = xmon_iabr_match; 2868 __debugger_dabr_match = xmon_dabr_match; 2869 __debugger_fault_handler = xmon_fault_handler; 2870 } else { 2871 __debugger = NULL; 2872 __debugger_ipi = NULL; 2873 __debugger_bpt = NULL; 2874 __debugger_sstep = NULL; 2875 __debugger_iabr_match = NULL; 2876 __debugger_dabr_match = NULL; 2877 __debugger_fault_handler = NULL; 2878 } 2879 xmon_map_scc(); 2880 } 2881 2882 #ifdef CONFIG_MAGIC_SYSRQ 2883 static void sysrq_handle_xmon(int key, struct tty_struct *tty) 2884 { 2885 /* ensure xmon is enabled */ 2886 xmon_init(1); 2887 debugger(get_irq_regs()); 2888 } 2889 2890 static struct sysrq_key_op sysrq_xmon_op = 2891 { 2892 .handler = sysrq_handle_xmon, 2893 .help_msg = "Xmon", 2894 .action_msg = "Entering xmon", 2895 }; 2896 2897 static int __init setup_xmon_sysrq(void) 2898 { 2899 #ifdef CONFIG_PPC_ISERIES 2900 if (firmware_has_feature(FW_FEATURE_ISERIES)) 2901 return 0; 2902 #endif 2903 register_sysrq_key('x', &sysrq_xmon_op); 2904 return 0; 2905 } 2906 __initcall(setup_xmon_sysrq); 2907 #endif /* CONFIG_MAGIC_SYSRQ */ 2908 2909 static int __initdata xmon_early, xmon_off; 2910 2911 static int __init early_parse_xmon(char *p) 2912 { 2913 if (!p || strncmp(p, "early", 5) == 0) { 2914 /* just "xmon" is equivalent to "xmon=early" */ 2915 xmon_init(1); 2916 xmon_early = 1; 2917 } else if (strncmp(p, "on", 2) == 0) 2918 xmon_init(1); 2919 else if (strncmp(p, "off", 3) == 0) 2920 xmon_off = 1; 2921 else if (strncmp(p, "nobt", 4) == 0) 2922 xmon_no_auto_backtrace = 1; 2923 else 2924 return 1; 2925 2926 return 0; 2927 } 2928 early_param("xmon", early_parse_xmon); 2929 2930 void __init xmon_setup(void) 2931 { 2932 #ifdef CONFIG_XMON_DEFAULT 2933 if (!xmon_off) 2934 xmon_init(1); 2935 #endif 2936 if (xmon_early) 2937 debugger(NULL); 2938 } 2939 2940 #ifdef CONFIG_SPU_BASE 2941 2942 struct spu_info { 2943 struct spu *spu; 2944 u64 saved_mfc_sr1_RW; 2945 u32 saved_spu_runcntl_RW; 2946 unsigned long dump_addr; 2947 u8 stopped_ok; 2948 }; 2949 2950 #define XMON_NUM_SPUS 16 /* Enough for current hardware */ 2951 2952 static struct spu_info spu_info[XMON_NUM_SPUS]; 2953 2954 void xmon_register_spus(struct list_head *list) 2955 { 2956 struct spu *spu; 2957 2958 list_for_each_entry(spu, list, full_list) { 2959 if (spu->number >= XMON_NUM_SPUS) { 2960 WARN_ON(1); 2961 continue; 2962 } 2963 2964 spu_info[spu->number].spu = spu; 2965 spu_info[spu->number].stopped_ok = 0; 2966 spu_info[spu->number].dump_addr = (unsigned long) 2967 spu_info[spu->number].spu->local_store; 2968 } 2969 } 2970 2971 static void stop_spus(void) 2972 { 2973 struct spu *spu; 2974 int i; 2975 u64 tmp; 2976 2977 for (i = 0; i < XMON_NUM_SPUS; i++) { 2978 if (!spu_info[i].spu) 2979 continue; 2980 2981 if (setjmp(bus_error_jmp) == 0) { 2982 catch_memory_errors = 1; 2983 sync(); 2984 2985 spu = spu_info[i].spu; 2986 2987 spu_info[i].saved_spu_runcntl_RW = 2988 in_be32(&spu->problem->spu_runcntl_RW); 2989 2990 tmp = spu_mfc_sr1_get(spu); 2991 spu_info[i].saved_mfc_sr1_RW = tmp; 2992 2993 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK; 2994 spu_mfc_sr1_set(spu, tmp); 2995 2996 sync(); 2997 __delay(200); 2998 2999 spu_info[i].stopped_ok = 1; 3000 3001 printf("Stopped spu %.2d (was %s)\n", i, 3002 spu_info[i].saved_spu_runcntl_RW ? 3003 "running" : "stopped"); 3004 } else { 3005 catch_memory_errors = 0; 3006 printf("*** Error stopping spu %.2d\n", i); 3007 } 3008 catch_memory_errors = 0; 3009 } 3010 } 3011 3012 static void restart_spus(void) 3013 { 3014 struct spu *spu; 3015 int i; 3016 3017 for (i = 0; i < XMON_NUM_SPUS; i++) { 3018 if (!spu_info[i].spu) 3019 continue; 3020 3021 if (!spu_info[i].stopped_ok) { 3022 printf("*** Error, spu %d was not successfully stopped" 3023 ", not restarting\n", i); 3024 continue; 3025 } 3026 3027 if (setjmp(bus_error_jmp) == 0) { 3028 catch_memory_errors = 1; 3029 sync(); 3030 3031 spu = spu_info[i].spu; 3032 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW); 3033 out_be32(&spu->problem->spu_runcntl_RW, 3034 spu_info[i].saved_spu_runcntl_RW); 3035 3036 sync(); 3037 __delay(200); 3038 3039 printf("Restarted spu %.2d\n", i); 3040 } else { 3041 catch_memory_errors = 0; 3042 printf("*** Error restarting spu %.2d\n", i); 3043 } 3044 catch_memory_errors = 0; 3045 } 3046 } 3047 3048 #define DUMP_WIDTH 23 3049 #define DUMP_VALUE(format, field, value) \ 3050 do { \ 3051 if (setjmp(bus_error_jmp) == 0) { \ 3052 catch_memory_errors = 1; \ 3053 sync(); \ 3054 printf(" %-*s = "format"\n", DUMP_WIDTH, \ 3055 #field, value); \ 3056 sync(); \ 3057 __delay(200); \ 3058 } else { \ 3059 catch_memory_errors = 0; \ 3060 printf(" %-*s = *** Error reading field.\n", \ 3061 DUMP_WIDTH, #field); \ 3062 } \ 3063 catch_memory_errors = 0; \ 3064 } while (0) 3065 3066 #define DUMP_FIELD(obj, format, field) \ 3067 DUMP_VALUE(format, field, obj->field) 3068 3069 static void dump_spu_fields(struct spu *spu) 3070 { 3071 printf("Dumping spu fields at address %p:\n", spu); 3072 3073 DUMP_FIELD(spu, "0x%x", number); 3074 DUMP_FIELD(spu, "%s", name); 3075 DUMP_FIELD(spu, "0x%lx", local_store_phys); 3076 DUMP_FIELD(spu, "0x%p", local_store); 3077 DUMP_FIELD(spu, "0x%lx", ls_size); 3078 DUMP_FIELD(spu, "0x%x", node); 3079 DUMP_FIELD(spu, "0x%lx", flags); 3080 DUMP_FIELD(spu, "%d", class_0_pending); 3081 DUMP_FIELD(spu, "0x%lx", class_0_dar); 3082 DUMP_FIELD(spu, "0x%lx", class_1_dar); 3083 DUMP_FIELD(spu, "0x%lx", class_1_dsisr); 3084 DUMP_FIELD(spu, "0x%lx", irqs[0]); 3085 DUMP_FIELD(spu, "0x%lx", irqs[1]); 3086 DUMP_FIELD(spu, "0x%lx", irqs[2]); 3087 DUMP_FIELD(spu, "0x%x", slb_replace); 3088 DUMP_FIELD(spu, "%d", pid); 3089 DUMP_FIELD(spu, "0x%p", mm); 3090 DUMP_FIELD(spu, "0x%p", ctx); 3091 DUMP_FIELD(spu, "0x%p", rq); 3092 DUMP_FIELD(spu, "0x%p", timestamp); 3093 DUMP_FIELD(spu, "0x%lx", problem_phys); 3094 DUMP_FIELD(spu, "0x%p", problem); 3095 DUMP_VALUE("0x%x", problem->spu_runcntl_RW, 3096 in_be32(&spu->problem->spu_runcntl_RW)); 3097 DUMP_VALUE("0x%x", problem->spu_status_R, 3098 in_be32(&spu->problem->spu_status_R)); 3099 DUMP_VALUE("0x%x", problem->spu_npc_RW, 3100 in_be32(&spu->problem->spu_npc_RW)); 3101 DUMP_FIELD(spu, "0x%p", priv2); 3102 DUMP_FIELD(spu, "0x%p", pdata); 3103 } 3104 3105 int 3106 spu_inst_dump(unsigned long adr, long count, int praddr) 3107 { 3108 return generic_inst_dump(adr, count, praddr, print_insn_spu); 3109 } 3110 3111 static void dump_spu_ls(unsigned long num, int subcmd) 3112 { 3113 unsigned long offset, addr, ls_addr; 3114 3115 if (setjmp(bus_error_jmp) == 0) { 3116 catch_memory_errors = 1; 3117 sync(); 3118 ls_addr = (unsigned long)spu_info[num].spu->local_store; 3119 sync(); 3120 __delay(200); 3121 } else { 3122 catch_memory_errors = 0; 3123 printf("*** Error: accessing spu info for spu %d\n", num); 3124 return; 3125 } 3126 catch_memory_errors = 0; 3127 3128 if (scanhex(&offset)) 3129 addr = ls_addr + offset; 3130 else 3131 addr = spu_info[num].dump_addr; 3132 3133 if (addr >= ls_addr + LS_SIZE) { 3134 printf("*** Error: address outside of local store\n"); 3135 return; 3136 } 3137 3138 switch (subcmd) { 3139 case 'i': 3140 addr += spu_inst_dump(addr, 16, 1); 3141 last_cmd = "sdi\n"; 3142 break; 3143 default: 3144 prdump(addr, 64); 3145 addr += 64; 3146 last_cmd = "sd\n"; 3147 break; 3148 } 3149 3150 spu_info[num].dump_addr = addr; 3151 } 3152 3153 static int do_spu_cmd(void) 3154 { 3155 static unsigned long num = 0; 3156 int cmd, subcmd = 0; 3157 3158 cmd = inchar(); 3159 switch (cmd) { 3160 case 's': 3161 stop_spus(); 3162 break; 3163 case 'r': 3164 restart_spus(); 3165 break; 3166 case 'd': 3167 subcmd = inchar(); 3168 if (isxdigit(subcmd) || subcmd == '\n') 3169 termch = subcmd; 3170 case 'f': 3171 scanhex(&num); 3172 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) { 3173 printf("*** Error: invalid spu number\n"); 3174 return 0; 3175 } 3176 3177 switch (cmd) { 3178 case 'f': 3179 dump_spu_fields(spu_info[num].spu); 3180 break; 3181 default: 3182 dump_spu_ls(num, subcmd); 3183 break; 3184 } 3185 3186 break; 3187 default: 3188 return -1; 3189 } 3190 3191 return 0; 3192 } 3193 #else /* ! CONFIG_SPU_BASE */ 3194 static int do_spu_cmd(void) 3195 { 3196 return -1; 3197 } 3198 #endif 3199