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