Committer: Michael Beasley <mike@snafu.setup>
[mikesnafu-overlay.git] / arch / powerpc / xmon / xmon.c
bloba34172ddc4683064c818608b86fb506ba59e4c2f
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>
25 #include <linux/bug.h>
27 #include <asm/ptrace.h>
28 #include <asm/string.h>
29 #include <asm/prom.h>
30 #include <asm/machdep.h>
31 #include <asm/xmon.h>
32 #include <asm/processor.h>
33 #include <asm/pgtable.h>
34 #include <asm/mmu.h>
35 #include <asm/mmu_context.h>
36 #include <asm/cputable.h>
37 #include <asm/rtas.h>
38 #include <asm/sstep.h>
39 #include <asm/irq_regs.h>
40 #include <asm/spu.h>
41 #include <asm/spu_priv1.h>
42 #include <asm/firmware.h>
43 #include <asm/setjmp.h>
45 #ifdef CONFIG_PPC64
46 #include <asm/hvcall.h>
47 #include <asm/paca.h>
48 #include <asm/iseries/it_lp_reg_save.h>
49 #endif
51 #include "nonstdio.h"
52 #include "dis-asm.h"
54 #define scanhex xmon_scanhex
55 #define skipbl xmon_skipbl
57 #ifdef CONFIG_SMP
58 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
59 static unsigned long xmon_taken = 1;
60 static int xmon_owner;
61 static int xmon_gate;
62 #endif /* CONFIG_SMP */
64 static unsigned long in_xmon = 0;
66 static unsigned long adrs;
67 static int size = 1;
68 #define MAX_DUMP (128 * 1024)
69 static unsigned long ndump = 64;
70 static unsigned long nidump = 16;
71 static unsigned long ncsum = 4096;
72 static int termch;
73 static char tmpstr[128];
75 static long bus_error_jmp[JMP_BUF_LEN];
76 static int catch_memory_errors;
77 static long *xmon_fault_jmp[NR_CPUS];
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 static void backtrace(struct pt_regs *);
114 static void excprint(struct pt_regs *);
115 static void prregs(struct pt_regs *);
116 static void memops(int);
117 static void memlocate(void);
118 static void memzcan(void);
119 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
120 int skipbl(void);
121 int scanhex(unsigned long *valp);
122 static void scannl(void);
123 static int hexdigit(int);
124 void getstring(char *, int);
125 static void flush_input(void);
126 static int inchar(void);
127 static void take_input(char *);
128 static unsigned long read_spr(int);
129 static void write_spr(int, unsigned long);
130 static void super_regs(void);
131 static void remove_bpts(void);
132 static void insert_bpts(void);
133 static void remove_cpu_bpts(void);
134 static void insert_cpu_bpts(void);
135 static struct bpt *at_breakpoint(unsigned long pc);
136 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
137 static int do_step(struct pt_regs *);
138 static void bpt_cmds(void);
139 static void cacheflush(void);
140 static int cpu_cmd(void);
141 static void csum(void);
142 static void bootcmds(void);
143 static void proccall(void);
144 void dump_segments(void);
145 static void symbol_lookup(void);
146 static void xmon_show_stack(unsigned long sp, unsigned long lr,
147 unsigned long pc);
148 static void xmon_print_symbol(unsigned long address, const char *mid,
149 const char *after);
150 static const char *getvecname(unsigned long vec);
152 static int do_spu_cmd(void);
154 #ifdef CONFIG_44x
155 static void dump_tlb_44x(void);
156 #endif
158 int xmon_no_auto_backtrace;
160 extern void xmon_enter(void);
161 extern void xmon_leave(void);
163 extern void xmon_save_regs(struct pt_regs *);
165 #ifdef CONFIG_PPC64
166 #define REG "%.16lx"
167 #define REGS_PER_LINE 4
168 #define LAST_VOLATILE 13
169 #else
170 #define REG "%.8lx"
171 #define REGS_PER_LINE 8
172 #define LAST_VOLATILE 12
173 #endif
175 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
177 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
178 || ('a' <= (c) && (c) <= 'f') \
179 || ('A' <= (c) && (c) <= 'F'))
180 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
181 || ('a' <= (c) && (c) <= 'z') \
182 || ('A' <= (c) && (c) <= 'Z'))
183 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
185 static char *help_string = "\
186 Commands:\n\
187 b show breakpoints\n\
188 bd set data breakpoint\n\
189 bi set instruction breakpoint\n\
190 bc clear breakpoint\n"
191 #ifdef CONFIG_SMP
193 c print cpus stopped in xmon\n\
194 c# try to switch to cpu number h (in hex)\n"
195 #endif
197 C checksum\n\
198 d dump bytes\n\
199 di dump instructions\n\
200 df dump float values\n\
201 dd dump double values\n\
202 dr dump stream of raw bytes\n\
203 e print exception information\n\
204 f flush cache\n\
205 la lookup symbol+offset of specified address\n\
206 ls lookup address of specified symbol\n\
207 m examine/change memory\n\
208 mm move a block of memory\n\
209 ms set a block of memory\n\
210 md compare two blocks of memory\n\
211 ml locate a block of memory\n\
212 mz zero a block of memory\n\
213 mi show information about memory allocation\n\
214 p call a procedure\n\
215 r print registers\n\
216 s single step\n"
217 #ifdef CONFIG_SPU_BASE
218 " ss stop execution on all spus\n\
219 sr restore execution on stopped spus\n\
220 sf # dump spu fields for spu # (in hex)\n\
221 sd # dump spu local store for spu # (in hex)\n\
222 sdi # disassemble 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 #ifdef CONFIG_44x
235 " u dump TLB\n"
236 #endif
237 " ? help\n"
238 " zr reboot\n\
239 zh halt\n"
242 static struct pt_regs *xmon_regs;
244 static inline void sync(void)
246 asm volatile("sync; isync");
249 static inline void store_inst(void *p)
251 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
254 static inline void cflush(void *p)
256 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
259 static inline void cinval(void *p)
261 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
265 * Disable surveillance (the service processor watchdog function)
266 * while we are in xmon.
267 * XXX we should re-enable it when we leave. :)
269 #define SURVEILLANCE_TOKEN 9000
271 static inline void disable_surveillance(void)
273 #ifdef CONFIG_PPC_PSERIES
274 /* Since this can't be a module, args should end up below 4GB. */
275 static struct rtas_args args;
278 * At this point we have got all the cpus we can into
279 * xmon, so there is hopefully no other cpu calling RTAS
280 * at the moment, even though we don't take rtas.lock.
281 * If we did try to take rtas.lock there would be a
282 * real possibility of deadlock.
284 args.token = rtas_token("set-indicator");
285 if (args.token == RTAS_UNKNOWN_SERVICE)
286 return;
287 args.nargs = 3;
288 args.nret = 1;
289 args.rets = &args.args[3];
290 args.args[0] = SURVEILLANCE_TOKEN;
291 args.args[1] = 0;
292 args.args[2] = 0;
293 enter_rtas(__pa(&args));
294 #endif /* CONFIG_PPC_PSERIES */
297 #ifdef CONFIG_SMP
298 static int xmon_speaker;
300 static void get_output_lock(void)
302 int me = smp_processor_id() + 0x100;
303 int last_speaker = 0, prev;
304 long timeout;
306 if (xmon_speaker == me)
307 return;
308 for (;;) {
309 if (xmon_speaker == 0) {
310 last_speaker = cmpxchg(&xmon_speaker, 0, me);
311 if (last_speaker == 0)
312 return;
314 timeout = 10000000;
315 while (xmon_speaker == last_speaker) {
316 if (--timeout > 0)
317 continue;
318 /* hostile takeover */
319 prev = cmpxchg(&xmon_speaker, last_speaker, me);
320 if (prev == last_speaker)
321 return;
322 break;
327 static void release_output_lock(void)
329 xmon_speaker = 0;
331 #endif
333 static int xmon_core(struct pt_regs *regs, int fromipi)
335 int cmd = 0;
336 struct bpt *bp;
337 long recurse_jmp[JMP_BUF_LEN];
338 unsigned long offset;
339 unsigned long flags;
340 #ifdef CONFIG_SMP
341 int cpu;
342 int secondary;
343 unsigned long timeout;
344 #endif
346 local_irq_save(flags);
348 bp = in_breakpoint_table(regs->nip, &offset);
349 if (bp != NULL) {
350 regs->nip = bp->address + offset;
351 atomic_dec(&bp->ref_count);
354 remove_cpu_bpts();
356 #ifdef CONFIG_SMP
357 cpu = smp_processor_id();
358 if (cpu_isset(cpu, cpus_in_xmon)) {
359 get_output_lock();
360 excprint(regs);
361 printf("cpu 0x%x: Exception %lx %s in xmon, "
362 "returning to main loop\n",
363 cpu, regs->trap, getvecname(TRAP(regs)));
364 release_output_lock();
365 longjmp(xmon_fault_jmp[cpu], 1);
368 if (setjmp(recurse_jmp) != 0) {
369 if (!in_xmon || !xmon_gate) {
370 get_output_lock();
371 printf("xmon: WARNING: bad recursive fault "
372 "on cpu 0x%x\n", cpu);
373 release_output_lock();
374 goto waiting;
376 secondary = !(xmon_taken && cpu == xmon_owner);
377 goto cmdloop;
380 xmon_fault_jmp[cpu] = recurse_jmp;
381 cpu_set(cpu, cpus_in_xmon);
383 bp = NULL;
384 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
385 bp = at_breakpoint(regs->nip);
386 if (bp || (regs->msr & MSR_RI) == 0)
387 fromipi = 0;
389 if (!fromipi) {
390 get_output_lock();
391 excprint(regs);
392 if (bp) {
393 printf("cpu 0x%x stopped at breakpoint 0x%x (",
394 cpu, BP_NUM(bp));
395 xmon_print_symbol(regs->nip, " ", ")\n");
397 if ((regs->msr & MSR_RI) == 0)
398 printf("WARNING: exception is not recoverable, "
399 "can't continue\n");
400 release_output_lock();
403 waiting:
404 secondary = 1;
405 while (secondary && !xmon_gate) {
406 if (in_xmon == 0) {
407 if (fromipi)
408 goto leave;
409 secondary = test_and_set_bit(0, &in_xmon);
411 barrier();
414 if (!secondary && !xmon_gate) {
415 /* we are the first cpu to come in */
416 /* interrupt other cpu(s) */
417 int ncpus = num_online_cpus();
419 xmon_owner = cpu;
420 mb();
421 if (ncpus > 1) {
422 smp_send_debugger_break(MSG_ALL_BUT_SELF);
423 /* wait for other cpus to come in */
424 for (timeout = 100000000; timeout != 0; --timeout) {
425 if (cpus_weight(cpus_in_xmon) >= ncpus)
426 break;
427 barrier();
430 remove_bpts();
431 disable_surveillance();
432 /* for breakpoint or single step, print the current instr. */
433 if (bp || TRAP(regs) == 0xd00)
434 ppc_inst_dump(regs->nip, 1, 0);
435 printf("enter ? for help\n");
436 mb();
437 xmon_gate = 1;
438 barrier();
441 cmdloop:
442 while (in_xmon) {
443 if (secondary) {
444 if (cpu == xmon_owner) {
445 if (!test_and_set_bit(0, &xmon_taken)) {
446 secondary = 0;
447 continue;
449 /* missed it */
450 while (cpu == xmon_owner)
451 barrier();
453 barrier();
454 } else {
455 cmd = cmds(regs);
456 if (cmd != 0) {
457 /* exiting xmon */
458 insert_bpts();
459 xmon_gate = 0;
460 wmb();
461 in_xmon = 0;
462 break;
464 /* have switched to some other cpu */
465 secondary = 1;
468 leave:
469 cpu_clear(cpu, cpus_in_xmon);
470 xmon_fault_jmp[cpu] = NULL;
471 #else
472 /* UP is simple... */
473 if (in_xmon) {
474 printf("Exception %lx %s in xmon, returning to main loop\n",
475 regs->trap, getvecname(TRAP(regs)));
476 longjmp(xmon_fault_jmp[0], 1);
478 if (setjmp(recurse_jmp) == 0) {
479 xmon_fault_jmp[0] = recurse_jmp;
480 in_xmon = 1;
482 excprint(regs);
483 bp = at_breakpoint(regs->nip);
484 if (bp) {
485 printf("Stopped at breakpoint %x (", BP_NUM(bp));
486 xmon_print_symbol(regs->nip, " ", ")\n");
488 if ((regs->msr & MSR_RI) == 0)
489 printf("WARNING: exception is not recoverable, "
490 "can't continue\n");
491 remove_bpts();
492 disable_surveillance();
493 /* for breakpoint or single step, print the current instr. */
494 if (bp || TRAP(regs) == 0xd00)
495 ppc_inst_dump(regs->nip, 1, 0);
496 printf("enter ? for help\n");
499 cmd = cmds(regs);
501 insert_bpts();
502 in_xmon = 0;
503 #endif
505 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
506 bp = at_breakpoint(regs->nip);
507 if (bp != NULL) {
508 int stepped = emulate_step(regs, bp->instr[0]);
509 if (stepped == 0) {
510 regs->nip = (unsigned long) &bp->instr[0];
511 atomic_inc(&bp->ref_count);
512 } else if (stepped < 0) {
513 printf("Couldn't single-step %s instruction\n",
514 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
519 insert_cpu_bpts();
521 local_irq_restore(flags);
523 return cmd != 'X' && cmd != EOF;
526 int xmon(struct pt_regs *excp)
528 struct pt_regs regs;
530 if (excp == NULL) {
531 xmon_save_regs(&regs);
532 excp = &regs;
535 return xmon_core(excp, 0);
537 EXPORT_SYMBOL(xmon);
539 irqreturn_t xmon_irq(int irq, void *d)
541 unsigned long flags;
542 local_irq_save(flags);
543 printf("Keyboard interrupt\n");
544 xmon(get_irq_regs());
545 local_irq_restore(flags);
546 return IRQ_HANDLED;
549 static int xmon_bpt(struct pt_regs *regs)
551 struct bpt *bp;
552 unsigned long offset;
554 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
555 return 0;
557 /* Are we at the trap at bp->instr[1] for some bp? */
558 bp = in_breakpoint_table(regs->nip, &offset);
559 if (bp != NULL && offset == 4) {
560 regs->nip = bp->address + 4;
561 atomic_dec(&bp->ref_count);
562 return 1;
565 /* Are we at a breakpoint? */
566 bp = at_breakpoint(regs->nip);
567 if (!bp)
568 return 0;
570 xmon_core(regs, 0);
572 return 1;
575 static int xmon_sstep(struct pt_regs *regs)
577 if (user_mode(regs))
578 return 0;
579 xmon_core(regs, 0);
580 return 1;
583 static int xmon_dabr_match(struct pt_regs *regs)
585 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
586 return 0;
587 if (dabr.enabled == 0)
588 return 0;
589 xmon_core(regs, 0);
590 return 1;
593 static int xmon_iabr_match(struct pt_regs *regs)
595 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
596 return 0;
597 if (iabr == 0)
598 return 0;
599 xmon_core(regs, 0);
600 return 1;
603 static int xmon_ipi(struct pt_regs *regs)
605 #ifdef CONFIG_SMP
606 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
607 xmon_core(regs, 1);
608 #endif
609 return 0;
612 static int xmon_fault_handler(struct pt_regs *regs)
614 struct bpt *bp;
615 unsigned long offset;
617 if (in_xmon && catch_memory_errors)
618 handle_fault(regs); /* doesn't return */
620 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
621 bp = in_breakpoint_table(regs->nip, &offset);
622 if (bp != NULL) {
623 regs->nip = bp->address + offset;
624 atomic_dec(&bp->ref_count);
628 return 0;
631 static struct bpt *at_breakpoint(unsigned long pc)
633 int i;
634 struct bpt *bp;
636 bp = bpts;
637 for (i = 0; i < NBPTS; ++i, ++bp)
638 if (bp->enabled && pc == bp->address)
639 return bp;
640 return NULL;
643 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
645 unsigned long off;
647 off = nip - (unsigned long) bpts;
648 if (off >= sizeof(bpts))
649 return NULL;
650 off %= sizeof(struct bpt);
651 if (off != offsetof(struct bpt, instr[0])
652 && off != offsetof(struct bpt, instr[1]))
653 return NULL;
654 *offp = off - offsetof(struct bpt, instr[0]);
655 return (struct bpt *) (nip - off);
658 static struct bpt *new_breakpoint(unsigned long a)
660 struct bpt *bp;
662 a &= ~3UL;
663 bp = at_breakpoint(a);
664 if (bp)
665 return bp;
667 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
668 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
669 bp->address = a;
670 bp->instr[1] = bpinstr;
671 store_inst(&bp->instr[1]);
672 return bp;
676 printf("Sorry, no free breakpoints. Please clear one first.\n");
677 return NULL;
680 static void insert_bpts(void)
682 int i;
683 struct bpt *bp;
685 bp = bpts;
686 for (i = 0; i < NBPTS; ++i, ++bp) {
687 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
688 continue;
689 if (mread(bp->address, &bp->instr[0], 4) != 4) {
690 printf("Couldn't read instruction at %lx, "
691 "disabling breakpoint there\n", bp->address);
692 bp->enabled = 0;
693 continue;
695 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
696 printf("Breakpoint at %lx is on an mtmsrd or rfid "
697 "instruction, disabling it\n", bp->address);
698 bp->enabled = 0;
699 continue;
701 store_inst(&bp->instr[0]);
702 if (bp->enabled & BP_IABR)
703 continue;
704 if (mwrite(bp->address, &bpinstr, 4) != 4) {
705 printf("Couldn't write instruction at %lx, "
706 "disabling breakpoint there\n", bp->address);
707 bp->enabled &= ~BP_TRAP;
708 continue;
710 store_inst((void *)bp->address);
714 static void insert_cpu_bpts(void)
716 if (dabr.enabled)
717 set_dabr(dabr.address | (dabr.enabled & 7));
718 if (iabr && cpu_has_feature(CPU_FTR_IABR))
719 mtspr(SPRN_IABR, iabr->address
720 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
723 static void remove_bpts(void)
725 int i;
726 struct bpt *bp;
727 unsigned instr;
729 bp = bpts;
730 for (i = 0; i < NBPTS; ++i, ++bp) {
731 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
732 continue;
733 if (mread(bp->address, &instr, 4) == 4
734 && instr == bpinstr
735 && mwrite(bp->address, &bp->instr, 4) != 4)
736 printf("Couldn't remove breakpoint at %lx\n",
737 bp->address);
738 else
739 store_inst((void *)bp->address);
743 static void remove_cpu_bpts(void)
745 set_dabr(0);
746 if (cpu_has_feature(CPU_FTR_IABR))
747 mtspr(SPRN_IABR, 0);
750 /* Command interpreting routine */
751 static char *last_cmd;
753 static int
754 cmds(struct pt_regs *excp)
756 int cmd = 0;
758 last_cmd = NULL;
759 xmon_regs = excp;
761 if (!xmon_no_auto_backtrace) {
762 xmon_no_auto_backtrace = 1;
763 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
766 for(;;) {
767 #ifdef CONFIG_SMP
768 printf("%x:", smp_processor_id());
769 #endif /* CONFIG_SMP */
770 printf("mon> ");
771 flush_input();
772 termch = 0;
773 cmd = skipbl();
774 if( cmd == '\n' ) {
775 if (last_cmd == NULL)
776 continue;
777 take_input(last_cmd);
778 last_cmd = NULL;
779 cmd = inchar();
781 switch (cmd) {
782 case 'm':
783 cmd = inchar();
784 switch (cmd) {
785 case 'm':
786 case 's':
787 case 'd':
788 memops(cmd);
789 break;
790 case 'l':
791 memlocate();
792 break;
793 case 'z':
794 memzcan();
795 break;
796 case 'i':
797 show_mem();
798 break;
799 default:
800 termch = cmd;
801 memex();
803 break;
804 case 'd':
805 dump();
806 break;
807 case 'l':
808 symbol_lookup();
809 break;
810 case 'r':
811 prregs(excp); /* print regs */
812 break;
813 case 'e':
814 excprint(excp);
815 break;
816 case 'S':
817 super_regs();
818 break;
819 case 't':
820 backtrace(excp);
821 break;
822 case 'f':
823 cacheflush();
824 break;
825 case 's':
826 if (do_spu_cmd() == 0)
827 break;
828 if (do_step(excp))
829 return cmd;
830 break;
831 case 'x':
832 case 'X':
833 return cmd;
834 case EOF:
835 printf(" <no input ...>\n");
836 mdelay(2000);
837 return cmd;
838 case '?':
839 xmon_puts(help_string);
840 break;
841 case 'b':
842 bpt_cmds();
843 break;
844 case 'C':
845 csum();
846 break;
847 case 'c':
848 if (cpu_cmd())
849 return 0;
850 break;
851 case 'z':
852 bootcmds();
853 break;
854 case 'p':
855 proccall();
856 break;
857 #ifdef CONFIG_PPC_STD_MMU
858 case 'u':
859 dump_segments();
860 break;
861 #endif
862 #ifdef CONFIG_4xx
863 case 'u':
864 dump_tlb_44x();
865 break;
866 #endif
867 default:
868 printf("Unrecognized command: ");
869 do {
870 if (' ' < cmd && cmd <= '~')
871 putchar(cmd);
872 else
873 printf("\\x%x", cmd);
874 cmd = inchar();
875 } while (cmd != '\n');
876 printf(" (type ? for help)\n");
877 break;
883 * Step a single instruction.
884 * Some instructions we emulate, others we execute with MSR_SE set.
886 static int do_step(struct pt_regs *regs)
888 unsigned int instr;
889 int stepped;
891 /* check we are in 64-bit kernel mode, translation enabled */
892 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
893 if (mread(regs->nip, &instr, 4) == 4) {
894 stepped = emulate_step(regs, instr);
895 if (stepped < 0) {
896 printf("Couldn't single-step %s instruction\n",
897 (IS_RFID(instr)? "rfid": "mtmsrd"));
898 return 0;
900 if (stepped > 0) {
901 regs->trap = 0xd00 | (regs->trap & 1);
902 printf("stepped to ");
903 xmon_print_symbol(regs->nip, " ", "\n");
904 ppc_inst_dump(regs->nip, 1, 0);
905 return 0;
909 regs->msr |= MSR_SE;
910 return 1;
913 static void bootcmds(void)
915 int cmd;
917 cmd = inchar();
918 if (cmd == 'r')
919 ppc_md.restart(NULL);
920 else if (cmd == 'h')
921 ppc_md.halt();
922 else if (cmd == 'p')
923 ppc_md.power_off();
926 static int cpu_cmd(void)
928 #ifdef CONFIG_SMP
929 unsigned long cpu;
930 int timeout;
931 int count;
933 if (!scanhex(&cpu)) {
934 /* print cpus waiting or in xmon */
935 printf("cpus stopped:");
936 count = 0;
937 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
938 if (cpu_isset(cpu, cpus_in_xmon)) {
939 if (count == 0)
940 printf(" %x", cpu);
941 ++count;
942 } else {
943 if (count > 1)
944 printf("-%x", cpu - 1);
945 count = 0;
948 if (count > 1)
949 printf("-%x", NR_CPUS - 1);
950 printf("\n");
951 return 0;
953 /* try to switch to cpu specified */
954 if (!cpu_isset(cpu, cpus_in_xmon)) {
955 printf("cpu 0x%x isn't in xmon\n", cpu);
956 return 0;
958 xmon_taken = 0;
959 mb();
960 xmon_owner = cpu;
961 timeout = 10000000;
962 while (!xmon_taken) {
963 if (--timeout == 0) {
964 if (test_and_set_bit(0, &xmon_taken))
965 break;
966 /* take control back */
967 mb();
968 xmon_owner = smp_processor_id();
969 printf("cpu %u didn't take control\n", cpu);
970 return 0;
972 barrier();
974 return 1;
975 #else
976 return 0;
977 #endif /* CONFIG_SMP */
980 static unsigned short fcstab[256] = {
981 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
982 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
983 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
984 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
985 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
986 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
987 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
988 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
989 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
990 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
991 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
992 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
993 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
994 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
995 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
996 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
997 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
998 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
999 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1000 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1001 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1002 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1003 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1004 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1005 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1006 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1007 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1008 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1009 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1010 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1011 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1012 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1015 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1017 static void
1018 csum(void)
1020 unsigned int i;
1021 unsigned short fcs;
1022 unsigned char v;
1024 if (!scanhex(&adrs))
1025 return;
1026 if (!scanhex(&ncsum))
1027 return;
1028 fcs = 0xffff;
1029 for (i = 0; i < ncsum; ++i) {
1030 if (mread(adrs+i, &v, 1) == 0) {
1031 printf("csum stopped at %x\n", adrs+i);
1032 break;
1034 fcs = FCS(fcs, v);
1036 printf("%x\n", fcs);
1040 * Check if this is a suitable place to put a breakpoint.
1042 static long check_bp_loc(unsigned long addr)
1044 unsigned int instr;
1046 addr &= ~3;
1047 if (!is_kernel_addr(addr)) {
1048 printf("Breakpoints may only be placed at kernel addresses\n");
1049 return 0;
1051 if (!mread(addr, &instr, sizeof(instr))) {
1052 printf("Can't read instruction at address %lx\n", addr);
1053 return 0;
1055 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1056 printf("Breakpoints may not be placed on mtmsrd or rfid "
1057 "instructions\n");
1058 return 0;
1060 return 1;
1063 static char *breakpoint_help_string =
1064 "Breakpoint command usage:\n"
1065 "b show breakpoints\n"
1066 "b <addr> [cnt] set breakpoint at given instr addr\n"
1067 "bc clear all breakpoints\n"
1068 "bc <n/addr> clear breakpoint number n or at addr\n"
1069 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1070 "bd <addr> [cnt] set hardware data breakpoint\n"
1073 static void
1074 bpt_cmds(void)
1076 int cmd;
1077 unsigned long a;
1078 int mode, i;
1079 struct bpt *bp;
1080 const char badaddr[] = "Only kernel addresses are permitted "
1081 "for breakpoints\n";
1083 cmd = inchar();
1084 switch (cmd) {
1085 #ifndef CONFIG_8xx
1086 case 'd': /* bd - hardware data breakpoint */
1087 mode = 7;
1088 cmd = inchar();
1089 if (cmd == 'r')
1090 mode = 5;
1091 else if (cmd == 'w')
1092 mode = 6;
1093 else
1094 termch = cmd;
1095 dabr.address = 0;
1096 dabr.enabled = 0;
1097 if (scanhex(&dabr.address)) {
1098 if (!is_kernel_addr(dabr.address)) {
1099 printf(badaddr);
1100 break;
1102 dabr.address &= ~7;
1103 dabr.enabled = mode | BP_DABR;
1105 break;
1107 case 'i': /* bi - hardware instr breakpoint */
1108 if (!cpu_has_feature(CPU_FTR_IABR)) {
1109 printf("Hardware instruction breakpoint "
1110 "not supported on this cpu\n");
1111 break;
1113 if (iabr) {
1114 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1115 iabr = NULL;
1117 if (!scanhex(&a))
1118 break;
1119 if (!check_bp_loc(a))
1120 break;
1121 bp = new_breakpoint(a);
1122 if (bp != NULL) {
1123 bp->enabled |= BP_IABR | BP_IABR_TE;
1124 iabr = bp;
1126 break;
1127 #endif
1129 case 'c':
1130 if (!scanhex(&a)) {
1131 /* clear all breakpoints */
1132 for (i = 0; i < NBPTS; ++i)
1133 bpts[i].enabled = 0;
1134 iabr = NULL;
1135 dabr.enabled = 0;
1136 printf("All breakpoints cleared\n");
1137 break;
1140 if (a <= NBPTS && a >= 1) {
1141 /* assume a breakpoint number */
1142 bp = &bpts[a-1]; /* bp nums are 1 based */
1143 } else {
1144 /* assume a breakpoint address */
1145 bp = at_breakpoint(a);
1146 if (bp == 0) {
1147 printf("No breakpoint at %x\n", a);
1148 break;
1152 printf("Cleared breakpoint %x (", BP_NUM(bp));
1153 xmon_print_symbol(bp->address, " ", ")\n");
1154 bp->enabled = 0;
1155 break;
1157 default:
1158 termch = cmd;
1159 cmd = skipbl();
1160 if (cmd == '?') {
1161 printf(breakpoint_help_string);
1162 break;
1164 termch = cmd;
1165 if (!scanhex(&a)) {
1166 /* print all breakpoints */
1167 printf(" type address\n");
1168 if (dabr.enabled) {
1169 printf(" data "REG" [", dabr.address);
1170 if (dabr.enabled & 1)
1171 printf("r");
1172 if (dabr.enabled & 2)
1173 printf("w");
1174 printf("]\n");
1176 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1177 if (!bp->enabled)
1178 continue;
1179 printf("%2x %s ", BP_NUM(bp),
1180 (bp->enabled & BP_IABR)? "inst": "trap");
1181 xmon_print_symbol(bp->address, " ", "\n");
1183 break;
1186 if (!check_bp_loc(a))
1187 break;
1188 bp = new_breakpoint(a);
1189 if (bp != NULL)
1190 bp->enabled |= BP_TRAP;
1191 break;
1195 /* Very cheap human name for vector lookup. */
1196 static
1197 const char *getvecname(unsigned long vec)
1199 char *ret;
1201 switch (vec) {
1202 case 0x100: ret = "(System Reset)"; break;
1203 case 0x200: ret = "(Machine Check)"; break;
1204 case 0x300: ret = "(Data Access)"; break;
1205 case 0x380: ret = "(Data SLB Access)"; break;
1206 case 0x400: ret = "(Instruction Access)"; break;
1207 case 0x480: ret = "(Instruction SLB Access)"; break;
1208 case 0x500: ret = "(Hardware Interrupt)"; break;
1209 case 0x600: ret = "(Alignment)"; break;
1210 case 0x700: ret = "(Program Check)"; break;
1211 case 0x800: ret = "(FPU Unavailable)"; break;
1212 case 0x900: ret = "(Decrementer)"; break;
1213 case 0xc00: ret = "(System Call)"; break;
1214 case 0xd00: ret = "(Single Step)"; break;
1215 case 0xf00: ret = "(Performance Monitor)"; break;
1216 case 0xf20: ret = "(Altivec Unavailable)"; break;
1217 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1218 default: ret = "";
1220 return ret;
1223 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1224 unsigned long *endp)
1226 unsigned long size, offset;
1227 const char *name;
1229 *startp = *endp = 0;
1230 if (pc == 0)
1231 return;
1232 if (setjmp(bus_error_jmp) == 0) {
1233 catch_memory_errors = 1;
1234 sync();
1235 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1236 if (name != NULL) {
1237 *startp = pc - offset;
1238 *endp = pc - offset + size;
1240 sync();
1242 catch_memory_errors = 0;
1245 static int xmon_depth_to_print = 64;
1247 #ifdef CONFIG_PPC64
1248 #define LRSAVE_OFFSET 0x10
1249 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1250 #define MARKER_OFFSET 0x60
1251 #define REGS_OFFSET 0x70
1252 #else
1253 #define LRSAVE_OFFSET 4
1254 #define REG_FRAME_MARKER 0x72656773
1255 #define MARKER_OFFSET 8
1256 #define REGS_OFFSET 16
1257 #endif
1259 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1260 unsigned long pc)
1262 unsigned long ip;
1263 unsigned long newsp;
1264 unsigned long marker;
1265 int count = 0;
1266 struct pt_regs regs;
1268 do {
1269 if (sp < PAGE_OFFSET) {
1270 if (sp != 0)
1271 printf("SP (%lx) is in userspace\n", sp);
1272 break;
1275 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1276 || !mread(sp, &newsp, sizeof(unsigned long))) {
1277 printf("Couldn't read stack frame at %lx\n", sp);
1278 break;
1282 * For the first stack frame, try to work out if
1283 * LR and/or the saved LR value in the bottommost
1284 * stack frame are valid.
1286 if ((pc | lr) != 0) {
1287 unsigned long fnstart, fnend;
1288 unsigned long nextip;
1289 int printip = 1;
1291 get_function_bounds(pc, &fnstart, &fnend);
1292 nextip = 0;
1293 if (newsp > sp)
1294 mread(newsp + LRSAVE_OFFSET, &nextip,
1295 sizeof(unsigned long));
1296 if (lr == ip) {
1297 if (lr < PAGE_OFFSET
1298 || (fnstart <= lr && lr < fnend))
1299 printip = 0;
1300 } else if (lr == nextip) {
1301 printip = 0;
1302 } else if (lr >= PAGE_OFFSET
1303 && !(fnstart <= lr && lr < fnend)) {
1304 printf("[link register ] ");
1305 xmon_print_symbol(lr, " ", "\n");
1307 if (printip) {
1308 printf("["REG"] ", sp);
1309 xmon_print_symbol(ip, " ", " (unreliable)\n");
1311 pc = lr = 0;
1313 } else {
1314 printf("["REG"] ", sp);
1315 xmon_print_symbol(ip, " ", "\n");
1318 /* Look for "regshere" marker to see if this is
1319 an exception frame. */
1320 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1321 && marker == REG_FRAME_MARKER) {
1322 if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
1323 != sizeof(regs)) {
1324 printf("Couldn't read registers at %lx\n",
1325 sp + REGS_OFFSET);
1326 break;
1328 printf("--- Exception: %lx %s at ", regs.trap,
1329 getvecname(TRAP(&regs)));
1330 pc = regs.nip;
1331 lr = regs.link;
1332 xmon_print_symbol(pc, " ", "\n");
1335 if (newsp == 0)
1336 break;
1338 sp = newsp;
1339 } while (count++ < xmon_depth_to_print);
1342 static void backtrace(struct pt_regs *excp)
1344 unsigned long sp;
1346 if (scanhex(&sp))
1347 xmon_show_stack(sp, 0, 0);
1348 else
1349 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1350 scannl();
1353 static void print_bug_trap(struct pt_regs *regs)
1355 const struct bug_entry *bug;
1356 unsigned long addr;
1358 if (regs->msr & MSR_PR)
1359 return; /* not in kernel */
1360 addr = regs->nip; /* address of trap instruction */
1361 if (addr < PAGE_OFFSET)
1362 return;
1363 bug = find_bug(regs->nip);
1364 if (bug == NULL)
1365 return;
1366 if (is_warning_bug(bug))
1367 return;
1369 #ifdef CONFIG_DEBUG_BUGVERBOSE
1370 printf("kernel BUG at %s:%u!\n",
1371 bug->file, bug->line);
1372 #else
1373 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1374 #endif
1377 void excprint(struct pt_regs *fp)
1379 unsigned long trap;
1381 #ifdef CONFIG_SMP
1382 printf("cpu 0x%x: ", smp_processor_id());
1383 #endif /* CONFIG_SMP */
1385 trap = TRAP(fp);
1386 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1387 printf(" pc: ");
1388 xmon_print_symbol(fp->nip, ": ", "\n");
1390 printf(" lr: ", fp->link);
1391 xmon_print_symbol(fp->link, ": ", "\n");
1393 printf(" sp: %lx\n", fp->gpr[1]);
1394 printf(" msr: %lx\n", fp->msr);
1396 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1397 printf(" dar: %lx\n", fp->dar);
1398 if (trap != 0x380)
1399 printf(" dsisr: %lx\n", fp->dsisr);
1402 printf(" current = 0x%lx\n", current);
1403 #ifdef CONFIG_PPC64
1404 printf(" paca = 0x%lx\n", get_paca());
1405 #endif
1406 if (current) {
1407 printf(" pid = %ld, comm = %s\n",
1408 current->pid, current->comm);
1411 if (trap == 0x700)
1412 print_bug_trap(fp);
1415 void prregs(struct pt_regs *fp)
1417 int n, trap;
1418 unsigned long base;
1419 struct pt_regs regs;
1421 if (scanhex(&base)) {
1422 if (setjmp(bus_error_jmp) == 0) {
1423 catch_memory_errors = 1;
1424 sync();
1425 regs = *(struct pt_regs *)base;
1426 sync();
1427 __delay(200);
1428 } else {
1429 catch_memory_errors = 0;
1430 printf("*** Error reading registers from "REG"\n",
1431 base);
1432 return;
1434 catch_memory_errors = 0;
1435 fp = &regs;
1438 #ifdef CONFIG_PPC64
1439 if (FULL_REGS(fp)) {
1440 for (n = 0; n < 16; ++n)
1441 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1442 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1443 } else {
1444 for (n = 0; n < 7; ++n)
1445 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1446 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1448 #else
1449 for (n = 0; n < 32; ++n) {
1450 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1451 (n & 3) == 3? "\n": " ");
1452 if (n == 12 && !FULL_REGS(fp)) {
1453 printf("\n");
1454 break;
1457 #endif
1458 printf("pc = ");
1459 xmon_print_symbol(fp->nip, " ", "\n");
1460 printf("lr = ");
1461 xmon_print_symbol(fp->link, " ", "\n");
1462 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1463 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1464 fp->ctr, fp->xer, fp->trap);
1465 trap = TRAP(fp);
1466 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1467 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1470 void cacheflush(void)
1472 int cmd;
1473 unsigned long nflush;
1475 cmd = inchar();
1476 if (cmd != 'i')
1477 termch = cmd;
1478 scanhex((void *)&adrs);
1479 if (termch != '\n')
1480 termch = 0;
1481 nflush = 1;
1482 scanhex(&nflush);
1483 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1484 if (setjmp(bus_error_jmp) == 0) {
1485 catch_memory_errors = 1;
1486 sync();
1488 if (cmd != 'i') {
1489 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1490 cflush((void *) adrs);
1491 } else {
1492 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1493 cinval((void *) adrs);
1495 sync();
1496 /* wait a little while to see if we get a machine check */
1497 __delay(200);
1499 catch_memory_errors = 0;
1502 unsigned long
1503 read_spr(int n)
1505 unsigned int instrs[2];
1506 unsigned long (*code)(void);
1507 unsigned long ret = -1UL;
1508 #ifdef CONFIG_PPC64
1509 unsigned long opd[3];
1511 opd[0] = (unsigned long)instrs;
1512 opd[1] = 0;
1513 opd[2] = 0;
1514 code = (unsigned long (*)(void)) opd;
1515 #else
1516 code = (unsigned long (*)(void)) instrs;
1517 #endif
1519 /* mfspr r3,n; blr */
1520 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1521 instrs[1] = 0x4e800020;
1522 store_inst(instrs);
1523 store_inst(instrs+1);
1525 if (setjmp(bus_error_jmp) == 0) {
1526 catch_memory_errors = 1;
1527 sync();
1529 ret = code();
1531 sync();
1532 /* wait a little while to see if we get a machine check */
1533 __delay(200);
1534 n = size;
1537 return ret;
1540 void
1541 write_spr(int n, unsigned long val)
1543 unsigned int instrs[2];
1544 unsigned long (*code)(unsigned long);
1545 #ifdef CONFIG_PPC64
1546 unsigned long opd[3];
1548 opd[0] = (unsigned long)instrs;
1549 opd[1] = 0;
1550 opd[2] = 0;
1551 code = (unsigned long (*)(unsigned long)) opd;
1552 #else
1553 code = (unsigned long (*)(unsigned long)) instrs;
1554 #endif
1556 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1557 instrs[1] = 0x4e800020;
1558 store_inst(instrs);
1559 store_inst(instrs+1);
1561 if (setjmp(bus_error_jmp) == 0) {
1562 catch_memory_errors = 1;
1563 sync();
1565 code(val);
1567 sync();
1568 /* wait a little while to see if we get a machine check */
1569 __delay(200);
1570 n = size;
1574 static unsigned long regno;
1575 extern char exc_prolog;
1576 extern char dec_exc;
1578 void super_regs(void)
1580 int cmd;
1581 unsigned long val;
1583 cmd = skipbl();
1584 if (cmd == '\n') {
1585 unsigned long sp, toc;
1586 asm("mr %0,1" : "=r" (sp) :);
1587 asm("mr %0,2" : "=r" (toc) :);
1589 printf("msr = "REG" sprg0= "REG"\n",
1590 mfmsr(), mfspr(SPRN_SPRG0));
1591 printf("pvr = "REG" sprg1= "REG"\n",
1592 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1593 printf("dec = "REG" sprg2= "REG"\n",
1594 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1595 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1596 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1597 #ifdef CONFIG_PPC_ISERIES
1598 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1599 struct paca_struct *ptrPaca;
1600 struct lppaca *ptrLpPaca;
1601 struct ItLpRegSave *ptrLpRegSave;
1603 /* Dump out relevant Paca data areas. */
1604 printf("Paca: \n");
1605 ptrPaca = get_paca();
1607 printf(" Local Processor Control Area (LpPaca): \n");
1608 ptrLpPaca = ptrPaca->lppaca_ptr;
1609 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1610 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1611 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1612 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1613 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1615 printf(" Local Processor Register Save Area (LpRegSave): \n");
1616 ptrLpRegSave = ptrPaca->reg_save_ptr;
1617 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1618 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1619 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1620 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1621 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1622 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1624 #endif
1626 return;
1629 scanhex(&regno);
1630 switch (cmd) {
1631 case 'w':
1632 val = read_spr(regno);
1633 scanhex(&val);
1634 write_spr(regno, val);
1635 /* fall through */
1636 case 'r':
1637 printf("spr %lx = %lx\n", regno, read_spr(regno));
1638 break;
1640 scannl();
1644 * Stuff for reading and writing memory safely
1647 mread(unsigned long adrs, void *buf, int size)
1649 volatile int n;
1650 char *p, *q;
1652 n = 0;
1653 if (setjmp(bus_error_jmp) == 0) {
1654 catch_memory_errors = 1;
1655 sync();
1656 p = (char *)adrs;
1657 q = (char *)buf;
1658 switch (size) {
1659 case 2:
1660 *(u16 *)q = *(u16 *)p;
1661 break;
1662 case 4:
1663 *(u32 *)q = *(u32 *)p;
1664 break;
1665 case 8:
1666 *(u64 *)q = *(u64 *)p;
1667 break;
1668 default:
1669 for( ; n < size; ++n) {
1670 *q++ = *p++;
1671 sync();
1674 sync();
1675 /* wait a little while to see if we get a machine check */
1676 __delay(200);
1677 n = size;
1679 catch_memory_errors = 0;
1680 return n;
1684 mwrite(unsigned long adrs, void *buf, int size)
1686 volatile int n;
1687 char *p, *q;
1689 n = 0;
1690 if (setjmp(bus_error_jmp) == 0) {
1691 catch_memory_errors = 1;
1692 sync();
1693 p = (char *) adrs;
1694 q = (char *) buf;
1695 switch (size) {
1696 case 2:
1697 *(u16 *)p = *(u16 *)q;
1698 break;
1699 case 4:
1700 *(u32 *)p = *(u32 *)q;
1701 break;
1702 case 8:
1703 *(u64 *)p = *(u64 *)q;
1704 break;
1705 default:
1706 for ( ; n < size; ++n) {
1707 *p++ = *q++;
1708 sync();
1711 sync();
1712 /* wait a little while to see if we get a machine check */
1713 __delay(200);
1714 n = size;
1715 } else {
1716 printf("*** Error writing address %x\n", adrs + n);
1718 catch_memory_errors = 0;
1719 return n;
1722 static int fault_type;
1723 static int fault_except;
1724 static char *fault_chars[] = { "--", "**", "##" };
1726 static int handle_fault(struct pt_regs *regs)
1728 fault_except = TRAP(regs);
1729 switch (TRAP(regs)) {
1730 case 0x200:
1731 fault_type = 0;
1732 break;
1733 case 0x300:
1734 case 0x380:
1735 fault_type = 1;
1736 break;
1737 default:
1738 fault_type = 2;
1741 longjmp(bus_error_jmp, 1);
1743 return 0;
1746 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1748 void
1749 byterev(unsigned char *val, int size)
1751 int t;
1753 switch (size) {
1754 case 2:
1755 SWAP(val[0], val[1], t);
1756 break;
1757 case 4:
1758 SWAP(val[0], val[3], t);
1759 SWAP(val[1], val[2], t);
1760 break;
1761 case 8: /* is there really any use for this? */
1762 SWAP(val[0], val[7], t);
1763 SWAP(val[1], val[6], t);
1764 SWAP(val[2], val[5], t);
1765 SWAP(val[3], val[4], t);
1766 break;
1770 static int brev;
1771 static int mnoread;
1773 static char *memex_help_string =
1774 "Memory examine command usage:\n"
1775 "m [addr] [flags] examine/change memory\n"
1776 " addr is optional. will start where left off.\n"
1777 " flags may include chars from this set:\n"
1778 " b modify by bytes (default)\n"
1779 " w modify by words (2 byte)\n"
1780 " l modify by longs (4 byte)\n"
1781 " d modify by doubleword (8 byte)\n"
1782 " r toggle reverse byte order mode\n"
1783 " n do not read memory (for i/o spaces)\n"
1784 " . ok to read (default)\n"
1785 "NOTE: flags are saved as defaults\n"
1788 static char *memex_subcmd_help_string =
1789 "Memory examine subcommands:\n"
1790 " hexval write this val to current location\n"
1791 " 'string' write chars from string to this location\n"
1792 " ' increment address\n"
1793 " ^ decrement address\n"
1794 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1795 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1796 " ` clear no-read flag\n"
1797 " ; stay at this addr\n"
1798 " v change to byte mode\n"
1799 " w change to word (2 byte) mode\n"
1800 " l change to long (4 byte) mode\n"
1801 " u change to doubleword (8 byte) mode\n"
1802 " m addr change current addr\n"
1803 " n toggle no-read flag\n"
1804 " r toggle byte reverse flag\n"
1805 " < count back up count bytes\n"
1806 " > count skip forward count bytes\n"
1807 " x exit this mode\n"
1810 void
1811 memex(void)
1813 int cmd, inc, i, nslash;
1814 unsigned long n;
1815 unsigned char val[16];
1817 scanhex((void *)&adrs);
1818 cmd = skipbl();
1819 if (cmd == '?') {
1820 printf(memex_help_string);
1821 return;
1822 } else {
1823 termch = cmd;
1825 last_cmd = "m\n";
1826 while ((cmd = skipbl()) != '\n') {
1827 switch( cmd ){
1828 case 'b': size = 1; break;
1829 case 'w': size = 2; break;
1830 case 'l': size = 4; break;
1831 case 'd': size = 8; break;
1832 case 'r': brev = !brev; break;
1833 case 'n': mnoread = 1; break;
1834 case '.': mnoread = 0; break;
1837 if( size <= 0 )
1838 size = 1;
1839 else if( size > 8 )
1840 size = 8;
1841 for(;;){
1842 if (!mnoread)
1843 n = mread(adrs, val, size);
1844 printf(REG"%c", adrs, brev? 'r': ' ');
1845 if (!mnoread) {
1846 if (brev)
1847 byterev(val, size);
1848 putchar(' ');
1849 for (i = 0; i < n; ++i)
1850 printf("%.2x", val[i]);
1851 for (; i < size; ++i)
1852 printf("%s", fault_chars[fault_type]);
1854 putchar(' ');
1855 inc = size;
1856 nslash = 0;
1857 for(;;){
1858 if( scanhex(&n) ){
1859 for (i = 0; i < size; ++i)
1860 val[i] = n >> (i * 8);
1861 if (!brev)
1862 byterev(val, size);
1863 mwrite(adrs, val, size);
1864 inc = size;
1866 cmd = skipbl();
1867 if (cmd == '\n')
1868 break;
1869 inc = 0;
1870 switch (cmd) {
1871 case '\'':
1872 for(;;){
1873 n = inchar();
1874 if( n == '\\' )
1875 n = bsesc();
1876 else if( n == '\'' )
1877 break;
1878 for (i = 0; i < size; ++i)
1879 val[i] = n >> (i * 8);
1880 if (!brev)
1881 byterev(val, size);
1882 mwrite(adrs, val, size);
1883 adrs += size;
1885 adrs -= size;
1886 inc = size;
1887 break;
1888 case ',':
1889 adrs += size;
1890 break;
1891 case '.':
1892 mnoread = 0;
1893 break;
1894 case ';':
1895 break;
1896 case 'x':
1897 case EOF:
1898 scannl();
1899 return;
1900 case 'b':
1901 case 'v':
1902 size = 1;
1903 break;
1904 case 'w':
1905 size = 2;
1906 break;
1907 case 'l':
1908 size = 4;
1909 break;
1910 case 'u':
1911 size = 8;
1912 break;
1913 case '^':
1914 adrs -= size;
1915 break;
1916 break;
1917 case '/':
1918 if (nslash > 0)
1919 adrs -= 1 << nslash;
1920 else
1921 nslash = 0;
1922 nslash += 4;
1923 adrs += 1 << nslash;
1924 break;
1925 case '\\':
1926 if (nslash < 0)
1927 adrs += 1 << -nslash;
1928 else
1929 nslash = 0;
1930 nslash -= 4;
1931 adrs -= 1 << -nslash;
1932 break;
1933 case 'm':
1934 scanhex((void *)&adrs);
1935 break;
1936 case 'n':
1937 mnoread = 1;
1938 break;
1939 case 'r':
1940 brev = !brev;
1941 break;
1942 case '<':
1943 n = size;
1944 scanhex(&n);
1945 adrs -= n;
1946 break;
1947 case '>':
1948 n = size;
1949 scanhex(&n);
1950 adrs += n;
1951 break;
1952 case '?':
1953 printf(memex_subcmd_help_string);
1954 break;
1957 adrs += inc;
1962 bsesc(void)
1964 int c;
1966 c = inchar();
1967 switch( c ){
1968 case 'n': c = '\n'; break;
1969 case 'r': c = '\r'; break;
1970 case 'b': c = '\b'; break;
1971 case 't': c = '\t'; break;
1973 return c;
1976 static void xmon_rawdump (unsigned long adrs, long ndump)
1978 long n, m, r, nr;
1979 unsigned char temp[16];
1981 for (n = ndump; n > 0;) {
1982 r = n < 16? n: 16;
1983 nr = mread(adrs, temp, r);
1984 adrs += nr;
1985 for (m = 0; m < r; ++m) {
1986 if (m < nr)
1987 printf("%.2x", temp[m]);
1988 else
1989 printf("%s", fault_chars[fault_type]);
1991 n -= r;
1992 if (nr < r)
1993 break;
1995 printf("\n");
1998 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1999 || ('a' <= (c) && (c) <= 'f') \
2000 || ('A' <= (c) && (c) <= 'F'))
2001 void
2002 dump(void)
2004 int c;
2006 c = inchar();
2007 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2008 termch = c;
2009 scanhex((void *)&adrs);
2010 if (termch != '\n')
2011 termch = 0;
2012 if (c == 'i') {
2013 scanhex(&nidump);
2014 if (nidump == 0)
2015 nidump = 16;
2016 else if (nidump > MAX_DUMP)
2017 nidump = MAX_DUMP;
2018 adrs += ppc_inst_dump(adrs, nidump, 1);
2019 last_cmd = "di\n";
2020 } else if (c == 'r') {
2021 scanhex(&ndump);
2022 if (ndump == 0)
2023 ndump = 64;
2024 xmon_rawdump(adrs, ndump);
2025 adrs += ndump;
2026 last_cmd = "dr\n";
2027 } else {
2028 scanhex(&ndump);
2029 if (ndump == 0)
2030 ndump = 64;
2031 else if (ndump > MAX_DUMP)
2032 ndump = MAX_DUMP;
2033 prdump(adrs, ndump);
2034 adrs += ndump;
2035 last_cmd = "d\n";
2039 void
2040 prdump(unsigned long adrs, long ndump)
2042 long n, m, c, r, nr;
2043 unsigned char temp[16];
2045 for (n = ndump; n > 0;) {
2046 printf(REG, adrs);
2047 putchar(' ');
2048 r = n < 16? n: 16;
2049 nr = mread(adrs, temp, r);
2050 adrs += nr;
2051 for (m = 0; m < r; ++m) {
2052 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2053 putchar(' ');
2054 if (m < nr)
2055 printf("%.2x", temp[m]);
2056 else
2057 printf("%s", fault_chars[fault_type]);
2059 for (; m < 16; ++m) {
2060 if ((m & (sizeof(long) - 1)) == 0)
2061 putchar(' ');
2062 printf(" ");
2064 printf(" |");
2065 for (m = 0; m < r; ++m) {
2066 if (m < nr) {
2067 c = temp[m];
2068 putchar(' ' <= c && c <= '~'? c: '.');
2069 } else
2070 putchar(' ');
2072 n -= r;
2073 for (; m < 16; ++m)
2074 putchar(' ');
2075 printf("|\n");
2076 if (nr < r)
2077 break;
2081 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2084 generic_inst_dump(unsigned long adr, long count, int praddr,
2085 instruction_dump_func dump_func)
2087 int nr, dotted;
2088 unsigned long first_adr;
2089 unsigned long inst, last_inst = 0;
2090 unsigned char val[4];
2092 dotted = 0;
2093 for (first_adr = adr; count > 0; --count, adr += 4) {
2094 nr = mread(adr, val, 4);
2095 if (nr == 0) {
2096 if (praddr) {
2097 const char *x = fault_chars[fault_type];
2098 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2100 break;
2102 inst = GETWORD(val);
2103 if (adr > first_adr && inst == last_inst) {
2104 if (!dotted) {
2105 printf(" ...\n");
2106 dotted = 1;
2108 continue;
2110 dotted = 0;
2111 last_inst = inst;
2112 if (praddr)
2113 printf(REG" %.8x", adr, inst);
2114 printf("\t");
2115 dump_func(inst, adr);
2116 printf("\n");
2118 return adr - first_adr;
2122 ppc_inst_dump(unsigned long adr, long count, int praddr)
2124 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2127 void
2128 print_address(unsigned long addr)
2130 xmon_print_symbol(addr, "\t# ", "");
2135 * Memory operations - move, set, print differences
2137 static unsigned long mdest; /* destination address */
2138 static unsigned long msrc; /* source address */
2139 static unsigned long mval; /* byte value to set memory to */
2140 static unsigned long mcount; /* # bytes to affect */
2141 static unsigned long mdiffs; /* max # differences to print */
2143 void
2144 memops(int cmd)
2146 scanhex((void *)&mdest);
2147 if( termch != '\n' )
2148 termch = 0;
2149 scanhex((void *)(cmd == 's'? &mval: &msrc));
2150 if( termch != '\n' )
2151 termch = 0;
2152 scanhex((void *)&mcount);
2153 switch( cmd ){
2154 case 'm':
2155 memmove((void *)mdest, (void *)msrc, mcount);
2156 break;
2157 case 's':
2158 memset((void *)mdest, mval, mcount);
2159 break;
2160 case 'd':
2161 if( termch != '\n' )
2162 termch = 0;
2163 scanhex((void *)&mdiffs);
2164 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2165 break;
2169 void
2170 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2172 unsigned n, prt;
2174 prt = 0;
2175 for( n = nb; n > 0; --n )
2176 if( *p1++ != *p2++ )
2177 if( ++prt <= maxpr )
2178 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2179 p1[-1], p2 - 1, p2[-1]);
2180 if( prt > maxpr )
2181 printf("Total of %d differences\n", prt);
2184 static unsigned mend;
2185 static unsigned mask;
2187 void
2188 memlocate(void)
2190 unsigned a, n;
2191 unsigned char val[4];
2193 last_cmd = "ml";
2194 scanhex((void *)&mdest);
2195 if (termch != '\n') {
2196 termch = 0;
2197 scanhex((void *)&mend);
2198 if (termch != '\n') {
2199 termch = 0;
2200 scanhex((void *)&mval);
2201 mask = ~0;
2202 if (termch != '\n') termch = 0;
2203 scanhex((void *)&mask);
2206 n = 0;
2207 for (a = mdest; a < mend; a += 4) {
2208 if (mread(a, val, 4) == 4
2209 && ((GETWORD(val) ^ mval) & mask) == 0) {
2210 printf("%.16x: %.16x\n", a, GETWORD(val));
2211 if (++n >= 10)
2212 break;
2217 static unsigned long mskip = 0x1000;
2218 static unsigned long mlim = 0xffffffff;
2220 void
2221 memzcan(void)
2223 unsigned char v;
2224 unsigned a;
2225 int ok, ook;
2227 scanhex(&mdest);
2228 if (termch != '\n') termch = 0;
2229 scanhex(&mskip);
2230 if (termch != '\n') termch = 0;
2231 scanhex(&mlim);
2232 ook = 0;
2233 for (a = mdest; a < mlim; a += mskip) {
2234 ok = mread(a, &v, 1);
2235 if (ok && !ook) {
2236 printf("%.8x .. ", a);
2237 } else if (!ok && ook)
2238 printf("%.8x\n", a - mskip);
2239 ook = ok;
2240 if (a + mskip < a)
2241 break;
2243 if (ook)
2244 printf("%.8x\n", a - mskip);
2247 void proccall(void)
2249 unsigned long args[8];
2250 unsigned long ret;
2251 int i;
2252 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2253 unsigned long, unsigned long, unsigned long,
2254 unsigned long, unsigned long, unsigned long);
2255 callfunc_t func;
2257 if (!scanhex(&adrs))
2258 return;
2259 if (termch != '\n')
2260 termch = 0;
2261 for (i = 0; i < 8; ++i)
2262 args[i] = 0;
2263 for (i = 0; i < 8; ++i) {
2264 if (!scanhex(&args[i]) || termch == '\n')
2265 break;
2266 termch = 0;
2268 func = (callfunc_t) adrs;
2269 ret = 0;
2270 if (setjmp(bus_error_jmp) == 0) {
2271 catch_memory_errors = 1;
2272 sync();
2273 ret = func(args[0], args[1], args[2], args[3],
2274 args[4], args[5], args[6], args[7]);
2275 sync();
2276 printf("return value is %x\n", ret);
2277 } else {
2278 printf("*** %x exception occurred\n", fault_except);
2280 catch_memory_errors = 0;
2283 /* Input scanning routines */
2285 skipbl(void)
2287 int c;
2289 if( termch != 0 ){
2290 c = termch;
2291 termch = 0;
2292 } else
2293 c = inchar();
2294 while( c == ' ' || c == '\t' )
2295 c = inchar();
2296 return c;
2299 #define N_PTREGS 44
2300 static char *regnames[N_PTREGS] = {
2301 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2302 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2303 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2304 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2305 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2306 #ifdef CONFIG_PPC64
2307 "softe",
2308 #else
2309 "mq",
2310 #endif
2311 "trap", "dar", "dsisr", "res"
2315 scanhex(unsigned long *vp)
2317 int c, d;
2318 unsigned long v;
2320 c = skipbl();
2321 if (c == '%') {
2322 /* parse register name */
2323 char regname[8];
2324 int i;
2326 for (i = 0; i < sizeof(regname) - 1; ++i) {
2327 c = inchar();
2328 if (!isalnum(c)) {
2329 termch = c;
2330 break;
2332 regname[i] = c;
2334 regname[i] = 0;
2335 for (i = 0; i < N_PTREGS; ++i) {
2336 if (strcmp(regnames[i], regname) == 0) {
2337 if (xmon_regs == NULL) {
2338 printf("regs not available\n");
2339 return 0;
2341 *vp = ((unsigned long *)xmon_regs)[i];
2342 return 1;
2345 printf("invalid register name '%%%s'\n", regname);
2346 return 0;
2349 /* skip leading "0x" if any */
2351 if (c == '0') {
2352 c = inchar();
2353 if (c == 'x') {
2354 c = inchar();
2355 } else {
2356 d = hexdigit(c);
2357 if (d == EOF) {
2358 termch = c;
2359 *vp = 0;
2360 return 1;
2363 } else if (c == '$') {
2364 int i;
2365 for (i=0; i<63; i++) {
2366 c = inchar();
2367 if (isspace(c)) {
2368 termch = c;
2369 break;
2371 tmpstr[i] = c;
2373 tmpstr[i++] = 0;
2374 *vp = 0;
2375 if (setjmp(bus_error_jmp) == 0) {
2376 catch_memory_errors = 1;
2377 sync();
2378 *vp = kallsyms_lookup_name(tmpstr);
2379 sync();
2381 catch_memory_errors = 0;
2382 if (!(*vp)) {
2383 printf("unknown symbol '%s'\n", tmpstr);
2384 return 0;
2386 return 1;
2389 d = hexdigit(c);
2390 if (d == EOF) {
2391 termch = c;
2392 return 0;
2394 v = 0;
2395 do {
2396 v = (v << 4) + d;
2397 c = inchar();
2398 d = hexdigit(c);
2399 } while (d != EOF);
2400 termch = c;
2401 *vp = v;
2402 return 1;
2405 void
2406 scannl(void)
2408 int c;
2410 c = termch;
2411 termch = 0;
2412 while( c != '\n' )
2413 c = inchar();
2416 int hexdigit(int c)
2418 if( '0' <= c && c <= '9' )
2419 return c - '0';
2420 if( 'A' <= c && c <= 'F' )
2421 return c - ('A' - 10);
2422 if( 'a' <= c && c <= 'f' )
2423 return c - ('a' - 10);
2424 return EOF;
2427 void
2428 getstring(char *s, int size)
2430 int c;
2432 c = skipbl();
2433 do {
2434 if( size > 1 ){
2435 *s++ = c;
2436 --size;
2438 c = inchar();
2439 } while( c != ' ' && c != '\t' && c != '\n' );
2440 termch = c;
2441 *s = 0;
2444 static char line[256];
2445 static char *lineptr;
2447 void
2448 flush_input(void)
2450 lineptr = NULL;
2454 inchar(void)
2456 if (lineptr == NULL || *lineptr == 0) {
2457 if (xmon_gets(line, sizeof(line)) == NULL) {
2458 lineptr = NULL;
2459 return EOF;
2461 lineptr = line;
2463 return *lineptr++;
2466 void
2467 take_input(char *str)
2469 lineptr = str;
2473 static void
2474 symbol_lookup(void)
2476 int type = inchar();
2477 unsigned long addr;
2478 static char tmp[64];
2480 switch (type) {
2481 case 'a':
2482 if (scanhex(&addr))
2483 xmon_print_symbol(addr, ": ", "\n");
2484 termch = 0;
2485 break;
2486 case 's':
2487 getstring(tmp, 64);
2488 if (setjmp(bus_error_jmp) == 0) {
2489 catch_memory_errors = 1;
2490 sync();
2491 addr = kallsyms_lookup_name(tmp);
2492 if (addr)
2493 printf("%s: %lx\n", tmp, addr);
2494 else
2495 printf("Symbol '%s' not found.\n", tmp);
2496 sync();
2498 catch_memory_errors = 0;
2499 termch = 0;
2500 break;
2505 /* Print an address in numeric and symbolic form (if possible) */
2506 static void xmon_print_symbol(unsigned long address, const char *mid,
2507 const char *after)
2509 char *modname;
2510 const char *name = NULL;
2511 unsigned long offset, size;
2513 printf(REG, address);
2514 if (setjmp(bus_error_jmp) == 0) {
2515 catch_memory_errors = 1;
2516 sync();
2517 name = kallsyms_lookup(address, &size, &offset, &modname,
2518 tmpstr);
2519 sync();
2520 /* wait a little while to see if we get a machine check */
2521 __delay(200);
2524 catch_memory_errors = 0;
2526 if (name) {
2527 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2528 if (modname)
2529 printf(" [%s]", modname);
2531 printf("%s", after);
2534 #ifdef CONFIG_PPC64
2535 static void dump_slb(void)
2537 int i;
2538 unsigned long esid,vsid,valid;
2539 unsigned long llp;
2541 printf("SLB contents of cpu %x\n", smp_processor_id());
2543 for (i = 0; i < mmu_slb_size; i++) {
2544 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2545 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2546 valid = (esid & SLB_ESID_V);
2547 if (valid | esid | vsid) {
2548 printf("%02d %016lx %016lx", i, esid, vsid);
2549 if (valid) {
2550 llp = vsid & SLB_VSID_LLP;
2551 if (vsid & SLB_VSID_B_1T) {
2552 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2553 GET_ESID_1T(esid),
2554 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2555 llp);
2556 } else {
2557 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2558 GET_ESID(esid),
2559 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2560 llp);
2562 } else
2563 printf("\n");
2568 static void dump_stab(void)
2570 int i;
2571 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2573 printf("Segment table contents of cpu %x\n", smp_processor_id());
2575 for (i = 0; i < PAGE_SIZE/16; i++) {
2576 unsigned long a, b;
2578 a = *tmp++;
2579 b = *tmp++;
2581 if (a || b) {
2582 printf("%03d %016lx ", i, a);
2583 printf("%016lx\n", b);
2588 void dump_segments(void)
2590 if (cpu_has_feature(CPU_FTR_SLB))
2591 dump_slb();
2592 else
2593 dump_stab();
2595 #endif
2597 #ifdef CONFIG_PPC_STD_MMU_32
2598 void dump_segments(void)
2600 int i;
2602 printf("sr0-15 =");
2603 for (i = 0; i < 16; ++i)
2604 printf(" %x", mfsrin(i));
2605 printf("\n");
2607 #endif
2609 #ifdef CONFIG_44x
2610 static void dump_tlb_44x(void)
2612 int i;
2614 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2615 unsigned long w0,w1,w2;
2616 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2617 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2618 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2619 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2620 if (w0 & PPC44x_TLB_VALID) {
2621 printf("V %08x -> %01x%08x %c%c%c%c%c",
2622 w0 & PPC44x_TLB_EPN_MASK,
2623 w1 & PPC44x_TLB_ERPN_MASK,
2624 w1 & PPC44x_TLB_RPN_MASK,
2625 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2626 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2627 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2628 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2629 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2631 printf("\n");
2634 #endif /* CONFIG_44x */
2635 void xmon_init(int enable)
2637 #ifdef CONFIG_PPC_ISERIES
2638 if (firmware_has_feature(FW_FEATURE_ISERIES))
2639 return;
2640 #endif
2641 if (enable) {
2642 __debugger = xmon;
2643 __debugger_ipi = xmon_ipi;
2644 __debugger_bpt = xmon_bpt;
2645 __debugger_sstep = xmon_sstep;
2646 __debugger_iabr_match = xmon_iabr_match;
2647 __debugger_dabr_match = xmon_dabr_match;
2648 __debugger_fault_handler = xmon_fault_handler;
2649 } else {
2650 __debugger = NULL;
2651 __debugger_ipi = NULL;
2652 __debugger_bpt = NULL;
2653 __debugger_sstep = NULL;
2654 __debugger_iabr_match = NULL;
2655 __debugger_dabr_match = NULL;
2656 __debugger_fault_handler = NULL;
2658 xmon_map_scc();
2661 #ifdef CONFIG_MAGIC_SYSRQ
2662 static void sysrq_handle_xmon(int key, struct tty_struct *tty)
2664 /* ensure xmon is enabled */
2665 xmon_init(1);
2666 debugger(get_irq_regs());
2669 static struct sysrq_key_op sysrq_xmon_op =
2671 .handler = sysrq_handle_xmon,
2672 .help_msg = "Xmon",
2673 .action_msg = "Entering xmon",
2676 static int __init setup_xmon_sysrq(void)
2678 #ifdef CONFIG_PPC_ISERIES
2679 if (firmware_has_feature(FW_FEATURE_ISERIES))
2680 return 0;
2681 #endif
2682 register_sysrq_key('x', &sysrq_xmon_op);
2683 return 0;
2685 __initcall(setup_xmon_sysrq);
2686 #endif /* CONFIG_MAGIC_SYSRQ */
2688 static int __initdata xmon_early, xmon_off;
2690 static int __init early_parse_xmon(char *p)
2692 if (!p || strncmp(p, "early", 5) == 0) {
2693 /* just "xmon" is equivalent to "xmon=early" */
2694 xmon_init(1);
2695 xmon_early = 1;
2696 } else if (strncmp(p, "on", 2) == 0)
2697 xmon_init(1);
2698 else if (strncmp(p, "off", 3) == 0)
2699 xmon_off = 1;
2700 else if (strncmp(p, "nobt", 4) == 0)
2701 xmon_no_auto_backtrace = 1;
2702 else
2703 return 1;
2705 return 0;
2707 early_param("xmon", early_parse_xmon);
2709 void __init xmon_setup(void)
2711 #ifdef CONFIG_XMON_DEFAULT
2712 if (!xmon_off)
2713 xmon_init(1);
2714 #endif
2715 if (xmon_early)
2716 debugger(NULL);
2719 #ifdef CONFIG_SPU_BASE
2721 struct spu_info {
2722 struct spu *spu;
2723 u64 saved_mfc_sr1_RW;
2724 u32 saved_spu_runcntl_RW;
2725 unsigned long dump_addr;
2726 u8 stopped_ok;
2729 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2731 static struct spu_info spu_info[XMON_NUM_SPUS];
2733 void xmon_register_spus(struct list_head *list)
2735 struct spu *spu;
2737 list_for_each_entry(spu, list, full_list) {
2738 if (spu->number >= XMON_NUM_SPUS) {
2739 WARN_ON(1);
2740 continue;
2743 spu_info[spu->number].spu = spu;
2744 spu_info[spu->number].stopped_ok = 0;
2745 spu_info[spu->number].dump_addr = (unsigned long)
2746 spu_info[spu->number].spu->local_store;
2750 static void stop_spus(void)
2752 struct spu *spu;
2753 int i;
2754 u64 tmp;
2756 for (i = 0; i < XMON_NUM_SPUS; i++) {
2757 if (!spu_info[i].spu)
2758 continue;
2760 if (setjmp(bus_error_jmp) == 0) {
2761 catch_memory_errors = 1;
2762 sync();
2764 spu = spu_info[i].spu;
2766 spu_info[i].saved_spu_runcntl_RW =
2767 in_be32(&spu->problem->spu_runcntl_RW);
2769 tmp = spu_mfc_sr1_get(spu);
2770 spu_info[i].saved_mfc_sr1_RW = tmp;
2772 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2773 spu_mfc_sr1_set(spu, tmp);
2775 sync();
2776 __delay(200);
2778 spu_info[i].stopped_ok = 1;
2780 printf("Stopped spu %.2d (was %s)\n", i,
2781 spu_info[i].saved_spu_runcntl_RW ?
2782 "running" : "stopped");
2783 } else {
2784 catch_memory_errors = 0;
2785 printf("*** Error stopping spu %.2d\n", i);
2787 catch_memory_errors = 0;
2791 static void restart_spus(void)
2793 struct spu *spu;
2794 int i;
2796 for (i = 0; i < XMON_NUM_SPUS; i++) {
2797 if (!spu_info[i].spu)
2798 continue;
2800 if (!spu_info[i].stopped_ok) {
2801 printf("*** Error, spu %d was not successfully stopped"
2802 ", not restarting\n", i);
2803 continue;
2806 if (setjmp(bus_error_jmp) == 0) {
2807 catch_memory_errors = 1;
2808 sync();
2810 spu = spu_info[i].spu;
2811 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2812 out_be32(&spu->problem->spu_runcntl_RW,
2813 spu_info[i].saved_spu_runcntl_RW);
2815 sync();
2816 __delay(200);
2818 printf("Restarted spu %.2d\n", i);
2819 } else {
2820 catch_memory_errors = 0;
2821 printf("*** Error restarting spu %.2d\n", i);
2823 catch_memory_errors = 0;
2827 #define DUMP_WIDTH 23
2828 #define DUMP_VALUE(format, field, value) \
2829 do { \
2830 if (setjmp(bus_error_jmp) == 0) { \
2831 catch_memory_errors = 1; \
2832 sync(); \
2833 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2834 #field, value); \
2835 sync(); \
2836 __delay(200); \
2837 } else { \
2838 catch_memory_errors = 0; \
2839 printf(" %-*s = *** Error reading field.\n", \
2840 DUMP_WIDTH, #field); \
2842 catch_memory_errors = 0; \
2843 } while (0)
2845 #define DUMP_FIELD(obj, format, field) \
2846 DUMP_VALUE(format, field, obj->field)
2848 static void dump_spu_fields(struct spu *spu)
2850 printf("Dumping spu fields at address %p:\n", spu);
2852 DUMP_FIELD(spu, "0x%x", number);
2853 DUMP_FIELD(spu, "%s", name);
2854 DUMP_FIELD(spu, "0x%lx", local_store_phys);
2855 DUMP_FIELD(spu, "0x%p", local_store);
2856 DUMP_FIELD(spu, "0x%lx", ls_size);
2857 DUMP_FIELD(spu, "0x%x", node);
2858 DUMP_FIELD(spu, "0x%lx", flags);
2859 DUMP_FIELD(spu, "0x%lx", dar);
2860 DUMP_FIELD(spu, "0x%lx", dsisr);
2861 DUMP_FIELD(spu, "%d", class_0_pending);
2862 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2863 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2864 DUMP_FIELD(spu, "0x%lx", irqs[2]);
2865 DUMP_FIELD(spu, "0x%x", slb_replace);
2866 DUMP_FIELD(spu, "%d", pid);
2867 DUMP_FIELD(spu, "0x%p", mm);
2868 DUMP_FIELD(spu, "0x%p", ctx);
2869 DUMP_FIELD(spu, "0x%p", rq);
2870 DUMP_FIELD(spu, "0x%p", timestamp);
2871 DUMP_FIELD(spu, "0x%lx", problem_phys);
2872 DUMP_FIELD(spu, "0x%p", problem);
2873 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2874 in_be32(&spu->problem->spu_runcntl_RW));
2875 DUMP_VALUE("0x%x", problem->spu_status_R,
2876 in_be32(&spu->problem->spu_status_R));
2877 DUMP_VALUE("0x%x", problem->spu_npc_RW,
2878 in_be32(&spu->problem->spu_npc_RW));
2879 DUMP_FIELD(spu, "0x%p", priv2);
2880 DUMP_FIELD(spu, "0x%p", pdata);
2884 spu_inst_dump(unsigned long adr, long count, int praddr)
2886 return generic_inst_dump(adr, count, praddr, print_insn_spu);
2889 static void dump_spu_ls(unsigned long num, int subcmd)
2891 unsigned long offset, addr, ls_addr;
2893 if (setjmp(bus_error_jmp) == 0) {
2894 catch_memory_errors = 1;
2895 sync();
2896 ls_addr = (unsigned long)spu_info[num].spu->local_store;
2897 sync();
2898 __delay(200);
2899 } else {
2900 catch_memory_errors = 0;
2901 printf("*** Error: accessing spu info for spu %d\n", num);
2902 return;
2904 catch_memory_errors = 0;
2906 if (scanhex(&offset))
2907 addr = ls_addr + offset;
2908 else
2909 addr = spu_info[num].dump_addr;
2911 if (addr >= ls_addr + LS_SIZE) {
2912 printf("*** Error: address outside of local store\n");
2913 return;
2916 switch (subcmd) {
2917 case 'i':
2918 addr += spu_inst_dump(addr, 16, 1);
2919 last_cmd = "sdi\n";
2920 break;
2921 default:
2922 prdump(addr, 64);
2923 addr += 64;
2924 last_cmd = "sd\n";
2925 break;
2928 spu_info[num].dump_addr = addr;
2931 static int do_spu_cmd(void)
2933 static unsigned long num = 0;
2934 int cmd, subcmd = 0;
2936 cmd = inchar();
2937 switch (cmd) {
2938 case 's':
2939 stop_spus();
2940 break;
2941 case 'r':
2942 restart_spus();
2943 break;
2944 case 'd':
2945 subcmd = inchar();
2946 if (isxdigit(subcmd) || subcmd == '\n')
2947 termch = subcmd;
2948 case 'f':
2949 scanhex(&num);
2950 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
2951 printf("*** Error: invalid spu number\n");
2952 return 0;
2955 switch (cmd) {
2956 case 'f':
2957 dump_spu_fields(spu_info[num].spu);
2958 break;
2959 default:
2960 dump_spu_ls(num, subcmd);
2961 break;
2964 break;
2965 default:
2966 return -1;
2969 return 0;
2971 #else /* ! CONFIG_SPU_BASE */
2972 static int do_spu_cmd(void)
2974 return -1;
2976 #endif