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