~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/xmon/xmon.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php