root/arch/powerpc/xmon/xmon.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dump_opal_msglog
  2. xmon_is_locked_down
  3. xmon_is_locked_down
  4. sync
  5. store_inst
  6. cflush
  7. cinval
  8. write_ciabr
  9. set_ciabr
  10. disable_surveillance
  11. get_output_lock
  12. release_output_lock
  13. cpus_are_in_xmon
  14. wait_for_other_cpus
  15. get_output_lock
  16. release_output_lock
  17. unrecoverable_excp
  18. xmon_core
  19. xmon
  20. xmon_irq
  21. xmon_bpt
  22. xmon_sstep
  23. xmon_break_match
  24. xmon_iabr_match
  25. xmon_ipi
  26. xmon_fault_handler
  27. force_enable_xmon
  28. at_breakpoint
  29. in_breakpoint_table
  30. new_breakpoint
  31. insert_bpts
  32. insert_cpu_bpts
  33. remove_bpts
  34. remove_cpu_bpts
  35. show_uptime
  36. set_lpp_cmd
  37. cmds
  38. do_step
  39. do_step
  40. bootcmds
  41. cpu_cmd
  42. csum
  43. check_bp_loc
  44. bpt_cmds
  45. getvecname
  46. get_function_bounds
  47. xmon_show_stack
  48. backtrace
  49. print_bug_trap
  50. excprint
  51. prregs
  52. cacheflush
  53. read_spr
  54. write_spr
  55. dump_206_sprs
  56. dump_207_sprs
  57. dump_300_sprs
  58. dump_one_spr
  59. super_regs
  60. mread
  61. mwrite
  62. handle_fault
  63. byterev
  64. memex
  65. bsesc
  66. xmon_rawdump
  67. dump_tracing
  68. dump_one_paca
  69. dump_all_pacas
  70. dump_pacas
  71. dump_one_xive
  72. dump_all_xives
  73. dump_one_xive_irq
  74. dump_all_xive_irq
  75. dump_xives
  76. dump_by_size
  77. dump
  78. prdump
  79. generic_inst_dump
  80. ppc_inst_dump
  81. print_address
  82. dump_log_buf
  83. dump_opal_msglog
  84. memops
  85. memdiffs
  86. memlocate
  87. memzcan
  88. show_task
  89. format_pte
  90. show_pte
  91. show_pte
  92. show_tasks
  93. proccall
  94. skipbl
  95. scanhex
  96. scannl
  97. hexdigit
  98. getstring
  99. flush_input
  100. inchar
  101. take_input
  102. symbol_lookup
  103. xmon_print_symbol
  104. dump_segments
  105. dump_segments
  106. dump_tlb_44x
  107. dump_tlb_book3e
  108. xmon_init
  109. sysrq_handle_xmon
  110. setup_xmon_sysrq
  111. clear_all_bpt
  112. xmon_dbgfs_set
  113. xmon_dbgfs_get
  114. setup_xmon_dbgfs
  115. early_parse_xmon
  116. xmon_setup
  117. xmon_register_spus
  118. stop_spus
  119. restart_spus
  120. dump_spu_fields
  121. spu_inst_dump
  122. dump_spu_ls
  123. do_spu_cmd
  124. do_spu_cmd

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Routines providing a simple monitor for use on the PowerMac.
   4  *
   5  * Copyright (C) 1996-2005 Paul Mackerras.
   6  * Copyright (C) 2001 PPC64 Team, IBM Corp
   7  * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
   8  */
   9 
  10 #include <linux/kernel.h>
  11 #include <linux/errno.h>
  12 #include <linux/sched/signal.h>
  13 #include <linux/smp.h>
  14 #include <linux/mm.h>
  15 #include <linux/reboot.h>
  16 #include <linux/delay.h>
  17 #include <linux/kallsyms.h>
  18 #include <linux/kmsg_dump.h>
  19 #include <linux/cpumask.h>
  20 #include <linux/export.h>
  21 #include <linux/sysrq.h>
  22 #include <linux/interrupt.h>
  23 #include <linux/irq.h>
  24 #include <linux/bug.h>
  25 #include <linux/nmi.h>
  26 #include <linux/ctype.h>
  27 #include <linux/highmem.h>
  28 #include <linux/security.h>
  29 
  30 #include <asm/debugfs.h>
  31 #include <asm/ptrace.h>
  32 #include <asm/smp.h>
  33 #include <asm/string.h>
  34 #include <asm/prom.h>
  35 #include <asm/machdep.h>
  36 #include <asm/xmon.h>
  37 #include <asm/processor.h>
  38 #include <asm/pgtable.h>
  39 #include <asm/mmu.h>
  40 #include <asm/mmu_context.h>
  41 #include <asm/plpar_wrappers.h>
  42 #include <asm/cputable.h>
  43 #include <asm/rtas.h>
  44 #include <asm/sstep.h>
  45 #include <asm/irq_regs.h>
  46 #include <asm/spu.h>
  47 #include <asm/spu_priv1.h>
  48 #include <asm/setjmp.h>
  49 #include <asm/reg.h>
  50 #include <asm/debug.h>
  51 #include <asm/hw_breakpoint.h>
  52 #include <asm/xive.h>
  53 #include <asm/opal.h>
  54 #include <asm/firmware.h>
  55 #include <asm/code-patching.h>
  56 #include <asm/sections.h>
  57 
  58 #ifdef CONFIG_PPC64
  59 #include <asm/hvcall.h>
  60 #include <asm/paca.h>
  61 #endif
  62 
  63 #include "nonstdio.h"
  64 #include "dis-asm.h"
  65 
  66 #ifdef CONFIG_SMP
  67 static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
  68 static unsigned long xmon_taken = 1;
  69 static int xmon_owner;
  70 static int xmon_gate;
  71 #else
  72 #define xmon_owner 0
  73 #endif /* CONFIG_SMP */
  74 
  75 #ifdef CONFIG_PPC_PSERIES
  76 static int set_indicator_token = RTAS_UNKNOWN_SERVICE;
  77 #endif
  78 static unsigned long in_xmon __read_mostly = 0;
  79 static int xmon_on = IS_ENABLED(CONFIG_XMON_DEFAULT);
  80 static bool xmon_is_ro = IS_ENABLED(CONFIG_XMON_DEFAULT_RO_MODE);
  81 
  82 static unsigned long adrs;
  83 static int size = 1;
  84 #define MAX_DUMP (128 * 1024)
  85 static unsigned long ndump = 64;
  86 static unsigned long nidump = 16;
  87 static unsigned long ncsum = 4096;
  88 static int termch;
  89 static char tmpstr[128];
  90 static int tracing_enabled;
  91 
  92 static long bus_error_jmp[JMP_BUF_LEN];
  93 static int catch_memory_errors;
  94 static int catch_spr_faults;
  95 static long *xmon_fault_jmp[NR_CPUS];
  96 
  97 /* Breakpoint stuff */
  98 struct bpt {
  99         unsigned long   address;
 100         unsigned int    instr[2];
 101         atomic_t        ref_count;
 102         int             enabled;
 103         unsigned long   pad;
 104 };
 105 
 106 /* Bits in bpt.enabled */
 107 #define BP_CIABR        1
 108 #define BP_TRAP         2
 109 #define BP_DABR         4
 110 
 111 #define NBPTS   256
 112 static struct bpt bpts[NBPTS];
 113 static struct bpt dabr;
 114 static struct bpt *iabr;
 115 static unsigned bpinstr = 0x7fe00008;   /* trap */
 116 
 117 #define BP_NUM(bp)      ((bp) - bpts + 1)
 118 
 119 /* Prototypes */
 120 static int cmds(struct pt_regs *);
 121 static int mread(unsigned long, void *, int);
 122 static int mwrite(unsigned long, void *, int);
 123 static int handle_fault(struct pt_regs *);
 124 static void byterev(unsigned char *, int);
 125 static void memex(void);
 126 static int bsesc(void);
 127 static void dump(void);
 128 static void show_pte(unsigned long);
 129 static void prdump(unsigned long, long);
 130 static int ppc_inst_dump(unsigned long, long, int);
 131 static void dump_log_buf(void);
 132 
 133 #ifdef CONFIG_PPC_POWERNV
 134 static void dump_opal_msglog(void);
 135 #else
 136 static inline void dump_opal_msglog(void)
 137 {
 138         printf("Machine is not running OPAL firmware.\n");
 139 }
 140 #endif
 141 
 142 static void backtrace(struct pt_regs *);
 143 static void excprint(struct pt_regs *);
 144 static void prregs(struct pt_regs *);
 145 static void memops(int);
 146 static void memlocate(void);
 147 static void memzcan(void);
 148 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
 149 int skipbl(void);
 150 int scanhex(unsigned long *valp);
 151 static void scannl(void);
 152 static int hexdigit(int);
 153 void getstring(char *, int);
 154 static void flush_input(void);
 155 static int inchar(void);
 156 static void take_input(char *);
 157 static int  read_spr(int, unsigned long *);
 158 static void write_spr(int, unsigned long);
 159 static void super_regs(void);
 160 static void remove_bpts(void);
 161 static void insert_bpts(void);
 162 static void remove_cpu_bpts(void);
 163 static void insert_cpu_bpts(void);
 164 static struct bpt *at_breakpoint(unsigned long pc);
 165 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
 166 static int  do_step(struct pt_regs *);
 167 static void bpt_cmds(void);
 168 static void cacheflush(void);
 169 static int  cpu_cmd(void);
 170 static void csum(void);
 171 static void bootcmds(void);
 172 static void proccall(void);
 173 static void show_tasks(void);
 174 void dump_segments(void);
 175 static void symbol_lookup(void);
 176 static void xmon_show_stack(unsigned long sp, unsigned long lr,
 177                             unsigned long pc);
 178 static void xmon_print_symbol(unsigned long address, const char *mid,
 179                               const char *after);
 180 static const char *getvecname(unsigned long vec);
 181 
 182 static int do_spu_cmd(void);
 183 
 184 #ifdef CONFIG_44x
 185 static void dump_tlb_44x(void);
 186 #endif
 187 #ifdef CONFIG_PPC_BOOK3E
 188 static void dump_tlb_book3e(void);
 189 #endif
 190 
 191 static void clear_all_bpt(void);
 192 
 193 #ifdef CONFIG_PPC64
 194 #define REG             "%.16lx"
 195 #else
 196 #define REG             "%.8lx"
 197 #endif
 198 
 199 #ifdef __LITTLE_ENDIAN__
 200 #define GETWORD(v)      (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
 201 #else
 202 #define GETWORD(v)      (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
 203 #endif
 204 
 205 static const char *xmon_ro_msg = "Operation disabled: xmon in read-only mode\n";
 206 
 207 static char *help_string = "\
 208 Commands:\n\
 209   b     show breakpoints\n\
 210   bd    set data breakpoint\n\
 211   bi    set instruction breakpoint\n\
 212   bc    clear breakpoint\n"
 213 #ifdef CONFIG_SMP
 214   "\
 215   c     print cpus stopped in xmon\n\
 216   c#    try to switch to cpu number h (in hex)\n"
 217 #endif
 218   "\
 219   C     checksum\n\
 220   d     dump bytes\n\
 221   d1    dump 1 byte values\n\
 222   d2    dump 2 byte values\n\
 223   d4    dump 4 byte values\n\
 224   d8    dump 8 byte values\n\
 225   di    dump instructions\n\
 226   df    dump float values\n\
 227   dd    dump double values\n\
 228   dl    dump the kernel log buffer\n"
 229 #ifdef CONFIG_PPC_POWERNV
 230   "\
 231   do    dump the OPAL message log\n"
 232 #endif
 233 #ifdef CONFIG_PPC64
 234   "\
 235   dp[#] dump paca for current cpu, or cpu #\n\
 236   dpa   dump paca for all possible cpus\n"
 237 #endif
 238   "\
 239   dr    dump stream of raw bytes\n\
 240   dv    dump virtual address translation \n\
 241   dt    dump the tracing buffers (uses printk)\n\
 242   dtc   dump the tracing buffers for current CPU (uses printk)\n\
 243 "
 244 #ifdef CONFIG_PPC_POWERNV
 245 "  dx#   dump xive on CPU #\n\
 246   dxi#  dump xive irq state #\n\
 247   dxa   dump xive on all CPUs\n"
 248 #endif
 249 "  e    print exception information\n\
 250   f     flush cache\n\
 251   la    lookup symbol+offset of specified address\n\
 252   ls    lookup address of specified symbol\n\
 253   lp s [#]      lookup address of percpu symbol s for current cpu, or cpu #\n\
 254   m     examine/change memory\n\
 255   mm    move a block of memory\n\
 256   ms    set a block of memory\n\
 257   md    compare two blocks of memory\n\
 258   ml    locate a block of memory\n\
 259   mz    zero a block of memory\n\
 260   mi    show information about memory allocation\n\
 261   p     call a procedure\n\
 262   P     list processes/tasks\n\
 263   r     print registers\n\
 264   s     single step\n"
 265 #ifdef CONFIG_SPU_BASE
 266 "  ss   stop execution on all spus\n\
 267   sr    restore execution on stopped spus\n\
 268   sf  # dump spu fields for spu # (in hex)\n\
 269   sd  # dump spu local store for spu # (in hex)\n\
 270   sdi # disassemble spu local store for spu # (in hex)\n"
 271 #endif
 272 "  S    print special registers\n\
 273   Sa    print all SPRs\n\
 274   Sr #  read SPR #\n\
 275   Sw #v write v to SPR #\n\
 276   t     print backtrace\n\
 277   x     exit monitor and recover\n\
 278   X     exit monitor and don't recover\n"
 279 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
 280 "  u    dump segment table or SLB\n"
 281 #elif defined(CONFIG_PPC_BOOK3S_32)
 282 "  u    dump segment registers\n"
 283 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
 284 "  u    dump TLB\n"
 285 #endif
 286 "  U    show uptime information\n"
 287 "  ?    help\n"
 288 "  # n  limit output to n lines per page (for dp, dpa, dl)\n"
 289 "  zr   reboot\n"
 290 "  zh   halt\n"
 291 ;
 292 
 293 #ifdef CONFIG_SECURITY
 294 static bool xmon_is_locked_down(void)
 295 {
 296         static bool lockdown;
 297 
 298         if (!lockdown) {
 299                 lockdown = !!security_locked_down(LOCKDOWN_XMON_RW);
 300                 if (lockdown) {
 301                         printf("xmon: Disabled due to kernel lockdown\n");
 302                         xmon_is_ro = true;
 303                 }
 304         }
 305 
 306         if (!xmon_is_ro) {
 307                 xmon_is_ro = !!security_locked_down(LOCKDOWN_XMON_WR);
 308                 if (xmon_is_ro)
 309                         printf("xmon: Read-only due to kernel lockdown\n");
 310         }
 311 
 312         return lockdown;
 313 }
 314 #else /* CONFIG_SECURITY */
 315 static inline bool xmon_is_locked_down(void)
 316 {
 317         return false;
 318 }
 319 #endif
 320 
 321 static struct pt_regs *xmon_regs;
 322 
 323 static inline void sync(void)
 324 {
 325         asm volatile("sync; isync");
 326 }
 327 
 328 static inline void store_inst(void *p)
 329 {
 330         asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
 331 }
 332 
 333 static inline void cflush(void *p)
 334 {
 335         asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
 336 }
 337 
 338 static inline void cinval(void *p)
 339 {
 340         asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
 341 }
 342 
 343 /**
 344  * write_ciabr() - write the CIABR SPR
 345  * @ciabr:      The value to write.
 346  *
 347  * This function writes a value to the CIARB register either directly
 348  * through mtspr instruction if the kernel is in HV privilege mode or
 349  * call a hypervisor function to achieve the same in case the kernel
 350  * is in supervisor privilege mode.
 351  */
 352 static void write_ciabr(unsigned long ciabr)
 353 {
 354         if (!cpu_has_feature(CPU_FTR_ARCH_207S))
 355                 return;
 356 
 357         if (cpu_has_feature(CPU_FTR_HVMODE)) {
 358                 mtspr(SPRN_CIABR, ciabr);
 359                 return;
 360         }
 361         plpar_set_ciabr(ciabr);
 362 }
 363 
 364 /**
 365  * set_ciabr() - set the CIABR
 366  * @addr:       The value to set.
 367  *
 368  * This function sets the correct privilege value into the the HW
 369  * breakpoint address before writing it up in the CIABR register.
 370  */
 371 static void set_ciabr(unsigned long addr)
 372 {
 373         addr &= ~CIABR_PRIV;
 374 
 375         if (cpu_has_feature(CPU_FTR_HVMODE))
 376                 addr |= CIABR_PRIV_HYPER;
 377         else
 378                 addr |= CIABR_PRIV_SUPER;
 379         write_ciabr(addr);
 380 }
 381 
 382 /*
 383  * Disable surveillance (the service processor watchdog function)
 384  * while we are in xmon.
 385  * XXX we should re-enable it when we leave. :)
 386  */
 387 #define SURVEILLANCE_TOKEN      9000
 388 
 389 static inline void disable_surveillance(void)
 390 {
 391 #ifdef CONFIG_PPC_PSERIES
 392         /* Since this can't be a module, args should end up below 4GB. */
 393         static struct rtas_args args;
 394 
 395         /*
 396          * At this point we have got all the cpus we can into
 397          * xmon, so there is hopefully no other cpu calling RTAS
 398          * at the moment, even though we don't take rtas.lock.
 399          * If we did try to take rtas.lock there would be a
 400          * real possibility of deadlock.
 401          */
 402         if (set_indicator_token == RTAS_UNKNOWN_SERVICE)
 403                 return;
 404 
 405         rtas_call_unlocked(&args, set_indicator_token, 3, 1, NULL,
 406                            SURVEILLANCE_TOKEN, 0, 0);
 407 
 408 #endif /* CONFIG_PPC_PSERIES */
 409 }
 410 
 411 #ifdef CONFIG_SMP
 412 static int xmon_speaker;
 413 
 414 static void get_output_lock(void)
 415 {
 416         int me = smp_processor_id() + 0x100;
 417         int last_speaker = 0, prev;
 418         long timeout;
 419 
 420         if (xmon_speaker == me)
 421                 return;
 422 
 423         for (;;) {
 424                 last_speaker = cmpxchg(&xmon_speaker, 0, me);
 425                 if (last_speaker == 0)
 426                         return;
 427 
 428                 /*
 429                  * Wait a full second for the lock, we might be on a slow
 430                  * console, but check every 100us.
 431                  */
 432                 timeout = 10000;
 433                 while (xmon_speaker == last_speaker) {
 434                         if (--timeout > 0) {
 435                                 udelay(100);
 436                                 continue;
 437                         }
 438 
 439                         /* hostile takeover */
 440                         prev = cmpxchg(&xmon_speaker, last_speaker, me);
 441                         if (prev == last_speaker)
 442                                 return;
 443                         break;
 444                 }
 445         }
 446 }
 447 
 448 static void release_output_lock(void)
 449 {
 450         xmon_speaker = 0;
 451 }
 452 
 453 int cpus_are_in_xmon(void)
 454 {
 455         return !cpumask_empty(&cpus_in_xmon);
 456 }
 457 
 458 static bool wait_for_other_cpus(int ncpus)
 459 {
 460         unsigned long timeout;
 461 
 462         /* We wait for 2s, which is a metric "little while" */
 463         for (timeout = 20000; timeout != 0; --timeout) {
 464                 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
 465                         return true;
 466                 udelay(100);
 467                 barrier();
 468         }
 469 
 470         return false;
 471 }
 472 #else /* CONFIG_SMP */
 473 static inline void get_output_lock(void) {}
 474 static inline void release_output_lock(void) {}
 475 #endif
 476 
 477 static inline int unrecoverable_excp(struct pt_regs *regs)
 478 {
 479 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
 480         /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
 481         return 0;
 482 #else
 483         return ((regs->msr & MSR_RI) == 0);
 484 #endif
 485 }
 486 
 487 static int xmon_core(struct pt_regs *regs, int fromipi)
 488 {
 489         int cmd = 0;
 490         struct bpt *bp;
 491         long recurse_jmp[JMP_BUF_LEN];
 492         bool locked_down;
 493         unsigned long offset;
 494         unsigned long flags;
 495 #ifdef CONFIG_SMP
 496         int cpu;
 497         int secondary;
 498 #endif
 499 
 500         local_irq_save(flags);
 501         hard_irq_disable();
 502 
 503         locked_down = xmon_is_locked_down();
 504 
 505         if (!fromipi) {
 506                 tracing_enabled = tracing_is_on();
 507                 tracing_off();
 508         }
 509 
 510         bp = in_breakpoint_table(regs->nip, &offset);
 511         if (bp != NULL) {
 512                 regs->nip = bp->address + offset;
 513                 atomic_dec(&bp->ref_count);
 514         }
 515 
 516         remove_cpu_bpts();
 517 
 518 #ifdef CONFIG_SMP
 519         cpu = smp_processor_id();
 520         if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
 521                 /*
 522                  * We catch SPR read/write faults here because the 0x700, 0xf60
 523                  * etc. handlers don't call debugger_fault_handler().
 524                  */
 525                 if (catch_spr_faults)
 526                         longjmp(bus_error_jmp, 1);
 527                 get_output_lock();
 528                 excprint(regs);
 529                 printf("cpu 0x%x: Exception %lx %s in xmon, "
 530                        "returning to main loop\n",
 531                        cpu, regs->trap, getvecname(TRAP(regs)));
 532                 release_output_lock();
 533                 longjmp(xmon_fault_jmp[cpu], 1);
 534         }
 535 
 536         if (setjmp(recurse_jmp) != 0) {
 537                 if (!in_xmon || !xmon_gate) {
 538                         get_output_lock();
 539                         printf("xmon: WARNING: bad recursive fault "
 540                                "on cpu 0x%x\n", cpu);
 541                         release_output_lock();
 542                         goto waiting;
 543                 }
 544                 secondary = !(xmon_taken && cpu == xmon_owner);
 545                 goto cmdloop;
 546         }
 547 
 548         xmon_fault_jmp[cpu] = recurse_jmp;
 549 
 550         bp = NULL;
 551         if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
 552                 bp = at_breakpoint(regs->nip);
 553         if (bp || unrecoverable_excp(regs))
 554                 fromipi = 0;
 555 
 556         if (!fromipi) {
 557                 get_output_lock();
 558                 if (!locked_down)
 559                         excprint(regs);
 560                 if (bp) {
 561                         printf("cpu 0x%x stopped at breakpoint 0x%tx (",
 562                                cpu, BP_NUM(bp));
 563                         xmon_print_symbol(regs->nip, " ", ")\n");
 564                 }
 565                 if (unrecoverable_excp(regs))
 566                         printf("WARNING: exception is not recoverable, "
 567                                "can't continue\n");
 568                 release_output_lock();
 569         }
 570 
 571         cpumask_set_cpu(cpu, &cpus_in_xmon);
 572 
 573  waiting:
 574         secondary = 1;
 575         spin_begin();
 576         while (secondary && !xmon_gate) {
 577                 if (in_xmon == 0) {
 578                         if (fromipi) {
 579                                 spin_end();
 580                                 goto leave;
 581                         }
 582                         secondary = test_and_set_bit(0, &in_xmon);
 583                 }
 584                 spin_cpu_relax();
 585                 touch_nmi_watchdog();
 586         }
 587         spin_end();
 588 
 589         if (!secondary && !xmon_gate) {
 590                 /* we are the first cpu to come in */
 591                 /* interrupt other cpu(s) */
 592                 int ncpus = num_online_cpus();
 593 
 594                 xmon_owner = cpu;
 595                 mb();
 596                 if (ncpus > 1) {
 597                         /*
 598                          * A system reset (trap == 0x100) can be triggered on
 599                          * all CPUs, so when we come in via 0x100 try waiting
 600                          * for the other CPUs to come in before we send the
 601                          * debugger break (IPI). This is similar to
 602                          * crash_kexec_secondary().
 603                          */
 604                         if (TRAP(regs) != 0x100 || !wait_for_other_cpus(ncpus))
 605                                 smp_send_debugger_break();
 606 
 607                         wait_for_other_cpus(ncpus);
 608                 }
 609                 remove_bpts();
 610                 disable_surveillance();
 611 
 612                 if (!locked_down) {
 613                         /* for breakpoint or single step, print curr insn */
 614                         if (bp || TRAP(regs) == 0xd00)
 615                                 ppc_inst_dump(regs->nip, 1, 0);
 616                         printf("enter ? for help\n");
 617                 }
 618 
 619                 mb();
 620                 xmon_gate = 1;
 621                 barrier();
 622                 touch_nmi_watchdog();
 623         }
 624 
 625  cmdloop:
 626         while (in_xmon) {
 627                 if (secondary) {
 628                         spin_begin();
 629                         if (cpu == xmon_owner) {
 630                                 if (!test_and_set_bit(0, &xmon_taken)) {
 631                                         secondary = 0;
 632                                         spin_end();
 633                                         continue;
 634                                 }
 635                                 /* missed it */
 636                                 while (cpu == xmon_owner)
 637                                         spin_cpu_relax();
 638                         }
 639                         spin_cpu_relax();
 640                         touch_nmi_watchdog();
 641                 } else {
 642                         if (!locked_down)
 643                                 cmd = cmds(regs);
 644                         if (locked_down || cmd != 0) {
 645                                 /* exiting xmon */
 646                                 insert_bpts();
 647                                 xmon_gate = 0;
 648                                 wmb();
 649                                 in_xmon = 0;
 650                                 break;
 651                         }
 652                         /* have switched to some other cpu */
 653                         secondary = 1;
 654                 }
 655         }
 656  leave:
 657         cpumask_clear_cpu(cpu, &cpus_in_xmon);
 658         xmon_fault_jmp[cpu] = NULL;
 659 #else
 660         /* UP is simple... */
 661         if (in_xmon) {
 662                 printf("Exception %lx %s in xmon, returning to main loop\n",
 663                        regs->trap, getvecname(TRAP(regs)));
 664                 longjmp(xmon_fault_jmp[0], 1);
 665         }
 666         if (setjmp(recurse_jmp) == 0) {
 667                 xmon_fault_jmp[0] = recurse_jmp;
 668                 in_xmon = 1;
 669 
 670                 excprint(regs);
 671                 bp = at_breakpoint(regs->nip);
 672                 if (bp) {
 673                         printf("Stopped at breakpoint %tx (", BP_NUM(bp));
 674                         xmon_print_symbol(regs->nip, " ", ")\n");
 675                 }
 676                 if (unrecoverable_excp(regs))
 677                         printf("WARNING: exception is not recoverable, "
 678                                "can't continue\n");
 679                 remove_bpts();
 680                 disable_surveillance();
 681                 if (!locked_down) {
 682                         /* for breakpoint or single step, print current insn */
 683                         if (bp || TRAP(regs) == 0xd00)
 684                                 ppc_inst_dump(regs->nip, 1, 0);
 685                         printf("enter ? for help\n");
 686                 }
 687         }
 688 
 689         if (!locked_down)
 690                 cmd = cmds(regs);
 691 
 692         insert_bpts();
 693         in_xmon = 0;
 694 #endif
 695 
 696 #ifdef CONFIG_BOOKE
 697         if (regs->msr & MSR_DE) {
 698                 bp = at_breakpoint(regs->nip);
 699                 if (bp != NULL) {
 700                         regs->nip = (unsigned long) &bp->instr[0];
 701                         atomic_inc(&bp->ref_count);
 702                 }
 703         }
 704 #else
 705         if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
 706                 bp = at_breakpoint(regs->nip);
 707                 if (bp != NULL) {
 708                         int stepped = emulate_step(regs, bp->instr[0]);
 709                         if (stepped == 0) {
 710                                 regs->nip = (unsigned long) &bp->instr[0];
 711                                 atomic_inc(&bp->ref_count);
 712                         } else if (stepped < 0) {
 713                                 printf("Couldn't single-step %s instruction\n",
 714                                     (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
 715                         }
 716                 }
 717         }
 718 #endif
 719         if (locked_down)
 720                 clear_all_bpt();
 721         else
 722                 insert_cpu_bpts();
 723 
 724         touch_nmi_watchdog();
 725         local_irq_restore(flags);
 726 
 727         return cmd != 'X' && cmd != EOF;
 728 }
 729 
 730 int xmon(struct pt_regs *excp)
 731 {
 732         struct pt_regs regs;
 733 
 734         if (excp == NULL) {
 735                 ppc_save_regs(&regs);
 736                 excp = &regs;
 737         }
 738 
 739         return xmon_core(excp, 0);
 740 }
 741 EXPORT_SYMBOL(xmon);
 742 
 743 irqreturn_t xmon_irq(int irq, void *d)
 744 {
 745         unsigned long flags;
 746         local_irq_save(flags);
 747         printf("Keyboard interrupt\n");
 748         xmon(get_irq_regs());
 749         local_irq_restore(flags);
 750         return IRQ_HANDLED;
 751 }
 752 
 753 static int xmon_bpt(struct pt_regs *regs)
 754 {
 755         struct bpt *bp;
 756         unsigned long offset;
 757 
 758         if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
 759                 return 0;
 760 
 761         /* Are we at the trap at bp->instr[1] for some bp? */
 762         bp = in_breakpoint_table(regs->nip, &offset);
 763         if (bp != NULL && offset == 4) {
 764                 regs->nip = bp->address + 4;
 765                 atomic_dec(&bp->ref_count);
 766                 return 1;
 767         }
 768 
 769         /* Are we at a breakpoint? */
 770         bp = at_breakpoint(regs->nip);
 771         if (!bp)
 772                 return 0;
 773 
 774         xmon_core(regs, 0);
 775 
 776         return 1;
 777 }
 778 
 779 static int xmon_sstep(struct pt_regs *regs)
 780 {
 781         if (user_mode(regs))
 782                 return 0;
 783         xmon_core(regs, 0);
 784         return 1;
 785 }
 786 
 787 static int xmon_break_match(struct pt_regs *regs)
 788 {
 789         if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
 790                 return 0;
 791         if (dabr.enabled == 0)
 792                 return 0;
 793         xmon_core(regs, 0);
 794         return 1;
 795 }
 796 
 797 static int xmon_iabr_match(struct pt_regs *regs)
 798 {
 799         if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
 800                 return 0;
 801         if (iabr == NULL)
 802                 return 0;
 803         xmon_core(regs, 0);
 804         return 1;
 805 }
 806 
 807 static int xmon_ipi(struct pt_regs *regs)
 808 {
 809 #ifdef CONFIG_SMP
 810         if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
 811                 xmon_core(regs, 1);
 812 #endif
 813         return 0;
 814 }
 815 
 816 static int xmon_fault_handler(struct pt_regs *regs)
 817 {
 818         struct bpt *bp;
 819         unsigned long offset;
 820 
 821         if (in_xmon && catch_memory_errors)
 822                 handle_fault(regs);     /* doesn't return */
 823 
 824         if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
 825                 bp = in_breakpoint_table(regs->nip, &offset);
 826                 if (bp != NULL) {
 827                         regs->nip = bp->address + offset;
 828                         atomic_dec(&bp->ref_count);
 829                 }
 830         }
 831 
 832         return 0;
 833 }
 834 
 835 /* Force enable xmon if not already enabled */
 836 static inline void force_enable_xmon(void)
 837 {
 838         /* Enable xmon hooks if needed */
 839         if (!xmon_on) {
 840                 printf("xmon: Enabling debugger hooks\n");
 841                 xmon_on = 1;
 842         }
 843 }
 844 
 845 static struct bpt *at_breakpoint(unsigned long pc)
 846 {
 847         int i;
 848         struct bpt *bp;
 849 
 850         bp = bpts;
 851         for (i = 0; i < NBPTS; ++i, ++bp)
 852                 if (bp->enabled && pc == bp->address)
 853                         return bp;
 854         return NULL;
 855 }
 856 
 857 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
 858 {
 859         unsigned long off;
 860 
 861         off = nip - (unsigned long) bpts;
 862         if (off >= sizeof(bpts))
 863                 return NULL;
 864         off %= sizeof(struct bpt);
 865         if (off != offsetof(struct bpt, instr[0])
 866             && off != offsetof(struct bpt, instr[1]))
 867                 return NULL;
 868         *offp = off - offsetof(struct bpt, instr[0]);
 869         return (struct bpt *) (nip - off);
 870 }
 871 
 872 static struct bpt *new_breakpoint(unsigned long a)
 873 {
 874         struct bpt *bp;
 875 
 876         a &= ~3UL;
 877         bp = at_breakpoint(a);
 878         if (bp)
 879                 return bp;
 880 
 881         for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
 882                 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
 883                         bp->address = a;
 884                         bp->instr[1] = bpinstr;
 885                         store_inst(&bp->instr[1]);
 886                         return bp;
 887                 }
 888         }
 889 
 890         printf("Sorry, no free breakpoints.  Please clear one first.\n");
 891         return NULL;
 892 }
 893 
 894 static void insert_bpts(void)
 895 {
 896         int i;
 897         struct bpt *bp;
 898 
 899         bp = bpts;
 900         for (i = 0; i < NBPTS; ++i, ++bp) {
 901                 if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
 902                         continue;
 903                 if (mread(bp->address, &bp->instr[0], 4) != 4) {
 904                         printf("Couldn't read instruction at %lx, "
 905                                "disabling breakpoint there\n", bp->address);
 906                         bp->enabled = 0;
 907                         continue;
 908                 }
 909                 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
 910                         printf("Breakpoint at %lx is on an mtmsrd or rfid "
 911                                "instruction, disabling it\n", bp->address);
 912                         bp->enabled = 0;
 913                         continue;
 914                 }
 915                 store_inst(&bp->instr[0]);
 916                 if (bp->enabled & BP_CIABR)
 917                         continue;
 918                 if (patch_instruction((unsigned int *)bp->address,
 919                                                         bpinstr) != 0) {
 920                         printf("Couldn't write instruction at %lx, "
 921                                "disabling breakpoint there\n", bp->address);
 922                         bp->enabled &= ~BP_TRAP;
 923                         continue;
 924                 }
 925                 store_inst((void *)bp->address);
 926         }
 927 }
 928 
 929 static void insert_cpu_bpts(void)
 930 {
 931         struct arch_hw_breakpoint brk;
 932 
 933         if (dabr.enabled) {
 934                 brk.address = dabr.address;
 935                 brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
 936                 brk.len = 8;
 937                 __set_breakpoint(&brk);
 938         }
 939 
 940         if (iabr)
 941                 set_ciabr(iabr->address);
 942 }
 943 
 944 static void remove_bpts(void)
 945 {
 946         int i;
 947         struct bpt *bp;
 948         unsigned instr;
 949 
 950         bp = bpts;
 951         for (i = 0; i < NBPTS; ++i, ++bp) {
 952                 if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
 953                         continue;
 954                 if (mread(bp->address, &instr, 4) == 4
 955                     && instr == bpinstr
 956                     && patch_instruction(
 957                         (unsigned int *)bp->address, bp->instr[0]) != 0)
 958                         printf("Couldn't remove breakpoint at %lx\n",
 959                                bp->address);
 960                 else
 961                         store_inst((void *)bp->address);
 962         }
 963 }
 964 
 965 static void remove_cpu_bpts(void)
 966 {
 967         hw_breakpoint_disable();
 968         write_ciabr(0);
 969 }
 970 
 971 /* Based on uptime_proc_show(). */
 972 static void
 973 show_uptime(void)
 974 {
 975         struct timespec64 uptime;
 976 
 977         if (setjmp(bus_error_jmp) == 0) {
 978                 catch_memory_errors = 1;
 979                 sync();
 980 
 981                 ktime_get_coarse_boottime_ts64(&uptime);
 982                 printf("Uptime: %lu.%.2lu seconds\n", (unsigned long)uptime.tv_sec,
 983                         ((unsigned long)uptime.tv_nsec / (NSEC_PER_SEC/100)));
 984 
 985                 sync();
 986                 __delay(200);                                           \
 987         }
 988         catch_memory_errors = 0;
 989 }
 990 
 991 static void set_lpp_cmd(void)
 992 {
 993         unsigned long lpp;
 994 
 995         if (!scanhex(&lpp)) {
 996                 printf("Invalid number.\n");
 997                 lpp = 0;
 998         }
 999         xmon_set_pagination_lpp(lpp);
1000 }
1001 /* Command interpreting routine */
1002 static char *last_cmd;
1003 
1004 static int
1005 cmds(struct pt_regs *excp)
1006 {
1007         int cmd = 0;
1008 
1009         last_cmd = NULL;
1010         xmon_regs = excp;
1011 
1012         xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1013 
1014         for(;;) {
1015 #ifdef CONFIG_SMP
1016                 printf("%x:", smp_processor_id());
1017 #endif /* CONFIG_SMP */
1018                 printf("mon> ");
1019                 flush_input();
1020                 termch = 0;
1021                 cmd = skipbl();
1022                 if( cmd == '\n' ) {
1023                         if (last_cmd == NULL)
1024                                 continue;
1025                         take_input(last_cmd);
1026                         last_cmd = NULL;
1027                         cmd = inchar();
1028                 }
1029                 switch (cmd) {
1030                 case 'm':
1031                         cmd = inchar();
1032                         switch (cmd) {
1033                         case 'm':
1034                         case 's':
1035                         case 'd':
1036                                 memops(cmd);
1037                                 break;
1038                         case 'l':
1039                                 memlocate();
1040                                 break;
1041                         case 'z':
1042                                 if (xmon_is_ro) {
1043                                         printf(xmon_ro_msg);
1044                                         break;
1045                                 }
1046                                 memzcan();
1047                                 break;
1048                         case 'i':
1049                                 show_mem(0, NULL);
1050                                 break;
1051                         default:
1052                                 termch = cmd;
1053                                 memex();
1054                         }
1055                         break;
1056                 case 'd':
1057                         dump();
1058                         break;
1059                 case 'l':
1060                         symbol_lookup();
1061                         break;
1062                 case 'r':
1063                         prregs(excp);   /* print regs */
1064                         break;
1065                 case 'e':
1066                         excprint(excp);
1067                         break;
1068                 case 'S':
1069                         super_regs();
1070                         break;
1071                 case 't':
1072                         backtrace(excp);
1073                         break;
1074                 case 'f':
1075                         cacheflush();
1076                         break;
1077                 case 's':
1078                         if (do_spu_cmd() == 0)
1079                                 break;
1080                         if (do_step(excp))
1081                                 return cmd;
1082                         break;
1083                 case 'x':
1084                 case 'X':
1085                         if (tracing_enabled)
1086                                 tracing_on();
1087                         return cmd;
1088                 case EOF:
1089                         printf(" <no input ...>\n");
1090                         mdelay(2000);
1091                         return cmd;
1092                 case '?':
1093                         xmon_puts(help_string);
1094                         break;
1095                 case '#':
1096                         set_lpp_cmd();
1097                         break;
1098                 case 'b':
1099                         if (xmon_is_ro) {
1100                                 printf(xmon_ro_msg);
1101                                 break;
1102                         }
1103                         bpt_cmds();
1104                         break;
1105                 case 'C':
1106                         csum();
1107                         break;
1108                 case 'c':
1109                         if (cpu_cmd())
1110                                 return 0;
1111                         break;
1112                 case 'z':
1113                         bootcmds();
1114                         break;
1115                 case 'p':
1116                         if (xmon_is_ro) {
1117                                 printf(xmon_ro_msg);
1118                                 break;
1119                         }
1120                         proccall();
1121                         break;
1122                 case 'P':
1123                         show_tasks();
1124                         break;
1125 #ifdef CONFIG_PPC_BOOK3S
1126                 case 'u':
1127                         dump_segments();
1128                         break;
1129 #elif defined(CONFIG_44x)
1130                 case 'u':
1131                         dump_tlb_44x();
1132                         break;
1133 #elif defined(CONFIG_PPC_BOOK3E)
1134                 case 'u':
1135                         dump_tlb_book3e();
1136                         break;
1137 #endif
1138                 case 'U':
1139                         show_uptime();
1140                         break;
1141                 default:
1142                         printf("Unrecognized command: ");
1143                         do {
1144                                 if (' ' < cmd && cmd <= '~')
1145                                         putchar(cmd);
1146                                 else
1147                                         printf("\\x%x", cmd);
1148                                 cmd = inchar();
1149                         } while (cmd != '\n');
1150                         printf(" (type ? for help)\n");
1151                         break;
1152                 }
1153         }
1154 }
1155 
1156 #ifdef CONFIG_BOOKE
1157 static int do_step(struct pt_regs *regs)
1158 {
1159         regs->msr |= MSR_DE;
1160         mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
1161         return 1;
1162 }
1163 #else
1164 /*
1165  * Step a single instruction.
1166  * Some instructions we emulate, others we execute with MSR_SE set.
1167  */
1168 static int do_step(struct pt_regs *regs)
1169 {
1170         unsigned int instr;
1171         int stepped;
1172 
1173         force_enable_xmon();
1174         /* check we are in 64-bit kernel mode, translation enabled */
1175         if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
1176                 if (mread(regs->nip, &instr, 4) == 4) {
1177                         stepped = emulate_step(regs, instr);
1178                         if (stepped < 0) {
1179                                 printf("Couldn't single-step %s instruction\n",
1180                                        (IS_RFID(instr)? "rfid": "mtmsrd"));
1181                                 return 0;
1182                         }
1183                         if (stepped > 0) {
1184                                 regs->trap = 0xd00 | (regs->trap & 1);
1185                                 printf("stepped to ");
1186                                 xmon_print_symbol(regs->nip, " ", "\n");
1187                                 ppc_inst_dump(regs->nip, 1, 0);
1188                                 return 0;
1189                         }
1190                 }
1191         }
1192         regs->msr |= MSR_SE;
1193         return 1;
1194 }
1195 #endif
1196 
1197 static void bootcmds(void)
1198 {
1199         int cmd;
1200 
1201         cmd = inchar();
1202         if (cmd == 'r')
1203                 ppc_md.restart(NULL);
1204         else if (cmd == 'h')
1205                 ppc_md.halt();
1206         else if (cmd == 'p')
1207                 if (pm_power_off)
1208                         pm_power_off();
1209 }
1210 
1211 static int cpu_cmd(void)
1212 {
1213 #ifdef CONFIG_SMP
1214         unsigned long cpu, first_cpu, last_cpu;
1215         int timeout;
1216 
1217         if (!scanhex(&cpu)) {
1218                 /* print cpus waiting or in xmon */
1219                 printf("cpus stopped:");
1220                 last_cpu = first_cpu = NR_CPUS;
1221                 for_each_possible_cpu(cpu) {
1222                         if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1223                                 if (cpu == last_cpu + 1) {
1224                                         last_cpu = cpu;
1225                                 } else {
1226                                         if (last_cpu != first_cpu)
1227                                                 printf("-0x%lx", last_cpu);
1228                                         last_cpu = first_cpu = cpu;
1229                                         printf(" 0x%lx", cpu);
1230                                 }
1231                         }
1232                 }
1233                 if (last_cpu != first_cpu)
1234                         printf("-0x%lx", last_cpu);
1235                 printf("\n");
1236                 return 0;
1237         }
1238         /* try to switch to cpu specified */
1239         if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1240                 printf("cpu 0x%lx isn't in xmon\n", cpu);
1241 #ifdef CONFIG_PPC64
1242                 printf("backtrace of paca[0x%lx].saved_r1 (possibly stale):\n", cpu);
1243                 xmon_show_stack(paca_ptrs[cpu]->saved_r1, 0, 0);
1244 #endif
1245                 return 0;
1246         }
1247         xmon_taken = 0;
1248         mb();
1249         xmon_owner = cpu;
1250         timeout = 10000000;
1251         while (!xmon_taken) {
1252                 if (--timeout == 0) {
1253                         if (test_and_set_bit(0, &xmon_taken))
1254                                 break;
1255                         /* take control back */
1256                         mb();
1257                         xmon_owner = smp_processor_id();
1258                         printf("cpu 0x%lx didn't take control\n", cpu);
1259                         return 0;
1260                 }
1261                 barrier();
1262         }
1263         return 1;
1264 #else
1265         return 0;
1266 #endif /* CONFIG_SMP */
1267 }
1268 
1269 static unsigned short fcstab[256] = {
1270         0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1271         0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1272         0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1273         0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1274         0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1275         0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1276         0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1277         0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1278         0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1279         0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1280         0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1281         0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1282         0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1283         0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1284         0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1285         0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1286         0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1287         0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1288         0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1289         0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1290         0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1291         0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1292         0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1293         0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1294         0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1295         0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1296         0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1297         0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1298         0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1299         0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1300         0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1301         0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1302 };
1303 
1304 #define FCS(fcs, c)     (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1305 
1306 static void
1307 csum(void)
1308 {
1309         unsigned int i;
1310         unsigned short fcs;
1311         unsigned char v;
1312 
1313         if (!scanhex(&adrs))
1314                 return;
1315         if (!scanhex(&ncsum))
1316                 return;
1317         fcs = 0xffff;
1318         for (i = 0; i < ncsum; ++i) {
1319                 if (mread(adrs+i, &v, 1) == 0) {
1320                         printf("csum stopped at "REG"\n", adrs+i);
1321                         break;
1322                 }
1323                 fcs = FCS(fcs, v);
1324         }
1325         printf("%x\n", fcs);
1326 }
1327 
1328 /*
1329  * Check if this is a suitable place to put a breakpoint.
1330  */
1331 static long check_bp_loc(unsigned long addr)
1332 {
1333         unsigned int instr;
1334 
1335         addr &= ~3;
1336         if (!is_kernel_addr(addr)) {
1337                 printf("Breakpoints may only be placed at kernel addresses\n");
1338                 return 0;
1339         }
1340         if (!mread(addr, &instr, sizeof(instr))) {
1341                 printf("Can't read instruction at address %lx\n", addr);
1342                 return 0;
1343         }
1344         if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1345                 printf("Breakpoints may not be placed on mtmsrd or rfid "
1346                        "instructions\n");
1347                 return 0;
1348         }
1349         return 1;
1350 }
1351 
1352 static char *breakpoint_help_string =
1353     "Breakpoint command usage:\n"
1354     "b                show breakpoints\n"
1355     "b <addr> [cnt]   set breakpoint at given instr addr\n"
1356     "bc               clear all breakpoints\n"
1357     "bc <n/addr>      clear breakpoint number n or at addr\n"
1358     "bi <addr> [cnt]  set hardware instr breakpoint (POWER8 only)\n"
1359     "bd <addr> [cnt]  set hardware data breakpoint\n"
1360     "";
1361 
1362 static void
1363 bpt_cmds(void)
1364 {
1365         int cmd;
1366         unsigned long a;
1367         int i;
1368         struct bpt *bp;
1369 
1370         cmd = inchar();
1371         switch (cmd) {
1372 #ifndef CONFIG_PPC_8xx
1373         static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
1374         int mode;
1375         case 'd':       /* bd - hardware data breakpoint */
1376                 if (!ppc_breakpoint_available()) {
1377                         printf("Hardware data breakpoint not supported on this cpu\n");
1378                         break;
1379                 }
1380                 mode = 7;
1381                 cmd = inchar();
1382                 if (cmd == 'r')
1383                         mode = 5;
1384                 else if (cmd == 'w')
1385                         mode = 6;
1386                 else
1387                         termch = cmd;
1388                 dabr.address = 0;
1389                 dabr.enabled = 0;
1390                 if (scanhex(&dabr.address)) {
1391                         if (!is_kernel_addr(dabr.address)) {
1392                                 printf(badaddr);
1393                                 break;
1394                         }
1395                         dabr.address &= ~HW_BRK_TYPE_DABR;
1396                         dabr.enabled = mode | BP_DABR;
1397                 }
1398 
1399                 force_enable_xmon();
1400                 break;
1401 
1402         case 'i':       /* bi - hardware instr breakpoint */
1403                 if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
1404                         printf("Hardware instruction breakpoint "
1405                                "not supported on this cpu\n");
1406                         break;
1407                 }
1408                 if (iabr) {
1409                         iabr->enabled &= ~BP_CIABR;
1410                         iabr = NULL;
1411                 }
1412                 if (!scanhex(&a))
1413                         break;
1414                 if (!check_bp_loc(a))
1415                         break;
1416                 bp = new_breakpoint(a);
1417                 if (bp != NULL) {
1418                         bp->enabled |= BP_CIABR;
1419                         iabr = bp;
1420                         force_enable_xmon();
1421                 }
1422                 break;
1423 #endif
1424 
1425         case 'c':
1426                 if (!scanhex(&a)) {
1427                         /* clear all breakpoints */
1428                         for (i = 0; i < NBPTS; ++i)
1429                                 bpts[i].enabled = 0;
1430                         iabr = NULL;
1431                         dabr.enabled = 0;
1432                         printf("All breakpoints cleared\n");
1433                         break;
1434                 }
1435 
1436                 if (a <= NBPTS && a >= 1) {
1437                         /* assume a breakpoint number */
1438                         bp = &bpts[a-1];        /* bp nums are 1 based */
1439                 } else {
1440                         /* assume a breakpoint address */
1441                         bp = at_breakpoint(a);
1442                         if (bp == NULL) {
1443                                 printf("No breakpoint at %lx\n", a);
1444                                 break;
1445                         }
1446                 }
1447 
1448                 printf("Cleared breakpoint %tx (", BP_NUM(bp));
1449                 xmon_print_symbol(bp->address, " ", ")\n");
1450                 bp->enabled = 0;
1451                 break;
1452 
1453         default:
1454                 termch = cmd;
1455                 cmd = skipbl();
1456                 if (cmd == '?') {
1457                         printf(breakpoint_help_string);
1458                         break;
1459                 }
1460                 termch = cmd;
1461                 if (!scanhex(&a)) {
1462                         /* print all breakpoints */
1463                         printf("   type            address\n");
1464                         if (dabr.enabled) {
1465                                 printf("   data   "REG"  [", dabr.address);
1466                                 if (dabr.enabled & 1)
1467                                         printf("r");
1468                                 if (dabr.enabled & 2)
1469                                         printf("w");
1470                                 printf("]\n");
1471                         }
1472                         for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1473                                 if (!bp->enabled)
1474                                         continue;
1475                                 printf("%tx %s   ", BP_NUM(bp),
1476                                     (bp->enabled & BP_CIABR) ? "inst": "trap");
1477                                 xmon_print_symbol(bp->address, "  ", "\n");
1478                         }
1479                         break;
1480                 }
1481 
1482                 if (!check_bp_loc(a))
1483                         break;
1484                 bp = new_breakpoint(a);
1485                 if (bp != NULL) {
1486                         bp->enabled |= BP_TRAP;
1487                         force_enable_xmon();
1488                 }
1489                 break;
1490         }
1491 }
1492 
1493 /* Very cheap human name for vector lookup. */
1494 static
1495 const char *getvecname(unsigned long vec)
1496 {
1497         char *ret;
1498 
1499         switch (vec) {
1500         case 0x100:     ret = "(System Reset)"; break;
1501         case 0x200:     ret = "(Machine Check)"; break;
1502         case 0x300:     ret = "(Data Access)"; break;
1503         case 0x380:
1504                 if (radix_enabled())
1505                         ret = "(Data Access Out of Range)";
1506                 else
1507                         ret = "(Data SLB Access)";
1508                 break;
1509         case 0x400:     ret = "(Instruction Access)"; break;
1510         case 0x480:
1511                 if (radix_enabled())
1512                         ret = "(Instruction Access Out of Range)";
1513                 else
1514                         ret = "(Instruction SLB Access)";
1515                 break;
1516         case 0x500:     ret = "(Hardware Interrupt)"; break;
1517         case 0x600:     ret = "(Alignment)"; break;
1518         case 0x700:     ret = "(Program Check)"; break;
1519         case 0x800:     ret = "(FPU Unavailable)"; break;
1520         case 0x900:     ret = "(Decrementer)"; break;
1521         case 0x980:     ret = "(Hypervisor Decrementer)"; break;
1522         case 0xa00:     ret = "(Doorbell)"; break;
1523         case 0xc00:     ret = "(System Call)"; break;
1524         case 0xd00:     ret = "(Single Step)"; break;
1525         case 0xe40:     ret = "(Emulation Assist)"; break;
1526         case 0xe60:     ret = "(HMI)"; break;
1527         case 0xe80:     ret = "(Hypervisor Doorbell)"; break;
1528         case 0xf00:     ret = "(Performance Monitor)"; break;
1529         case 0xf20:     ret = "(Altivec Unavailable)"; break;
1530         case 0x1300:    ret = "(Instruction Breakpoint)"; break;
1531         case 0x1500:    ret = "(Denormalisation)"; break;
1532         case 0x1700:    ret = "(Altivec Assist)"; break;
1533         default: ret = "";
1534         }
1535         return ret;
1536 }
1537 
1538 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1539                                 unsigned long *endp)
1540 {
1541         unsigned long size, offset;
1542         const char *name;
1543 
1544         *startp = *endp = 0;
1545         if (pc == 0)
1546                 return;
1547         if (setjmp(bus_error_jmp) == 0) {
1548                 catch_memory_errors = 1;
1549                 sync();
1550                 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1551                 if (name != NULL) {
1552                         *startp = pc - offset;
1553                         *endp = pc - offset + size;
1554                 }
1555                 sync();
1556         }
1557         catch_memory_errors = 0;
1558 }
1559 
1560 #define LRSAVE_OFFSET           (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1561 #define MARKER_OFFSET           (STACK_FRAME_MARKER * sizeof(unsigned long))
1562 
1563 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1564                             unsigned long pc)
1565 {
1566         int max_to_print = 64;
1567         unsigned long ip;
1568         unsigned long newsp;
1569         unsigned long marker;
1570         struct pt_regs regs;
1571 
1572         while (max_to_print--) {
1573                 if (!is_kernel_addr(sp)) {
1574                         if (sp != 0)
1575                                 printf("SP (%lx) is in userspace\n", sp);
1576                         break;
1577                 }
1578 
1579                 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1580                     || !mread(sp, &newsp, sizeof(unsigned long))) {
1581                         printf("Couldn't read stack frame at %lx\n", sp);
1582                         break;
1583                 }
1584 
1585                 /*
1586                  * For the first stack frame, try to work out if
1587                  * LR and/or the saved LR value in the bottommost
1588                  * stack frame are valid.
1589                  */
1590                 if ((pc | lr) != 0) {
1591                         unsigned long fnstart, fnend;
1592                         unsigned long nextip;
1593                         int printip = 1;
1594 
1595                         get_function_bounds(pc, &fnstart, &fnend);
1596                         nextip = 0;
1597                         if (newsp > sp)
1598                                 mread(newsp + LRSAVE_OFFSET, &nextip,
1599                                       sizeof(unsigned long));
1600                         if (lr == ip) {
1601                                 if (!is_kernel_addr(lr)
1602                                     || (fnstart <= lr && lr < fnend))
1603                                         printip = 0;
1604                         } else if (lr == nextip) {
1605                                 printip = 0;
1606                         } else if (is_kernel_addr(lr)
1607                                    && !(fnstart <= lr && lr < fnend)) {
1608                                 printf("[link register   ] ");
1609                                 xmon_print_symbol(lr, " ", "\n");
1610                         }
1611                         if (printip) {
1612                                 printf("["REG"] ", sp);
1613                                 xmon_print_symbol(ip, " ", " (unreliable)\n");
1614                         }
1615                         pc = lr = 0;
1616 
1617                 } else {
1618                         printf("["REG"] ", sp);
1619                         xmon_print_symbol(ip, " ", "\n");
1620                 }
1621 
1622                 /* Look for "regshere" marker to see if this is
1623                    an exception frame. */
1624                 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1625                     && marker == STACK_FRAME_REGS_MARKER) {
1626                         if (mread(sp + STACK_FRAME_OVERHEAD, &regs, sizeof(regs))
1627                             != sizeof(regs)) {
1628                                 printf("Couldn't read registers at %lx\n",
1629                                        sp + STACK_FRAME_OVERHEAD);
1630                                 break;
1631                         }
1632                         printf("--- Exception: %lx %s at ", regs.trap,
1633                                getvecname(TRAP(&regs)));
1634                         pc = regs.nip;
1635                         lr = regs.link;
1636                         xmon_print_symbol(pc, " ", "\n");
1637                 }
1638 
1639                 if (newsp == 0)
1640                         break;
1641 
1642                 sp = newsp;
1643         }
1644 }
1645 
1646 static void backtrace(struct pt_regs *excp)
1647 {
1648         unsigned long sp;
1649 
1650         if (scanhex(&sp))
1651                 xmon_show_stack(sp, 0, 0);
1652         else
1653                 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1654         scannl();
1655 }
1656 
1657 static void print_bug_trap(struct pt_regs *regs)
1658 {
1659 #ifdef CONFIG_BUG
1660         const struct bug_entry *bug;
1661         unsigned long addr;
1662 
1663         if (regs->msr & MSR_PR)
1664                 return;         /* not in kernel */
1665         addr = regs->nip;       /* address of trap instruction */
1666         if (!is_kernel_addr(addr))
1667                 return;
1668         bug = find_bug(regs->nip);
1669         if (bug == NULL)
1670                 return;
1671         if (is_warning_bug(bug))
1672                 return;
1673 
1674 #ifdef CONFIG_DEBUG_BUGVERBOSE
1675         printf("kernel BUG at %s:%u!\n",
1676                bug->file, bug->line);
1677 #else
1678         printf("kernel BUG at %px!\n", (void *)bug->bug_addr);
1679 #endif
1680 #endif /* CONFIG_BUG */
1681 }
1682 
1683 static void excprint(struct pt_regs *fp)
1684 {
1685         unsigned long trap;
1686 
1687 #ifdef CONFIG_SMP
1688         printf("cpu 0x%x: ", smp_processor_id());
1689 #endif /* CONFIG_SMP */
1690 
1691         trap = TRAP(fp);
1692         printf("Vector: %lx %s at [%px]\n", fp->trap, getvecname(trap), fp);
1693         printf("    pc: ");
1694         xmon_print_symbol(fp->nip, ": ", "\n");
1695 
1696         printf("    lr: ");
1697         xmon_print_symbol(fp->link, ": ", "\n");
1698 
1699         printf("    sp: %lx\n", fp->gpr[1]);
1700         printf("   msr: %lx\n", fp->msr);
1701 
1702         if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
1703                 printf("   dar: %lx\n", fp->dar);
1704                 if (trap != 0x380)
1705                         printf(" dsisr: %lx\n", fp->dsisr);
1706         }
1707 
1708         printf("  current = 0x%px\n", current);
1709 #ifdef CONFIG_PPC64
1710         printf("  paca    = 0x%px\t irqmask: 0x%02x\t irq_happened: 0x%02x\n",
1711                local_paca, local_paca->irq_soft_mask, local_paca->irq_happened);
1712 #endif
1713         if (current) {
1714                 printf("    pid   = %d, comm = %s\n",
1715                        current->pid, current->comm);
1716         }
1717 
1718         if (trap == 0x700)
1719                 print_bug_trap(fp);
1720 
1721         printf(linux_banner);
1722 }
1723 
1724 static void prregs(struct pt_regs *fp)
1725 {
1726         int n, trap;
1727         unsigned long base;
1728         struct pt_regs regs;
1729 
1730         if (scanhex(&base)) {
1731                 if (setjmp(bus_error_jmp) == 0) {
1732                         catch_memory_errors = 1;
1733                         sync();
1734                         regs = *(struct pt_regs *)base;
1735                         sync();
1736                         __delay(200);
1737                 } else {
1738                         catch_memory_errors = 0;
1739                         printf("*** Error reading registers from "REG"\n",
1740                                base);
1741                         return;
1742                 }
1743                 catch_memory_errors = 0;
1744                 fp = &regs;
1745         }
1746 
1747 #ifdef CONFIG_PPC64
1748         if (FULL_REGS(fp)) {
1749                 for (n = 0; n < 16; ++n)
1750                         printf("R%.2d = "REG"   R%.2d = "REG"\n",
1751                                n, fp->gpr[n], n+16, fp->gpr[n+16]);
1752         } else {
1753                 for (n = 0; n < 7; ++n)
1754                         printf("R%.2d = "REG"   R%.2d = "REG"\n",
1755                                n, fp->gpr[n], n+7, fp->gpr[n+7]);
1756         }
1757 #else
1758         for (n = 0; n < 32; ++n) {
1759                 printf("R%.2d = %.8lx%s", n, fp->gpr[n],
1760                        (n & 3) == 3? "\n": "   ");
1761                 if (n == 12 && !FULL_REGS(fp)) {
1762                         printf("\n");
1763                         break;
1764                 }
1765         }
1766 #endif
1767         printf("pc  = ");
1768         xmon_print_symbol(fp->nip, " ", "\n");
1769         if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
1770                 printf("cfar= ");
1771                 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1772         }
1773         printf("lr  = ");
1774         xmon_print_symbol(fp->link, " ", "\n");
1775         printf("msr = "REG"   cr  = %.8lx\n", fp->msr, fp->ccr);
1776         printf("ctr = "REG"   xer = "REG"   trap = %4lx\n",
1777                fp->ctr, fp->xer, fp->trap);
1778         trap = TRAP(fp);
1779         if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1780                 printf("dar = "REG"   dsisr = %.8lx\n", fp->dar, fp->dsisr);
1781 }
1782 
1783 static void cacheflush(void)
1784 {
1785         int cmd;
1786         unsigned long nflush;
1787 
1788         cmd = inchar();
1789         if (cmd != 'i')
1790                 termch = cmd;
1791         scanhex((void *)&adrs);
1792         if (termch != '\n')
1793                 termch = 0;
1794         nflush = 1;
1795         scanhex(&nflush);
1796         nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1797         if (setjmp(bus_error_jmp) == 0) {
1798                 catch_memory_errors = 1;
1799                 sync();
1800 
1801                 if (cmd != 'i') {
1802                         for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1803                                 cflush((void *) adrs);
1804                 } else {
1805                         for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1806                                 cinval((void *) adrs);
1807                 }
1808                 sync();
1809                 /* wait a little while to see if we get a machine check */
1810                 __delay(200);
1811         }
1812         catch_memory_errors = 0;
1813 }
1814 
1815 extern unsigned long xmon_mfspr(int spr, unsigned long default_value);
1816 extern void xmon_mtspr(int spr, unsigned long value);
1817 
1818 static int
1819 read_spr(int n, unsigned long *vp)
1820 {
1821         unsigned long ret = -1UL;
1822         int ok = 0;
1823 
1824         if (setjmp(bus_error_jmp) == 0) {
1825                 catch_spr_faults = 1;
1826                 sync();
1827 
1828                 ret = xmon_mfspr(n, *vp);
1829 
1830                 sync();
1831                 *vp = ret;
1832                 ok = 1;
1833         }
1834         catch_spr_faults = 0;
1835 
1836         return ok;
1837 }
1838 
1839 static void
1840 write_spr(int n, unsigned long val)
1841 {
1842         if (xmon_is_ro) {
1843                 printf(xmon_ro_msg);
1844                 return;
1845         }
1846 
1847         if (setjmp(bus_error_jmp) == 0) {
1848                 catch_spr_faults = 1;
1849                 sync();
1850 
1851                 xmon_mtspr(n, val);
1852 
1853                 sync();
1854         } else {
1855                 printf("SPR 0x%03x (%4d) Faulted during write\n", n, n);
1856         }
1857         catch_spr_faults = 0;
1858 }
1859 
1860 static void dump_206_sprs(void)
1861 {
1862 #ifdef CONFIG_PPC64
1863         if (!cpu_has_feature(CPU_FTR_ARCH_206))
1864                 return;
1865 
1866         /* Actually some of these pre-date 2.06, but whatevs */
1867 
1868         printf("srr0   = %.16lx  srr1  = %.16lx dsisr  = %.8lx\n",
1869                 mfspr(SPRN_SRR0), mfspr(SPRN_SRR1), mfspr(SPRN_DSISR));
1870         printf("dscr   = %.16lx  ppr   = %.16lx pir    = %.8lx\n",
1871                 mfspr(SPRN_DSCR), mfspr(SPRN_PPR), mfspr(SPRN_PIR));
1872         printf("amr    = %.16lx  uamor = %.16lx\n",
1873                 mfspr(SPRN_AMR), mfspr(SPRN_UAMOR));
1874 
1875         if (!(mfmsr() & MSR_HV))
1876                 return;
1877 
1878         printf("sdr1   = %.16lx  hdar  = %.16lx hdsisr = %.8lx\n",
1879                 mfspr(SPRN_SDR1), mfspr(SPRN_HDAR), mfspr(SPRN_HDSISR));
1880         printf("hsrr0  = %.16lx hsrr1  = %.16lx hdec   = %.16lx\n",
1881                 mfspr(SPRN_HSRR0), mfspr(SPRN_HSRR1), mfspr(SPRN_HDEC));
1882         printf("lpcr   = %.16lx  pcr   = %.16lx lpidr  = %.8lx\n",
1883                 mfspr(SPRN_LPCR), mfspr(SPRN_PCR), mfspr(SPRN_LPID));
1884         printf("hsprg0 = %.16lx hsprg1 = %.16lx amor   = %.16lx\n",
1885                 mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1), mfspr(SPRN_AMOR));
1886         printf("dabr   = %.16lx dabrx  = %.16lx\n",
1887                 mfspr(SPRN_DABR), mfspr(SPRN_DABRX));
1888 #endif
1889 }
1890 
1891 static void dump_207_sprs(void)
1892 {
1893 #ifdef CONFIG_PPC64
1894         unsigned long msr;
1895 
1896         if (!cpu_has_feature(CPU_FTR_ARCH_207S))
1897                 return;
1898 
1899         printf("dpdes  = %.16lx  tir   = %.16lx cir    = %.8lx\n",
1900                 mfspr(SPRN_DPDES), mfspr(SPRN_TIR), mfspr(SPRN_CIR));
1901 
1902         printf("fscr   = %.16lx  tar   = %.16lx pspb   = %.8lx\n",
1903                 mfspr(SPRN_FSCR), mfspr(SPRN_TAR), mfspr(SPRN_PSPB));
1904 
1905         msr = mfmsr();
1906         if (msr & MSR_TM) {
1907                 /* Only if TM has been enabled in the kernel */
1908                 printf("tfhar  = %.16lx  tfiar = %.16lx texasr = %.16lx\n",
1909                         mfspr(SPRN_TFHAR), mfspr(SPRN_TFIAR),
1910                         mfspr(SPRN_TEXASR));
1911         }
1912 
1913         printf("mmcr0  = %.16lx  mmcr1 = %.16lx mmcr2  = %.16lx\n",
1914                 mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCR2));
1915         printf("pmc1   = %.8lx pmc2 = %.8lx  pmc3 = %.8lx  pmc4   = %.8lx\n",
1916                 mfspr(SPRN_PMC1), mfspr(SPRN_PMC2),
1917                 mfspr(SPRN_PMC3), mfspr(SPRN_PMC4));
1918         printf("mmcra  = %.16lx   siar = %.16lx pmc5   = %.8lx\n",
1919                 mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5));
1920         printf("sdar   = %.16lx   sier = %.16lx pmc6   = %.8lx\n",
1921                 mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6));
1922         printf("ebbhr  = %.16lx  ebbrr = %.16lx bescr  = %.16lx\n",
1923                 mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
1924         printf("iamr   = %.16lx\n", mfspr(SPRN_IAMR));
1925 
1926         if (!(msr & MSR_HV))
1927                 return;
1928 
1929         printf("hfscr  = %.16lx  dhdes = %.16lx rpr    = %.16lx\n",
1930                 mfspr(SPRN_HFSCR), mfspr(SPRN_DHDES), mfspr(SPRN_RPR));
1931         printf("dawr   = %.16lx  dawrx = %.16lx ciabr  = %.16lx\n",
1932                 mfspr(SPRN_DAWR), mfspr(SPRN_DAWRX), mfspr(SPRN_CIABR));
1933 #endif
1934 }
1935 
1936 static void dump_300_sprs(void)
1937 {
1938 #ifdef CONFIG_PPC64
1939         bool hv = mfmsr() & MSR_HV;
1940 
1941         if (!cpu_has_feature(CPU_FTR_ARCH_300))
1942                 return;
1943 
1944         printf("pidr   = %.16lx  tidr  = %.16lx\n",
1945                 mfspr(SPRN_PID), mfspr(SPRN_TIDR));
1946         printf("psscr  = %.16lx\n",
1947                 hv ? mfspr(SPRN_PSSCR) : mfspr(SPRN_PSSCR_PR));
1948 
1949         if (!hv)
1950                 return;
1951 
1952         printf("ptcr   = %.16lx  asdr  = %.16lx\n",
1953                 mfspr(SPRN_PTCR), mfspr(SPRN_ASDR));
1954 #endif
1955 }
1956 
1957 static void dump_one_spr(int spr, bool show_unimplemented)
1958 {
1959         unsigned long val;
1960 
1961         val = 0xdeadbeef;
1962         if (!read_spr(spr, &val)) {
1963                 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
1964                 return;
1965         }
1966 
1967         if (val == 0xdeadbeef) {
1968                 /* Looks like read was a nop, confirm */
1969                 val = 0x0badcafe;
1970                 if (!read_spr(spr, &val)) {
1971                         printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
1972                         return;
1973                 }
1974 
1975                 if (val == 0x0badcafe) {
1976                         if (show_unimplemented)
1977                                 printf("SPR 0x%03x (%4d) Unimplemented\n", spr, spr);
1978                         return;
1979                 }
1980         }
1981 
1982         printf("SPR 0x%03x (%4d) = 0x%lx\n", spr, spr, val);
1983 }
1984 
1985 static void super_regs(void)
1986 {
1987         static unsigned long regno;
1988         int cmd;
1989         int spr;
1990 
1991         cmd = skipbl();
1992 
1993         switch (cmd) {
1994         case '\n': {
1995                 unsigned long sp, toc;
1996                 asm("mr %0,1" : "=r" (sp) :);
1997                 asm("mr %0,2" : "=r" (toc) :);
1998 
1999                 printf("msr    = "REG"  sprg0 = "REG"\n",
2000                        mfmsr(), mfspr(SPRN_SPRG0));
2001                 printf("pvr    = "REG"  sprg1 = "REG"\n",
2002                        mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
2003                 printf("dec    = "REG"  sprg2 = "REG"\n",
2004                        mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
2005                 printf("sp     = "REG"  sprg3 = "REG"\n", sp, mfspr(SPRN_SPRG3));
2006                 printf("toc    = "REG"  dar   = "REG"\n", toc, mfspr(SPRN_DAR));
2007 
2008                 dump_206_sprs();
2009                 dump_207_sprs();
2010                 dump_300_sprs();
2011 
2012                 return;
2013         }
2014         case 'w': {
2015                 unsigned long val;
2016                 scanhex(&regno);
2017                 val = 0;
2018                 read_spr(regno, &val);
2019                 scanhex(&val);
2020                 write_spr(regno, val);
2021                 dump_one_spr(regno, true);
2022                 break;
2023         }
2024         case 'r':
2025                 scanhex(&regno);
2026                 dump_one_spr(regno, true);
2027                 break;
2028         case 'a':
2029                 /* dump ALL SPRs */
2030                 for (spr = 1; spr < 1024; ++spr)
2031                         dump_one_spr(spr, false);
2032                 break;
2033         }
2034 
2035         scannl();
2036 }
2037 
2038 /*
2039  * Stuff for reading and writing memory safely
2040  */
2041 static int
2042 mread(unsigned long adrs, void *buf, int size)
2043 {
2044         volatile int n;
2045         char *p, *q;
2046 
2047         n = 0;
2048         if (setjmp(bus_error_jmp) == 0) {
2049                 catch_memory_errors = 1;
2050                 sync();
2051                 p = (char *)adrs;
2052                 q = (char *)buf;
2053                 switch (size) {
2054                 case 2:
2055                         *(u16 *)q = *(u16 *)p;
2056                         break;
2057                 case 4:
2058                         *(u32 *)q = *(u32 *)p;
2059                         break;
2060                 case 8:
2061                         *(u64 *)q = *(u64 *)p;
2062                         break;
2063                 default:
2064                         for( ; n < size; ++n) {
2065                                 *q++ = *p++;
2066                                 sync();
2067                         }
2068                 }
2069                 sync();
2070                 /* wait a little while to see if we get a machine check */
2071                 __delay(200);
2072                 n = size;
2073         }
2074         catch_memory_errors = 0;
2075         return n;
2076 }
2077 
2078 static int
2079 mwrite(unsigned long adrs, void *buf, int size)
2080 {
2081         volatile int n;
2082         char *p, *q;
2083 
2084         n = 0;
2085 
2086         if (xmon_is_ro) {
2087                 printf(xmon_ro_msg);
2088                 return n;
2089         }
2090 
2091         if (setjmp(bus_error_jmp) == 0) {
2092                 catch_memory_errors = 1;
2093                 sync();
2094                 p = (char *) adrs;
2095                 q = (char *) buf;
2096                 switch (size) {
2097                 case 2:
2098                         *(u16 *)p = *(u16 *)q;
2099                         break;
2100                 case 4:
2101                         *(u32 *)p = *(u32 *)q;
2102                         break;
2103                 case 8:
2104                         *(u64 *)p = *(u64 *)q;
2105                         break;
2106                 default:
2107                         for ( ; n < size; ++n) {
2108                                 *p++ = *q++;
2109                                 sync();
2110                         }
2111                 }
2112                 sync();
2113                 /* wait a little while to see if we get a machine check */
2114                 __delay(200);
2115                 n = size;
2116         } else {
2117                 printf("*** Error writing address "REG"\n", adrs + n);
2118         }
2119         catch_memory_errors = 0;
2120         return n;
2121 }
2122 
2123 static int fault_type;
2124 static int fault_except;
2125 static char *fault_chars[] = { "--", "**", "##" };
2126 
2127 static int handle_fault(struct pt_regs *regs)
2128 {
2129         fault_except = TRAP(regs);
2130         switch (TRAP(regs)) {
2131         case 0x200:
2132                 fault_type = 0;
2133                 break;
2134         case 0x300:
2135         case 0x380:
2136                 fault_type = 1;
2137                 break;
2138         default:
2139                 fault_type = 2;
2140         }
2141 
2142         longjmp(bus_error_jmp, 1);
2143 
2144         return 0;
2145 }
2146 
2147 #define SWAP(a, b, t)   ((t) = (a), (a) = (b), (b) = (t))
2148 
2149 static void
2150 byterev(unsigned char *val, int size)
2151 {
2152         int t;
2153         
2154         switch (size) {
2155         case 2:
2156                 SWAP(val[0], val[1], t);
2157                 break;
2158         case 4:
2159                 SWAP(val[0], val[3], t);
2160                 SWAP(val[1], val[2], t);
2161                 break;
2162         case 8: /* is there really any use for this? */
2163                 SWAP(val[0], val[7], t);
2164                 SWAP(val[1], val[6], t);
2165                 SWAP(val[2], val[5], t);
2166                 SWAP(val[3], val[4], t);
2167                 break;
2168         }
2169 }
2170 
2171 static int brev;
2172 static int mnoread;
2173 
2174 static char *memex_help_string =
2175     "Memory examine command usage:\n"
2176     "m [addr] [flags] examine/change memory\n"
2177     "  addr is optional.  will start where left off.\n"
2178     "  flags may include chars from this set:\n"
2179     "    b   modify by bytes (default)\n"
2180     "    w   modify by words (2 byte)\n"
2181     "    l   modify by longs (4 byte)\n"
2182     "    d   modify by doubleword (8 byte)\n"
2183     "    r   toggle reverse byte order mode\n"
2184     "    n   do not read memory (for i/o spaces)\n"
2185     "    .   ok to read (default)\n"
2186     "NOTE: flags are saved as defaults\n"
2187     "";
2188 
2189 static char *memex_subcmd_help_string =
2190     "Memory examine subcommands:\n"
2191     "  hexval   write this val to current location\n"
2192     "  'string' write chars from string to this location\n"
2193     "  '        increment address\n"
2194     "  ^        decrement address\n"
2195     "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etc\n"
2196     "  \\        decrement addr by 0x10.  \\\\=0x100, \\\\\\=0x1000, etc\n"
2197     "  `        clear no-read flag\n"
2198     "  ;        stay at this addr\n"
2199     "  v        change to byte mode\n"
2200     "  w        change to word (2 byte) mode\n"
2201     "  l        change to long (4 byte) mode\n"
2202     "  u        change to doubleword (8 byte) mode\n"
2203     "  m addr   change current addr\n"
2204     "  n        toggle no-read flag\n"
2205     "  r        toggle byte reverse flag\n"
2206     "  < count  back up count bytes\n"
2207     "  > count  skip forward count bytes\n"
2208     "  x        exit this mode\n"
2209     "";
2210 
2211 static void
2212 memex(void)
2213 {
2214         int cmd, inc, i, nslash;
2215         unsigned long n;
2216         unsigned char val[16];
2217 
2218         scanhex((void *)&adrs);
2219         cmd = skipbl();
2220         if (cmd == '?') {
2221                 printf(memex_help_string);
2222                 return;
2223         } else {
2224                 termch = cmd;
2225         }
2226         last_cmd = "m\n";
2227         while ((cmd = skipbl()) != '\n') {
2228                 switch( cmd ){
2229                 case 'b':       size = 1;       break;
2230                 case 'w':       size = 2;       break;
2231                 case 'l':       size = 4;       break;
2232                 case 'd':       size = 8;       break;
2233                 case 'r':       brev = !brev;   break;
2234                 case 'n':       mnoread = 1;    break;
2235                 case '.':       mnoread = 0;    break;
2236                 }
2237         }
2238         if( size <= 0 )
2239                 size = 1;
2240         else if( size > 8 )
2241                 size = 8;
2242         for(;;){
2243                 if (!mnoread)
2244                         n = mread(adrs, val, size);
2245                 printf(REG"%c", adrs, brev? 'r': ' ');
2246                 if (!mnoread) {
2247                         if (brev)
2248                                 byterev(val, size);
2249                         putchar(' ');
2250                         for (i = 0; i < n; ++i)
2251                                 printf("%.2x", val[i]);
2252                         for (; i < size; ++i)
2253                                 printf("%s", fault_chars[fault_type]);
2254                 }
2255                 putchar(' ');
2256                 inc = size;
2257                 nslash = 0;
2258                 for(;;){
2259                         if( scanhex(&n) ){
2260                                 for (i = 0; i < size; ++i)
2261                                         val[i] = n >> (i * 8);
2262                                 if (!brev)
2263                                         byterev(val, size);
2264                                 mwrite(adrs, val, size);
2265                                 inc = size;
2266                         }
2267                         cmd = skipbl();
2268                         if (cmd == '\n')
2269                                 break;
2270                         inc = 0;
2271                         switch (cmd) {
2272                         case '\'':
2273                                 for(;;){
2274                                         n = inchar();
2275                                         if( n == '\\' )
2276                                                 n = bsesc();
2277                                         else if( n == '\'' )
2278                                                 break;
2279                                         for (i = 0; i < size; ++i)
2280                                                 val[i] = n >> (i * 8);
2281                                         if (!brev)
2282                                                 byterev(val, size);
2283                                         mwrite(adrs, val, size);
2284                                         adrs += size;
2285                                 }
2286                                 adrs -= size;
2287                                 inc = size;
2288                                 break;
2289                         case ',':
2290                                 adrs += size;
2291                                 break;
2292                         case '.':
2293                                 mnoread = 0;
2294                                 break;
2295                         case ';':
2296                                 break;
2297                         case 'x':
2298                         case EOF:
2299                                 scannl();
2300                                 return;
2301                         case 'b':
2302                         case 'v':
2303                                 size = 1;
2304                                 break;
2305                         case 'w':
2306                                 size = 2;
2307                                 break;
2308                         case 'l':
2309                                 size = 4;
2310                                 break;
2311                         case 'u':
2312                                 size = 8;
2313                                 break;
2314                         case '^':
2315                                 adrs -= size;
2316                                 break;
2317                         case '/':
2318                                 if (nslash > 0)
2319                                         adrs -= 1 << nslash;
2320                                 else
2321                                         nslash = 0;
2322                                 nslash += 4;
2323                                 adrs += 1 << nslash;
2324                                 break;
2325                         case '\\':
2326                                 if (nslash < 0)
2327                                         adrs += 1 << -nslash;
2328                                 else
2329                                         nslash = 0;
2330                                 nslash -= 4;
2331                                 adrs -= 1 << -nslash;
2332                                 break;
2333                         case 'm':
2334                                 scanhex((void *)&adrs);
2335                                 break;
2336                         case 'n':
2337                                 mnoread = 1;
2338                                 break;
2339                         case 'r':
2340                                 brev = !brev;
2341                                 break;
2342                         case '<':
2343                                 n = size;
2344                                 scanhex(&n);
2345                                 adrs -= n;
2346                                 break;
2347                         case '>':
2348                                 n = size;
2349                                 scanhex(&n);
2350                                 adrs += n;
2351                                 break;
2352                         case '?':
2353                                 printf(memex_subcmd_help_string);
2354                                 break;
2355                         }
2356                 }
2357                 adrs += inc;
2358         }
2359 }
2360 
2361 static int
2362 bsesc(void)
2363 {
2364         int c;
2365 
2366         c = inchar();
2367         switch( c ){
2368         case 'n':       c = '\n';       break;
2369         case 'r':       c = '\r';       break;
2370         case 'b':       c = '\b';       break;
2371         case 't':       c = '\t';       break;
2372         }
2373         return c;
2374 }
2375 
2376 static void xmon_rawdump (unsigned long adrs, long ndump)
2377 {
2378         long n, m, r, nr;
2379         unsigned char temp[16];
2380 
2381         for (n = ndump; n > 0;) {
2382                 r = n < 16? n: 16;
2383                 nr = mread(adrs, temp, r);
2384                 adrs += nr;
2385                 for (m = 0; m < r; ++m) {
2386                         if (m < nr)
2387                                 printf("%.2x", temp[m]);
2388                         else
2389                                 printf("%s", fault_chars[fault_type]);
2390                 }
2391                 n -= r;
2392                 if (nr < r)
2393                         break;
2394         }
2395         printf("\n");
2396 }
2397 
2398 static void dump_tracing(void)
2399 {
2400         int c;
2401 
2402         c = inchar();
2403         if (c == 'c')
2404                 ftrace_dump(DUMP_ORIG);
2405         else
2406                 ftrace_dump(DUMP_ALL);
2407 }
2408 
2409 #ifdef CONFIG_PPC64
2410 static void dump_one_paca(int cpu)
2411 {
2412         struct paca_struct *p;
2413 #ifdef CONFIG_PPC_BOOK3S_64
2414         int i = 0;
2415 #endif
2416 
2417         if (setjmp(bus_error_jmp) != 0) {
2418                 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2419                 return;
2420         }
2421 
2422         catch_memory_errors = 1;
2423         sync();
2424 
2425         p = paca_ptrs[cpu];
2426 
2427         printf("paca for cpu 0x%x @ %px:\n", cpu, p);
2428 
2429         printf(" %-*s = %s\n", 25, "possible", cpu_possible(cpu) ? "yes" : "no");
2430         printf(" %-*s = %s\n", 25, "present", cpu_present(cpu) ? "yes" : "no");
2431         printf(" %-*s = %s\n", 25, "online", cpu_online(cpu) ? "yes" : "no");
2432 
2433 #define DUMP(paca, name, format)                                \
2434         printf(" %-*s = "format"\t(0x%lx)\n", 25, #name, 18, paca->name, \
2435                 offsetof(struct paca_struct, name));
2436 
2437         DUMP(p, lock_token, "%#-*x");
2438         DUMP(p, paca_index, "%#-*x");
2439         DUMP(p, kernel_toc, "%#-*llx");
2440         DUMP(p, kernelbase, "%#-*llx");
2441         DUMP(p, kernel_msr, "%#-*llx");
2442         DUMP(p, emergency_sp, "%-*px");
2443 #ifdef CONFIG_PPC_BOOK3S_64
2444         DUMP(p, nmi_emergency_sp, "%-*px");
2445         DUMP(p, mc_emergency_sp, "%-*px");
2446         DUMP(p, in_nmi, "%#-*x");
2447         DUMP(p, in_mce, "%#-*x");
2448         DUMP(p, hmi_event_available, "%#-*x");
2449 #endif
2450         DUMP(p, data_offset, "%#-*llx");
2451         DUMP(p, hw_cpu_id, "%#-*x");
2452         DUMP(p, cpu_start, "%#-*x");
2453         DUMP(p, kexec_state, "%#-*x");
2454 #ifdef CONFIG_PPC_BOOK3S_64
2455         if (!early_radix_enabled()) {
2456                 for (i = 0; i < SLB_NUM_BOLTED; i++) {
2457                         u64 esid, vsid;
2458 
2459                         if (!p->slb_shadow_ptr)
2460                                 continue;
2461 
2462                         esid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].esid);
2463                         vsid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].vsid);
2464 
2465                         if (esid || vsid) {
2466                                 printf(" %-*s[%d] = 0x%016llx 0x%016llx\n",
2467                                        22, "slb_shadow", i, esid, vsid);
2468                         }
2469                 }
2470                 DUMP(p, vmalloc_sllp, "%#-*x");
2471                 DUMP(p, stab_rr, "%#-*x");
2472                 DUMP(p, slb_used_bitmap, "%#-*x");
2473                 DUMP(p, slb_kern_bitmap, "%#-*x");
2474 
2475                 if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
2476                         DUMP(p, slb_cache_ptr, "%#-*x");
2477                         for (i = 0; i < SLB_CACHE_ENTRIES; i++)
2478                                 printf(" %-*s[%d] = 0x%016x\n",
2479                                        22, "slb_cache", i, p->slb_cache[i]);
2480                 }
2481         }
2482 
2483         DUMP(p, rfi_flush_fallback_area, "%-*px");
2484 #endif
2485         DUMP(p, dscr_default, "%#-*llx");
2486 #ifdef CONFIG_PPC_BOOK3E
2487         DUMP(p, pgd, "%-*px");
2488         DUMP(p, kernel_pgd, "%-*px");
2489         DUMP(p, tcd_ptr, "%-*px");
2490         DUMP(p, mc_kstack, "%-*px");
2491         DUMP(p, crit_kstack, "%-*px");
2492         DUMP(p, dbg_kstack, "%-*px");
2493 #endif
2494         DUMP(p, __current, "%-*px");
2495         DUMP(p, kstack, "%#-*llx");
2496         printf(" %-*s = 0x%016llx\n", 25, "kstack_base", p->kstack & ~(THREAD_SIZE - 1));
2497 #ifdef CONFIG_STACKPROTECTOR
2498         DUMP(p, canary, "%#-*lx");
2499 #endif
2500         DUMP(p, saved_r1, "%#-*llx");
2501 #ifdef CONFIG_PPC_BOOK3E
2502         DUMP(p, trap_save, "%#-*x");
2503 #endif
2504         DUMP(p, irq_soft_mask, "%#-*x");
2505         DUMP(p, irq_happened, "%#-*x");
2506 #ifdef CONFIG_MMIOWB
2507         DUMP(p, mmiowb_state.nesting_count, "%#-*x");
2508         DUMP(p, mmiowb_state.mmiowb_pending, "%#-*x");
2509 #endif
2510         DUMP(p, irq_work_pending, "%#-*x");
2511         DUMP(p, sprg_vdso, "%#-*llx");
2512 
2513 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2514         DUMP(p, tm_scratch, "%#-*llx");
2515 #endif
2516 
2517 #ifdef CONFIG_PPC_POWERNV
2518         DUMP(p, idle_state, "%#-*lx");
2519         if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
2520                 DUMP(p, thread_idle_state, "%#-*x");
2521                 DUMP(p, subcore_sibling_mask, "%#-*x");
2522         } else {
2523 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
2524                 DUMP(p, requested_psscr, "%#-*llx");
2525                 DUMP(p, dont_stop.counter, "%#-*x");
2526 #endif
2527         }
2528 #endif
2529 
2530         DUMP(p, accounting.utime, "%#-*lx");
2531         DUMP(p, accounting.stime, "%#-*lx");
2532 #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2533         DUMP(p, accounting.utime_scaled, "%#-*lx");
2534 #endif
2535         DUMP(p, accounting.starttime, "%#-*lx");
2536         DUMP(p, accounting.starttime_user, "%#-*lx");
2537 #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2538         DUMP(p, accounting.startspurr, "%#-*lx");
2539         DUMP(p, accounting.utime_sspurr, "%#-*lx");
2540 #endif
2541         DUMP(p, accounting.steal_time, "%#-*lx");
2542 #undef DUMP
2543 
2544         catch_memory_errors = 0;
2545         sync();
2546 }
2547 
2548 static void dump_all_pacas(void)
2549 {
2550         int cpu;
2551 
2552         if (num_possible_cpus() == 0) {
2553                 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2554                 return;
2555         }
2556 
2557         for_each_possible_cpu(cpu)
2558                 dump_one_paca(cpu);
2559 }
2560 
2561 static void dump_pacas(void)
2562 {
2563         unsigned long num;
2564         int c;
2565 
2566         c = inchar();
2567         if (c == 'a') {
2568                 dump_all_pacas();
2569                 return;
2570         }
2571 
2572         termch = c;     /* Put c back, it wasn't 'a' */
2573 
2574         if (scanhex(&num))
2575                 dump_one_paca(num);
2576         else
2577                 dump_one_paca(xmon_owner);
2578 }
2579 #endif
2580 
2581 #ifdef CONFIG_PPC_POWERNV
2582 static void dump_one_xive(int cpu)
2583 {
2584         unsigned int hwid = get_hard_smp_processor_id(cpu);
2585         bool hv = cpu_has_feature(CPU_FTR_HVMODE);
2586 
2587         if (hv) {
2588                 opal_xive_dump(XIVE_DUMP_TM_HYP, hwid);
2589                 opal_xive_dump(XIVE_DUMP_TM_POOL, hwid);
2590                 opal_xive_dump(XIVE_DUMP_TM_OS, hwid);
2591                 opal_xive_dump(XIVE_DUMP_TM_USER, hwid);
2592                 opal_xive_dump(XIVE_DUMP_VP, hwid);
2593                 opal_xive_dump(XIVE_DUMP_EMU_STATE, hwid);
2594         }
2595 
2596         if (setjmp(bus_error_jmp) != 0) {
2597                 catch_memory_errors = 0;
2598                 printf("*** Error dumping xive on cpu %d\n", cpu);
2599                 return;
2600         }
2601 
2602         catch_memory_errors = 1;
2603         sync();
2604         xmon_xive_do_dump(cpu);
2605         sync();
2606         __delay(200);
2607         catch_memory_errors = 0;
2608 }
2609 
2610 static void dump_all_xives(void)
2611 {
2612         int cpu;
2613 
2614         if (num_possible_cpus() == 0) {
2615                 printf("No possible cpus, use 'dx #' to dump individual cpus\n");
2616                 return;
2617         }
2618 
2619         for_each_possible_cpu(cpu)
2620                 dump_one_xive(cpu);
2621 }
2622 
2623 static void dump_one_xive_irq(u32 num, struct irq_data *d)
2624 {
2625         xmon_xive_get_irq_config(num, d);
2626 }
2627 
2628 static void dump_all_xive_irq(void)
2629 {
2630         unsigned int i;
2631         struct irq_desc *desc;
2632 
2633         for_each_irq_desc(i, desc) {
2634                 struct irq_data *d = irq_desc_get_irq_data(desc);
2635                 unsigned int hwirq;
2636 
2637                 if (!d)
2638                         continue;
2639 
2640                 hwirq = (unsigned int)irqd_to_hwirq(d);
2641                 /* IPIs are special (HW number 0) */
2642                 if (hwirq)
2643                         dump_one_xive_irq(hwirq, d);
2644         }
2645 }
2646 
2647 static void dump_xives(void)
2648 {
2649         unsigned long num;
2650         int c;
2651 
2652         if (!xive_enabled()) {
2653                 printf("Xive disabled on this system\n");
2654                 return;
2655         }
2656 
2657         c = inchar();
2658         if (c == 'a') {
2659                 dump_all_xives();
2660                 return;
2661         } else if (c == 'i') {
2662                 if (scanhex(&num))
2663                         dump_one_xive_irq(num, NULL);
2664                 else
2665                         dump_all_xive_irq();
2666                 return;
2667         }
2668 
2669         termch = c;     /* Put c back, it wasn't 'a' */
2670 
2671         if (scanhex(&num))
2672                 dump_one_xive(num);
2673         else
2674                 dump_one_xive(xmon_owner);
2675 }
2676 #endif /* CONFIG_PPC_POWERNV */
2677 
2678 static void dump_by_size(unsigned long addr, long count, int size)
2679 {
2680         unsigned char temp[16];
2681         int i, j;
2682         u64 val;
2683 
2684         count = ALIGN(count, 16);
2685 
2686         for (i = 0; i < count; i += 16, addr += 16) {
2687                 printf(REG, addr);
2688 
2689                 if (mread(addr, temp, 16) != 16) {
2690                         printf("\nFaulted reading %d bytes from 0x"REG"\n", 16, addr);
2691                         return;
2692                 }
2693 
2694                 for (j = 0; j < 16; j += size) {
2695                         putchar(' ');
2696                         switch (size) {
2697                         case 1: val = temp[j]; break;
2698                         case 2: val = *(u16 *)&temp[j]; break;
2699                         case 4: val = *(u32 *)&temp[j]; break;
2700                         case 8: val = *(u64 *)&temp[j]; break;
2701                         default: val = 0;
2702                         }
2703 
2704                         printf("%0*llx", size * 2, val);
2705                 }
2706                 printf("\n");
2707         }
2708 }
2709 
2710 static void
2711 dump(void)
2712 {
2713         static char last[] = { "d?\n" };
2714         int c;
2715 
2716         c = inchar();
2717 
2718 #ifdef CONFIG_PPC64
2719         if (c == 'p') {
2720                 xmon_start_pagination();
2721                 dump_pacas();
2722                 xmon_end_pagination();
2723                 return;
2724         }
2725 #endif
2726 #ifdef CONFIG_PPC_POWERNV
2727         if (c == 'x') {
2728                 xmon_start_pagination();
2729                 dump_xives();
2730                 xmon_end_pagination();
2731                 return;
2732         }
2733 #endif
2734 
2735         if (c == 't') {
2736                 dump_tracing();
2737                 return;
2738         }
2739 
2740         if (c == '\n')
2741                 termch = c;
2742 
2743         scanhex((void *)&adrs);
2744         if (termch != '\n')
2745                 termch = 0;
2746         if (c == 'i') {
2747                 scanhex(&nidump);
2748                 if (nidump == 0)
2749                         nidump = 16;
2750                 else if (nidump > MAX_DUMP)
2751                         nidump = MAX_DUMP;
2752                 adrs += ppc_inst_dump(adrs, nidump, 1);
2753                 last_cmd = "di\n";
2754         } else if (c == 'l') {
2755                 dump_log_buf();
2756         } else if (c == 'o') {
2757                 dump_opal_msglog();
2758         } else if (c == 'v') {
2759                 /* dump virtual to physical translation */
2760                 show_pte(adrs);
2761         } else if (c == 'r') {
2762                 scanhex(&ndump);
2763                 if (ndump == 0)
2764                         ndump = 64;
2765                 xmon_rawdump(adrs, ndump);
2766                 adrs += ndump;
2767                 last_cmd = "dr\n";
2768         } else {
2769                 scanhex(&ndump);
2770                 if (ndump == 0)
2771                         ndump = 64;
2772                 else if (ndump > MAX_DUMP)
2773                         ndump = MAX_DUMP;
2774 
2775                 switch (c) {
2776                 case '8':
2777                 case '4':
2778                 case '2':
2779                 case '1':
2780                         ndump = ALIGN(ndump, 16);
2781                         dump_by_size(adrs, ndump, c - '0');
2782                         last[1] = c;
2783                         last_cmd = last;
2784                         break;
2785                 default:
2786                         prdump(adrs, ndump);
2787                         last_cmd = "d\n";
2788                 }
2789 
2790                 adrs += ndump;
2791         }
2792 }
2793 
2794 static void
2795 prdump(unsigned long adrs, long ndump)
2796 {
2797         long n, m, c, r, nr;
2798         unsigned char temp[16];
2799 
2800         for (n = ndump; n > 0;) {
2801                 printf(REG, adrs);
2802                 putchar(' ');
2803                 r = n < 16? n: 16;
2804                 nr = mread(adrs, temp, r);
2805                 adrs += nr;
2806                 for (m = 0; m < r; ++m) {
2807                         if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2808                                 putchar(' ');
2809                         if (m < nr)
2810                                 printf("%.2x", temp[m]);
2811                         else
2812                                 printf("%s", fault_chars[fault_type]);
2813                 }
2814                 for (; m < 16; ++m) {
2815                         if ((m & (sizeof(long) - 1)) == 0)
2816                                 putchar(' ');
2817                         printf("  ");
2818                 }
2819                 printf("  |");
2820                 for (m = 0; m < r; ++m) {
2821                         if (m < nr) {
2822                                 c = temp[m];
2823                                 putchar(' ' <= c && c <= '~'? c: '.');
2824                         } else
2825                                 putchar(' ');
2826                 }
2827                 n -= r;
2828                 for (; m < 16; ++m)
2829                         putchar(' ');
2830                 printf("|\n");
2831                 if (nr < r)
2832                         break;
2833         }
2834 }
2835 
2836 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2837 
2838 static int
2839 generic_inst_dump(unsigned long adr, long count, int praddr,
2840                         instruction_dump_func dump_func)
2841 {
2842         int nr, dotted;
2843         unsigned long first_adr;
2844         unsigned int inst, last_inst = 0;
2845         unsigned char val[4];
2846 
2847         dotted = 0;
2848         for (first_adr = adr; count > 0; --count, adr += 4) {
2849                 nr = mread(adr, val, 4);
2850                 if (nr == 0) {
2851                         if (praddr) {
2852                                 const char *x = fault_chars[fault_type];
2853                                 printf(REG"  %s%s%s%s\n", adr, x, x, x, x);
2854                         }
2855                         break;
2856                 }
2857                 inst = GETWORD(val);
2858                 if (adr > first_adr && inst == last_inst) {
2859                         if (!dotted) {
2860                                 printf(" ...\n");
2861                                 dotted = 1;
2862                         }
2863                         continue;
2864                 }
2865                 dotted = 0;
2866                 last_inst = inst;
2867                 if (praddr)
2868                         printf(REG"  %.8x", adr, inst);
2869                 printf("\t");
2870                 dump_func(inst, adr);
2871                 printf("\n");
2872         }
2873         return adr - first_adr;
2874 }
2875 
2876 static int
2877 ppc_inst_dump(unsigned long adr, long count, int praddr)
2878 {
2879         return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2880 }
2881 
2882 void
2883 print_address(unsigned long addr)
2884 {
2885         xmon_print_symbol(addr, "\t# ", "");
2886 }
2887 
2888 static void
2889 dump_log_buf(void)
2890 {
2891         struct kmsg_dumper dumper = { .active = 1 };
2892         unsigned char buf[128];
2893         size_t len;
2894 
2895         if (setjmp(bus_error_jmp) != 0) {
2896                 printf("Error dumping printk buffer!\n");
2897                 return;
2898         }
2899 
2900         catch_memory_errors = 1;
2901         sync();
2902 
2903         kmsg_dump_rewind_nolock(&dumper);
2904         xmon_start_pagination();
2905         while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
2906                 buf[len] = '\0';
2907                 printf("%s", buf);
2908         }
2909         xmon_end_pagination();
2910 
2911         sync();
2912         /* wait a little while to see if we get a machine check */
2913         __delay(200);
2914         catch_memory_errors = 0;
2915 }
2916 
2917 #ifdef CONFIG_PPC_POWERNV
2918 static void dump_opal_msglog(void)
2919 {
2920         unsigned char buf[128];
2921         ssize_t res;
2922         loff_t pos = 0;
2923 
2924         if (!firmware_has_feature(FW_FEATURE_OPAL)) {
2925                 printf("Machine is not running OPAL firmware.\n");
2926                 return;
2927         }
2928 
2929         if (setjmp(bus_error_jmp) != 0) {
2930                 printf("Error dumping OPAL msglog!\n");
2931                 return;
2932         }
2933 
2934         catch_memory_errors = 1;
2935         sync();
2936 
2937         xmon_start_pagination();
2938         while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) {
2939                 if (res < 0) {
2940                         printf("Error dumping OPAL msglog! Error: %zd\n", res);
2941                         break;
2942                 }
2943                 buf[res] = '\0';
2944                 printf("%s", buf);
2945                 pos += res;
2946         }
2947         xmon_end_pagination();
2948 
2949         sync();
2950         /* wait a little while to see if we get a machine check */
2951         __delay(200);
2952         catch_memory_errors = 0;
2953 }
2954 #endif
2955 
2956 /*
2957  * Memory operations - move, set, print differences
2958  */
2959 static unsigned long mdest;             /* destination address */
2960 static unsigned long msrc;              /* source address */
2961 static unsigned long mval;              /* byte value to set memory to */
2962 static unsigned long mcount;            /* # bytes to affect */
2963 static unsigned long mdiffs;            /* max # differences to print */
2964 
2965 static void
2966 memops(int cmd)
2967 {
2968         scanhex((void *)&mdest);
2969         if( termch != '\n' )
2970                 termch = 0;
2971         scanhex((void *)(cmd == 's'? &mval: &msrc));
2972         if( termch != '\n' )
2973                 termch = 0;
2974         scanhex((void *)&mcount);
2975         switch( cmd ){
2976         case 'm':
2977                 if (xmon_is_ro) {
2978                         printf(xmon_ro_msg);
2979                         break;
2980                 }
2981                 memmove((void *)mdest, (void *)msrc, mcount);
2982                 break;
2983         case 's':
2984                 if (xmon_is_ro) {
2985                         printf(xmon_ro_msg);
2986                         break;
2987                 }
2988                 memset((void *)mdest, mval, mcount);
2989                 break;
2990         case 'd':
2991                 if( termch != '\n' )
2992                         termch = 0;
2993                 scanhex((void *)&mdiffs);
2994                 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2995                 break;
2996         }
2997 }
2998 
2999 static void
3000 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
3001 {
3002         unsigned n, prt;
3003 
3004         prt = 0;
3005         for( n = nb; n > 0; --n )
3006                 if( *p1++ != *p2++ )
3007                         if( ++prt <= maxpr )
3008                                 printf("%px %.2x # %px %.2x\n", p1 - 1,
3009                                         p1[-1], p2 - 1, p2[-1]);
3010         if( prt > maxpr )
3011                 printf("Total of %d differences\n", prt);
3012 }
3013 
3014 static unsigned mend;
3015 static unsigned mask;
3016 
3017 static void
3018 memlocate(void)
3019 {
3020         unsigned a, n;
3021         unsigned char val[4];
3022 
3023         last_cmd = "ml";
3024         scanhex((void *)&mdest);
3025         if (termch != '\n') {
3026                 termch = 0;
3027                 scanhex((void *)&mend);
3028                 if (termch != '\n') {
3029                         termch = 0;
3030                         scanhex((void *)&mval);
3031                         mask = ~0;
3032                         if (termch != '\n') termch = 0;
3033                         scanhex((void *)&mask);
3034                 }
3035         }
3036         n = 0;
3037         for (a = mdest; a < mend; a += 4) {
3038                 if (mread(a, val, 4) == 4
3039                         && ((GETWORD(val) ^ mval) & mask) == 0) {
3040                         printf("%.16x:  %.16x\n", a, GETWORD(val));
3041                         if (++n >= 10)
3042                                 break;
3043                 }
3044         }
3045 }
3046 
3047 static unsigned long mskip = 0x1000;
3048 static unsigned long mlim = 0xffffffff;
3049 
3050 static void
3051 memzcan(void)
3052 {
3053         unsigned char v;
3054         unsigned a;
3055         int ok, ook;
3056 
3057         scanhex(&mdest);
3058         if (termch != '\n') termch = 0;
3059         scanhex(&mskip);
3060         if (termch != '\n') termch = 0;
3061         scanhex(&mlim);
3062         ook = 0;
3063         for (a = mdest; a < mlim; a += mskip) {
3064                 ok = mread(a, &v, 1);
3065                 if (ok && !ook) {
3066                         printf("%.8x .. ", a);
3067                 } else if (!ok && ook)
3068                         printf("%.8lx\n", a - mskip);
3069                 ook = ok;
3070                 if (a + mskip < a)
3071                         break;
3072         }
3073         if (ook)
3074                 printf("%.8lx\n", a - mskip);
3075 }
3076 
3077 static void show_task(struct task_struct *tsk)
3078 {
3079         char state;
3080 
3081         /*
3082          * Cloned from kdb_task_state_char(), which is not entirely
3083          * appropriate for calling from xmon. This could be moved
3084          * to a common, generic, routine used by both.
3085          */
3086         state = (tsk->state == 0) ? 'R' :
3087                 (tsk->state < 0) ? 'U' :
3088                 (tsk->state & TASK_UNINTERRUPTIBLE) ? 'D' :
3089                 (tsk->state & TASK_STOPPED) ? 'T' :
3090                 (tsk->state & TASK_TRACED) ? 'C' :
3091                 (tsk->exit_state & EXIT_ZOMBIE) ? 'Z' :
3092                 (tsk->exit_state & EXIT_DEAD) ? 'E' :
3093                 (tsk->state & TASK_INTERRUPTIBLE) ? 'S' : '?';
3094 
3095         printf("%px %016lx %6d %6d %c %2d %s\n", tsk,
3096                 tsk->thread.ksp,
3097                 tsk->pid, rcu_dereference(tsk->parent)->pid,
3098                 state, task_cpu(tsk),
3099                 tsk->comm);
3100 }
3101 
3102 #ifdef CONFIG_PPC_BOOK3S_64
3103 static void format_pte(void *ptep, unsigned long pte)
3104 {
3105         pte_t entry = __pte(pte);
3106 
3107         printf("ptep @ 0x%016lx = 0x%016lx\n", (unsigned long)ptep, pte);
3108         printf("Maps physical address = 0x%016lx\n", pte & PTE_RPN_MASK);
3109 
3110         printf("Flags = %s%s%s%s%s\n",
3111                pte_young(entry) ? "Accessed " : "",
3112                pte_dirty(entry) ? "Dirty " : "",
3113                pte_read(entry)  ? "Read " : "",
3114                pte_write(entry) ? "Write " : "",
3115                pte_exec(entry)  ? "Exec " : "");
3116 }
3117 
3118 static void show_pte(unsigned long addr)
3119 {
3120         unsigned long tskv = 0;
3121         struct task_struct *tsk = NULL;
3122         struct mm_struct *mm;
3123         pgd_t *pgdp, *pgdir;
3124         pud_t *pudp;
3125         pmd_t *pmdp;
3126         pte_t *ptep;
3127 
3128         if (!scanhex(&tskv))
3129                 mm = &init_mm;
3130         else
3131                 tsk = (struct task_struct *)tskv;
3132 
3133         if (tsk == NULL)
3134                 mm = &init_mm;
3135         else
3136                 mm = tsk->active_mm;
3137 
3138         if (setjmp(bus_error_jmp) != 0) {
3139                 catch_memory_errors = 0;
3140                 printf("*** Error dumping pte for task %px\n", tsk);
3141                 return;
3142         }
3143 
3144         catch_memory_errors = 1;
3145         sync();
3146 
3147         if (mm == &init_mm) {
3148                 pgdp = pgd_offset_k(addr);
3149                 pgdir = pgd_offset_k(0);
3150         } else {
3151                 pgdp = pgd_offset(mm, addr);
3152                 pgdir = pgd_offset(mm, 0);
3153         }
3154 
3155         if (pgd_none(*pgdp)) {
3156                 printf("no linux page table for address\n");
3157                 return;
3158         }
3159 
3160         printf("pgd  @ 0x%px\n", pgdir);
3161 
3162         if (pgd_is_leaf(*pgdp)) {
3163                 format_pte(pgdp, pgd_val(*pgdp));
3164                 return;
3165         }
3166         printf("pgdp @ 0x%px = 0x%016lx\n", pgdp, pgd_val(*pgdp));
3167 
3168         pudp = pud_offset(pgdp, addr);
3169 
3170         if (pud_none(*pudp)) {
3171                 printf("No valid PUD\n");
3172                 return;
3173         }
3174 
3175         if (pud_is_leaf(*pudp)) {
3176                 format_pte(pudp, pud_val(*pudp));
3177                 return;
3178         }
3179 
3180         printf("pudp @ 0x%px = 0x%016lx\n", pudp, pud_val(*pudp));
3181 
3182         pmdp = pmd_offset(pudp, addr);
3183 
3184         if (pmd_none(*pmdp)) {
3185                 printf("No valid PMD\n");
3186                 return;
3187         }
3188 
3189         if (pmd_is_leaf(*pmdp)) {
3190                 format_pte(pmdp, pmd_val(*pmdp));
3191                 return;
3192         }
3193         printf("pmdp @ 0x%px = 0x%016lx\n", pmdp, pmd_val(*pmdp));
3194 
3195         ptep = pte_offset_map(pmdp, addr);
3196         if (pte_none(*ptep)) {
3197                 printf("no valid PTE\n");
3198                 return;
3199         }
3200 
3201         format_pte(ptep, pte_val(*ptep));
3202 
3203         sync();
3204         __delay(200);
3205         catch_memory_errors = 0;
3206 }
3207 #else
3208 static void show_pte(unsigned long addr)
3209 {
3210         printf("show_pte not yet implemented\n");
3211 }
3212 #endif /* CONFIG_PPC_BOOK3S_64 */
3213 
3214 static void show_tasks(void)
3215 {
3216         unsigned long tskv;
3217         struct task_struct *tsk = NULL;
3218 
3219         printf("     task_struct     ->thread.ksp    PID   PPID S  P CMD\n");
3220 
3221         if (scanhex(&tskv))
3222                 tsk = (struct task_struct *)tskv;
3223 
3224         if (setjmp(bus_error_jmp) != 0) {
3225                 catch_memory_errors = 0;
3226                 printf("*** Error dumping task %px\n", tsk);
3227                 return;
3228         }
3229 
3230         catch_memory_errors = 1;
3231         sync();
3232 
3233         if (tsk)
3234                 show_task(tsk);
3235         else
3236                 for_each_process(tsk)
3237                         show_task(tsk);
3238 
3239         sync();
3240         __delay(200);
3241         catch_memory_errors = 0;
3242 }
3243 
3244 static void proccall(void)
3245 {
3246         unsigned long args[8];
3247         unsigned long ret;
3248         int i;
3249         typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
3250                         unsigned long, unsigned long, unsigned long,
3251                         unsigned long, unsigned long, unsigned long);
3252         callfunc_t func;
3253 
3254         if (!scanhex(&adrs))
3255                 return;
3256         if (termch != '\n')
3257                 termch = 0;
3258         for (i = 0; i < 8; ++i)
3259                 args[i] = 0;
3260         for (i = 0; i < 8; ++i) {
3261                 if (!scanhex(&args[i]) || termch == '\n')
3262                         break;
3263                 termch = 0;
3264         }
3265         func = (callfunc_t) adrs;
3266         ret = 0;
3267         if (setjmp(bus_error_jmp) == 0) {
3268                 catch_memory_errors = 1;
3269                 sync();
3270                 ret = func(args[0], args[1], args[2], args[3],
3271                            args[4], args[5], args[6], args[7]);
3272                 sync();
3273                 printf("return value is 0x%lx\n", ret);
3274         } else {
3275                 printf("*** %x exception occurred\n", fault_except);
3276         }
3277         catch_memory_errors = 0;
3278 }
3279 
3280 /* Input scanning routines */
3281 int
3282 skipbl(void)
3283 {
3284         int c;
3285 
3286         if( termch != 0 ){
3287                 c = termch;
3288                 termch = 0;
3289         } else
3290                 c = inchar();
3291         while( c == ' ' || c == '\t' )
3292                 c = inchar();
3293         return c;
3294 }
3295 
3296 #define N_PTREGS        44
3297 static const char *regnames[N_PTREGS] = {
3298         "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3299         "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
3300         "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
3301         "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
3302         "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
3303 #ifdef CONFIG_PPC64
3304         "softe",
3305 #else
3306         "mq",
3307 #endif
3308         "trap", "dar", "dsisr", "res"
3309 };
3310 
3311 int
3312 scanhex(unsigned long *vp)
3313 {
3314         int c, d;
3315         unsigned long v;
3316 
3317         c = skipbl();
3318         if (c == '%') {
3319                 /* parse register name */
3320                 char regname[8];
3321                 int i;
3322 
3323                 for (i = 0; i < sizeof(regname) - 1; ++i) {
3324                         c = inchar();
3325                         if (!isalnum(c)) {
3326                                 termch = c;
3327                                 break;
3328                         }
3329                         regname[i] = c;
3330                 }
3331                 regname[i] = 0;
3332                 i = match_string(regnames, N_PTREGS, regname);
3333                 if (i < 0) {
3334                         printf("invalid register name '%%%s'\n", regname);
3335                         return 0;
3336                 }
3337                 if (xmon_regs == NULL) {
3338                         printf("regs not available\n");
3339                         return 0;
3340                 }
3341                 *vp = ((unsigned long *)xmon_regs)[i];
3342                 return 1;
3343         }
3344 
3345         /* skip leading "0x" if any */
3346 
3347         if (c == '0') {
3348                 c = inchar();
3349                 if (c == 'x') {
3350                         c = inchar();
3351                 } else {
3352                         d = hexdigit(c);
3353                         if (d == EOF) {
3354                                 termch = c;
3355                                 *vp = 0;
3356                                 return 1;
3357                         }
3358                 }
3359         } else if (c == '$') {
3360                 int i;
3361                 for (i=0; i<63; i++) {
3362                         c = inchar();
3363                         if (isspace(c) || c == '\0') {
3364                                 termch = c;
3365                                 break;
3366                         }
3367                         tmpstr[i] = c;
3368                 }
3369                 tmpstr[i++] = 0;
3370                 *vp = 0;
3371                 if (setjmp(bus_error_jmp) == 0) {
3372                         catch_memory_errors = 1;
3373                         sync();
3374                         *vp = kallsyms_lookup_name(tmpstr);
3375                         sync();
3376                 }
3377                 catch_memory_errors = 0;
3378                 if (!(*vp)) {
3379                         printf("unknown symbol '%s'\n", tmpstr);
3380                         return 0;
3381                 }
3382                 return 1;
3383         }
3384 
3385         d = hexdigit(c);
3386         if (d == EOF) {
3387                 termch = c;
3388                 return 0;
3389         }
3390         v = 0;
3391         do {
3392                 v = (v << 4) + d;
3393                 c = inchar();
3394                 d = hexdigit(c);
3395         } while (d != EOF);
3396         termch = c;
3397         *vp = v;
3398         return 1;
3399 }
3400 
3401 static void
3402 scannl(void)
3403 {
3404         int c;
3405 
3406         c = termch;
3407         termch = 0;
3408         while( c != '\n' )
3409                 c = inchar();
3410 }
3411 
3412 static int hexdigit(int c)
3413 {
3414         if( '0' <= c && c <= '9' )
3415                 return c - '0';
3416         if( 'A' <= c && c <= 'F' )
3417                 return c - ('A' - 10);
3418         if( 'a' <= c && c <= 'f' )
3419                 return c - ('a' - 10);
3420         return EOF;
3421 }
3422 
3423 void
3424 getstring(char *s, int size)
3425 {
3426         int c;
3427 
3428         c = skipbl();
3429         do {
3430                 if( size > 1 ){
3431                         *s++ = c;
3432                         --size;
3433                 }
3434                 c = inchar();
3435         } while( c != ' ' && c != '\t' && c != '\n' );
3436         termch = c;
3437         *s = 0;
3438 }
3439 
3440 static char line[256];
3441 static char *lineptr;
3442 
3443 static void
3444 flush_input(void)
3445 {
3446         lineptr = NULL;
3447 }
3448 
3449 static int
3450 inchar(void)
3451 {
3452         if (lineptr == NULL || *lineptr == 0) {
3453                 if (xmon_gets(line, sizeof(line)) == NULL) {
3454                         lineptr = NULL;
3455                         return EOF;
3456                 }
3457                 lineptr = line;
3458         }
3459         return *lineptr++;
3460 }
3461 
3462 static void
3463 take_input(char *str)
3464 {
3465         lineptr = str;
3466 }
3467 
3468 
3469 static void
3470 symbol_lookup(void)
3471 {
3472         int type = inchar();
3473         unsigned long addr, cpu;
3474         void __percpu *ptr = NULL;
3475         static char tmp[64];
3476 
3477         switch (type) {
3478         case 'a':
3479                 if (scanhex(&addr))
3480                         xmon_print_symbol(addr, ": ", "\n");
3481                 termch = 0;
3482                 break;
3483         case 's':
3484                 getstring(tmp, 64);
3485                 if (setjmp(bus_error_jmp) == 0) {
3486                         catch_memory_errors = 1;
3487                         sync();
3488                         addr = kallsyms_lookup_name(tmp);
3489                         if (addr)
3490                                 printf("%s: %lx\n", tmp, addr);
3491                         else
3492                                 printf("Symbol '%s' not found.\n", tmp);
3493                         sync();
3494                 }
3495                 catch_memory_errors = 0;
3496                 termch = 0;
3497                 break;
3498         case 'p':
3499                 getstring(tmp, 64);
3500                 if (setjmp(bus_error_jmp) == 0) {
3501                         catch_memory_errors = 1;
3502                         sync();
3503                         ptr = (void __percpu *)kallsyms_lookup_name(tmp);
3504                         sync();
3505                 }
3506 
3507                 if (ptr &&
3508                     ptr >= (void __percpu *)__per_cpu_start &&
3509                     ptr < (void __percpu *)__per_cpu_end)
3510                 {
3511                         if (scanhex(&cpu) && cpu < num_possible_cpus()) {
3512                                 addr = (unsigned long)per_cpu_ptr(ptr, cpu);
3513                         } else {
3514                                 cpu = raw_smp_processor_id();
3515                                 addr = (unsigned long)this_cpu_ptr(ptr);
3516                         }
3517 
3518                         printf("%s for cpu 0x%lx: %lx\n", tmp, cpu, addr);
3519                 } else {
3520                         printf("Percpu symbol '%s' not found.\n", tmp);
3521                 }
3522 
3523                 catch_memory_errors = 0;
3524                 termch = 0;
3525                 break;
3526         }
3527 }
3528 
3529 
3530 /* Print an address in numeric and symbolic form (if possible) */
3531 static void xmon_print_symbol(unsigned long address, const char *mid,
3532                               const char *after)
3533 {
3534         char *modname;
3535         const char *name = NULL;
3536         unsigned long offset, size;
3537 
3538         printf(REG, address);
3539         if (setjmp(bus_error_jmp) == 0) {
3540                 catch_memory_errors = 1;
3541                 sync();
3542                 name = kallsyms_lookup(address, &size, &offset, &modname,
3543                                        tmpstr);
3544                 sync();
3545                 /* wait a little while to see if we get a machine check */
3546                 __delay(200);
3547         }
3548 
3549         catch_memory_errors = 0;
3550 
3551         if (name) {
3552                 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
3553                 if (modname)
3554                         printf(" [%s]", modname);
3555         }
3556         printf("%s", after);
3557 }
3558 
3559 #ifdef CONFIG_PPC_BOOK3S_64
3560 void dump_segments(void)
3561 {
3562         int i;
3563         unsigned long esid,vsid;
3564         unsigned long llp;
3565 
3566         printf("SLB contents of cpu 0x%x\n", smp_processor_id());
3567 
3568         for (i = 0; i < mmu_slb_size; i++) {
3569                 asm volatile("slbmfee  %0,%1" : "=r" (esid) : "r" (i));
3570                 asm volatile("slbmfev  %0,%1" : "=r" (vsid) : "r" (i));
3571 
3572                 if (!esid && !vsid)
3573                         continue;
3574 
3575                 printf("%02d %016lx %016lx", i, esid, vsid);
3576 
3577                 if (!(esid & SLB_ESID_V)) {
3578                         printf("\n");
3579                         continue;
3580                 }
3581 
3582                 llp = vsid & SLB_VSID_LLP;
3583                 if (vsid & SLB_VSID_B_1T) {
3584                         printf("  1T  ESID=%9lx  VSID=%13lx LLP:%3lx \n",
3585                                 GET_ESID_1T(esid),
3586                                 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
3587                                 llp);
3588                 } else {
3589                         printf(" 256M ESID=%9lx  VSID=%13lx LLP:%3lx \n",
3590                                 GET_ESID(esid),
3591                                 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
3592                                 llp);
3593                 }
3594         }
3595 }
3596 #endif
3597 
3598 #ifdef CONFIG_PPC_BOOK3S_32
3599 void dump_segments(void)
3600 {
3601         int i;
3602 
3603         printf("sr0-15 =");
3604         for (i = 0; i < 16; ++i)
3605                 printf(" %x", mfsrin(i << 28));
3606         printf("\n");
3607 }
3608 #endif
3609 
3610 #ifdef CONFIG_44x
3611 static void dump_tlb_44x(void)
3612 {
3613         int i;
3614 
3615         for (i = 0; i < PPC44x_TLB_SIZE; i++) {
3616                 unsigned long w0,w1,w2;
3617                 asm volatile("tlbre  %0,%1,0" : "=r" (w0) : "r" (i));
3618                 asm volatile("tlbre  %0,%1,1" : "=r" (w1) : "r" (i));
3619                 asm volatile("tlbre  %0,%1,2" : "=r" (w2) : "r" (i));
3620                 printf("[%02x] %08lx %08lx %08lx ", i, w0, w1, w2);
3621                 if (w0 & PPC44x_TLB_VALID) {
3622                         printf("V %08lx -> %01lx%08lx %c%c%c%c%c",
3623                                w0 & PPC44x_TLB_EPN_MASK,
3624                                w1 & PPC44x_TLB_ERPN_MASK,
3625                                w1 & PPC44x_TLB_RPN_MASK,
3626                                (w2 & PPC44x_TLB_W) ? 'W' : 'w',
3627                                (w2 & PPC44x_TLB_I) ? 'I' : 'i',
3628                                (w2 & PPC44x_TLB_M) ? 'M' : 'm',
3629                                (w2 & PPC44x_TLB_G) ? 'G' : 'g',
3630                                (w2 & PPC44x_TLB_E) ? 'E' : 'e');
3631                 }
3632                 printf("\n");
3633         }
3634 }
3635 #endif /* CONFIG_44x */
3636 
3637 #ifdef CONFIG_PPC_BOOK3E
3638 static void dump_tlb_book3e(void)
3639 {
3640         u32 mmucfg, pidmask, lpidmask;
3641         u64 ramask;
3642         int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
3643         int mmu_version;
3644         static const char *pgsz_names[] = {
3645                 "  1K",
3646                 "  2K",
3647                 "  4K",
3648                 "  8K",
3649                 " 16K",
3650                 " 32K",
3651                 " 64K",
3652                 "128K",
3653                 "256K",
3654                 "512K",
3655                 "  1M",
3656                 "  2M",
3657                 "  4M",
3658                 "  8M",
3659                 " 16M",
3660                 " 32M",
3661                 " 64M",
3662                 "128M",
3663                 "256M",
3664                 "512M",
3665                 "  1G",
3666                 "  2G",
3667                 "  4G",
3668                 "  8G",
3669                 " 16G",
3670                 " 32G",
3671                 " 64G",
3672                 "128G",
3673                 "256G",
3674                 "512G",
3675                 "  1T",
3676                 "  2T",
3677         };
3678 
3679         /* Gather some infos about the MMU */
3680         mmucfg = mfspr(SPRN_MMUCFG);
3681         mmu_version = (mmucfg & 3) + 1;
3682         ntlbs = ((mmucfg >> 2) & 3) + 1;
3683         pidsz = ((mmucfg >> 6) & 0x1f) + 1;
3684         lpidsz = (mmucfg >> 24) & 0xf;
3685         rasz = (mmucfg >> 16) & 0x7f;
3686         if ((mmu_version > 1) && (mmucfg & 0x10000))
3687                 lrat = 1;
3688         printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
3689                mmu_version, ntlbs, pidsz, lpidsz, rasz);
3690         pidmask = (1ul << pidsz) - 1;
3691         lpidmask = (1ul << lpidsz) - 1;
3692         ramask = (1ull << rasz) - 1;
3693 
3694         for (tlb = 0; tlb < ntlbs; tlb++) {
3695                 u32 tlbcfg;
3696                 int nent, assoc, new_cc = 1;
3697                 printf("TLB %d:\n------\n", tlb);
3698                 switch(tlb) {
3699                 case 0:
3700                         tlbcfg = mfspr(SPRN_TLB0CFG);
3701                         break;
3702                 case 1:
3703                         tlbcfg = mfspr(SPRN_TLB1CFG);
3704                         break;
3705                 case 2:
3706                         tlbcfg = mfspr(SPRN_TLB2CFG);
3707                         break;
3708                 case 3:
3709                         tlbcfg = mfspr(SPRN_TLB3CFG);
3710                         break;
3711                 default:
3712                         printf("Unsupported TLB number !\n");
3713                         continue;
3714                 }
3715                 nent = tlbcfg & 0xfff;
3716                 assoc = (tlbcfg >> 24) & 0xff;
3717                 for (i = 0; i < nent; i++) {
3718                         u32 mas0 = MAS0_TLBSEL(tlb);
3719                         u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
3720                         u64 mas2 = 0;
3721                         u64 mas7_mas3;
3722                         int esel = i, cc = i;
3723 
3724                         if (assoc != 0) {
3725                                 cc = i / assoc;
3726                                 esel = i % assoc;
3727                                 mas2 = cc * 0x1000;
3728                         }
3729 
3730                         mas0 |= MAS0_ESEL(esel);
3731                         mtspr(SPRN_MAS0, mas0);
3732                         mtspr(SPRN_MAS1, mas1);
3733                         mtspr(SPRN_MAS2, mas2);
3734                         asm volatile("tlbre  0,0,0" : : : "memory");
3735                         mas1 = mfspr(SPRN_MAS1);
3736                         mas2 = mfspr(SPRN_MAS2);
3737                         mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
3738                         if (assoc && (i % assoc) == 0)
3739                                 new_cc = 1;
3740                         if (!(mas1 & MAS1_VALID))
3741                                 continue;
3742                         if (assoc == 0)
3743                                 printf("%04x- ", i);
3744                         else if (new_cc)
3745                                 printf("%04x-%c", cc, 'A' + esel);
3746                         else
3747                                 printf("    |%c", 'A' + esel);
3748                         new_cc = 0;
3749                         printf(" %016llx %04x %s %c%c AS%c",
3750                                mas2 & ~0x3ffull,
3751                                (mas1 >> 16) & 0x3fff,
3752                                pgsz_names[(mas1 >> 7) & 0x1f],
3753                                mas1 & MAS1_IND ? 'I' : ' ',
3754                                mas1 & MAS1_IPROT ? 'P' : ' ',
3755                                mas1 & MAS1_TS ? '1' : '0');
3756                         printf(" %c%c%c%c%c%c%c",
3757                                mas2 & MAS2_X0 ? 'a' : ' ',
3758                                mas2 & MAS2_X1 ? 'v' : ' ',
3759                                mas2 & MAS2_W  ? 'w' : ' ',
3760                                mas2 & MAS2_I  ? 'i' : ' ',
3761                                mas2 & MAS2_M  ? 'm' : ' ',
3762                                mas2 & MAS2_G  ? 'g' : ' ',
3763                                mas2 & MAS2_E  ? 'e' : ' ');
3764                         printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
3765                         if (mas1 & MAS1_IND)
3766                                 printf(" %s\n",
3767                                        pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
3768                         else
3769                                 printf(" U%c%c%c S%c%c%c\n",
3770                                        mas7_mas3 & MAS3_UX ? 'x' : ' ',
3771                                        mas7_mas3 & MAS3_UW ? 'w' : ' ',
3772                                        mas7_mas3 & MAS3_UR ? 'r' : ' ',
3773                                        mas7_mas3 & MAS3_SX ? 'x' : ' ',
3774                                        mas7_mas3 & MAS3_SW ? 'w' : ' ',
3775                                        mas7_mas3 & MAS3_SR ? 'r' : ' ');
3776                 }
3777         }
3778 }
3779 #endif /* CONFIG_PPC_BOOK3E */
3780 
3781 static void xmon_init(int enable)
3782 {
3783         if (enable) {
3784                 __debugger = xmon;
3785                 __debugger_ipi = xmon_ipi;
3786                 __debugger_bpt = xmon_bpt;
3787                 __debugger_sstep = xmon_sstep;
3788                 __debugger_iabr_match = xmon_iabr_match;
3789                 __debugger_break_match = xmon_break_match;
3790                 __debugger_fault_handler = xmon_fault_handler;
3791 
3792 #ifdef CONFIG_PPC_PSERIES
3793                 /*
3794                  * Get the token here to avoid trying to get a lock
3795                  * during the crash, causing a deadlock.
3796                  */
3797                 set_indicator_token = rtas_token("set-indicator");
3798 #endif
3799         } else {
3800                 __debugger = NULL;
3801                 __debugger_ipi = NULL;
3802                 __debugger_bpt = NULL;
3803                 __debugger_sstep = NULL;
3804                 __debugger_iabr_match = NULL;
3805                 __debugger_break_match = NULL;
3806                 __debugger_fault_handler = NULL;
3807         }
3808 }
3809 
3810 #ifdef CONFIG_MAGIC_SYSRQ
3811 static void sysrq_handle_xmon(int key)
3812 {
3813         if (xmon_is_locked_down()) {
3814                 clear_all_bpt();
3815                 xmon_init(0);
3816                 return;
3817         }
3818         /* ensure xmon is enabled */
3819         xmon_init(1);
3820         debugger(get_irq_regs());
3821         if (!xmon_on)
3822                 xmon_init(0);
3823 }
3824 
3825 static struct sysrq_key_op sysrq_xmon_op = {
3826         .handler =      sysrq_handle_xmon,
3827         .help_msg =     "xmon(x)",
3828         .action_msg =   "Entering xmon",
3829 };
3830 
3831 static int __init setup_xmon_sysrq(void)
3832 {
3833         register_sysrq_key('x', &sysrq_xmon_op);
3834         return 0;
3835 }
3836 device_initcall(setup_xmon_sysrq);
3837 #endif /* CONFIG_MAGIC_SYSRQ */
3838 
3839 static void clear_all_bpt(void)
3840 {
3841         int i;
3842 
3843         /* clear/unpatch all breakpoints */
3844         remove_bpts();
3845         remove_cpu_bpts();
3846 
3847         /* Disable all breakpoints */
3848         for (i = 0; i < NBPTS; ++i)
3849                 bpts[i].enabled = 0;
3850 
3851         /* Clear any data or iabr breakpoints */
3852         if (iabr || dabr.enabled) {
3853                 iabr = NULL;
3854                 dabr.enabled = 0;
3855         }
3856 }
3857 
3858 #ifdef CONFIG_DEBUG_FS
3859 static int xmon_dbgfs_set(void *data, u64 val)
3860 {
3861         xmon_on = !!val;
3862         xmon_init(xmon_on);
3863 
3864         /* make sure all breakpoints removed when disabling */
3865         if (!xmon_on) {
3866                 clear_all_bpt();
3867                 get_output_lock();
3868                 printf("xmon: All breakpoints cleared\n");
3869                 release_output_lock();
3870         }
3871 
3872         return 0;
3873 }
3874 
3875 static int xmon_dbgfs_get(void *data, u64 *val)
3876 {
3877         *val = xmon_on;
3878         return 0;
3879 }
3880 
3881 DEFINE_SIMPLE_ATTRIBUTE(xmon_dbgfs_ops, xmon_dbgfs_get,
3882                         xmon_dbgfs_set, "%llu\n");
3883 
3884 static int __init setup_xmon_dbgfs(void)
3885 {
3886         debugfs_create_file("xmon", 0600, powerpc_debugfs_root, NULL,
3887                                 &xmon_dbgfs_ops);
3888         return 0;
3889 }
3890 device_initcall(setup_xmon_dbgfs);
3891 #endif /* CONFIG_DEBUG_FS */
3892 
3893 static int xmon_early __initdata;
3894 
3895 static int __init early_parse_xmon(char *p)
3896 {
3897         if (xmon_is_locked_down()) {
3898                 xmon_init(0);
3899                 xmon_early = 0;
3900                 xmon_on = 0;
3901         } else if (!p || strncmp(p, "early", 5) == 0) {
3902                 /* just "xmon" is equivalent to "xmon=early" */
3903                 xmon_init(1);
3904                 xmon_early = 1;
3905                 xmon_on = 1;
3906         } else if (strncmp(p, "on", 2) == 0) {
3907                 xmon_init(1);
3908                 xmon_on = 1;
3909         } else if (strncmp(p, "rw", 2) == 0) {
3910                 xmon_init(1);
3911                 xmon_on = 1;
3912                 xmon_is_ro = false;
3913         } else if (strncmp(p, "ro", 2) == 0) {
3914                 xmon_init(1);
3915                 xmon_on = 1;
3916                 xmon_is_ro = true;
3917         } else if (strncmp(p, "off", 3) == 0)
3918                 xmon_on = 0;
3919         else
3920                 return 1;
3921 
3922         return 0;
3923 }
3924 early_param("xmon", early_parse_xmon);
3925 
3926 void __init xmon_setup(void)
3927 {
3928         if (xmon_on)
3929                 xmon_init(1);
3930         if (xmon_early)
3931                 debugger(NULL);
3932 }
3933 
3934 #ifdef CONFIG_SPU_BASE
3935 
3936 struct spu_info {
3937         struct spu *spu;
3938         u64 saved_mfc_sr1_RW;
3939         u32 saved_spu_runcntl_RW;
3940         unsigned long dump_addr;
3941         u8 stopped_ok;
3942 };
3943 
3944 #define XMON_NUM_SPUS   16      /* Enough for current hardware */
3945 
3946 static struct spu_info spu_info[XMON_NUM_SPUS];
3947 
3948 void xmon_register_spus(struct list_head *list)
3949 {
3950         struct spu *spu;
3951 
3952         list_for_each_entry(spu, list, full_list) {
3953                 if (spu->number >= XMON_NUM_SPUS) {
3954                         WARN_ON(1);
3955                         continue;
3956                 }
3957 
3958                 spu_info[spu->number].spu = spu;
3959                 spu_info[spu->number].stopped_ok = 0;
3960                 spu_info[spu->number].dump_addr = (unsigned long)
3961                                 spu_info[spu->number].spu->local_store;
3962         }
3963 }
3964 
3965 static void stop_spus(void)
3966 {
3967         struct spu *spu;
3968         int i;
3969         u64 tmp;
3970 
3971         for (i = 0; i < XMON_NUM_SPUS; i++) {
3972                 if (!spu_info[i].spu)
3973                         continue;
3974 
3975                 if (setjmp(bus_error_jmp) == 0) {
3976                         catch_memory_errors = 1;
3977                         sync();
3978 
3979                         spu = spu_info[i].spu;
3980 
3981                         spu_info[i].saved_spu_runcntl_RW =
3982                                 in_be32(&spu->problem->spu_runcntl_RW);
3983 
3984                         tmp = spu_mfc_sr1_get(spu);
3985                         spu_info[i].saved_mfc_sr1_RW = tmp;
3986 
3987                         tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
3988                         spu_mfc_sr1_set(spu, tmp);
3989 
3990                         sync();
3991                         __delay(200);
3992 
3993                         spu_info[i].stopped_ok = 1;
3994 
3995                         printf("Stopped spu %.2d (was %s)\n", i,
3996                                         spu_info[i].saved_spu_runcntl_RW ?
3997                                         "running" : "stopped");
3998                 } else {
3999                         catch_memory_errors = 0;
4000                         printf("*** Error stopping spu %.2d\n", i);
4001                 }
4002                 catch_memory_errors = 0;
4003         }
4004 }
4005 
4006 static void restart_spus(void)
4007 {
4008         struct spu *spu;
4009         int i;
4010 
4011         for (i = 0; i < XMON_NUM_SPUS; i++) {
4012                 if (!spu_info[i].spu)
4013                         continue;
4014 
4015                 if (!spu_info[i].stopped_ok) {
4016                         printf("*** Error, spu %d was not successfully stopped"
4017                                         ", not restarting\n", i);
4018                         continue;
4019                 }
4020 
4021                 if (setjmp(bus_error_jmp) == 0) {
4022                         catch_memory_errors = 1;
4023                         sync();
4024 
4025                         spu = spu_info[i].spu;
4026                         spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
4027                         out_be32(&spu->problem->spu_runcntl_RW,
4028                                         spu_info[i].saved_spu_runcntl_RW);
4029 
4030                         sync();
4031                         __delay(200);
4032 
4033                         printf("Restarted spu %.2d\n", i);
4034                 } else {
4035                         catch_memory_errors = 0;
4036                         printf("*** Error restarting spu %.2d\n", i);
4037                 }
4038                 catch_memory_errors = 0;
4039         }
4040 }
4041 
4042 #define DUMP_WIDTH      23
4043 #define DUMP_VALUE(format, field, value)                                \
4044 do {                                                                    \
4045         if (setjmp(bus_error_jmp) == 0) {                               \
4046                 catch_memory_errors = 1;                                \
4047                 sync();                                                 \
4048                 printf("  %-*s = "format"\n", DUMP_WIDTH,               \
4049                                 #field, value);                         \
4050                 sync();                                                 \
4051                 __delay(200);                                           \
4052         } else {                                                        \
4053                 catch_memory_errors = 0;                                \
4054                 printf("  %-*s = *** Error reading field.\n",           \
4055                                         DUMP_WIDTH, #field);            \
4056         }                                                               \
4057         catch_memory_errors = 0;                                        \
4058 } while (0)
4059 
4060 #define DUMP_FIELD(obj, format, field)  \
4061         DUMP_VALUE(format, field, obj->field)
4062 
4063 static void dump_spu_fields(struct spu *spu)
4064 {
4065         printf("Dumping spu fields at address %p:\n", spu);
4066 
4067         DUMP_FIELD(spu, "0x%x", number);
4068         DUMP_FIELD(spu, "%s", name);
4069         DUMP_FIELD(spu, "0x%lx", local_store_phys);
4070         DUMP_FIELD(spu, "0x%p", local_store);
4071         DUMP_FIELD(spu, "0x%lx", ls_size);
4072         DUMP_FIELD(spu, "0x%x", node);
4073         DUMP_FIELD(spu, "0x%lx", flags);
4074         DUMP_FIELD(spu, "%llu", class_0_pending);
4075         DUMP_FIELD(spu, "0x%llx", class_0_dar);
4076         DUMP_FIELD(spu, "0x%llx", class_1_dar);
4077         DUMP_FIELD(spu, "0x%llx", class_1_dsisr);
4078         DUMP_FIELD(spu, "0x%x", irqs[0]);
4079         DUMP_FIELD(spu, "0x%x", irqs[1]);
4080         DUMP_FIELD(spu, "0x%x", irqs[2]);
4081         DUMP_FIELD(spu, "0x%x", slb_replace);
4082         DUMP_FIELD(spu, "%d", pid);
4083         DUMP_FIELD(spu, "0x%p", mm);
4084         DUMP_FIELD(spu, "0x%p", ctx);
4085         DUMP_FIELD(spu, "0x%p", rq);
4086         DUMP_FIELD(spu, "0x%llx", timestamp);
4087         DUMP_FIELD(spu, "0x%lx", problem_phys);
4088         DUMP_FIELD(spu, "0x%p", problem);
4089         DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
4090                         in_be32(&spu->problem->spu_runcntl_RW));
4091         DUMP_VALUE("0x%x", problem->spu_status_R,
4092                         in_be32(&spu->problem->spu_status_R));
4093         DUMP_VALUE("0x%x", problem->spu_npc_RW,
4094                         in_be32(&spu->problem->spu_npc_RW));
4095         DUMP_FIELD(spu, "0x%p", priv2);
4096         DUMP_FIELD(spu, "0x%p", pdata);
4097 }
4098 
4099 int
4100 spu_inst_dump(unsigned long adr, long count, int praddr)
4101 {
4102         return generic_inst_dump(adr, count, praddr, print_insn_spu);
4103 }
4104 
4105 static void dump_spu_ls(unsigned long num, int subcmd)
4106 {
4107         unsigned long offset, addr, ls_addr;
4108 
4109         if (setjmp(bus_error_jmp) == 0) {
4110                 catch_memory_errors = 1;
4111                 sync();
4112                 ls_addr = (unsigned long)spu_info[num].spu->local_store;
4113                 sync();
4114                 __delay(200);
4115         } else {
4116                 catch_memory_errors = 0;
4117                 printf("*** Error: accessing spu info for spu %ld\n", num);
4118                 return;
4119         }
4120         catch_memory_errors = 0;
4121 
4122         if (scanhex(&offset))
4123                 addr = ls_addr + offset;
4124         else
4125                 addr = spu_info[num].dump_addr;
4126 
4127         if (addr >= ls_addr + LS_SIZE) {
4128                 printf("*** Error: address outside of local store\n");
4129                 return;
4130         }
4131 
4132         switch (subcmd) {
4133         case 'i':
4134                 addr += spu_inst_dump(addr, 16, 1);
4135                 last_cmd = "sdi\n";
4136                 break;
4137         default:
4138                 prdump(addr, 64);
4139                 addr += 64;
4140                 last_cmd = "sd\n";
4141                 break;
4142         }
4143 
4144         spu_info[num].dump_addr = addr;
4145 }
4146 
4147 static int do_spu_cmd(void)
4148 {
4149         static unsigned long num = 0;
4150         int cmd, subcmd = 0;
4151 
4152         cmd = inchar();
4153         switch (cmd) {
4154         case 's':
4155                 stop_spus();
4156                 break;
4157         case 'r':
4158                 restart_spus();
4159                 break;
4160         case 'd':
4161                 subcmd = inchar();
4162                 if (isxdigit(subcmd) || subcmd == '\n')
4163                         termch = subcmd;
4164                 /* fall through */
4165         case 'f':
4166                 scanhex(&num);
4167                 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
4168                         printf("*** Error: invalid spu number\n");
4169                         return 0;
4170                 }
4171 
4172                 switch (cmd) {
4173                 case 'f':
4174                         dump_spu_fields(spu_info[num].spu);
4175                         break;
4176                 default:
4177                         dump_spu_ls(num, subcmd);
4178                         break;
4179                 }
4180 
4181                 break;
4182         default:
4183                 return -1;
4184         }
4185 
4186         return 0;
4187 }
4188 #else /* ! CONFIG_SPU_BASE */
4189 static int do_spu_cmd(void)
4190 {
4191         return -1;
4192 }
4193 #endif

/* [<][>][^][v][top][bottom][index][help] */