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