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