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