[POWERPC] Add a sd command (spu dump) to xmon to dump spu local store
[linux-2.6/x86.git] / arch / powerpc / xmon / xmon.c
blobbe2c12d687857d1b8475cd0978b387c584b9d12d
1 /*
2 * Routines providing a simple monitor for use on the PowerMac.
4 * Copyright (C) 1996-2005 Paul Mackerras.
5 * Copyright (C) 2001 PPC64 Team, IBM Corp
6 * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
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.
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>
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>
44 #ifdef CONFIG_PPC64
45 #include <asm/hvcall.h>
46 #include <asm/paca.h>
47 #endif
49 #include "nonstdio.h"
51 #define scanhex xmon_scanhex
52 #define skipbl xmon_skipbl
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 */
61 static unsigned long in_xmon = 0;
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];
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
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;
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
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 */
100 #define BP_NUM(bp) ((bp) - bpts + 1)
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);
153 static int do_spu_cmd(void);
155 int xmon_no_auto_backtrace;
157 extern int print_insn_powerpc(unsigned long, unsigned long, int);
159 extern void xmon_enter(void);
160 extern void xmon_leave(void);
162 extern long setjmp(long *);
163 extern void longjmp(long *, long);
164 extern void xmon_save_regs(struct pt_regs *);
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
176 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
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)
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
194 c print cpus stopped in xmon\n\
195 c# try to switch to cpu number h (in hex)\n"
196 #endif
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 sd # dump spu local store for spu # (in hex)\n"
223 #endif
224 " S print special registers\n\
225 t print backtrace\n\
226 x exit monitor and recover\n\
227 X exit monitor and dont recover\n"
228 #ifdef CONFIG_PPC64
229 " u dump segment table or SLB\n"
230 #endif
231 #ifdef CONFIG_PPC_STD_MMU_32
232 " u dump segment registers\n"
233 #endif
234 " ? help\n"
235 " zr reboot\n\
236 zh halt\n"
239 static struct pt_regs *xmon_regs;
241 static inline void sync(void)
243 asm volatile("sync; isync");
246 static inline void store_inst(void *p)
248 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
251 static inline void cflush(void *p)
253 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
256 static inline void cinval(void *p)
258 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
262 * Disable surveillance (the service processor watchdog function)
263 * while we are in xmon.
264 * XXX we should re-enable it when we leave. :)
266 #define SURVEILLANCE_TOKEN 9000
268 static inline void disable_surveillance(void)
270 #ifdef CONFIG_PPC_PSERIES
271 /* Since this can't be a module, args should end up below 4GB. */
272 static struct rtas_args args;
275 * At this point we have got all the cpus we can into
276 * xmon, so there is hopefully no other cpu calling RTAS
277 * at the moment, even though we don't take rtas.lock.
278 * If we did try to take rtas.lock there would be a
279 * real possibility of deadlock.
281 args.token = rtas_token("set-indicator");
282 if (args.token == RTAS_UNKNOWN_SERVICE)
283 return;
284 args.nargs = 3;
285 args.nret = 1;
286 args.rets = &args.args[3];
287 args.args[0] = SURVEILLANCE_TOKEN;
288 args.args[1] = 0;
289 args.args[2] = 0;
290 enter_rtas(__pa(&args));
291 #endif /* CONFIG_PPC_PSERIES */
294 #ifdef CONFIG_SMP
295 static int xmon_speaker;
297 static void get_output_lock(void)
299 int me = smp_processor_id() + 0x100;
300 int last_speaker = 0, prev;
301 long timeout;
303 if (xmon_speaker == me)
304 return;
305 for (;;) {
306 if (xmon_speaker == 0) {
307 last_speaker = cmpxchg(&xmon_speaker, 0, me);
308 if (last_speaker == 0)
309 return;
311 timeout = 10000000;
312 while (xmon_speaker == last_speaker) {
313 if (--timeout > 0)
314 continue;
315 /* hostile takeover */
316 prev = cmpxchg(&xmon_speaker, last_speaker, me);
317 if (prev == last_speaker)
318 return;
319 break;
324 static void release_output_lock(void)
326 xmon_speaker = 0;
328 #endif
330 static int xmon_core(struct pt_regs *regs, int fromipi)
332 int cmd = 0;
333 unsigned long msr;
334 struct bpt *bp;
335 long recurse_jmp[JMP_BUF_LEN];
336 unsigned long offset;
337 #ifdef CONFIG_SMP
338 int cpu;
339 int secondary;
340 unsigned long timeout;
341 #endif
343 msr = mfmsr();
344 mtmsr(msr & ~MSR_EE); /* disable interrupts */
346 bp = in_breakpoint_table(regs->nip, &offset);
347 if (bp != NULL) {
348 regs->nip = bp->address + offset;
349 atomic_dec(&bp->ref_count);
352 remove_cpu_bpts();
354 #ifdef CONFIG_SMP
355 cpu = smp_processor_id();
356 if (cpu_isset(cpu, cpus_in_xmon)) {
357 get_output_lock();
358 excprint(regs);
359 printf("cpu 0x%x: Exception %lx %s in xmon, "
360 "returning to main loop\n",
361 cpu, regs->trap, getvecname(TRAP(regs)));
362 release_output_lock();
363 longjmp(xmon_fault_jmp[cpu], 1);
366 if (setjmp(recurse_jmp) != 0) {
367 if (!in_xmon || !xmon_gate) {
368 get_output_lock();
369 printf("xmon: WARNING: bad recursive fault "
370 "on cpu 0x%x\n", cpu);
371 release_output_lock();
372 goto waiting;
374 secondary = !(xmon_taken && cpu == xmon_owner);
375 goto cmdloop;
378 xmon_fault_jmp[cpu] = recurse_jmp;
379 cpu_set(cpu, cpus_in_xmon);
381 bp = NULL;
382 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
383 bp = at_breakpoint(regs->nip);
384 if (bp || (regs->msr & MSR_RI) == 0)
385 fromipi = 0;
387 if (!fromipi) {
388 get_output_lock();
389 excprint(regs);
390 if (bp) {
391 printf("cpu 0x%x stopped at breakpoint 0x%x (",
392 cpu, BP_NUM(bp));
393 xmon_print_symbol(regs->nip, " ", ")\n");
395 if ((regs->msr & MSR_RI) == 0)
396 printf("WARNING: exception is not recoverable, "
397 "can't continue\n");
398 release_output_lock();
401 waiting:
402 secondary = 1;
403 while (secondary && !xmon_gate) {
404 if (in_xmon == 0) {
405 if (fromipi)
406 goto leave;
407 secondary = test_and_set_bit(0, &in_xmon);
409 barrier();
412 if (!secondary && !xmon_gate) {
413 /* we are the first cpu to come in */
414 /* interrupt other cpu(s) */
415 int ncpus = num_online_cpus();
417 xmon_owner = cpu;
418 mb();
419 if (ncpus > 1) {
420 smp_send_debugger_break(MSG_ALL_BUT_SELF);
421 /* wait for other cpus to come in */
422 for (timeout = 100000000; timeout != 0; --timeout) {
423 if (cpus_weight(cpus_in_xmon) >= ncpus)
424 break;
425 barrier();
428 remove_bpts();
429 disable_surveillance();
430 /* for breakpoint or single step, print the current instr. */
431 if (bp || TRAP(regs) == 0xd00)
432 ppc_inst_dump(regs->nip, 1, 0);
433 printf("enter ? for help\n");
434 mb();
435 xmon_gate = 1;
436 barrier();
439 cmdloop:
440 while (in_xmon) {
441 if (secondary) {
442 if (cpu == xmon_owner) {
443 if (!test_and_set_bit(0, &xmon_taken)) {
444 secondary = 0;
445 continue;
447 /* missed it */
448 while (cpu == xmon_owner)
449 barrier();
451 barrier();
452 } else {
453 cmd = cmds(regs);
454 if (cmd != 0) {
455 /* exiting xmon */
456 insert_bpts();
457 xmon_gate = 0;
458 wmb();
459 in_xmon = 0;
460 break;
462 /* have switched to some other cpu */
463 secondary = 1;
466 leave:
467 cpu_clear(cpu, cpus_in_xmon);
468 xmon_fault_jmp[cpu] = NULL;
469 #else
470 /* UP is simple... */
471 if (in_xmon) {
472 printf("Exception %lx %s in xmon, returning to main loop\n",
473 regs->trap, getvecname(TRAP(regs)));
474 longjmp(xmon_fault_jmp[0], 1);
476 if (setjmp(recurse_jmp) == 0) {
477 xmon_fault_jmp[0] = recurse_jmp;
478 in_xmon = 1;
480 excprint(regs);
481 bp = at_breakpoint(regs->nip);
482 if (bp) {
483 printf("Stopped at breakpoint %x (", BP_NUM(bp));
484 xmon_print_symbol(regs->nip, " ", ")\n");
486 if ((regs->msr & MSR_RI) == 0)
487 printf("WARNING: exception is not recoverable, "
488 "can't continue\n");
489 remove_bpts();
490 disable_surveillance();
491 /* for breakpoint or single step, print the current instr. */
492 if (bp || TRAP(regs) == 0xd00)
493 ppc_inst_dump(regs->nip, 1, 0);
494 printf("enter ? for help\n");
497 cmd = cmds(regs);
499 insert_bpts();
500 in_xmon = 0;
501 #endif
503 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
504 bp = at_breakpoint(regs->nip);
505 if (bp != NULL) {
506 int stepped = emulate_step(regs, bp->instr[0]);
507 if (stepped == 0) {
508 regs->nip = (unsigned long) &bp->instr[0];
509 atomic_inc(&bp->ref_count);
510 } else if (stepped < 0) {
511 printf("Couldn't single-step %s instruction\n",
512 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
517 insert_cpu_bpts();
519 mtmsr(msr); /* restore interrupt enable */
521 return cmd != 'X' && cmd != EOF;
524 int xmon(struct pt_regs *excp)
526 struct pt_regs regs;
528 if (excp == NULL) {
529 xmon_save_regs(&regs);
530 excp = &regs;
533 return xmon_core(excp, 0);
535 EXPORT_SYMBOL(xmon);
537 irqreturn_t xmon_irq(int irq, void *d)
539 unsigned long flags;
540 local_irq_save(flags);
541 printf("Keyboard interrupt\n");
542 xmon(get_irq_regs());
543 local_irq_restore(flags);
544 return IRQ_HANDLED;
547 static int xmon_bpt(struct pt_regs *regs)
549 struct bpt *bp;
550 unsigned long offset;
552 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
553 return 0;
555 /* Are we at the trap at bp->instr[1] for some bp? */
556 bp = in_breakpoint_table(regs->nip, &offset);
557 if (bp != NULL && offset == 4) {
558 regs->nip = bp->address + 4;
559 atomic_dec(&bp->ref_count);
560 return 1;
563 /* Are we at a breakpoint? */
564 bp = at_breakpoint(regs->nip);
565 if (!bp)
566 return 0;
568 xmon_core(regs, 0);
570 return 1;
573 static int xmon_sstep(struct pt_regs *regs)
575 if (user_mode(regs))
576 return 0;
577 xmon_core(regs, 0);
578 return 1;
581 static int xmon_dabr_match(struct pt_regs *regs)
583 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
584 return 0;
585 if (dabr.enabled == 0)
586 return 0;
587 xmon_core(regs, 0);
588 return 1;
591 static int xmon_iabr_match(struct pt_regs *regs)
593 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
594 return 0;
595 if (iabr == 0)
596 return 0;
597 xmon_core(regs, 0);
598 return 1;
601 static int xmon_ipi(struct pt_regs *regs)
603 #ifdef CONFIG_SMP
604 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
605 xmon_core(regs, 1);
606 #endif
607 return 0;
610 static int xmon_fault_handler(struct pt_regs *regs)
612 struct bpt *bp;
613 unsigned long offset;
615 if (in_xmon && catch_memory_errors)
616 handle_fault(regs); /* doesn't return */
618 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
619 bp = in_breakpoint_table(regs->nip, &offset);
620 if (bp != NULL) {
621 regs->nip = bp->address + offset;
622 atomic_dec(&bp->ref_count);
626 return 0;
629 static struct bpt *at_breakpoint(unsigned long pc)
631 int i;
632 struct bpt *bp;
634 bp = bpts;
635 for (i = 0; i < NBPTS; ++i, ++bp)
636 if (bp->enabled && pc == bp->address)
637 return bp;
638 return NULL;
641 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
643 unsigned long off;
645 off = nip - (unsigned long) bpts;
646 if (off >= sizeof(bpts))
647 return NULL;
648 off %= sizeof(struct bpt);
649 if (off != offsetof(struct bpt, instr[0])
650 && off != offsetof(struct bpt, instr[1]))
651 return NULL;
652 *offp = off - offsetof(struct bpt, instr[0]);
653 return (struct bpt *) (nip - off);
656 static struct bpt *new_breakpoint(unsigned long a)
658 struct bpt *bp;
660 a &= ~3UL;
661 bp = at_breakpoint(a);
662 if (bp)
663 return bp;
665 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
666 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
667 bp->address = a;
668 bp->instr[1] = bpinstr;
669 store_inst(&bp->instr[1]);
670 return bp;
674 printf("Sorry, no free breakpoints. Please clear one first.\n");
675 return NULL;
678 static void insert_bpts(void)
680 int i;
681 struct bpt *bp;
683 bp = bpts;
684 for (i = 0; i < NBPTS; ++i, ++bp) {
685 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
686 continue;
687 if (mread(bp->address, &bp->instr[0], 4) != 4) {
688 printf("Couldn't read instruction at %lx, "
689 "disabling breakpoint there\n", bp->address);
690 bp->enabled = 0;
691 continue;
693 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
694 printf("Breakpoint at %lx is on an mtmsrd or rfid "
695 "instruction, disabling it\n", bp->address);
696 bp->enabled = 0;
697 continue;
699 store_inst(&bp->instr[0]);
700 if (bp->enabled & BP_IABR)
701 continue;
702 if (mwrite(bp->address, &bpinstr, 4) != 4) {
703 printf("Couldn't write instruction at %lx, "
704 "disabling breakpoint there\n", bp->address);
705 bp->enabled &= ~BP_TRAP;
706 continue;
708 store_inst((void *)bp->address);
712 static void insert_cpu_bpts(void)
714 if (dabr.enabled)
715 set_dabr(dabr.address | (dabr.enabled & 7));
716 if (iabr && cpu_has_feature(CPU_FTR_IABR))
717 mtspr(SPRN_IABR, iabr->address
718 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
721 static void remove_bpts(void)
723 int i;
724 struct bpt *bp;
725 unsigned instr;
727 bp = bpts;
728 for (i = 0; i < NBPTS; ++i, ++bp) {
729 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
730 continue;
731 if (mread(bp->address, &instr, 4) == 4
732 && instr == bpinstr
733 && mwrite(bp->address, &bp->instr, 4) != 4)
734 printf("Couldn't remove breakpoint at %lx\n",
735 bp->address);
736 else
737 store_inst((void *)bp->address);
741 static void remove_cpu_bpts(void)
743 set_dabr(0);
744 if (cpu_has_feature(CPU_FTR_IABR))
745 mtspr(SPRN_IABR, 0);
748 /* Command interpreting routine */
749 static char *last_cmd;
751 static int
752 cmds(struct pt_regs *excp)
754 int cmd = 0;
756 last_cmd = NULL;
757 xmon_regs = excp;
759 if (!xmon_no_auto_backtrace) {
760 xmon_no_auto_backtrace = 1;
761 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
764 for(;;) {
765 #ifdef CONFIG_SMP
766 printf("%x:", smp_processor_id());
767 #endif /* CONFIG_SMP */
768 printf("mon> ");
769 flush_input();
770 termch = 0;
771 cmd = skipbl();
772 if( cmd == '\n' ) {
773 if (last_cmd == NULL)
774 continue;
775 take_input(last_cmd);
776 last_cmd = NULL;
777 cmd = inchar();
779 switch (cmd) {
780 case 'm':
781 cmd = inchar();
782 switch (cmd) {
783 case 'm':
784 case 's':
785 case 'd':
786 memops(cmd);
787 break;
788 case 'l':
789 memlocate();
790 break;
791 case 'z':
792 memzcan();
793 break;
794 case 'i':
795 show_mem();
796 break;
797 default:
798 termch = cmd;
799 memex();
801 break;
802 case 'd':
803 dump();
804 break;
805 case 'l':
806 symbol_lookup();
807 break;
808 case 'r':
809 prregs(excp); /* print regs */
810 break;
811 case 'e':
812 excprint(excp);
813 break;
814 case 'S':
815 super_regs();
816 break;
817 case 't':
818 backtrace(excp);
819 break;
820 case 'f':
821 cacheflush();
822 break;
823 case 's':
824 if (do_spu_cmd() == 0)
825 break;
826 if (do_step(excp))
827 return cmd;
828 break;
829 case 'x':
830 case 'X':
831 return cmd;
832 case EOF:
833 printf(" <no input ...>\n");
834 mdelay(2000);
835 return cmd;
836 case '?':
837 printf(help_string);
838 break;
839 case 'b':
840 bpt_cmds();
841 break;
842 case 'C':
843 csum();
844 break;
845 case 'c':
846 if (cpu_cmd())
847 return 0;
848 break;
849 case 'z':
850 bootcmds();
851 break;
852 case 'p':
853 proccall();
854 break;
855 #ifdef CONFIG_PPC_STD_MMU
856 case 'u':
857 dump_segments();
858 break;
859 #endif
860 default:
861 printf("Unrecognized command: ");
862 do {
863 if (' ' < cmd && cmd <= '~')
864 putchar(cmd);
865 else
866 printf("\\x%x", cmd);
867 cmd = inchar();
868 } while (cmd != '\n');
869 printf(" (type ? for help)\n");
870 break;
876 * Step a single instruction.
877 * Some instructions we emulate, others we execute with MSR_SE set.
879 static int do_step(struct pt_regs *regs)
881 unsigned int instr;
882 int stepped;
884 /* check we are in 64-bit kernel mode, translation enabled */
885 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
886 if (mread(regs->nip, &instr, 4) == 4) {
887 stepped = emulate_step(regs, instr);
888 if (stepped < 0) {
889 printf("Couldn't single-step %s instruction\n",
890 (IS_RFID(instr)? "rfid": "mtmsrd"));
891 return 0;
893 if (stepped > 0) {
894 regs->trap = 0xd00 | (regs->trap & 1);
895 printf("stepped to ");
896 xmon_print_symbol(regs->nip, " ", "\n");
897 ppc_inst_dump(regs->nip, 1, 0);
898 return 0;
902 regs->msr |= MSR_SE;
903 return 1;
906 static void bootcmds(void)
908 int cmd;
910 cmd = inchar();
911 if (cmd == 'r')
912 ppc_md.restart(NULL);
913 else if (cmd == 'h')
914 ppc_md.halt();
915 else if (cmd == 'p')
916 ppc_md.power_off();
919 static int cpu_cmd(void)
921 #ifdef CONFIG_SMP
922 unsigned long cpu;
923 int timeout;
924 int count;
926 if (!scanhex(&cpu)) {
927 /* print cpus waiting or in xmon */
928 printf("cpus stopped:");
929 count = 0;
930 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
931 if (cpu_isset(cpu, cpus_in_xmon)) {
932 if (count == 0)
933 printf(" %x", cpu);
934 ++count;
935 } else {
936 if (count > 1)
937 printf("-%x", cpu - 1);
938 count = 0;
941 if (count > 1)
942 printf("-%x", NR_CPUS - 1);
943 printf("\n");
944 return 0;
946 /* try to switch to cpu specified */
947 if (!cpu_isset(cpu, cpus_in_xmon)) {
948 printf("cpu 0x%x isn't in xmon\n", cpu);
949 return 0;
951 xmon_taken = 0;
952 mb();
953 xmon_owner = cpu;
954 timeout = 10000000;
955 while (!xmon_taken) {
956 if (--timeout == 0) {
957 if (test_and_set_bit(0, &xmon_taken))
958 break;
959 /* take control back */
960 mb();
961 xmon_owner = smp_processor_id();
962 printf("cpu %u didn't take control\n", cpu);
963 return 0;
965 barrier();
967 return 1;
968 #else
969 return 0;
970 #endif /* CONFIG_SMP */
973 static unsigned short fcstab[256] = {
974 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
975 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
976 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
977 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
978 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
979 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
980 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
981 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
982 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
983 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
984 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
985 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
986 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
987 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
988 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
989 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
990 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
991 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
992 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
993 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
994 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
995 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
996 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
997 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
998 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
999 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1000 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1001 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1002 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1003 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1004 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1005 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1008 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1010 static void
1011 csum(void)
1013 unsigned int i;
1014 unsigned short fcs;
1015 unsigned char v;
1017 if (!scanhex(&adrs))
1018 return;
1019 if (!scanhex(&ncsum))
1020 return;
1021 fcs = 0xffff;
1022 for (i = 0; i < ncsum; ++i) {
1023 if (mread(adrs+i, &v, 1) == 0) {
1024 printf("csum stopped at %x\n", adrs+i);
1025 break;
1027 fcs = FCS(fcs, v);
1029 printf("%x\n", fcs);
1033 * Check if this is a suitable place to put a breakpoint.
1035 static long check_bp_loc(unsigned long addr)
1037 unsigned int instr;
1039 addr &= ~3;
1040 if (!is_kernel_addr(addr)) {
1041 printf("Breakpoints may only be placed at kernel addresses\n");
1042 return 0;
1044 if (!mread(addr, &instr, sizeof(instr))) {
1045 printf("Can't read instruction at address %lx\n", addr);
1046 return 0;
1048 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1049 printf("Breakpoints may not be placed on mtmsrd or rfid "
1050 "instructions\n");
1051 return 0;
1053 return 1;
1056 static char *breakpoint_help_string =
1057 "Breakpoint command usage:\n"
1058 "b show breakpoints\n"
1059 "b <addr> [cnt] set breakpoint at given instr addr\n"
1060 "bc clear all breakpoints\n"
1061 "bc <n/addr> clear breakpoint number n or at addr\n"
1062 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1063 "bd <addr> [cnt] set hardware data breakpoint\n"
1066 static void
1067 bpt_cmds(void)
1069 int cmd;
1070 unsigned long a;
1071 int mode, i;
1072 struct bpt *bp;
1073 const char badaddr[] = "Only kernel addresses are permitted "
1074 "for breakpoints\n";
1076 cmd = inchar();
1077 switch (cmd) {
1078 #ifndef CONFIG_8xx
1079 case 'd': /* bd - hardware data breakpoint */
1080 mode = 7;
1081 cmd = inchar();
1082 if (cmd == 'r')
1083 mode = 5;
1084 else if (cmd == 'w')
1085 mode = 6;
1086 else
1087 termch = cmd;
1088 dabr.address = 0;
1089 dabr.enabled = 0;
1090 if (scanhex(&dabr.address)) {
1091 if (!is_kernel_addr(dabr.address)) {
1092 printf(badaddr);
1093 break;
1095 dabr.address &= ~7;
1096 dabr.enabled = mode | BP_DABR;
1098 break;
1100 case 'i': /* bi - hardware instr breakpoint */
1101 if (!cpu_has_feature(CPU_FTR_IABR)) {
1102 printf("Hardware instruction breakpoint "
1103 "not supported on this cpu\n");
1104 break;
1106 if (iabr) {
1107 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1108 iabr = NULL;
1110 if (!scanhex(&a))
1111 break;
1112 if (!check_bp_loc(a))
1113 break;
1114 bp = new_breakpoint(a);
1115 if (bp != NULL) {
1116 bp->enabled |= BP_IABR | BP_IABR_TE;
1117 iabr = bp;
1119 break;
1120 #endif
1122 case 'c':
1123 if (!scanhex(&a)) {
1124 /* clear all breakpoints */
1125 for (i = 0; i < NBPTS; ++i)
1126 bpts[i].enabled = 0;
1127 iabr = NULL;
1128 dabr.enabled = 0;
1129 printf("All breakpoints cleared\n");
1130 break;
1133 if (a <= NBPTS && a >= 1) {
1134 /* assume a breakpoint number */
1135 bp = &bpts[a-1]; /* bp nums are 1 based */
1136 } else {
1137 /* assume a breakpoint address */
1138 bp = at_breakpoint(a);
1139 if (bp == 0) {
1140 printf("No breakpoint at %x\n", a);
1141 break;
1145 printf("Cleared breakpoint %x (", BP_NUM(bp));
1146 xmon_print_symbol(bp->address, " ", ")\n");
1147 bp->enabled = 0;
1148 break;
1150 default:
1151 termch = cmd;
1152 cmd = skipbl();
1153 if (cmd == '?') {
1154 printf(breakpoint_help_string);
1155 break;
1157 termch = cmd;
1158 if (!scanhex(&a)) {
1159 /* print all breakpoints */
1160 printf(" type address\n");
1161 if (dabr.enabled) {
1162 printf(" data "REG" [", dabr.address);
1163 if (dabr.enabled & 1)
1164 printf("r");
1165 if (dabr.enabled & 2)
1166 printf("w");
1167 printf("]\n");
1169 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1170 if (!bp->enabled)
1171 continue;
1172 printf("%2x %s ", BP_NUM(bp),
1173 (bp->enabled & BP_IABR)? "inst": "trap");
1174 xmon_print_symbol(bp->address, " ", "\n");
1176 break;
1179 if (!check_bp_loc(a))
1180 break;
1181 bp = new_breakpoint(a);
1182 if (bp != NULL)
1183 bp->enabled |= BP_TRAP;
1184 break;
1188 /* Very cheap human name for vector lookup. */
1189 static
1190 const char *getvecname(unsigned long vec)
1192 char *ret;
1194 switch (vec) {
1195 case 0x100: ret = "(System Reset)"; break;
1196 case 0x200: ret = "(Machine Check)"; break;
1197 case 0x300: ret = "(Data Access)"; break;
1198 case 0x380: ret = "(Data SLB Access)"; break;
1199 case 0x400: ret = "(Instruction Access)"; break;
1200 case 0x480: ret = "(Instruction SLB Access)"; break;
1201 case 0x500: ret = "(Hardware Interrupt)"; break;
1202 case 0x600: ret = "(Alignment)"; break;
1203 case 0x700: ret = "(Program Check)"; break;
1204 case 0x800: ret = "(FPU Unavailable)"; break;
1205 case 0x900: ret = "(Decrementer)"; break;
1206 case 0xc00: ret = "(System Call)"; break;
1207 case 0xd00: ret = "(Single Step)"; break;
1208 case 0xf00: ret = "(Performance Monitor)"; break;
1209 case 0xf20: ret = "(Altivec Unavailable)"; break;
1210 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1211 default: ret = "";
1213 return ret;
1216 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1217 unsigned long *endp)
1219 unsigned long size, offset;
1220 const char *name;
1221 char *modname;
1223 *startp = *endp = 0;
1224 if (pc == 0)
1225 return;
1226 if (setjmp(bus_error_jmp) == 0) {
1227 catch_memory_errors = 1;
1228 sync();
1229 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1230 if (name != NULL) {
1231 *startp = pc - offset;
1232 *endp = pc - offset + size;
1234 sync();
1236 catch_memory_errors = 0;
1239 static int xmon_depth_to_print = 64;
1241 #ifdef CONFIG_PPC64
1242 #define LRSAVE_OFFSET 0x10
1243 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1244 #define MARKER_OFFSET 0x60
1245 #define REGS_OFFSET 0x70
1246 #else
1247 #define LRSAVE_OFFSET 4
1248 #define REG_FRAME_MARKER 0x72656773
1249 #define MARKER_OFFSET 8
1250 #define REGS_OFFSET 16
1251 #endif
1253 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1254 unsigned long pc)
1256 unsigned long ip;
1257 unsigned long newsp;
1258 unsigned long marker;
1259 int count = 0;
1260 struct pt_regs regs;
1262 do {
1263 if (sp < PAGE_OFFSET) {
1264 if (sp != 0)
1265 printf("SP (%lx) is in userspace\n", sp);
1266 break;
1269 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1270 || !mread(sp, &newsp, sizeof(unsigned long))) {
1271 printf("Couldn't read stack frame at %lx\n", sp);
1272 break;
1276 * For the first stack frame, try to work out if
1277 * LR and/or the saved LR value in the bottommost
1278 * stack frame are valid.
1280 if ((pc | lr) != 0) {
1281 unsigned long fnstart, fnend;
1282 unsigned long nextip;
1283 int printip = 1;
1285 get_function_bounds(pc, &fnstart, &fnend);
1286 nextip = 0;
1287 if (newsp > sp)
1288 mread(newsp + LRSAVE_OFFSET, &nextip,
1289 sizeof(unsigned long));
1290 if (lr == ip) {
1291 if (lr < PAGE_OFFSET
1292 || (fnstart <= lr && lr < fnend))
1293 printip = 0;
1294 } else if (lr == nextip) {
1295 printip = 0;
1296 } else if (lr >= PAGE_OFFSET
1297 && !(fnstart <= lr && lr < fnend)) {
1298 printf("[link register ] ");
1299 xmon_print_symbol(lr, " ", "\n");
1301 if (printip) {
1302 printf("["REG"] ", sp);
1303 xmon_print_symbol(ip, " ", " (unreliable)\n");
1305 pc = lr = 0;
1307 } else {
1308 printf("["REG"] ", sp);
1309 xmon_print_symbol(ip, " ", "\n");
1312 /* Look for "regshere" marker to see if this is
1313 an exception frame. */
1314 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1315 && marker == REG_FRAME_MARKER) {
1316 if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
1317 != sizeof(regs)) {
1318 printf("Couldn't read registers at %lx\n",
1319 sp + REGS_OFFSET);
1320 break;
1322 printf("--- Exception: %lx %s at ", regs.trap,
1323 getvecname(TRAP(&regs)));
1324 pc = regs.nip;
1325 lr = regs.link;
1326 xmon_print_symbol(pc, " ", "\n");
1329 if (newsp == 0)
1330 break;
1332 sp = newsp;
1333 } while (count++ < xmon_depth_to_print);
1336 static void backtrace(struct pt_regs *excp)
1338 unsigned long sp;
1340 if (scanhex(&sp))
1341 xmon_show_stack(sp, 0, 0);
1342 else
1343 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1344 scannl();
1347 static void print_bug_trap(struct pt_regs *regs)
1349 struct bug_entry *bug;
1350 unsigned long addr;
1352 if (regs->msr & MSR_PR)
1353 return; /* not in kernel */
1354 addr = regs->nip; /* address of trap instruction */
1355 if (addr < PAGE_OFFSET)
1356 return;
1357 bug = find_bug(regs->nip);
1358 if (bug == NULL)
1359 return;
1360 if (bug->line & BUG_WARNING_TRAP)
1361 return;
1363 printf("kernel BUG in %s at %s:%d!\n",
1364 bug->function, bug->file, (unsigned int)bug->line);
1367 void excprint(struct pt_regs *fp)
1369 unsigned long trap;
1371 #ifdef CONFIG_SMP
1372 printf("cpu 0x%x: ", smp_processor_id());
1373 #endif /* CONFIG_SMP */
1375 trap = TRAP(fp);
1376 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1377 printf(" pc: ");
1378 xmon_print_symbol(fp->nip, ": ", "\n");
1380 printf(" lr: ", fp->link);
1381 xmon_print_symbol(fp->link, ": ", "\n");
1383 printf(" sp: %lx\n", fp->gpr[1]);
1384 printf(" msr: %lx\n", fp->msr);
1386 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1387 printf(" dar: %lx\n", fp->dar);
1388 if (trap != 0x380)
1389 printf(" dsisr: %lx\n", fp->dsisr);
1392 printf(" current = 0x%lx\n", current);
1393 #ifdef CONFIG_PPC64
1394 printf(" paca = 0x%lx\n", get_paca());
1395 #endif
1396 if (current) {
1397 printf(" pid = %ld, comm = %s\n",
1398 current->pid, current->comm);
1401 if (trap == 0x700)
1402 print_bug_trap(fp);
1405 void prregs(struct pt_regs *fp)
1407 int n, trap;
1408 unsigned long base;
1409 struct pt_regs regs;
1411 if (scanhex(&base)) {
1412 if (setjmp(bus_error_jmp) == 0) {
1413 catch_memory_errors = 1;
1414 sync();
1415 regs = *(struct pt_regs *)base;
1416 sync();
1417 __delay(200);
1418 } else {
1419 catch_memory_errors = 0;
1420 printf("*** Error reading registers from "REG"\n",
1421 base);
1422 return;
1424 catch_memory_errors = 0;
1425 fp = &regs;
1428 #ifdef CONFIG_PPC64
1429 if (FULL_REGS(fp)) {
1430 for (n = 0; n < 16; ++n)
1431 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1432 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1433 } else {
1434 for (n = 0; n < 7; ++n)
1435 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1436 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1438 #else
1439 for (n = 0; n < 32; ++n) {
1440 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1441 (n & 3) == 3? "\n": " ");
1442 if (n == 12 && !FULL_REGS(fp)) {
1443 printf("\n");
1444 break;
1447 #endif
1448 printf("pc = ");
1449 xmon_print_symbol(fp->nip, " ", "\n");
1450 printf("lr = ");
1451 xmon_print_symbol(fp->link, " ", "\n");
1452 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1453 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1454 fp->ctr, fp->xer, fp->trap);
1455 trap = TRAP(fp);
1456 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1457 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1460 void cacheflush(void)
1462 int cmd;
1463 unsigned long nflush;
1465 cmd = inchar();
1466 if (cmd != 'i')
1467 termch = cmd;
1468 scanhex((void *)&adrs);
1469 if (termch != '\n')
1470 termch = 0;
1471 nflush = 1;
1472 scanhex(&nflush);
1473 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1474 if (setjmp(bus_error_jmp) == 0) {
1475 catch_memory_errors = 1;
1476 sync();
1478 if (cmd != 'i') {
1479 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1480 cflush((void *) adrs);
1481 } else {
1482 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1483 cinval((void *) adrs);
1485 sync();
1486 /* wait a little while to see if we get a machine check */
1487 __delay(200);
1489 catch_memory_errors = 0;
1492 unsigned long
1493 read_spr(int n)
1495 unsigned int instrs[2];
1496 unsigned long (*code)(void);
1497 unsigned long ret = -1UL;
1498 #ifdef CONFIG_PPC64
1499 unsigned long opd[3];
1501 opd[0] = (unsigned long)instrs;
1502 opd[1] = 0;
1503 opd[2] = 0;
1504 code = (unsigned long (*)(void)) opd;
1505 #else
1506 code = (unsigned long (*)(void)) instrs;
1507 #endif
1509 /* mfspr r3,n; blr */
1510 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1511 instrs[1] = 0x4e800020;
1512 store_inst(instrs);
1513 store_inst(instrs+1);
1515 if (setjmp(bus_error_jmp) == 0) {
1516 catch_memory_errors = 1;
1517 sync();
1519 ret = code();
1521 sync();
1522 /* wait a little while to see if we get a machine check */
1523 __delay(200);
1524 n = size;
1527 return ret;
1530 void
1531 write_spr(int n, unsigned long val)
1533 unsigned int instrs[2];
1534 unsigned long (*code)(unsigned long);
1535 #ifdef CONFIG_PPC64
1536 unsigned long opd[3];
1538 opd[0] = (unsigned long)instrs;
1539 opd[1] = 0;
1540 opd[2] = 0;
1541 code = (unsigned long (*)(unsigned long)) opd;
1542 #else
1543 code = (unsigned long (*)(unsigned long)) instrs;
1544 #endif
1546 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1547 instrs[1] = 0x4e800020;
1548 store_inst(instrs);
1549 store_inst(instrs+1);
1551 if (setjmp(bus_error_jmp) == 0) {
1552 catch_memory_errors = 1;
1553 sync();
1555 code(val);
1557 sync();
1558 /* wait a little while to see if we get a machine check */
1559 __delay(200);
1560 n = size;
1564 static unsigned long regno;
1565 extern char exc_prolog;
1566 extern char dec_exc;
1568 void super_regs(void)
1570 int cmd;
1571 unsigned long val;
1573 cmd = skipbl();
1574 if (cmd == '\n') {
1575 unsigned long sp, toc;
1576 asm("mr %0,1" : "=r" (sp) :);
1577 asm("mr %0,2" : "=r" (toc) :);
1579 printf("msr = "REG" sprg0= "REG"\n",
1580 mfmsr(), mfspr(SPRN_SPRG0));
1581 printf("pvr = "REG" sprg1= "REG"\n",
1582 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1583 printf("dec = "REG" sprg2= "REG"\n",
1584 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1585 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1586 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1587 #ifdef CONFIG_PPC_ISERIES
1588 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1589 struct paca_struct *ptrPaca;
1590 struct lppaca *ptrLpPaca;
1591 struct ItLpRegSave *ptrLpRegSave;
1593 /* Dump out relevant Paca data areas. */
1594 printf("Paca: \n");
1595 ptrPaca = get_paca();
1597 printf(" Local Processor Control Area (LpPaca): \n");
1598 ptrLpPaca = ptrPaca->lppaca_ptr;
1599 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1600 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1601 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1602 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1603 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1605 printf(" Local Processor Register Save Area (LpRegSave): \n");
1606 ptrLpRegSave = ptrPaca->reg_save_ptr;
1607 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1608 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1609 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1610 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1611 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1612 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1614 #endif
1616 return;
1619 scanhex(&regno);
1620 switch (cmd) {
1621 case 'w':
1622 val = read_spr(regno);
1623 scanhex(&val);
1624 write_spr(regno, val);
1625 /* fall through */
1626 case 'r':
1627 printf("spr %lx = %lx\n", regno, read_spr(regno));
1628 break;
1630 scannl();
1634 * Stuff for reading and writing memory safely
1637 mread(unsigned long adrs, void *buf, int size)
1639 volatile int n;
1640 char *p, *q;
1642 n = 0;
1643 if (setjmp(bus_error_jmp) == 0) {
1644 catch_memory_errors = 1;
1645 sync();
1646 p = (char *)adrs;
1647 q = (char *)buf;
1648 switch (size) {
1649 case 2:
1650 *(u16 *)q = *(u16 *)p;
1651 break;
1652 case 4:
1653 *(u32 *)q = *(u32 *)p;
1654 break;
1655 case 8:
1656 *(u64 *)q = *(u64 *)p;
1657 break;
1658 default:
1659 for( ; n < size; ++n) {
1660 *q++ = *p++;
1661 sync();
1664 sync();
1665 /* wait a little while to see if we get a machine check */
1666 __delay(200);
1667 n = size;
1669 catch_memory_errors = 0;
1670 return n;
1674 mwrite(unsigned long adrs, void *buf, int size)
1676 volatile int n;
1677 char *p, *q;
1679 n = 0;
1680 if (setjmp(bus_error_jmp) == 0) {
1681 catch_memory_errors = 1;
1682 sync();
1683 p = (char *) adrs;
1684 q = (char *) buf;
1685 switch (size) {
1686 case 2:
1687 *(u16 *)p = *(u16 *)q;
1688 break;
1689 case 4:
1690 *(u32 *)p = *(u32 *)q;
1691 break;
1692 case 8:
1693 *(u64 *)p = *(u64 *)q;
1694 break;
1695 default:
1696 for ( ; n < size; ++n) {
1697 *p++ = *q++;
1698 sync();
1701 sync();
1702 /* wait a little while to see if we get a machine check */
1703 __delay(200);
1704 n = size;
1705 } else {
1706 printf("*** Error writing address %x\n", adrs + n);
1708 catch_memory_errors = 0;
1709 return n;
1712 static int fault_type;
1713 static int fault_except;
1714 static char *fault_chars[] = { "--", "**", "##" };
1716 static int handle_fault(struct pt_regs *regs)
1718 fault_except = TRAP(regs);
1719 switch (TRAP(regs)) {
1720 case 0x200:
1721 fault_type = 0;
1722 break;
1723 case 0x300:
1724 case 0x380:
1725 fault_type = 1;
1726 break;
1727 default:
1728 fault_type = 2;
1731 longjmp(bus_error_jmp, 1);
1733 return 0;
1736 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1738 void
1739 byterev(unsigned char *val, int size)
1741 int t;
1743 switch (size) {
1744 case 2:
1745 SWAP(val[0], val[1], t);
1746 break;
1747 case 4:
1748 SWAP(val[0], val[3], t);
1749 SWAP(val[1], val[2], t);
1750 break;
1751 case 8: /* is there really any use for this? */
1752 SWAP(val[0], val[7], t);
1753 SWAP(val[1], val[6], t);
1754 SWAP(val[2], val[5], t);
1755 SWAP(val[3], val[4], t);
1756 break;
1760 static int brev;
1761 static int mnoread;
1763 static char *memex_help_string =
1764 "Memory examine command usage:\n"
1765 "m [addr] [flags] examine/change memory\n"
1766 " addr is optional. will start where left off.\n"
1767 " flags may include chars from this set:\n"
1768 " b modify by bytes (default)\n"
1769 " w modify by words (2 byte)\n"
1770 " l modify by longs (4 byte)\n"
1771 " d modify by doubleword (8 byte)\n"
1772 " r toggle reverse byte order mode\n"
1773 " n do not read memory (for i/o spaces)\n"
1774 " . ok to read (default)\n"
1775 "NOTE: flags are saved as defaults\n"
1778 static char *memex_subcmd_help_string =
1779 "Memory examine subcommands:\n"
1780 " hexval write this val to current location\n"
1781 " 'string' write chars from string to this location\n"
1782 " ' increment address\n"
1783 " ^ decrement address\n"
1784 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1785 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1786 " ` clear no-read flag\n"
1787 " ; stay at this addr\n"
1788 " v change to byte mode\n"
1789 " w change to word (2 byte) mode\n"
1790 " l change to long (4 byte) mode\n"
1791 " u change to doubleword (8 byte) mode\n"
1792 " m addr change current addr\n"
1793 " n toggle no-read flag\n"
1794 " r toggle byte reverse flag\n"
1795 " < count back up count bytes\n"
1796 " > count skip forward count bytes\n"
1797 " x exit this mode\n"
1800 void
1801 memex(void)
1803 int cmd, inc, i, nslash;
1804 unsigned long n;
1805 unsigned char val[16];
1807 scanhex((void *)&adrs);
1808 cmd = skipbl();
1809 if (cmd == '?') {
1810 printf(memex_help_string);
1811 return;
1812 } else {
1813 termch = cmd;
1815 last_cmd = "m\n";
1816 while ((cmd = skipbl()) != '\n') {
1817 switch( cmd ){
1818 case 'b': size = 1; break;
1819 case 'w': size = 2; break;
1820 case 'l': size = 4; break;
1821 case 'd': size = 8; break;
1822 case 'r': brev = !brev; break;
1823 case 'n': mnoread = 1; break;
1824 case '.': mnoread = 0; break;
1827 if( size <= 0 )
1828 size = 1;
1829 else if( size > 8 )
1830 size = 8;
1831 for(;;){
1832 if (!mnoread)
1833 n = mread(adrs, val, size);
1834 printf(REG"%c", adrs, brev? 'r': ' ');
1835 if (!mnoread) {
1836 if (brev)
1837 byterev(val, size);
1838 putchar(' ');
1839 for (i = 0; i < n; ++i)
1840 printf("%.2x", val[i]);
1841 for (; i < size; ++i)
1842 printf("%s", fault_chars[fault_type]);
1844 putchar(' ');
1845 inc = size;
1846 nslash = 0;
1847 for(;;){
1848 if( scanhex(&n) ){
1849 for (i = 0; i < size; ++i)
1850 val[i] = n >> (i * 8);
1851 if (!brev)
1852 byterev(val, size);
1853 mwrite(adrs, val, size);
1854 inc = size;
1856 cmd = skipbl();
1857 if (cmd == '\n')
1858 break;
1859 inc = 0;
1860 switch (cmd) {
1861 case '\'':
1862 for(;;){
1863 n = inchar();
1864 if( n == '\\' )
1865 n = bsesc();
1866 else if( n == '\'' )
1867 break;
1868 for (i = 0; i < size; ++i)
1869 val[i] = n >> (i * 8);
1870 if (!brev)
1871 byterev(val, size);
1872 mwrite(adrs, val, size);
1873 adrs += size;
1875 adrs -= size;
1876 inc = size;
1877 break;
1878 case ',':
1879 adrs += size;
1880 break;
1881 case '.':
1882 mnoread = 0;
1883 break;
1884 case ';':
1885 break;
1886 case 'x':
1887 case EOF:
1888 scannl();
1889 return;
1890 case 'b':
1891 case 'v':
1892 size = 1;
1893 break;
1894 case 'w':
1895 size = 2;
1896 break;
1897 case 'l':
1898 size = 4;
1899 break;
1900 case 'u':
1901 size = 8;
1902 break;
1903 case '^':
1904 adrs -= size;
1905 break;
1906 break;
1907 case '/':
1908 if (nslash > 0)
1909 adrs -= 1 << nslash;
1910 else
1911 nslash = 0;
1912 nslash += 4;
1913 adrs += 1 << nslash;
1914 break;
1915 case '\\':
1916 if (nslash < 0)
1917 adrs += 1 << -nslash;
1918 else
1919 nslash = 0;
1920 nslash -= 4;
1921 adrs -= 1 << -nslash;
1922 break;
1923 case 'm':
1924 scanhex((void *)&adrs);
1925 break;
1926 case 'n':
1927 mnoread = 1;
1928 break;
1929 case 'r':
1930 brev = !brev;
1931 break;
1932 case '<':
1933 n = size;
1934 scanhex(&n);
1935 adrs -= n;
1936 break;
1937 case '>':
1938 n = size;
1939 scanhex(&n);
1940 adrs += n;
1941 break;
1942 case '?':
1943 printf(memex_subcmd_help_string);
1944 break;
1947 adrs += inc;
1952 bsesc(void)
1954 int c;
1956 c = inchar();
1957 switch( c ){
1958 case 'n': c = '\n'; break;
1959 case 'r': c = '\r'; break;
1960 case 'b': c = '\b'; break;
1961 case 't': c = '\t'; break;
1963 return c;
1966 static void xmon_rawdump (unsigned long adrs, long ndump)
1968 long n, m, r, nr;
1969 unsigned char temp[16];
1971 for (n = ndump; n > 0;) {
1972 r = n < 16? n: 16;
1973 nr = mread(adrs, temp, r);
1974 adrs += nr;
1975 for (m = 0; m < r; ++m) {
1976 if (m < nr)
1977 printf("%.2x", temp[m]);
1978 else
1979 printf("%s", fault_chars[fault_type]);
1981 n -= r;
1982 if (nr < r)
1983 break;
1985 printf("\n");
1988 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1989 || ('a' <= (c) && (c) <= 'f') \
1990 || ('A' <= (c) && (c) <= 'F'))
1991 void
1992 dump(void)
1994 int c;
1996 c = inchar();
1997 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1998 termch = c;
1999 scanhex((void *)&adrs);
2000 if (termch != '\n')
2001 termch = 0;
2002 if (c == 'i') {
2003 scanhex(&nidump);
2004 if (nidump == 0)
2005 nidump = 16;
2006 else if (nidump > MAX_DUMP)
2007 nidump = MAX_DUMP;
2008 adrs += ppc_inst_dump(adrs, nidump, 1);
2009 last_cmd = "di\n";
2010 } else if (c == 'r') {
2011 scanhex(&ndump);
2012 if (ndump == 0)
2013 ndump = 64;
2014 xmon_rawdump(adrs, ndump);
2015 adrs += ndump;
2016 last_cmd = "dr\n";
2017 } else {
2018 scanhex(&ndump);
2019 if (ndump == 0)
2020 ndump = 64;
2021 else if (ndump > MAX_DUMP)
2022 ndump = MAX_DUMP;
2023 prdump(adrs, ndump);
2024 adrs += ndump;
2025 last_cmd = "d\n";
2029 void
2030 prdump(unsigned long adrs, long ndump)
2032 long n, m, c, r, nr;
2033 unsigned char temp[16];
2035 for (n = ndump; n > 0;) {
2036 printf(REG, adrs);
2037 putchar(' ');
2038 r = n < 16? n: 16;
2039 nr = mread(adrs, temp, r);
2040 adrs += nr;
2041 for (m = 0; m < r; ++m) {
2042 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2043 putchar(' ');
2044 if (m < nr)
2045 printf("%.2x", temp[m]);
2046 else
2047 printf("%s", fault_chars[fault_type]);
2049 for (; m < 16; ++m) {
2050 if ((m & (sizeof(long) - 1)) == 0)
2051 putchar(' ');
2052 printf(" ");
2054 printf(" |");
2055 for (m = 0; m < r; ++m) {
2056 if (m < nr) {
2057 c = temp[m];
2058 putchar(' ' <= c && c <= '~'? c: '.');
2059 } else
2060 putchar(' ');
2062 n -= r;
2063 for (; m < 16; ++m)
2064 putchar(' ');
2065 printf("|\n");
2066 if (nr < r)
2067 break;
2072 ppc_inst_dump(unsigned long adr, long count, int praddr)
2074 int nr, dotted;
2075 unsigned long first_adr;
2076 unsigned long inst, last_inst = 0;
2077 unsigned char val[4];
2079 dotted = 0;
2080 for (first_adr = adr; count > 0; --count, adr += 4) {
2081 nr = mread(adr, val, 4);
2082 if (nr == 0) {
2083 if (praddr) {
2084 const char *x = fault_chars[fault_type];
2085 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2087 break;
2089 inst = GETWORD(val);
2090 if (adr > first_adr && inst == last_inst) {
2091 if (!dotted) {
2092 printf(" ...\n");
2093 dotted = 1;
2095 continue;
2097 dotted = 0;
2098 last_inst = inst;
2099 if (praddr)
2100 printf(REG" %.8x", adr, inst);
2101 printf("\t");
2102 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2103 printf("\n");
2105 return adr - first_adr;
2108 void
2109 print_address(unsigned long addr)
2111 xmon_print_symbol(addr, "\t# ", "");
2116 * Memory operations - move, set, print differences
2118 static unsigned long mdest; /* destination address */
2119 static unsigned long msrc; /* source address */
2120 static unsigned long mval; /* byte value to set memory to */
2121 static unsigned long mcount; /* # bytes to affect */
2122 static unsigned long mdiffs; /* max # differences to print */
2124 void
2125 memops(int cmd)
2127 scanhex((void *)&mdest);
2128 if( termch != '\n' )
2129 termch = 0;
2130 scanhex((void *)(cmd == 's'? &mval: &msrc));
2131 if( termch != '\n' )
2132 termch = 0;
2133 scanhex((void *)&mcount);
2134 switch( cmd ){
2135 case 'm':
2136 memmove((void *)mdest, (void *)msrc, mcount);
2137 break;
2138 case 's':
2139 memset((void *)mdest, mval, mcount);
2140 break;
2141 case 'd':
2142 if( termch != '\n' )
2143 termch = 0;
2144 scanhex((void *)&mdiffs);
2145 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2146 break;
2150 void
2151 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2153 unsigned n, prt;
2155 prt = 0;
2156 for( n = nb; n > 0; --n )
2157 if( *p1++ != *p2++ )
2158 if( ++prt <= maxpr )
2159 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2160 p1[-1], p2 - 1, p2[-1]);
2161 if( prt > maxpr )
2162 printf("Total of %d differences\n", prt);
2165 static unsigned mend;
2166 static unsigned mask;
2168 void
2169 memlocate(void)
2171 unsigned a, n;
2172 unsigned char val[4];
2174 last_cmd = "ml";
2175 scanhex((void *)&mdest);
2176 if (termch != '\n') {
2177 termch = 0;
2178 scanhex((void *)&mend);
2179 if (termch != '\n') {
2180 termch = 0;
2181 scanhex((void *)&mval);
2182 mask = ~0;
2183 if (termch != '\n') termch = 0;
2184 scanhex((void *)&mask);
2187 n = 0;
2188 for (a = mdest; a < mend; a += 4) {
2189 if (mread(a, val, 4) == 4
2190 && ((GETWORD(val) ^ mval) & mask) == 0) {
2191 printf("%.16x: %.16x\n", a, GETWORD(val));
2192 if (++n >= 10)
2193 break;
2198 static unsigned long mskip = 0x1000;
2199 static unsigned long mlim = 0xffffffff;
2201 void
2202 memzcan(void)
2204 unsigned char v;
2205 unsigned a;
2206 int ok, ook;
2208 scanhex(&mdest);
2209 if (termch != '\n') termch = 0;
2210 scanhex(&mskip);
2211 if (termch != '\n') termch = 0;
2212 scanhex(&mlim);
2213 ook = 0;
2214 for (a = mdest; a < mlim; a += mskip) {
2215 ok = mread(a, &v, 1);
2216 if (ok && !ook) {
2217 printf("%.8x .. ", a);
2218 } else if (!ok && ook)
2219 printf("%.8x\n", a - mskip);
2220 ook = ok;
2221 if (a + mskip < a)
2222 break;
2224 if (ook)
2225 printf("%.8x\n", a - mskip);
2228 void proccall(void)
2230 unsigned long args[8];
2231 unsigned long ret;
2232 int i;
2233 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2234 unsigned long, unsigned long, unsigned long,
2235 unsigned long, unsigned long, unsigned long);
2236 callfunc_t func;
2238 if (!scanhex(&adrs))
2239 return;
2240 if (termch != '\n')
2241 termch = 0;
2242 for (i = 0; i < 8; ++i)
2243 args[i] = 0;
2244 for (i = 0; i < 8; ++i) {
2245 if (!scanhex(&args[i]) || termch == '\n')
2246 break;
2247 termch = 0;
2249 func = (callfunc_t) adrs;
2250 ret = 0;
2251 if (setjmp(bus_error_jmp) == 0) {
2252 catch_memory_errors = 1;
2253 sync();
2254 ret = func(args[0], args[1], args[2], args[3],
2255 args[4], args[5], args[6], args[7]);
2256 sync();
2257 printf("return value is %x\n", ret);
2258 } else {
2259 printf("*** %x exception occurred\n", fault_except);
2261 catch_memory_errors = 0;
2264 /* Input scanning routines */
2266 skipbl(void)
2268 int c;
2270 if( termch != 0 ){
2271 c = termch;
2272 termch = 0;
2273 } else
2274 c = inchar();
2275 while( c == ' ' || c == '\t' )
2276 c = inchar();
2277 return c;
2280 #define N_PTREGS 44
2281 static char *regnames[N_PTREGS] = {
2282 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2283 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2284 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2285 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2286 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2287 #ifdef CONFIG_PPC64
2288 "softe",
2289 #else
2290 "mq",
2291 #endif
2292 "trap", "dar", "dsisr", "res"
2296 scanhex(unsigned long *vp)
2298 int c, d;
2299 unsigned long v;
2301 c = skipbl();
2302 if (c == '%') {
2303 /* parse register name */
2304 char regname[8];
2305 int i;
2307 for (i = 0; i < sizeof(regname) - 1; ++i) {
2308 c = inchar();
2309 if (!isalnum(c)) {
2310 termch = c;
2311 break;
2313 regname[i] = c;
2315 regname[i] = 0;
2316 for (i = 0; i < N_PTREGS; ++i) {
2317 if (strcmp(regnames[i], regname) == 0) {
2318 if (xmon_regs == NULL) {
2319 printf("regs not available\n");
2320 return 0;
2322 *vp = ((unsigned long *)xmon_regs)[i];
2323 return 1;
2326 printf("invalid register name '%%%s'\n", regname);
2327 return 0;
2330 /* skip leading "0x" if any */
2332 if (c == '0') {
2333 c = inchar();
2334 if (c == 'x') {
2335 c = inchar();
2336 } else {
2337 d = hexdigit(c);
2338 if (d == EOF) {
2339 termch = c;
2340 *vp = 0;
2341 return 1;
2344 } else if (c == '$') {
2345 int i;
2346 for (i=0; i<63; i++) {
2347 c = inchar();
2348 if (isspace(c)) {
2349 termch = c;
2350 break;
2352 tmpstr[i] = c;
2354 tmpstr[i++] = 0;
2355 *vp = 0;
2356 if (setjmp(bus_error_jmp) == 0) {
2357 catch_memory_errors = 1;
2358 sync();
2359 *vp = kallsyms_lookup_name(tmpstr);
2360 sync();
2362 catch_memory_errors = 0;
2363 if (!(*vp)) {
2364 printf("unknown symbol '%s'\n", tmpstr);
2365 return 0;
2367 return 1;
2370 d = hexdigit(c);
2371 if (d == EOF) {
2372 termch = c;
2373 return 0;
2375 v = 0;
2376 do {
2377 v = (v << 4) + d;
2378 c = inchar();
2379 d = hexdigit(c);
2380 } while (d != EOF);
2381 termch = c;
2382 *vp = v;
2383 return 1;
2386 void
2387 scannl(void)
2389 int c;
2391 c = termch;
2392 termch = 0;
2393 while( c != '\n' )
2394 c = inchar();
2397 int hexdigit(int c)
2399 if( '0' <= c && c <= '9' )
2400 return c - '0';
2401 if( 'A' <= c && c <= 'F' )
2402 return c - ('A' - 10);
2403 if( 'a' <= c && c <= 'f' )
2404 return c - ('a' - 10);
2405 return EOF;
2408 void
2409 getstring(char *s, int size)
2411 int c;
2413 c = skipbl();
2414 do {
2415 if( size > 1 ){
2416 *s++ = c;
2417 --size;
2419 c = inchar();
2420 } while( c != ' ' && c != '\t' && c != '\n' );
2421 termch = c;
2422 *s = 0;
2425 static char line[256];
2426 static char *lineptr;
2428 void
2429 flush_input(void)
2431 lineptr = NULL;
2435 inchar(void)
2437 if (lineptr == NULL || *lineptr == 0) {
2438 if (xmon_gets(line, sizeof(line)) == NULL) {
2439 lineptr = NULL;
2440 return EOF;
2442 lineptr = line;
2444 return *lineptr++;
2447 void
2448 take_input(char *str)
2450 lineptr = str;
2454 static void
2455 symbol_lookup(void)
2457 int type = inchar();
2458 unsigned long addr;
2459 static char tmp[64];
2461 switch (type) {
2462 case 'a':
2463 if (scanhex(&addr))
2464 xmon_print_symbol(addr, ": ", "\n");
2465 termch = 0;
2466 break;
2467 case 's':
2468 getstring(tmp, 64);
2469 if (setjmp(bus_error_jmp) == 0) {
2470 catch_memory_errors = 1;
2471 sync();
2472 addr = kallsyms_lookup_name(tmp);
2473 if (addr)
2474 printf("%s: %lx\n", tmp, addr);
2475 else
2476 printf("Symbol '%s' not found.\n", tmp);
2477 sync();
2479 catch_memory_errors = 0;
2480 termch = 0;
2481 break;
2486 /* Print an address in numeric and symbolic form (if possible) */
2487 static void xmon_print_symbol(unsigned long address, const char *mid,
2488 const char *after)
2490 char *modname;
2491 const char *name = NULL;
2492 unsigned long offset, size;
2494 printf(REG, address);
2495 if (setjmp(bus_error_jmp) == 0) {
2496 catch_memory_errors = 1;
2497 sync();
2498 name = kallsyms_lookup(address, &size, &offset, &modname,
2499 tmpstr);
2500 sync();
2501 /* wait a little while to see if we get a machine check */
2502 __delay(200);
2505 catch_memory_errors = 0;
2507 if (name) {
2508 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2509 if (modname)
2510 printf(" [%s]", modname);
2512 printf("%s", after);
2515 #ifdef CONFIG_PPC64
2516 static void dump_slb(void)
2518 int i;
2519 unsigned long tmp;
2521 printf("SLB contents of cpu %x\n", smp_processor_id());
2523 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2524 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2525 printf("%02d %016lx ", i, tmp);
2527 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2528 printf("%016lx\n", tmp);
2532 static void dump_stab(void)
2534 int i;
2535 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2537 printf("Segment table contents of cpu %x\n", smp_processor_id());
2539 for (i = 0; i < PAGE_SIZE/16; i++) {
2540 unsigned long a, b;
2542 a = *tmp++;
2543 b = *tmp++;
2545 if (a || b) {
2546 printf("%03d %016lx ", i, a);
2547 printf("%016lx\n", b);
2552 void dump_segments(void)
2554 if (cpu_has_feature(CPU_FTR_SLB))
2555 dump_slb();
2556 else
2557 dump_stab();
2559 #endif
2561 #ifdef CONFIG_PPC_STD_MMU_32
2562 void dump_segments(void)
2564 int i;
2566 printf("sr0-15 =");
2567 for (i = 0; i < 16; ++i)
2568 printf(" %x", mfsrin(i));
2569 printf("\n");
2571 #endif
2573 void xmon_init(int enable)
2575 if (enable) {
2576 __debugger = xmon;
2577 __debugger_ipi = xmon_ipi;
2578 __debugger_bpt = xmon_bpt;
2579 __debugger_sstep = xmon_sstep;
2580 __debugger_iabr_match = xmon_iabr_match;
2581 __debugger_dabr_match = xmon_dabr_match;
2582 __debugger_fault_handler = xmon_fault_handler;
2583 } else {
2584 __debugger = NULL;
2585 __debugger_ipi = NULL;
2586 __debugger_bpt = NULL;
2587 __debugger_sstep = NULL;
2588 __debugger_iabr_match = NULL;
2589 __debugger_dabr_match = NULL;
2590 __debugger_fault_handler = NULL;
2592 xmon_map_scc();
2595 #ifdef CONFIG_MAGIC_SYSRQ
2596 static void sysrq_handle_xmon(int key, struct tty_struct *tty)
2598 /* ensure xmon is enabled */
2599 xmon_init(1);
2600 debugger(get_irq_regs());
2603 static struct sysrq_key_op sysrq_xmon_op =
2605 .handler = sysrq_handle_xmon,
2606 .help_msg = "Xmon",
2607 .action_msg = "Entering xmon",
2610 static int __init setup_xmon_sysrq(void)
2612 register_sysrq_key('x', &sysrq_xmon_op);
2613 return 0;
2615 __initcall(setup_xmon_sysrq);
2616 #endif /* CONFIG_MAGIC_SYSRQ */
2618 int __initdata xmon_early, xmon_off;
2620 static int __init early_parse_xmon(char *p)
2622 if (!p || strncmp(p, "early", 5) == 0) {
2623 /* just "xmon" is equivalent to "xmon=early" */
2624 xmon_init(1);
2625 xmon_early = 1;
2626 } else if (strncmp(p, "on", 2) == 0)
2627 xmon_init(1);
2628 else if (strncmp(p, "off", 3) == 0)
2629 xmon_off = 1;
2630 else if (strncmp(p, "nobt", 4) == 0)
2631 xmon_no_auto_backtrace = 1;
2632 else
2633 return 1;
2635 return 0;
2637 early_param("xmon", early_parse_xmon);
2639 void __init xmon_setup(void)
2641 #ifdef CONFIG_XMON_DEFAULT
2642 if (!xmon_off)
2643 xmon_init(1);
2644 #endif
2645 if (xmon_early)
2646 debugger(NULL);
2649 #ifdef CONFIG_PPC_CELL
2651 struct spu_info {
2652 struct spu *spu;
2653 u64 saved_mfc_sr1_RW;
2654 u32 saved_spu_runcntl_RW;
2655 unsigned long dump_addr;
2656 u8 stopped_ok;
2659 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2661 static struct spu_info spu_info[XMON_NUM_SPUS];
2663 void xmon_register_spus(struct list_head *list)
2665 struct spu *spu;
2667 list_for_each_entry(spu, list, full_list) {
2668 if (spu->number >= XMON_NUM_SPUS) {
2669 WARN_ON(1);
2670 continue;
2673 spu_info[spu->number].spu = spu;
2674 spu_info[spu->number].stopped_ok = 0;
2675 spu_info[spu->number].dump_addr = (unsigned long)
2676 spu_info[spu->number].spu->local_store;
2680 static void stop_spus(void)
2682 struct spu *spu;
2683 int i;
2684 u64 tmp;
2686 for (i = 0; i < XMON_NUM_SPUS; i++) {
2687 if (!spu_info[i].spu)
2688 continue;
2690 if (setjmp(bus_error_jmp) == 0) {
2691 catch_memory_errors = 1;
2692 sync();
2694 spu = spu_info[i].spu;
2696 spu_info[i].saved_spu_runcntl_RW =
2697 in_be32(&spu->problem->spu_runcntl_RW);
2699 tmp = spu_mfc_sr1_get(spu);
2700 spu_info[i].saved_mfc_sr1_RW = tmp;
2702 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2703 spu_mfc_sr1_set(spu, tmp);
2705 sync();
2706 __delay(200);
2708 spu_info[i].stopped_ok = 1;
2710 printf("Stopped spu %.2d (was %s)\n", i,
2711 spu_info[i].saved_spu_runcntl_RW ?
2712 "running" : "stopped");
2713 } else {
2714 catch_memory_errors = 0;
2715 printf("*** Error stopping spu %.2d\n", i);
2717 catch_memory_errors = 0;
2721 static void restart_spus(void)
2723 struct spu *spu;
2724 int i;
2726 for (i = 0; i < XMON_NUM_SPUS; i++) {
2727 if (!spu_info[i].spu)
2728 continue;
2730 if (!spu_info[i].stopped_ok) {
2731 printf("*** Error, spu %d was not successfully stopped"
2732 ", not restarting\n", i);
2733 continue;
2736 if (setjmp(bus_error_jmp) == 0) {
2737 catch_memory_errors = 1;
2738 sync();
2740 spu = spu_info[i].spu;
2741 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2742 out_be32(&spu->problem->spu_runcntl_RW,
2743 spu_info[i].saved_spu_runcntl_RW);
2745 sync();
2746 __delay(200);
2748 printf("Restarted spu %.2d\n", i);
2749 } else {
2750 catch_memory_errors = 0;
2751 printf("*** Error restarting spu %.2d\n", i);
2753 catch_memory_errors = 0;
2757 #define DUMP_WIDTH 23
2758 #define DUMP_VALUE(format, field, value) \
2759 do { \
2760 if (setjmp(bus_error_jmp) == 0) { \
2761 catch_memory_errors = 1; \
2762 sync(); \
2763 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2764 #field, value); \
2765 sync(); \
2766 __delay(200); \
2767 } else { \
2768 catch_memory_errors = 0; \
2769 printf(" %-*s = *** Error reading field.\n", \
2770 DUMP_WIDTH, #field); \
2772 catch_memory_errors = 0; \
2773 } while (0)
2775 #define DUMP_FIELD(obj, format, field) \
2776 DUMP_VALUE(format, field, obj->field)
2778 static void dump_spu_fields(struct spu *spu)
2780 printf("Dumping spu fields at address %p:\n", spu);
2782 DUMP_FIELD(spu, "0x%x", number);
2783 DUMP_FIELD(spu, "%s", name);
2784 DUMP_FIELD(spu, "%s", devnode->full_name);
2785 DUMP_FIELD(spu, "0x%x", nid);
2786 DUMP_FIELD(spu, "0x%lx", local_store_phys);
2787 DUMP_FIELD(spu, "0x%p", local_store);
2788 DUMP_FIELD(spu, "0x%lx", ls_size);
2789 DUMP_FIELD(spu, "0x%x", node);
2790 DUMP_FIELD(spu, "0x%lx", flags);
2791 DUMP_FIELD(spu, "0x%lx", dar);
2792 DUMP_FIELD(spu, "0x%lx", dsisr);
2793 DUMP_FIELD(spu, "%d", class_0_pending);
2794 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2795 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2796 DUMP_FIELD(spu, "0x%lx", irqs[2]);
2797 DUMP_FIELD(spu, "0x%x", slb_replace);
2798 DUMP_FIELD(spu, "%d", pid);
2799 DUMP_FIELD(spu, "%d", prio);
2800 DUMP_FIELD(spu, "0x%p", mm);
2801 DUMP_FIELD(spu, "0x%p", ctx);
2802 DUMP_FIELD(spu, "0x%p", rq);
2803 DUMP_FIELD(spu, "0x%p", timestamp);
2804 DUMP_FIELD(spu, "0x%lx", problem_phys);
2805 DUMP_FIELD(spu, "0x%p", problem);
2806 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2807 in_be32(&spu->problem->spu_runcntl_RW));
2808 DUMP_VALUE("0x%x", problem->spu_status_R,
2809 in_be32(&spu->problem->spu_status_R));
2810 DUMP_VALUE("0x%x", problem->spu_npc_RW,
2811 in_be32(&spu->problem->spu_npc_RW));
2812 DUMP_FIELD(spu, "0x%p", priv1);
2814 if (spu->priv1) {
2815 DUMP_VALUE("0x%lx", priv1->mfc_sr1_RW,
2816 in_be64(&spu->priv1->mfc_sr1_RW));
2819 DUMP_FIELD(spu, "0x%p", priv2);
2822 static void dump_spu_ls(unsigned long num)
2824 unsigned long offset, addr, ls_addr;
2826 if (setjmp(bus_error_jmp) == 0) {
2827 catch_memory_errors = 1;
2828 sync();
2829 ls_addr = (unsigned long)spu_info[num].spu->local_store;
2830 sync();
2831 __delay(200);
2832 } else {
2833 catch_memory_errors = 0;
2834 printf("*** Error: accessing spu info for spu %d\n", num);
2835 return;
2837 catch_memory_errors = 0;
2839 if (scanhex(&offset))
2840 addr = ls_addr + offset;
2841 else
2842 addr = spu_info[num].dump_addr;
2844 if (addr >= ls_addr + LS_SIZE) {
2845 printf("*** Error: address outside of local store\n");
2846 return;
2849 prdump(addr, 64);
2850 addr += 64;
2851 last_cmd = "sd\n";
2853 spu_info[num].dump_addr = addr;
2856 static int do_spu_cmd(void)
2858 static unsigned long num = 0;
2859 int cmd;
2861 cmd = inchar();
2862 switch (cmd) {
2863 case 's':
2864 stop_spus();
2865 break;
2866 case 'r':
2867 restart_spus();
2868 break;
2869 case 'f':
2870 case 'd':
2871 scanhex(&num);
2872 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
2873 printf("*** Error: invalid spu number\n");
2874 return 0;
2877 switch (cmd) {
2878 case 'f':
2879 dump_spu_fields(spu_info[num].spu);
2880 break;
2881 default:
2882 dump_spu_ls(num);
2883 break;
2886 break;
2887 default:
2888 return -1;
2891 return 0;
2893 #else /* ! CONFIG_PPC_CELL */
2894 static int do_spu_cmd(void)
2896 return -1;
2898 #endif