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