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