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