Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[pandora-kernel.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/export.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 !cpumask_empty(&cpus_in_xmon);
338 }
339 #endif
340
341 static inline int unrecoverable_excp(struct pt_regs *regs)
342 {
343 #if defined(CONFIG_4xx) || defined(CONFIG_BOOK3E)
344         /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
345         return 0;
346 #else
347         return ((regs->msr & MSR_RI) == 0);
348 #endif
349 }
350
351 static int xmon_core(struct pt_regs *regs, int fromipi)
352 {
353         int cmd = 0;
354         struct bpt *bp;
355         long recurse_jmp[JMP_BUF_LEN];
356         unsigned long offset;
357         unsigned long flags;
358 #ifdef CONFIG_SMP
359         int cpu;
360         int secondary;
361         unsigned long timeout;
362 #endif
363
364         local_irq_save(flags);
365
366         bp = in_breakpoint_table(regs->nip, &offset);
367         if (bp != NULL) {
368                 regs->nip = bp->address + offset;
369                 atomic_dec(&bp->ref_count);
370         }
371
372         remove_cpu_bpts();
373
374 #ifdef CONFIG_SMP
375         cpu = smp_processor_id();
376         if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
377                 get_output_lock();
378                 excprint(regs);
379                 printf("cpu 0x%x: Exception %lx %s in xmon, "
380                        "returning to main loop\n",
381                        cpu, regs->trap, getvecname(TRAP(regs)));
382                 release_output_lock();
383                 longjmp(xmon_fault_jmp[cpu], 1);
384         }
385
386         if (setjmp(recurse_jmp) != 0) {
387                 if (!in_xmon || !xmon_gate) {
388                         get_output_lock();
389                         printf("xmon: WARNING: bad recursive fault "
390                                "on cpu 0x%x\n", cpu);
391                         release_output_lock();
392                         goto waiting;
393                 }
394                 secondary = !(xmon_taken && cpu == xmon_owner);
395                 goto cmdloop;
396         }
397
398         xmon_fault_jmp[cpu] = recurse_jmp;
399         cpumask_set_cpu(cpu, &cpus_in_xmon);
400
401         bp = NULL;
402         if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
403                 bp = at_breakpoint(regs->nip);
404         if (bp || unrecoverable_excp(regs))
405                 fromipi = 0;
406
407         if (!fromipi) {
408                 get_output_lock();
409                 excprint(regs);
410                 if (bp) {
411                         printf("cpu 0x%x stopped at breakpoint 0x%x (",
412                                cpu, BP_NUM(bp));
413                         xmon_print_symbol(regs->nip, " ", ")\n");
414                 }
415                 if (unrecoverable_excp(regs))
416                         printf("WARNING: exception is not recoverable, "
417                                "can't continue\n");
418                 release_output_lock();
419         }
420
421  waiting:
422         secondary = 1;
423         while (secondary && !xmon_gate) {
424                 if (in_xmon == 0) {
425                         if (fromipi)
426                                 goto leave;
427                         secondary = test_and_set_bit(0, &in_xmon);
428                 }
429                 barrier();
430         }
431
432         if (!secondary && !xmon_gate) {
433                 /* we are the first cpu to come in */
434                 /* interrupt other cpu(s) */
435                 int ncpus = num_online_cpus();
436
437                 xmon_owner = cpu;
438                 mb();
439                 if (ncpus > 1) {
440                         smp_send_debugger_break();
441                         /* wait for other cpus to come in */
442                         for (timeout = 100000000; timeout != 0; --timeout) {
443                                 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
444                                         break;
445                                 barrier();
446                         }
447                 }
448                 remove_bpts();
449                 disable_surveillance();
450                 /* for breakpoint or single step, print the current instr. */
451                 if (bp || TRAP(regs) == 0xd00)
452                         ppc_inst_dump(regs->nip, 1, 0);
453                 printf("enter ? for help\n");
454                 mb();
455                 xmon_gate = 1;
456                 barrier();
457         }
458
459  cmdloop:
460         while (in_xmon) {
461                 if (secondary) {
462                         if (cpu == xmon_owner) {
463                                 if (!test_and_set_bit(0, &xmon_taken)) {
464                                         secondary = 0;
465                                         continue;
466                                 }
467                                 /* missed it */
468                                 while (cpu == xmon_owner)
469                                         barrier();
470                         }
471                         barrier();
472                 } else {
473                         cmd = cmds(regs);
474                         if (cmd != 0) {
475                                 /* exiting xmon */
476                                 insert_bpts();
477                                 xmon_gate = 0;
478                                 wmb();
479                                 in_xmon = 0;
480                                 break;
481                         }
482                         /* have switched to some other cpu */
483                         secondary = 1;
484                 }
485         }
486  leave:
487         cpumask_clear_cpu(cpu, &cpus_in_xmon);
488         xmon_fault_jmp[cpu] = NULL;
489 #else
490         /* UP is simple... */
491         if (in_xmon) {
492                 printf("Exception %lx %s in xmon, returning to main loop\n",
493                        regs->trap, getvecname(TRAP(regs)));
494                 longjmp(xmon_fault_jmp[0], 1);
495         }
496         if (setjmp(recurse_jmp) == 0) {
497                 xmon_fault_jmp[0] = recurse_jmp;
498                 in_xmon = 1;
499
500                 excprint(regs);
501                 bp = at_breakpoint(regs->nip);
502                 if (bp) {
503                         printf("Stopped at breakpoint %x (", BP_NUM(bp));
504                         xmon_print_symbol(regs->nip, " ", ")\n");
505                 }
506                 if (unrecoverable_excp(regs))
507                         printf("WARNING: exception is not recoverable, "
508                                "can't continue\n");
509                 remove_bpts();
510                 disable_surveillance();
511                 /* for breakpoint or single step, print the current instr. */
512                 if (bp || TRAP(regs) == 0xd00)
513                         ppc_inst_dump(regs->nip, 1, 0);
514                 printf("enter ? for help\n");
515         }
516
517         cmd = cmds(regs);
518
519         insert_bpts();
520         in_xmon = 0;
521 #endif
522
523 #ifdef CONFIG_BOOKE
524         if (regs->msr & MSR_DE) {
525                 bp = at_breakpoint(regs->nip);
526                 if (bp != NULL) {
527                         regs->nip = (unsigned long) &bp->instr[0];
528                         atomic_inc(&bp->ref_count);
529                 }
530         }
531 #else
532         if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
533                 bp = at_breakpoint(regs->nip);
534                 if (bp != NULL) {
535                         int stepped = emulate_step(regs, bp->instr[0]);
536                         if (stepped == 0) {
537                                 regs->nip = (unsigned long) &bp->instr[0];
538                                 atomic_inc(&bp->ref_count);
539                         } else if (stepped < 0) {
540                                 printf("Couldn't single-step %s instruction\n",
541                                     (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
542                         }
543                 }
544         }
545 #endif
546         insert_cpu_bpts();
547
548         local_irq_restore(flags);
549
550         return cmd != 'X' && cmd != EOF;
551 }
552
553 int xmon(struct pt_regs *excp)
554 {
555         struct pt_regs regs;
556
557         if (excp == NULL) {
558                 ppc_save_regs(&regs);
559                 excp = &regs;
560         }
561
562         return xmon_core(excp, 0);
563 }
564 EXPORT_SYMBOL(xmon);
565
566 irqreturn_t xmon_irq(int irq, void *d)
567 {
568         unsigned long flags;
569         local_irq_save(flags);
570         printf("Keyboard interrupt\n");
571         xmon(get_irq_regs());
572         local_irq_restore(flags);
573         return IRQ_HANDLED;
574 }
575
576 static int xmon_bpt(struct pt_regs *regs)
577 {
578         struct bpt *bp;
579         unsigned long offset;
580
581         if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
582                 return 0;
583
584         /* Are we at the trap at bp->instr[1] for some bp? */
585         bp = in_breakpoint_table(regs->nip, &offset);
586         if (bp != NULL && offset == 4) {
587                 regs->nip = bp->address + 4;
588                 atomic_dec(&bp->ref_count);
589                 return 1;
590         }
591
592         /* Are we at a breakpoint? */
593         bp = at_breakpoint(regs->nip);
594         if (!bp)
595                 return 0;
596
597         xmon_core(regs, 0);
598
599         return 1;
600 }
601
602 static int xmon_sstep(struct pt_regs *regs)
603 {
604         if (user_mode(regs))
605                 return 0;
606         xmon_core(regs, 0);
607         return 1;
608 }
609
610 static int xmon_dabr_match(struct pt_regs *regs)
611 {
612         if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
613                 return 0;
614         if (dabr.enabled == 0)
615                 return 0;
616         xmon_core(regs, 0);
617         return 1;
618 }
619
620 static int xmon_iabr_match(struct pt_regs *regs)
621 {
622         if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
623                 return 0;
624         if (iabr == NULL)
625                 return 0;
626         xmon_core(regs, 0);
627         return 1;
628 }
629
630 static int xmon_ipi(struct pt_regs *regs)
631 {
632 #ifdef CONFIG_SMP
633         if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
634                 xmon_core(regs, 1);
635 #endif
636         return 0;
637 }
638
639 static int xmon_fault_handler(struct pt_regs *regs)
640 {
641         struct bpt *bp;
642         unsigned long offset;
643
644         if (in_xmon && catch_memory_errors)
645                 handle_fault(regs);     /* doesn't return */
646
647         if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
648                 bp = in_breakpoint_table(regs->nip, &offset);
649                 if (bp != NULL) {
650                         regs->nip = bp->address + offset;
651                         atomic_dec(&bp->ref_count);
652                 }
653         }
654
655         return 0;
656 }
657
658 static struct bpt *at_breakpoint(unsigned long pc)
659 {
660         int i;
661         struct bpt *bp;
662
663         bp = bpts;
664         for (i = 0; i < NBPTS; ++i, ++bp)
665                 if (bp->enabled && pc == bp->address)
666                         return bp;
667         return NULL;
668 }
669
670 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
671 {
672         unsigned long off;
673
674         off = nip - (unsigned long) bpts;
675         if (off >= sizeof(bpts))
676                 return NULL;
677         off %= sizeof(struct bpt);
678         if (off != offsetof(struct bpt, instr[0])
679             && off != offsetof(struct bpt, instr[1]))
680                 return NULL;
681         *offp = off - offsetof(struct bpt, instr[0]);
682         return (struct bpt *) (nip - off);
683 }
684
685 static struct bpt *new_breakpoint(unsigned long a)
686 {
687         struct bpt *bp;
688
689         a &= ~3UL;
690         bp = at_breakpoint(a);
691         if (bp)
692                 return bp;
693
694         for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
695                 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
696                         bp->address = a;
697                         bp->instr[1] = bpinstr;
698                         store_inst(&bp->instr[1]);
699                         return bp;
700                 }
701         }
702
703         printf("Sorry, no free breakpoints.  Please clear one first.\n");
704         return NULL;
705 }
706
707 static void insert_bpts(void)
708 {
709         int i;
710         struct bpt *bp;
711
712         bp = bpts;
713         for (i = 0; i < NBPTS; ++i, ++bp) {
714                 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
715                         continue;
716                 if (mread(bp->address, &bp->instr[0], 4) != 4) {
717                         printf("Couldn't read instruction at %lx, "
718                                "disabling breakpoint there\n", bp->address);
719                         bp->enabled = 0;
720                         continue;
721                 }
722                 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
723                         printf("Breakpoint at %lx is on an mtmsrd or rfid "
724                                "instruction, disabling it\n", bp->address);
725                         bp->enabled = 0;
726                         continue;
727                 }
728                 store_inst(&bp->instr[0]);
729                 if (bp->enabled & BP_IABR)
730                         continue;
731                 if (mwrite(bp->address, &bpinstr, 4) != 4) {
732                         printf("Couldn't write instruction at %lx, "
733                                "disabling breakpoint there\n", bp->address);
734                         bp->enabled &= ~BP_TRAP;
735                         continue;
736                 }
737                 store_inst((void *)bp->address);
738         }
739 }
740
741 static void insert_cpu_bpts(void)
742 {
743         if (dabr.enabled)
744                 set_dabr(dabr.address | (dabr.enabled & 7));
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_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|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 (cpumask_test_cpu(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 (!cpumask_test_cpu(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         if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
1501                 printf("cfar= ");
1502                 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1503         }
1504         printf("lr  = ");
1505         xmon_print_symbol(fp->link, " ", "\n");
1506         printf("msr = "REG"   cr  = %.8lx\n", fp->msr, fp->ccr);
1507         printf("ctr = "REG"   xer = "REG"   trap = %4lx\n",
1508                fp->ctr, fp->xer, fp->trap);
1509         trap = TRAP(fp);
1510         if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1511                 printf("dar = "REG"   dsisr = %.8lx\n", fp->dar, fp->dsisr);
1512 }
1513
1514 static void cacheflush(void)
1515 {
1516         int cmd;
1517         unsigned long nflush;
1518
1519         cmd = inchar();
1520         if (cmd != 'i')
1521                 termch = cmd;
1522         scanhex((void *)&adrs);
1523         if (termch != '\n')
1524                 termch = 0;
1525         nflush = 1;
1526         scanhex(&nflush);
1527         nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1528         if (setjmp(bus_error_jmp) == 0) {
1529                 catch_memory_errors = 1;
1530                 sync();
1531
1532                 if (cmd != 'i') {
1533                         for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1534                                 cflush((void *) adrs);
1535                 } else {
1536                         for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1537                                 cinval((void *) adrs);
1538                 }
1539                 sync();
1540                 /* wait a little while to see if we get a machine check */
1541                 __delay(200);
1542         }
1543         catch_memory_errors = 0;
1544 }
1545
1546 static unsigned long
1547 read_spr(int n)
1548 {
1549         unsigned int instrs[2];
1550         unsigned long (*code)(void);
1551         unsigned long ret = -1UL;
1552 #ifdef CONFIG_PPC64
1553         unsigned long opd[3];
1554
1555         opd[0] = (unsigned long)instrs;
1556         opd[1] = 0;
1557         opd[2] = 0;
1558         code = (unsigned long (*)(void)) opd;
1559 #else
1560         code = (unsigned long (*)(void)) instrs;
1561 #endif
1562
1563         /* mfspr r3,n; blr */
1564         instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1565         instrs[1] = 0x4e800020;
1566         store_inst(instrs);
1567         store_inst(instrs+1);
1568
1569         if (setjmp(bus_error_jmp) == 0) {
1570                 catch_memory_errors = 1;
1571                 sync();
1572
1573                 ret = code();
1574
1575                 sync();
1576                 /* wait a little while to see if we get a machine check */
1577                 __delay(200);
1578                 n = size;
1579         }
1580
1581         return ret;
1582 }
1583
1584 static void
1585 write_spr(int n, unsigned long val)
1586 {
1587         unsigned int instrs[2];
1588         unsigned long (*code)(unsigned long);
1589 #ifdef CONFIG_PPC64
1590         unsigned long opd[3];
1591
1592         opd[0] = (unsigned long)instrs;
1593         opd[1] = 0;
1594         opd[2] = 0;
1595         code = (unsigned long (*)(unsigned long)) opd;
1596 #else
1597         code = (unsigned long (*)(unsigned long)) instrs;
1598 #endif
1599
1600         instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1601         instrs[1] = 0x4e800020;
1602         store_inst(instrs);
1603         store_inst(instrs+1);
1604
1605         if (setjmp(bus_error_jmp) == 0) {
1606                 catch_memory_errors = 1;
1607                 sync();
1608
1609                 code(val);
1610
1611                 sync();
1612                 /* wait a little while to see if we get a machine check */
1613                 __delay(200);
1614                 n = size;
1615         }
1616 }
1617
1618 static unsigned long regno;
1619 extern char exc_prolog;
1620 extern char dec_exc;
1621
1622 static void super_regs(void)
1623 {
1624         int cmd;
1625         unsigned long val;
1626
1627         cmd = skipbl();
1628         if (cmd == '\n') {
1629                 unsigned long sp, toc;
1630                 asm("mr %0,1" : "=r" (sp) :);
1631                 asm("mr %0,2" : "=r" (toc) :);
1632
1633                 printf("msr  = "REG"  sprg0= "REG"\n",
1634                        mfmsr(), mfspr(SPRN_SPRG0));
1635                 printf("pvr  = "REG"  sprg1= "REG"\n",
1636                        mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); 
1637                 printf("dec  = "REG"  sprg2= "REG"\n",
1638                        mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1639                 printf("sp   = "REG"  sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1640                 printf("toc  = "REG"  dar  = "REG"\n", toc, mfspr(SPRN_DAR));
1641 #ifdef CONFIG_PPC_ISERIES
1642                 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1643                         struct paca_struct *ptrPaca;
1644                         struct lppaca *ptrLpPaca;
1645
1646                         /* Dump out relevant Paca data areas. */
1647                         printf("Paca: \n");
1648                         ptrPaca = get_paca();
1649
1650                         printf("  Local Processor Control Area (LpPaca): \n");
1651                         ptrLpPaca = ptrPaca->lppaca_ptr;
1652                         printf("    Saved Srr0=%.16lx  Saved Srr1=%.16lx \n",
1653                                ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1654                         printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",
1655                                ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1656                         printf("    Saved Gpr5=%.16lx \n",
1657                                 ptrLpPaca->gpr5_dword.saved_gpr5);
1658                 }
1659 #endif
1660
1661                 return;
1662         }
1663
1664         scanhex(&regno);
1665         switch (cmd) {
1666         case 'w':
1667                 val = read_spr(regno);
1668                 scanhex(&val);
1669                 write_spr(regno, val);
1670                 /* fall through */
1671         case 'r':
1672                 printf("spr %lx = %lx\n", regno, read_spr(regno));
1673                 break;
1674         }
1675         scannl();
1676 }
1677
1678 /*
1679  * Stuff for reading and writing memory safely
1680  */
1681 static int
1682 mread(unsigned long adrs, void *buf, int size)
1683 {
1684         volatile int n;
1685         char *p, *q;
1686
1687         n = 0;
1688         if (setjmp(bus_error_jmp) == 0) {
1689                 catch_memory_errors = 1;
1690                 sync();
1691                 p = (char *)adrs;
1692                 q = (char *)buf;
1693                 switch (size) {
1694                 case 2:
1695                         *(u16 *)q = *(u16 *)p;
1696                         break;
1697                 case 4:
1698                         *(u32 *)q = *(u32 *)p;
1699                         break;
1700                 case 8:
1701                         *(u64 *)q = *(u64 *)p;
1702                         break;
1703                 default:
1704                         for( ; n < size; ++n) {
1705                                 *q++ = *p++;
1706                                 sync();
1707                         }
1708                 }
1709                 sync();
1710                 /* wait a little while to see if we get a machine check */
1711                 __delay(200);
1712                 n = size;
1713         }
1714         catch_memory_errors = 0;
1715         return n;
1716 }
1717
1718 static int
1719 mwrite(unsigned long adrs, void *buf, int size)
1720 {
1721         volatile int n;
1722         char *p, *q;
1723
1724         n = 0;
1725         if (setjmp(bus_error_jmp) == 0) {
1726                 catch_memory_errors = 1;
1727                 sync();
1728                 p = (char *) adrs;
1729                 q = (char *) buf;
1730                 switch (size) {
1731                 case 2:
1732                         *(u16 *)p = *(u16 *)q;
1733                         break;
1734                 case 4:
1735                         *(u32 *)p = *(u32 *)q;
1736                         break;
1737                 case 8:
1738                         *(u64 *)p = *(u64 *)q;
1739                         break;
1740                 default:
1741                         for ( ; n < size; ++n) {
1742                                 *p++ = *q++;
1743                                 sync();
1744                         }
1745                 }
1746                 sync();
1747                 /* wait a little while to see if we get a machine check */
1748                 __delay(200);
1749                 n = size;
1750         } else {
1751                 printf("*** Error writing address %x\n", adrs + n);
1752         }
1753         catch_memory_errors = 0;
1754         return n;
1755 }
1756
1757 static int fault_type;
1758 static int fault_except;
1759 static char *fault_chars[] = { "--", "**", "##" };
1760
1761 static int handle_fault(struct pt_regs *regs)
1762 {
1763         fault_except = TRAP(regs);
1764         switch (TRAP(regs)) {
1765         case 0x200:
1766                 fault_type = 0;
1767                 break;
1768         case 0x300:
1769         case 0x380:
1770                 fault_type = 1;
1771                 break;
1772         default:
1773                 fault_type = 2;
1774         }
1775
1776         longjmp(bus_error_jmp, 1);
1777
1778         return 0;
1779 }
1780
1781 #define SWAP(a, b, t)   ((t) = (a), (a) = (b), (b) = (t))
1782
1783 static void
1784 byterev(unsigned char *val, int size)
1785 {
1786         int t;
1787         
1788         switch (size) {
1789         case 2:
1790                 SWAP(val[0], val[1], t);
1791                 break;
1792         case 4:
1793                 SWAP(val[0], val[3], t);
1794                 SWAP(val[1], val[2], t);
1795                 break;
1796         case 8: /* is there really any use for this? */
1797                 SWAP(val[0], val[7], t);
1798                 SWAP(val[1], val[6], t);
1799                 SWAP(val[2], val[5], t);
1800                 SWAP(val[3], val[4], t);
1801                 break;
1802         }
1803 }
1804
1805 static int brev;
1806 static int mnoread;
1807
1808 static char *memex_help_string = 
1809     "Memory examine command usage:\n"
1810     "m [addr] [flags] examine/change memory\n"
1811     "  addr is optional.  will start where left off.\n"
1812     "  flags may include chars from this set:\n"
1813     "    b   modify by bytes (default)\n"
1814     "    w   modify by words (2 byte)\n"
1815     "    l   modify by longs (4 byte)\n"
1816     "    d   modify by doubleword (8 byte)\n"
1817     "    r   toggle reverse byte order mode\n"
1818     "    n   do not read memory (for i/o spaces)\n"
1819     "    .   ok to read (default)\n"
1820     "NOTE: flags are saved as defaults\n"
1821     "";
1822
1823 static char *memex_subcmd_help_string = 
1824     "Memory examine subcommands:\n"
1825     "  hexval   write this val to current location\n"
1826     "  'string' write chars from string to this location\n"
1827     "  '        increment address\n"
1828     "  ^        decrement address\n"
1829     "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etc\n"
1830     "  \\        decrement addr by 0x10.  \\\\=0x100, \\\\\\=0x1000, etc\n"
1831     "  `        clear no-read flag\n"
1832     "  ;        stay at this addr\n"
1833     "  v        change to byte mode\n"
1834     "  w        change to word (2 byte) mode\n"
1835     "  l        change to long (4 byte) mode\n"
1836     "  u        change to doubleword (8 byte) mode\n"
1837     "  m addr   change current addr\n"
1838     "  n        toggle no-read flag\n"
1839     "  r        toggle byte reverse flag\n"
1840     "  < count  back up count bytes\n"
1841     "  > count  skip forward count bytes\n"
1842     "  x        exit this mode\n"
1843     "";
1844
1845 static void
1846 memex(void)
1847 {
1848         int cmd, inc, i, nslash;
1849         unsigned long n;
1850         unsigned char val[16];
1851
1852         scanhex((void *)&adrs);
1853         cmd = skipbl();
1854         if (cmd == '?') {
1855                 printf(memex_help_string);
1856                 return;
1857         } else {
1858                 termch = cmd;
1859         }
1860         last_cmd = "m\n";
1861         while ((cmd = skipbl()) != '\n') {
1862                 switch( cmd ){
1863                 case 'b':       size = 1;       break;
1864                 case 'w':       size = 2;       break;
1865                 case 'l':       size = 4;       break;
1866                 case 'd':       size = 8;       break;
1867                 case 'r':       brev = !brev;   break;
1868                 case 'n':       mnoread = 1;    break;
1869                 case '.':       mnoread = 0;    break;
1870                 }
1871         }
1872         if( size <= 0 )
1873                 size = 1;
1874         else if( size > 8 )
1875                 size = 8;
1876         for(;;){
1877                 if (!mnoread)
1878                         n = mread(adrs, val, size);
1879                 printf(REG"%c", adrs, brev? 'r': ' ');
1880                 if (!mnoread) {
1881                         if (brev)
1882                                 byterev(val, size);
1883                         putchar(' ');
1884                         for (i = 0; i < n; ++i)
1885                                 printf("%.2x", val[i]);
1886                         for (; i < size; ++i)
1887                                 printf("%s", fault_chars[fault_type]);
1888                 }
1889                 putchar(' ');
1890                 inc = size;
1891                 nslash = 0;
1892                 for(;;){
1893                         if( scanhex(&n) ){
1894                                 for (i = 0; i < size; ++i)
1895                                         val[i] = n >> (i * 8);
1896                                 if (!brev)
1897                                         byterev(val, size);
1898                                 mwrite(adrs, val, size);
1899                                 inc = size;
1900                         }
1901                         cmd = skipbl();
1902                         if (cmd == '\n')
1903                                 break;
1904                         inc = 0;
1905                         switch (cmd) {
1906                         case '\'':
1907                                 for(;;){
1908                                         n = inchar();
1909                                         if( n == '\\' )
1910                                                 n = bsesc();
1911                                         else if( n == '\'' )
1912                                                 break;
1913                                         for (i = 0; i < size; ++i)
1914                                                 val[i] = n >> (i * 8);
1915                                         if (!brev)
1916                                                 byterev(val, size);
1917                                         mwrite(adrs, val, size);
1918                                         adrs += size;
1919                                 }
1920                                 adrs -= size;
1921                                 inc = size;
1922                                 break;
1923                         case ',':
1924                                 adrs += size;
1925                                 break;
1926                         case '.':
1927                                 mnoread = 0;
1928                                 break;
1929                         case ';':
1930                                 break;
1931                         case 'x':
1932                         case EOF:
1933                                 scannl();
1934                                 return;
1935                         case 'b':
1936                         case 'v':
1937                                 size = 1;
1938                                 break;
1939                         case 'w':
1940                                 size = 2;
1941                                 break;
1942                         case 'l':
1943                                 size = 4;
1944                                 break;
1945                         case 'u':
1946                                 size = 8;
1947                                 break;
1948                         case '^':
1949                                 adrs -= size;
1950                                 break;
1951                                 break;
1952                         case '/':
1953                                 if (nslash > 0)
1954                                         adrs -= 1 << nslash;
1955                                 else
1956                                         nslash = 0;
1957                                 nslash += 4;
1958                                 adrs += 1 << nslash;
1959                                 break;
1960                         case '\\':
1961                                 if (nslash < 0)
1962                                         adrs += 1 << -nslash;
1963                                 else
1964                                         nslash = 0;
1965                                 nslash -= 4;
1966                                 adrs -= 1 << -nslash;
1967                                 break;
1968                         case 'm':
1969                                 scanhex((void *)&adrs);
1970                                 break;
1971                         case 'n':
1972                                 mnoread = 1;
1973                                 break;
1974                         case 'r':
1975                                 brev = !brev;
1976                                 break;
1977                         case '<':
1978                                 n = size;
1979                                 scanhex(&n);
1980                                 adrs -= n;
1981                                 break;
1982                         case '>':
1983                                 n = size;
1984                                 scanhex(&n);
1985                                 adrs += n;
1986                                 break;
1987                         case '?':
1988                                 printf(memex_subcmd_help_string);
1989                                 break;
1990                         }
1991                 }
1992                 adrs += inc;
1993         }
1994 }
1995
1996 static int
1997 bsesc(void)
1998 {
1999         int c;
2000
2001         c = inchar();
2002         switch( c ){
2003         case 'n':       c = '\n';       break;
2004         case 'r':       c = '\r';       break;
2005         case 'b':       c = '\b';       break;
2006         case 't':       c = '\t';       break;
2007         }
2008         return c;
2009 }
2010
2011 static void xmon_rawdump (unsigned long adrs, long ndump)
2012 {
2013         long n, m, r, nr;
2014         unsigned char temp[16];
2015
2016         for (n = ndump; n > 0;) {
2017                 r = n < 16? n: 16;
2018                 nr = mread(adrs, temp, r);
2019                 adrs += nr;
2020                 for (m = 0; m < r; ++m) {
2021                         if (m < nr)
2022                                 printf("%.2x", temp[m]);
2023                         else
2024                                 printf("%s", fault_chars[fault_type]);
2025                 }
2026                 n -= r;
2027                 if (nr < r)
2028                         break;
2029         }
2030         printf("\n");
2031 }
2032
2033 #define isxdigit(c)     (('0' <= (c) && (c) <= '9') \
2034                          || ('a' <= (c) && (c) <= 'f') \
2035                          || ('A' <= (c) && (c) <= 'F'))
2036 static void
2037 dump(void)
2038 {
2039         int c;
2040
2041         c = inchar();
2042         if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2043                 termch = c;
2044         scanhex((void *)&adrs);
2045         if (termch != '\n')
2046                 termch = 0;
2047         if (c == 'i') {
2048                 scanhex(&nidump);
2049                 if (nidump == 0)
2050                         nidump = 16;
2051                 else if (nidump > MAX_DUMP)
2052                         nidump = MAX_DUMP;
2053                 adrs += ppc_inst_dump(adrs, nidump, 1);
2054                 last_cmd = "di\n";
2055         } else if (c == 'l') {
2056                 dump_log_buf();
2057         } else if (c == 'r') {
2058                 scanhex(&ndump);
2059                 if (ndump == 0)
2060                         ndump = 64;
2061                 xmon_rawdump(adrs, ndump);
2062                 adrs += ndump;
2063                 last_cmd = "dr\n";
2064         } else {
2065                 scanhex(&ndump);
2066                 if (ndump == 0)
2067                         ndump = 64;
2068                 else if (ndump > MAX_DUMP)
2069                         ndump = MAX_DUMP;
2070                 prdump(adrs, ndump);
2071                 adrs += ndump;
2072                 last_cmd = "d\n";
2073         }
2074 }
2075
2076 static void
2077 prdump(unsigned long adrs, long ndump)
2078 {
2079         long n, m, c, r, nr;
2080         unsigned char temp[16];
2081
2082         for (n = ndump; n > 0;) {
2083                 printf(REG, adrs);
2084                 putchar(' ');
2085                 r = n < 16? n: 16;
2086                 nr = mread(adrs, temp, r);
2087                 adrs += nr;
2088                 for (m = 0; m < r; ++m) {
2089                         if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2090                                 putchar(' ');
2091                         if (m < nr)
2092                                 printf("%.2x", temp[m]);
2093                         else
2094                                 printf("%s", fault_chars[fault_type]);
2095                 }
2096                 for (; m < 16; ++m) {
2097                         if ((m & (sizeof(long) - 1)) == 0)
2098                                 putchar(' ');
2099                         printf("  ");
2100                 }
2101                 printf("  |");
2102                 for (m = 0; m < r; ++m) {
2103                         if (m < nr) {
2104                                 c = temp[m];
2105                                 putchar(' ' <= c && c <= '~'? c: '.');
2106                         } else
2107                                 putchar(' ');
2108                 }
2109                 n -= r;
2110                 for (; m < 16; ++m)
2111                         putchar(' ');
2112                 printf("|\n");
2113                 if (nr < r)
2114                         break;
2115         }
2116 }
2117
2118 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2119
2120 static int
2121 generic_inst_dump(unsigned long adr, long count, int praddr,
2122                         instruction_dump_func dump_func)
2123 {
2124         int nr, dotted;
2125         unsigned long first_adr;
2126         unsigned long inst, last_inst = 0;
2127         unsigned char val[4];
2128
2129         dotted = 0;
2130         for (first_adr = adr; count > 0; --count, adr += 4) {
2131                 nr = mread(adr, val, 4);
2132                 if (nr == 0) {
2133                         if (praddr) {
2134                                 const char *x = fault_chars[fault_type];
2135                                 printf(REG"  %s%s%s%s\n", adr, x, x, x, x);
2136                         }
2137                         break;
2138                 }
2139                 inst = GETWORD(val);
2140                 if (adr > first_adr && inst == last_inst) {
2141                         if (!dotted) {
2142                                 printf(" ...\n");
2143                                 dotted = 1;
2144                         }
2145                         continue;
2146                 }
2147                 dotted = 0;
2148                 last_inst = inst;
2149                 if (praddr)
2150                         printf(REG"  %.8x", adr, inst);
2151                 printf("\t");
2152                 dump_func(inst, adr);
2153                 printf("\n");
2154         }
2155         return adr - first_adr;
2156 }
2157
2158 static int
2159 ppc_inst_dump(unsigned long adr, long count, int praddr)
2160 {
2161         return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2162 }
2163
2164 void
2165 print_address(unsigned long addr)
2166 {
2167         xmon_print_symbol(addr, "\t# ", "");
2168 }
2169
2170 void
2171 dump_log_buf(void)
2172 {
2173         const unsigned long size = 128;
2174         unsigned long end, addr;
2175         unsigned char buf[size + 1];
2176
2177         addr = 0;
2178         buf[size] = '\0';
2179
2180         if (setjmp(bus_error_jmp) != 0) {
2181                 printf("Unable to lookup symbol __log_buf!\n");
2182                 return;
2183         }
2184
2185         catch_memory_errors = 1;
2186         sync();
2187         addr = kallsyms_lookup_name("__log_buf");
2188
2189         if (! addr)
2190                 printf("Symbol __log_buf not found!\n");
2191         else {
2192                 end = addr + (1 << CONFIG_LOG_BUF_SHIFT);
2193                 while (addr < end) {
2194                         if (! mread(addr, buf, size)) {
2195                                 printf("Can't read memory at address 0x%lx\n", addr);
2196                                 break;
2197                         }
2198
2199                         printf("%s", buf);
2200
2201                         if (strlen(buf) < size)
2202                                 break;
2203
2204                         addr += size;
2205                 }
2206         }
2207
2208         sync();
2209         /* wait a little while to see if we get a machine check */
2210         __delay(200);
2211         catch_memory_errors = 0;
2212 }
2213
2214 /*
2215  * Memory operations - move, set, print differences
2216  */
2217 static unsigned long mdest;             /* destination address */
2218 static unsigned long msrc;              /* source address */
2219 static unsigned long mval;              /* byte value to set memory to */
2220 static unsigned long mcount;            /* # bytes to affect */
2221 static unsigned long mdiffs;            /* max # differences to print */
2222
2223 static void
2224 memops(int cmd)
2225 {
2226         scanhex((void *)&mdest);
2227         if( termch != '\n' )
2228                 termch = 0;
2229         scanhex((void *)(cmd == 's'? &mval: &msrc));
2230         if( termch != '\n' )
2231                 termch = 0;
2232         scanhex((void *)&mcount);
2233         switch( cmd ){
2234         case 'm':
2235                 memmove((void *)mdest, (void *)msrc, mcount);
2236                 break;
2237         case 's':
2238                 memset((void *)mdest, mval, mcount);
2239                 break;
2240         case 'd':
2241                 if( termch != '\n' )
2242                         termch = 0;
2243                 scanhex((void *)&mdiffs);
2244                 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2245                 break;
2246         }
2247 }
2248
2249 static void
2250 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2251 {
2252         unsigned n, prt;
2253
2254         prt = 0;
2255         for( n = nb; n > 0; --n )
2256                 if( *p1++ != *p2++ )
2257                         if( ++prt <= maxpr )
2258                                 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2259                                         p1[-1], p2 - 1, p2[-1]);
2260         if( prt > maxpr )
2261                 printf("Total of %d differences\n", prt);
2262 }
2263
2264 static unsigned mend;
2265 static unsigned mask;
2266
2267 static void
2268 memlocate(void)
2269 {
2270         unsigned a, n;
2271         unsigned char val[4];
2272
2273         last_cmd = "ml";
2274         scanhex((void *)&mdest);
2275         if (termch != '\n') {
2276                 termch = 0;
2277                 scanhex((void *)&mend);
2278                 if (termch != '\n') {
2279                         termch = 0;
2280                         scanhex((void *)&mval);
2281                         mask = ~0;
2282                         if (termch != '\n') termch = 0;
2283                         scanhex((void *)&mask);
2284                 }
2285         }
2286         n = 0;
2287         for (a = mdest; a < mend; a += 4) {
2288                 if (mread(a, val, 4) == 4
2289                         && ((GETWORD(val) ^ mval) & mask) == 0) {
2290                         printf("%.16x:  %.16x\n", a, GETWORD(val));
2291                         if (++n >= 10)
2292                                 break;
2293                 }
2294         }
2295 }
2296
2297 static unsigned long mskip = 0x1000;
2298 static unsigned long mlim = 0xffffffff;
2299
2300 static void
2301 memzcan(void)
2302 {
2303         unsigned char v;
2304         unsigned a;
2305         int ok, ook;
2306
2307         scanhex(&mdest);
2308         if (termch != '\n') termch = 0;
2309         scanhex(&mskip);
2310         if (termch != '\n') termch = 0;
2311         scanhex(&mlim);
2312         ook = 0;
2313         for (a = mdest; a < mlim; a += mskip) {
2314                 ok = mread(a, &v, 1);
2315                 if (ok && !ook) {
2316                         printf("%.8x .. ", a);
2317                 } else if (!ok && ook)
2318                         printf("%.8x\n", a - mskip);
2319                 ook = ok;
2320                 if (a + mskip < a)
2321                         break;
2322         }
2323         if (ook)
2324                 printf("%.8x\n", a - mskip);
2325 }
2326
2327 static void proccall(void)
2328 {
2329         unsigned long args[8];
2330         unsigned long ret;
2331         int i;
2332         typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2333                         unsigned long, unsigned long, unsigned long,
2334                         unsigned long, unsigned long, unsigned long);
2335         callfunc_t func;
2336
2337         if (!scanhex(&adrs))
2338                 return;
2339         if (termch != '\n')
2340                 termch = 0;
2341         for (i = 0; i < 8; ++i)
2342                 args[i] = 0;
2343         for (i = 0; i < 8; ++i) {
2344                 if (!scanhex(&args[i]) || termch == '\n')
2345                         break;
2346                 termch = 0;
2347         }
2348         func = (callfunc_t) adrs;
2349         ret = 0;
2350         if (setjmp(bus_error_jmp) == 0) {
2351                 catch_memory_errors = 1;
2352                 sync();
2353                 ret = func(args[0], args[1], args[2], args[3],
2354                            args[4], args[5], args[6], args[7]);
2355                 sync();
2356                 printf("return value is %x\n", ret);
2357         } else {
2358                 printf("*** %x exception occurred\n", fault_except);
2359         }
2360         catch_memory_errors = 0;
2361 }
2362
2363 /* Input scanning routines */
2364 int
2365 skipbl(void)
2366 {
2367         int c;
2368
2369         if( termch != 0 ){
2370                 c = termch;
2371                 termch = 0;
2372         } else
2373                 c = inchar();
2374         while( c == ' ' || c == '\t' )
2375                 c = inchar();
2376         return c;
2377 }
2378
2379 #define N_PTREGS        44
2380 static char *regnames[N_PTREGS] = {
2381         "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2382         "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2383         "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2384         "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2385         "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2386 #ifdef CONFIG_PPC64
2387         "softe",
2388 #else
2389         "mq",
2390 #endif
2391         "trap", "dar", "dsisr", "res"
2392 };
2393
2394 int
2395 scanhex(unsigned long *vp)
2396 {
2397         int c, d;
2398         unsigned long v;
2399
2400         c = skipbl();
2401         if (c == '%') {
2402                 /* parse register name */
2403                 char regname[8];
2404                 int i;
2405
2406                 for (i = 0; i < sizeof(regname) - 1; ++i) {
2407                         c = inchar();
2408                         if (!isalnum(c)) {
2409                                 termch = c;
2410                                 break;
2411                         }
2412                         regname[i] = c;
2413                 }
2414                 regname[i] = 0;
2415                 for (i = 0; i < N_PTREGS; ++i) {
2416                         if (strcmp(regnames[i], regname) == 0) {
2417                                 if (xmon_regs == NULL) {
2418                                         printf("regs not available\n");
2419                                         return 0;
2420                                 }
2421                                 *vp = ((unsigned long *)xmon_regs)[i];
2422                                 return 1;
2423                         }
2424                 }
2425                 printf("invalid register name '%%%s'\n", regname);
2426                 return 0;
2427         }
2428
2429         /* skip leading "0x" if any */
2430
2431         if (c == '0') {
2432                 c = inchar();
2433                 if (c == 'x') {
2434                         c = inchar();
2435                 } else {
2436                         d = hexdigit(c);
2437                         if (d == EOF) {
2438                                 termch = c;
2439                                 *vp = 0;
2440                                 return 1;
2441                         }
2442                 }
2443         } else if (c == '$') {
2444                 int i;
2445                 for (i=0; i<63; i++) {
2446                         c = inchar();
2447                         if (isspace(c)) {
2448                                 termch = c;
2449                                 break;
2450                         }
2451                         tmpstr[i] = c;
2452                 }
2453                 tmpstr[i++] = 0;
2454                 *vp = 0;
2455                 if (setjmp(bus_error_jmp) == 0) {
2456                         catch_memory_errors = 1;
2457                         sync();
2458                         *vp = kallsyms_lookup_name(tmpstr);
2459                         sync();
2460                 }
2461                 catch_memory_errors = 0;
2462                 if (!(*vp)) {
2463                         printf("unknown symbol '%s'\n", tmpstr);
2464                         return 0;
2465                 }
2466                 return 1;
2467         }
2468
2469         d = hexdigit(c);
2470         if (d == EOF) {
2471                 termch = c;
2472                 return 0;
2473         }
2474         v = 0;
2475         do {
2476                 v = (v << 4) + d;
2477                 c = inchar();
2478                 d = hexdigit(c);
2479         } while (d != EOF);
2480         termch = c;
2481         *vp = v;
2482         return 1;
2483 }
2484
2485 static void
2486 scannl(void)
2487 {
2488         int c;
2489
2490         c = termch;
2491         termch = 0;
2492         while( c != '\n' )
2493                 c = inchar();
2494 }
2495
2496 static int hexdigit(int c)
2497 {
2498         if( '0' <= c && c <= '9' )
2499                 return c - '0';
2500         if( 'A' <= c && c <= 'F' )
2501                 return c - ('A' - 10);
2502         if( 'a' <= c && c <= 'f' )
2503                 return c - ('a' - 10);
2504         return EOF;
2505 }
2506
2507 void
2508 getstring(char *s, int size)
2509 {
2510         int c;
2511
2512         c = skipbl();
2513         do {
2514                 if( size > 1 ){
2515                         *s++ = c;
2516                         --size;
2517                 }
2518                 c = inchar();
2519         } while( c != ' ' && c != '\t' && c != '\n' );
2520         termch = c;
2521         *s = 0;
2522 }
2523
2524 static char line[256];
2525 static char *lineptr;
2526
2527 static void
2528 flush_input(void)
2529 {
2530         lineptr = NULL;
2531 }
2532
2533 static int
2534 inchar(void)
2535 {
2536         if (lineptr == NULL || *lineptr == 0) {
2537                 if (xmon_gets(line, sizeof(line)) == NULL) {
2538                         lineptr = NULL;
2539                         return EOF;
2540                 }
2541                 lineptr = line;
2542         }
2543         return *lineptr++;
2544 }
2545
2546 static void
2547 take_input(char *str)
2548 {
2549         lineptr = str;
2550 }
2551
2552
2553 static void
2554 symbol_lookup(void)
2555 {
2556         int type = inchar();
2557         unsigned long addr;
2558         static char tmp[64];
2559
2560         switch (type) {
2561         case 'a':
2562                 if (scanhex(&addr))
2563                         xmon_print_symbol(addr, ": ", "\n");
2564                 termch = 0;
2565                 break;
2566         case 's':
2567                 getstring(tmp, 64);
2568                 if (setjmp(bus_error_jmp) == 0) {
2569                         catch_memory_errors = 1;
2570                         sync();
2571                         addr = kallsyms_lookup_name(tmp);
2572                         if (addr)
2573                                 printf("%s: %lx\n", tmp, addr);
2574                         else
2575                                 printf("Symbol '%s' not found.\n", tmp);
2576                         sync();
2577                 }
2578                 catch_memory_errors = 0;
2579                 termch = 0;
2580                 break;
2581         }
2582 }
2583
2584
2585 /* Print an address in numeric and symbolic form (if possible) */
2586 static void xmon_print_symbol(unsigned long address, const char *mid,
2587                               const char *after)
2588 {
2589         char *modname;
2590         const char *name = NULL;
2591         unsigned long offset, size;
2592
2593         printf(REG, address);
2594         if (setjmp(bus_error_jmp) == 0) {
2595                 catch_memory_errors = 1;
2596                 sync();
2597                 name = kallsyms_lookup(address, &size, &offset, &modname,
2598                                        tmpstr);
2599                 sync();
2600                 /* wait a little while to see if we get a machine check */
2601                 __delay(200);
2602         }
2603
2604         catch_memory_errors = 0;
2605
2606         if (name) {
2607                 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2608                 if (modname)
2609                         printf(" [%s]", modname);
2610         }
2611         printf("%s", after);
2612 }
2613
2614 #ifdef CONFIG_PPC_BOOK3S_64
2615 static void dump_slb(void)
2616 {
2617         int i;
2618         unsigned long esid,vsid,valid;
2619         unsigned long llp;
2620
2621         printf("SLB contents of cpu %x\n", smp_processor_id());
2622
2623         for (i = 0; i < mmu_slb_size; i++) {
2624                 asm volatile("slbmfee  %0,%1" : "=r" (esid) : "r" (i));
2625                 asm volatile("slbmfev  %0,%1" : "=r" (vsid) : "r" (i));
2626                 valid = (esid & SLB_ESID_V);
2627                 if (valid | esid | vsid) {
2628                         printf("%02d %016lx %016lx", i, esid, vsid);
2629                         if (valid) {
2630                                 llp = vsid & SLB_VSID_LLP;
2631                                 if (vsid & SLB_VSID_B_1T) {
2632                                         printf("  1T  ESID=%9lx  VSID=%13lx LLP:%3lx \n",
2633                                                 GET_ESID_1T(esid),
2634                                                 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2635                                                 llp);
2636                                 } else {
2637                                         printf(" 256M ESID=%9lx  VSID=%13lx LLP:%3lx \n",
2638                                                 GET_ESID(esid),
2639                                                 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2640                                                 llp);
2641                                 }
2642                         } else
2643                                 printf("\n");
2644                 }
2645         }
2646 }
2647
2648 static void dump_stab(void)
2649 {
2650         int i;
2651         unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2652
2653         printf("Segment table contents of cpu %x\n", smp_processor_id());
2654
2655         for (i = 0; i < PAGE_SIZE/16; i++) {
2656                 unsigned long a, b;
2657
2658                 a = *tmp++;
2659                 b = *tmp++;
2660
2661                 if (a || b) {
2662                         printf("%03d %016lx ", i, a);
2663                         printf("%016lx\n", b);
2664                 }
2665         }
2666 }
2667
2668 void dump_segments(void)
2669 {
2670         if (mmu_has_feature(MMU_FTR_SLB))
2671                 dump_slb();
2672         else
2673                 dump_stab();
2674 }
2675 #endif
2676
2677 #ifdef CONFIG_PPC_STD_MMU_32
2678 void dump_segments(void)
2679 {
2680         int i;
2681
2682         printf("sr0-15 =");
2683         for (i = 0; i < 16; ++i)
2684                 printf(" %x", mfsrin(i));
2685         printf("\n");
2686 }
2687 #endif
2688
2689 #ifdef CONFIG_44x
2690 static void dump_tlb_44x(void)
2691 {
2692         int i;
2693
2694         for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2695                 unsigned long w0,w1,w2;
2696                 asm volatile("tlbre  %0,%1,0" : "=r" (w0) : "r" (i));
2697                 asm volatile("tlbre  %0,%1,1" : "=r" (w1) : "r" (i));
2698                 asm volatile("tlbre  %0,%1,2" : "=r" (w2) : "r" (i));
2699                 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2700                 if (w0 & PPC44x_TLB_VALID) {
2701                         printf("V %08x -> %01x%08x %c%c%c%c%c",
2702                                w0 & PPC44x_TLB_EPN_MASK,
2703                                w1 & PPC44x_TLB_ERPN_MASK,
2704                                w1 & PPC44x_TLB_RPN_MASK,
2705                                (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2706                                (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2707                                (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2708                                (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2709                                (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2710                 }
2711                 printf("\n");
2712         }
2713 }
2714 #endif /* CONFIG_44x */
2715
2716 #ifdef CONFIG_PPC_BOOK3E
2717 static void dump_tlb_book3e(void)
2718 {
2719         u32 mmucfg, pidmask, lpidmask;
2720         u64 ramask;
2721         int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
2722         int mmu_version;
2723         static const char *pgsz_names[] = {
2724                 "  1K",
2725                 "  2K",
2726                 "  4K",
2727                 "  8K",
2728                 " 16K",
2729                 " 32K",
2730                 " 64K",
2731                 "128K",
2732                 "256K",
2733                 "512K",
2734                 "  1M",
2735                 "  2M",
2736                 "  4M",
2737                 "  8M",
2738                 " 16M",
2739                 " 32M",
2740                 " 64M",
2741                 "128M",
2742                 "256M",
2743                 "512M",
2744                 "  1G",
2745                 "  2G",
2746                 "  4G",
2747                 "  8G",
2748                 " 16G",
2749                 " 32G",
2750                 " 64G",
2751                 "128G",
2752                 "256G",
2753                 "512G",
2754                 "  1T",
2755                 "  2T",
2756         };
2757
2758         /* Gather some infos about the MMU */
2759         mmucfg = mfspr(SPRN_MMUCFG);
2760         mmu_version = (mmucfg & 3) + 1;
2761         ntlbs = ((mmucfg >> 2) & 3) + 1;
2762         pidsz = ((mmucfg >> 6) & 0x1f) + 1;
2763         lpidsz = (mmucfg >> 24) & 0xf;
2764         rasz = (mmucfg >> 16) & 0x7f;
2765         if ((mmu_version > 1) && (mmucfg & 0x10000))
2766                 lrat = 1;
2767         printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2768                mmu_version, ntlbs, pidsz, lpidsz, rasz);
2769         pidmask = (1ul << pidsz) - 1;
2770         lpidmask = (1ul << lpidsz) - 1;
2771         ramask = (1ull << rasz) - 1;
2772
2773         for (tlb = 0; tlb < ntlbs; tlb++) {
2774                 u32 tlbcfg;
2775                 int nent, assoc, new_cc = 1;
2776                 printf("TLB %d:\n------\n", tlb);
2777                 switch(tlb) {
2778                 case 0:
2779                         tlbcfg = mfspr(SPRN_TLB0CFG);
2780                         break;
2781                 case 1:
2782                         tlbcfg = mfspr(SPRN_TLB1CFG);
2783                         break;
2784                 case 2:
2785                         tlbcfg = mfspr(SPRN_TLB2CFG);
2786                         break;
2787                 case 3:
2788                         tlbcfg = mfspr(SPRN_TLB3CFG);
2789                         break;
2790                 default:
2791                         printf("Unsupported TLB number !\n");
2792                         continue;
2793                 }
2794                 nent = tlbcfg & 0xfff;
2795                 assoc = (tlbcfg >> 24) & 0xff;
2796                 for (i = 0; i < nent; i++) {
2797                         u32 mas0 = MAS0_TLBSEL(tlb);
2798                         u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
2799                         u64 mas2 = 0;
2800                         u64 mas7_mas3;
2801                         int esel = i, cc = i;
2802
2803                         if (assoc != 0) {
2804                                 cc = i / assoc;
2805                                 esel = i % assoc;
2806                                 mas2 = cc * 0x1000;
2807                         }
2808
2809                         mas0 |= MAS0_ESEL(esel);
2810                         mtspr(SPRN_MAS0, mas0);
2811                         mtspr(SPRN_MAS1, mas1);
2812                         mtspr(SPRN_MAS2, mas2);
2813                         asm volatile("tlbre  0,0,0" : : : "memory");
2814                         mas1 = mfspr(SPRN_MAS1);
2815                         mas2 = mfspr(SPRN_MAS2);
2816                         mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
2817                         if (assoc && (i % assoc) == 0)
2818                                 new_cc = 1;
2819                         if (!(mas1 & MAS1_VALID))
2820                                 continue;
2821                         if (assoc == 0)
2822                                 printf("%04x- ", i);
2823                         else if (new_cc)
2824                                 printf("%04x-%c", cc, 'A' + esel);
2825                         else
2826                                 printf("    |%c", 'A' + esel);
2827                         new_cc = 0;
2828                         printf(" %016llx %04x %s %c%c AS%c",
2829                                mas2 & ~0x3ffull,
2830                                (mas1 >> 16) & 0x3fff,
2831                                pgsz_names[(mas1 >> 7) & 0x1f],
2832                                mas1 & MAS1_IND ? 'I' : ' ',
2833                                mas1 & MAS1_IPROT ? 'P' : ' ',
2834                                mas1 & MAS1_TS ? '1' : '0');
2835                         printf(" %c%c%c%c%c%c%c",
2836                                mas2 & MAS2_X0 ? 'a' : ' ',
2837                                mas2 & MAS2_X1 ? 'v' : ' ',
2838                                mas2 & MAS2_W  ? 'w' : ' ',
2839                                mas2 & MAS2_I  ? 'i' : ' ',
2840                                mas2 & MAS2_M  ? 'm' : ' ',
2841                                mas2 & MAS2_G  ? 'g' : ' ',
2842                                mas2 & MAS2_E  ? 'e' : ' ');
2843                         printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
2844                         if (mas1 & MAS1_IND)
2845                                 printf(" %s\n",
2846                                        pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
2847                         else
2848                                 printf(" U%c%c%c S%c%c%c\n",
2849                                        mas7_mas3 & MAS3_UX ? 'x' : ' ',
2850                                        mas7_mas3 & MAS3_UW ? 'w' : ' ',
2851                                        mas7_mas3 & MAS3_UR ? 'r' : ' ',
2852                                        mas7_mas3 & MAS3_SX ? 'x' : ' ',
2853                                        mas7_mas3 & MAS3_SW ? 'w' : ' ',
2854                                        mas7_mas3 & MAS3_SR ? 'r' : ' ');
2855                 }
2856         }
2857 }
2858 #endif /* CONFIG_PPC_BOOK3E */
2859
2860 static void xmon_init(int enable)
2861 {
2862 #ifdef CONFIG_PPC_ISERIES
2863         if (firmware_has_feature(FW_FEATURE_ISERIES))
2864                 return;
2865 #endif
2866         if (enable) {
2867                 __debugger = xmon;
2868                 __debugger_ipi = xmon_ipi;
2869                 __debugger_bpt = xmon_bpt;
2870                 __debugger_sstep = xmon_sstep;
2871                 __debugger_iabr_match = xmon_iabr_match;
2872                 __debugger_dabr_match = xmon_dabr_match;
2873                 __debugger_fault_handler = xmon_fault_handler;
2874         } else {
2875                 __debugger = NULL;
2876                 __debugger_ipi = NULL;
2877                 __debugger_bpt = NULL;
2878                 __debugger_sstep = NULL;
2879                 __debugger_iabr_match = NULL;
2880                 __debugger_dabr_match = NULL;
2881                 __debugger_fault_handler = NULL;
2882         }
2883         xmon_map_scc();
2884 }
2885
2886 #ifdef CONFIG_MAGIC_SYSRQ
2887 static void sysrq_handle_xmon(int key)
2888 {
2889         /* ensure xmon is enabled */
2890         xmon_init(1);
2891         debugger(get_irq_regs());
2892 }
2893
2894 static struct sysrq_key_op sysrq_xmon_op = {
2895         .handler =      sysrq_handle_xmon,
2896         .help_msg =     "Xmon",
2897         .action_msg =   "Entering xmon",
2898 };
2899
2900 static int __init setup_xmon_sysrq(void)
2901 {
2902 #ifdef CONFIG_PPC_ISERIES
2903         if (firmware_has_feature(FW_FEATURE_ISERIES))
2904                 return 0;
2905 #endif
2906         register_sysrq_key('x', &sysrq_xmon_op);
2907         return 0;
2908 }
2909 __initcall(setup_xmon_sysrq);
2910 #endif /* CONFIG_MAGIC_SYSRQ */
2911
2912 static int __initdata xmon_early, xmon_off;
2913
2914 static int __init early_parse_xmon(char *p)
2915 {
2916         if (!p || strncmp(p, "early", 5) == 0) {
2917                 /* just "xmon" is equivalent to "xmon=early" */
2918                 xmon_init(1);
2919                 xmon_early = 1;
2920         } else if (strncmp(p, "on", 2) == 0)
2921                 xmon_init(1);
2922         else if (strncmp(p, "off", 3) == 0)
2923                 xmon_off = 1;
2924         else if (strncmp(p, "nobt", 4) == 0)
2925                 xmon_no_auto_backtrace = 1;
2926         else
2927                 return 1;
2928
2929         return 0;
2930 }
2931 early_param("xmon", early_parse_xmon);
2932
2933 void __init xmon_setup(void)
2934 {
2935 #ifdef CONFIG_XMON_DEFAULT
2936         if (!xmon_off)
2937                 xmon_init(1);
2938 #endif
2939         if (xmon_early)
2940                 debugger(NULL);
2941 }
2942
2943 #ifdef CONFIG_SPU_BASE
2944
2945 struct spu_info {
2946         struct spu *spu;
2947         u64 saved_mfc_sr1_RW;
2948         u32 saved_spu_runcntl_RW;
2949         unsigned long dump_addr;
2950         u8 stopped_ok;
2951 };
2952
2953 #define XMON_NUM_SPUS   16      /* Enough for current hardware */
2954
2955 static struct spu_info spu_info[XMON_NUM_SPUS];
2956
2957 void xmon_register_spus(struct list_head *list)
2958 {
2959         struct spu *spu;
2960
2961         list_for_each_entry(spu, list, full_list) {
2962                 if (spu->number >= XMON_NUM_SPUS) {
2963                         WARN_ON(1);
2964                         continue;
2965                 }
2966
2967                 spu_info[spu->number].spu = spu;
2968                 spu_info[spu->number].stopped_ok = 0;
2969                 spu_info[spu->number].dump_addr = (unsigned long)
2970                                 spu_info[spu->number].spu->local_store;
2971         }
2972 }
2973
2974 static void stop_spus(void)
2975 {
2976         struct spu *spu;
2977         int i;
2978         u64 tmp;
2979
2980         for (i = 0; i < XMON_NUM_SPUS; i++) {
2981                 if (!spu_info[i].spu)
2982                         continue;
2983
2984                 if (setjmp(bus_error_jmp) == 0) {
2985                         catch_memory_errors = 1;
2986                         sync();
2987
2988                         spu = spu_info[i].spu;
2989
2990                         spu_info[i].saved_spu_runcntl_RW =
2991                                 in_be32(&spu->problem->spu_runcntl_RW);
2992
2993                         tmp = spu_mfc_sr1_get(spu);
2994                         spu_info[i].saved_mfc_sr1_RW = tmp;
2995
2996                         tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2997                         spu_mfc_sr1_set(spu, tmp);
2998
2999                         sync();
3000                         __delay(200);
3001
3002                         spu_info[i].stopped_ok = 1;
3003
3004                         printf("Stopped spu %.2d (was %s)\n", i,
3005                                         spu_info[i].saved_spu_runcntl_RW ?
3006                                         "running" : "stopped");
3007                 } else {
3008                         catch_memory_errors = 0;
3009                         printf("*** Error stopping spu %.2d\n", i);
3010                 }
3011                 catch_memory_errors = 0;
3012         }
3013 }
3014
3015 static void restart_spus(void)
3016 {
3017         struct spu *spu;
3018         int i;
3019
3020         for (i = 0; i < XMON_NUM_SPUS; i++) {
3021                 if (!spu_info[i].spu)
3022                         continue;
3023
3024                 if (!spu_info[i].stopped_ok) {
3025                         printf("*** Error, spu %d was not successfully stopped"
3026                                         ", not restarting\n", i);
3027                         continue;
3028                 }
3029
3030                 if (setjmp(bus_error_jmp) == 0) {
3031                         catch_memory_errors = 1;
3032                         sync();
3033
3034                         spu = spu_info[i].spu;
3035                         spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3036                         out_be32(&spu->problem->spu_runcntl_RW,
3037                                         spu_info[i].saved_spu_runcntl_RW);
3038
3039                         sync();
3040                         __delay(200);
3041
3042                         printf("Restarted spu %.2d\n", i);
3043                 } else {
3044                         catch_memory_errors = 0;
3045                         printf("*** Error restarting spu %.2d\n", i);
3046                 }
3047                 catch_memory_errors = 0;
3048         }
3049 }
3050
3051 #define DUMP_WIDTH      23
3052 #define DUMP_VALUE(format, field, value)                                \
3053 do {                                                                    \
3054         if (setjmp(bus_error_jmp) == 0) {                               \
3055                 catch_memory_errors = 1;                                \
3056                 sync();                                                 \
3057                 printf("  %-*s = "format"\n", DUMP_WIDTH,               \
3058                                 #field, value);                         \
3059                 sync();                                                 \
3060                 __delay(200);                                           \
3061         } else {                                                        \
3062                 catch_memory_errors = 0;                                \
3063                 printf("  %-*s = *** Error reading field.\n",           \
3064                                         DUMP_WIDTH, #field);            \
3065         }                                                               \
3066         catch_memory_errors = 0;                                        \
3067 } while (0)
3068
3069 #define DUMP_FIELD(obj, format, field)  \
3070         DUMP_VALUE(format, field, obj->field)
3071
3072 static void dump_spu_fields(struct spu *spu)
3073 {
3074         printf("Dumping spu fields at address %p:\n", spu);
3075
3076         DUMP_FIELD(spu, "0x%x", number);
3077         DUMP_FIELD(spu, "%s", name);
3078         DUMP_FIELD(spu, "0x%lx", local_store_phys);
3079         DUMP_FIELD(spu, "0x%p", local_store);
3080         DUMP_FIELD(spu, "0x%lx", ls_size);
3081         DUMP_FIELD(spu, "0x%x", node);
3082         DUMP_FIELD(spu, "0x%lx", flags);
3083         DUMP_FIELD(spu, "%d", class_0_pending);
3084         DUMP_FIELD(spu, "0x%lx", class_0_dar);
3085         DUMP_FIELD(spu, "0x%lx", class_1_dar);
3086         DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
3087         DUMP_FIELD(spu, "0x%lx", irqs[0]);
3088         DUMP_FIELD(spu, "0x%lx", irqs[1]);
3089         DUMP_FIELD(spu, "0x%lx", irqs[2]);
3090         DUMP_FIELD(spu, "0x%x", slb_replace);
3091         DUMP_FIELD(spu, "%d", pid);
3092         DUMP_FIELD(spu, "0x%p", mm);
3093         DUMP_FIELD(spu, "0x%p", ctx);
3094         DUMP_FIELD(spu, "0x%p", rq);
3095         DUMP_FIELD(spu, "0x%p", timestamp);
3096         DUMP_FIELD(spu, "0x%lx", problem_phys);
3097         DUMP_FIELD(spu, "0x%p", problem);
3098         DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
3099                         in_be32(&spu->problem->spu_runcntl_RW));
3100         DUMP_VALUE("0x%x", problem->spu_status_R,
3101                         in_be32(&spu->problem->spu_status_R));
3102         DUMP_VALUE("0x%x", problem->spu_npc_RW,
3103                         in_be32(&spu->problem->spu_npc_RW));
3104         DUMP_FIELD(spu, "0x%p", priv2);
3105         DUMP_FIELD(spu, "0x%p", pdata);
3106 }
3107
3108 int
3109 spu_inst_dump(unsigned long adr, long count, int praddr)
3110 {
3111         return generic_inst_dump(adr, count, praddr, print_insn_spu);
3112 }
3113
3114 static void dump_spu_ls(unsigned long num, int subcmd)
3115 {
3116         unsigned long offset, addr, ls_addr;
3117
3118         if (setjmp(bus_error_jmp) == 0) {
3119                 catch_memory_errors = 1;
3120                 sync();
3121                 ls_addr = (unsigned long)spu_info[num].spu->local_store;
3122                 sync();
3123                 __delay(200);
3124         } else {
3125                 catch_memory_errors = 0;
3126                 printf("*** Error: accessing spu info for spu %d\n", num);
3127                 return;
3128         }
3129         catch_memory_errors = 0;
3130
3131         if (scanhex(&offset))
3132                 addr = ls_addr + offset;
3133         else
3134                 addr = spu_info[num].dump_addr;
3135
3136         if (addr >= ls_addr + LS_SIZE) {
3137                 printf("*** Error: address outside of local store\n");
3138                 return;
3139         }
3140
3141         switch (subcmd) {
3142         case 'i':
3143                 addr += spu_inst_dump(addr, 16, 1);
3144                 last_cmd = "sdi\n";
3145                 break;
3146         default:
3147                 prdump(addr, 64);
3148                 addr += 64;
3149                 last_cmd = "sd\n";
3150                 break;
3151         }
3152
3153         spu_info[num].dump_addr = addr;
3154 }
3155
3156 static int do_spu_cmd(void)
3157 {
3158         static unsigned long num = 0;
3159         int cmd, subcmd = 0;
3160
3161         cmd = inchar();
3162         switch (cmd) {
3163         case 's':
3164                 stop_spus();
3165                 break;
3166         case 'r':
3167                 restart_spus();
3168                 break;
3169         case 'd':
3170                 subcmd = inchar();
3171                 if (isxdigit(subcmd) || subcmd == '\n')
3172                         termch = subcmd;
3173         case 'f':
3174                 scanhex(&num);
3175                 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
3176                         printf("*** Error: invalid spu number\n");
3177                         return 0;
3178                 }
3179
3180                 switch (cmd) {
3181                 case 'f':
3182                         dump_spu_fields(spu_info[num].spu);
3183                         break;
3184                 default:
3185                         dump_spu_ls(num, subcmd);
3186                         break;
3187                 }
3188
3189                 break;
3190         default:
3191                 return -1;
3192         }
3193
3194         return 0;
3195 }
3196 #else /* ! CONFIG_SPU_BASE */
3197 static int do_spu_cmd(void)
3198 {
3199         return -1;
3200 }
3201 #endif