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