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