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