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