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