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