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