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