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