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