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