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