viafb: cleanup viafb_cursor
[linux-2.6/linux-2.6-openrd.git] / arch / powerpc / xmon / xmon.c
blob0e09a45ac79a633c83a8e0ed282876397db64750
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>
44 #include <asm/reg.h>
46 #ifdef CONFIG_PPC64
47 #include <asm/hvcall.h>
48 #include <asm/paca.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 static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
59 static unsigned long xmon_taken = 1;
60 static int xmon_owner;
61 static int xmon_gate;
62 #endif /* CONFIG_SMP */
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 dump_log_buf(void);
114 static void backtrace(struct pt_regs *);
115 static void excprint(struct pt_regs *);
116 static void prregs(struct pt_regs *);
117 static void memops(int);
118 static void memlocate(void);
119 static void memzcan(void);
120 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
121 int skipbl(void);
122 int scanhex(unsigned long *valp);
123 static void scannl(void);
124 static int hexdigit(int);
125 void getstring(char *, int);
126 static void flush_input(void);
127 static int inchar(void);
128 static void take_input(char *);
129 static unsigned long read_spr(int);
130 static void write_spr(int, unsigned long);
131 static void super_regs(void);
132 static void remove_bpts(void);
133 static void insert_bpts(void);
134 static void remove_cpu_bpts(void);
135 static void insert_cpu_bpts(void);
136 static struct bpt *at_breakpoint(unsigned long pc);
137 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
138 static int do_step(struct pt_regs *);
139 static void bpt_cmds(void);
140 static void cacheflush(void);
141 static int cpu_cmd(void);
142 static void csum(void);
143 static void bootcmds(void);
144 static void proccall(void);
145 void dump_segments(void);
146 static void symbol_lookup(void);
147 static void xmon_show_stack(unsigned long sp, unsigned long lr,
148 unsigned long pc);
149 static void xmon_print_symbol(unsigned long address, const char *mid,
150 const char *after);
151 static const char *getvecname(unsigned long vec);
153 static int do_spu_cmd(void);
155 #ifdef CONFIG_44x
156 static void dump_tlb_44x(void);
157 #endif
159 static int xmon_no_auto_backtrace;
161 extern void xmon_enter(void);
162 extern void xmon_leave(void);
164 #ifdef CONFIG_PPC64
165 #define REG "%.16lx"
166 #define REGS_PER_LINE 4
167 #define LAST_VOLATILE 13
168 #else
169 #define REG "%.8lx"
170 #define REGS_PER_LINE 8
171 #define LAST_VOLATILE 12
172 #endif
174 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
176 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
177 || ('a' <= (c) && (c) <= 'f') \
178 || ('A' <= (c) && (c) <= 'F'))
179 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
180 || ('a' <= (c) && (c) <= 'z') \
181 || ('A' <= (c) && (c) <= 'Z'))
182 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
184 static char *help_string = "\
185 Commands:\n\
186 b show breakpoints\n\
187 bd set data breakpoint\n\
188 bi set instruction breakpoint\n\
189 bc clear breakpoint\n"
190 #ifdef CONFIG_SMP
192 c print cpus stopped in xmon\n\
193 c# try to switch to cpu number h (in hex)\n"
194 #endif
196 C checksum\n\
197 d dump bytes\n\
198 di dump instructions\n\
199 df dump float values\n\
200 dd dump double values\n\
201 dl dump the kernel log buffer\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;
332 int cpus_are_in_xmon(void)
334 return !cpus_empty(cpus_in_xmon);
336 #endif
338 static int xmon_core(struct pt_regs *regs, int fromipi)
340 int cmd = 0;
341 struct bpt *bp;
342 long recurse_jmp[JMP_BUF_LEN];
343 unsigned long offset;
344 unsigned long flags;
345 #ifdef CONFIG_SMP
346 int cpu;
347 int secondary;
348 unsigned long timeout;
349 #endif
351 local_irq_save(flags);
353 bp = in_breakpoint_table(regs->nip, &offset);
354 if (bp != NULL) {
355 regs->nip = bp->address + offset;
356 atomic_dec(&bp->ref_count);
359 remove_cpu_bpts();
361 #ifdef CONFIG_SMP
362 cpu = smp_processor_id();
363 if (cpu_isset(cpu, cpus_in_xmon)) {
364 get_output_lock();
365 excprint(regs);
366 printf("cpu 0x%x: Exception %lx %s in xmon, "
367 "returning to main loop\n",
368 cpu, regs->trap, getvecname(TRAP(regs)));
369 release_output_lock();
370 longjmp(xmon_fault_jmp[cpu], 1);
373 if (setjmp(recurse_jmp) != 0) {
374 if (!in_xmon || !xmon_gate) {
375 get_output_lock();
376 printf("xmon: WARNING: bad recursive fault "
377 "on cpu 0x%x\n", cpu);
378 release_output_lock();
379 goto waiting;
381 secondary = !(xmon_taken && cpu == xmon_owner);
382 goto cmdloop;
385 xmon_fault_jmp[cpu] = recurse_jmp;
386 cpu_set(cpu, cpus_in_xmon);
388 bp = NULL;
389 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
390 bp = at_breakpoint(regs->nip);
391 if (bp || (regs->msr & MSR_RI) == 0)
392 fromipi = 0;
394 if (!fromipi) {
395 get_output_lock();
396 excprint(regs);
397 if (bp) {
398 printf("cpu 0x%x stopped at breakpoint 0x%x (",
399 cpu, BP_NUM(bp));
400 xmon_print_symbol(regs->nip, " ", ")\n");
402 if ((regs->msr & MSR_RI) == 0)
403 printf("WARNING: exception is not recoverable, "
404 "can't continue\n");
405 release_output_lock();
408 waiting:
409 secondary = 1;
410 while (secondary && !xmon_gate) {
411 if (in_xmon == 0) {
412 if (fromipi)
413 goto leave;
414 secondary = test_and_set_bit(0, &in_xmon);
416 barrier();
419 if (!secondary && !xmon_gate) {
420 /* we are the first cpu to come in */
421 /* interrupt other cpu(s) */
422 int ncpus = num_online_cpus();
424 xmon_owner = cpu;
425 mb();
426 if (ncpus > 1) {
427 smp_send_debugger_break(MSG_ALL_BUT_SELF);
428 /* wait for other cpus to come in */
429 for (timeout = 100000000; timeout != 0; --timeout) {
430 if (cpus_weight(cpus_in_xmon) >= ncpus)
431 break;
432 barrier();
435 remove_bpts();
436 disable_surveillance();
437 /* for breakpoint or single step, print the current instr. */
438 if (bp || TRAP(regs) == 0xd00)
439 ppc_inst_dump(regs->nip, 1, 0);
440 printf("enter ? for help\n");
441 mb();
442 xmon_gate = 1;
443 barrier();
446 cmdloop:
447 while (in_xmon) {
448 if (secondary) {
449 if (cpu == xmon_owner) {
450 if (!test_and_set_bit(0, &xmon_taken)) {
451 secondary = 0;
452 continue;
454 /* missed it */
455 while (cpu == xmon_owner)
456 barrier();
458 barrier();
459 } else {
460 cmd = cmds(regs);
461 if (cmd != 0) {
462 /* exiting xmon */
463 insert_bpts();
464 xmon_gate = 0;
465 wmb();
466 in_xmon = 0;
467 break;
469 /* have switched to some other cpu */
470 secondary = 1;
473 leave:
474 cpu_clear(cpu, cpus_in_xmon);
475 xmon_fault_jmp[cpu] = NULL;
476 #else
477 /* UP is simple... */
478 if (in_xmon) {
479 printf("Exception %lx %s in xmon, returning to main loop\n",
480 regs->trap, getvecname(TRAP(regs)));
481 longjmp(xmon_fault_jmp[0], 1);
483 if (setjmp(recurse_jmp) == 0) {
484 xmon_fault_jmp[0] = recurse_jmp;
485 in_xmon = 1;
487 excprint(regs);
488 bp = at_breakpoint(regs->nip);
489 if (bp) {
490 printf("Stopped at breakpoint %x (", BP_NUM(bp));
491 xmon_print_symbol(regs->nip, " ", ")\n");
493 if ((regs->msr & MSR_RI) == 0)
494 printf("WARNING: exception is not recoverable, "
495 "can't continue\n");
496 remove_bpts();
497 disable_surveillance();
498 /* for breakpoint or single step, print the current instr. */
499 if (bp || TRAP(regs) == 0xd00)
500 ppc_inst_dump(regs->nip, 1, 0);
501 printf("enter ? for help\n");
504 cmd = cmds(regs);
506 insert_bpts();
507 in_xmon = 0;
508 #endif
510 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
511 bp = at_breakpoint(regs->nip);
512 if (bp != NULL) {
513 int stepped = emulate_step(regs, bp->instr[0]);
514 if (stepped == 0) {
515 regs->nip = (unsigned long) &bp->instr[0];
516 atomic_inc(&bp->ref_count);
517 } else if (stepped < 0) {
518 printf("Couldn't single-step %s instruction\n",
519 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
524 insert_cpu_bpts();
526 local_irq_restore(flags);
528 return cmd != 'X' && cmd != EOF;
531 int xmon(struct pt_regs *excp)
533 struct pt_regs regs;
535 if (excp == NULL) {
536 ppc_save_regs(&regs);
537 excp = &regs;
540 return xmon_core(excp, 0);
542 EXPORT_SYMBOL(xmon);
544 irqreturn_t xmon_irq(int irq, void *d)
546 unsigned long flags;
547 local_irq_save(flags);
548 printf("Keyboard interrupt\n");
549 xmon(get_irq_regs());
550 local_irq_restore(flags);
551 return IRQ_HANDLED;
554 static int xmon_bpt(struct pt_regs *regs)
556 struct bpt *bp;
557 unsigned long offset;
559 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
560 return 0;
562 /* Are we at the trap at bp->instr[1] for some bp? */
563 bp = in_breakpoint_table(regs->nip, &offset);
564 if (bp != NULL && offset == 4) {
565 regs->nip = bp->address + 4;
566 atomic_dec(&bp->ref_count);
567 return 1;
570 /* Are we at a breakpoint? */
571 bp = at_breakpoint(regs->nip);
572 if (!bp)
573 return 0;
575 xmon_core(regs, 0);
577 return 1;
580 static int xmon_sstep(struct pt_regs *regs)
582 if (user_mode(regs))
583 return 0;
584 xmon_core(regs, 0);
585 return 1;
588 static int xmon_dabr_match(struct pt_regs *regs)
590 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
591 return 0;
592 if (dabr.enabled == 0)
593 return 0;
594 xmon_core(regs, 0);
595 return 1;
598 static int xmon_iabr_match(struct pt_regs *regs)
600 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
601 return 0;
602 if (iabr == NULL)
603 return 0;
604 xmon_core(regs, 0);
605 return 1;
608 static int xmon_ipi(struct pt_regs *regs)
610 #ifdef CONFIG_SMP
611 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
612 xmon_core(regs, 1);
613 #endif
614 return 0;
617 static int xmon_fault_handler(struct pt_regs *regs)
619 struct bpt *bp;
620 unsigned long offset;
622 if (in_xmon && catch_memory_errors)
623 handle_fault(regs); /* doesn't return */
625 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
626 bp = in_breakpoint_table(regs->nip, &offset);
627 if (bp != NULL) {
628 regs->nip = bp->address + offset;
629 atomic_dec(&bp->ref_count);
633 return 0;
636 static struct bpt *at_breakpoint(unsigned long pc)
638 int i;
639 struct bpt *bp;
641 bp = bpts;
642 for (i = 0; i < NBPTS; ++i, ++bp)
643 if (bp->enabled && pc == bp->address)
644 return bp;
645 return NULL;
648 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
650 unsigned long off;
652 off = nip - (unsigned long) bpts;
653 if (off >= sizeof(bpts))
654 return NULL;
655 off %= sizeof(struct bpt);
656 if (off != offsetof(struct bpt, instr[0])
657 && off != offsetof(struct bpt, instr[1]))
658 return NULL;
659 *offp = off - offsetof(struct bpt, instr[0]);
660 return (struct bpt *) (nip - off);
663 static struct bpt *new_breakpoint(unsigned long a)
665 struct bpt *bp;
667 a &= ~3UL;
668 bp = at_breakpoint(a);
669 if (bp)
670 return bp;
672 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
673 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
674 bp->address = a;
675 bp->instr[1] = bpinstr;
676 store_inst(&bp->instr[1]);
677 return bp;
681 printf("Sorry, no free breakpoints. Please clear one first.\n");
682 return NULL;
685 static void insert_bpts(void)
687 int i;
688 struct bpt *bp;
690 bp = bpts;
691 for (i = 0; i < NBPTS; ++i, ++bp) {
692 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
693 continue;
694 if (mread(bp->address, &bp->instr[0], 4) != 4) {
695 printf("Couldn't read instruction at %lx, "
696 "disabling breakpoint there\n", bp->address);
697 bp->enabled = 0;
698 continue;
700 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
701 printf("Breakpoint at %lx is on an mtmsrd or rfid "
702 "instruction, disabling it\n", bp->address);
703 bp->enabled = 0;
704 continue;
706 store_inst(&bp->instr[0]);
707 if (bp->enabled & BP_IABR)
708 continue;
709 if (mwrite(bp->address, &bpinstr, 4) != 4) {
710 printf("Couldn't write instruction at %lx, "
711 "disabling breakpoint there\n", bp->address);
712 bp->enabled &= ~BP_TRAP;
713 continue;
715 store_inst((void *)bp->address);
719 static void insert_cpu_bpts(void)
721 if (dabr.enabled)
722 set_dabr(dabr.address | (dabr.enabled & 7));
723 if (iabr && cpu_has_feature(CPU_FTR_IABR))
724 mtspr(SPRN_IABR, iabr->address
725 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
728 static void remove_bpts(void)
730 int i;
731 struct bpt *bp;
732 unsigned instr;
734 bp = bpts;
735 for (i = 0; i < NBPTS; ++i, ++bp) {
736 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
737 continue;
738 if (mread(bp->address, &instr, 4) == 4
739 && instr == bpinstr
740 && mwrite(bp->address, &bp->instr, 4) != 4)
741 printf("Couldn't remove breakpoint at %lx\n",
742 bp->address);
743 else
744 store_inst((void *)bp->address);
748 static void remove_cpu_bpts(void)
750 set_dabr(0);
751 if (cpu_has_feature(CPU_FTR_IABR))
752 mtspr(SPRN_IABR, 0);
755 /* Command interpreting routine */
756 static char *last_cmd;
758 static int
759 cmds(struct pt_regs *excp)
761 int cmd = 0;
763 last_cmd = NULL;
764 xmon_regs = excp;
766 if (!xmon_no_auto_backtrace) {
767 xmon_no_auto_backtrace = 1;
768 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
771 for(;;) {
772 #ifdef CONFIG_SMP
773 printf("%x:", smp_processor_id());
774 #endif /* CONFIG_SMP */
775 printf("mon> ");
776 flush_input();
777 termch = 0;
778 cmd = skipbl();
779 if( cmd == '\n' ) {
780 if (last_cmd == NULL)
781 continue;
782 take_input(last_cmd);
783 last_cmd = NULL;
784 cmd = inchar();
786 switch (cmd) {
787 case 'm':
788 cmd = inchar();
789 switch (cmd) {
790 case 'm':
791 case 's':
792 case 'd':
793 memops(cmd);
794 break;
795 case 'l':
796 memlocate();
797 break;
798 case 'z':
799 memzcan();
800 break;
801 case 'i':
802 show_mem();
803 break;
804 default:
805 termch = cmd;
806 memex();
808 break;
809 case 'd':
810 dump();
811 break;
812 case 'l':
813 symbol_lookup();
814 break;
815 case 'r':
816 prregs(excp); /* print regs */
817 break;
818 case 'e':
819 excprint(excp);
820 break;
821 case 'S':
822 super_regs();
823 break;
824 case 't':
825 backtrace(excp);
826 break;
827 case 'f':
828 cacheflush();
829 break;
830 case 's':
831 if (do_spu_cmd() == 0)
832 break;
833 if (do_step(excp))
834 return cmd;
835 break;
836 case 'x':
837 case 'X':
838 return cmd;
839 case EOF:
840 printf(" <no input ...>\n");
841 mdelay(2000);
842 return cmd;
843 case '?':
844 xmon_puts(help_string);
845 break;
846 case 'b':
847 bpt_cmds();
848 break;
849 case 'C':
850 csum();
851 break;
852 case 'c':
853 if (cpu_cmd())
854 return 0;
855 break;
856 case 'z':
857 bootcmds();
858 break;
859 case 'p':
860 proccall();
861 break;
862 #ifdef CONFIG_PPC_STD_MMU
863 case 'u':
864 dump_segments();
865 break;
866 #endif
867 #ifdef CONFIG_4xx
868 case 'u':
869 dump_tlb_44x();
870 break;
871 #endif
872 default:
873 printf("Unrecognized command: ");
874 do {
875 if (' ' < cmd && cmd <= '~')
876 putchar(cmd);
877 else
878 printf("\\x%x", cmd);
879 cmd = inchar();
880 } while (cmd != '\n');
881 printf(" (type ? for help)\n");
882 break;
888 * Step a single instruction.
889 * Some instructions we emulate, others we execute with MSR_SE set.
891 static int do_step(struct pt_regs *regs)
893 unsigned int instr;
894 int stepped;
896 /* check we are in 64-bit kernel mode, translation enabled */
897 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
898 if (mread(regs->nip, &instr, 4) == 4) {
899 stepped = emulate_step(regs, instr);
900 if (stepped < 0) {
901 printf("Couldn't single-step %s instruction\n",
902 (IS_RFID(instr)? "rfid": "mtmsrd"));
903 return 0;
905 if (stepped > 0) {
906 regs->trap = 0xd00 | (regs->trap & 1);
907 printf("stepped to ");
908 xmon_print_symbol(regs->nip, " ", "\n");
909 ppc_inst_dump(regs->nip, 1, 0);
910 return 0;
914 regs->msr |= MSR_SE;
915 return 1;
918 static void bootcmds(void)
920 int cmd;
922 cmd = inchar();
923 if (cmd == 'r')
924 ppc_md.restart(NULL);
925 else if (cmd == 'h')
926 ppc_md.halt();
927 else if (cmd == 'p')
928 ppc_md.power_off();
931 static int cpu_cmd(void)
933 #ifdef CONFIG_SMP
934 unsigned long cpu;
935 int timeout;
936 int count;
938 if (!scanhex(&cpu)) {
939 /* print cpus waiting or in xmon */
940 printf("cpus stopped:");
941 count = 0;
942 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
943 if (cpu_isset(cpu, cpus_in_xmon)) {
944 if (count == 0)
945 printf(" %x", cpu);
946 ++count;
947 } else {
948 if (count > 1)
949 printf("-%x", cpu - 1);
950 count = 0;
953 if (count > 1)
954 printf("-%x", NR_CPUS - 1);
955 printf("\n");
956 return 0;
958 /* try to switch to cpu specified */
959 if (!cpu_isset(cpu, cpus_in_xmon)) {
960 printf("cpu 0x%x isn't in xmon\n", cpu);
961 return 0;
963 xmon_taken = 0;
964 mb();
965 xmon_owner = cpu;
966 timeout = 10000000;
967 while (!xmon_taken) {
968 if (--timeout == 0) {
969 if (test_and_set_bit(0, &xmon_taken))
970 break;
971 /* take control back */
972 mb();
973 xmon_owner = smp_processor_id();
974 printf("cpu %u didn't take control\n", cpu);
975 return 0;
977 barrier();
979 return 1;
980 #else
981 return 0;
982 #endif /* CONFIG_SMP */
985 static unsigned short fcstab[256] = {
986 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
987 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
988 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
989 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
990 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
991 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
992 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
993 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
994 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
995 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
996 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
997 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
998 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
999 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1000 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1001 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1002 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1003 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1004 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1005 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1006 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1007 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1008 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1009 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1010 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1011 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1012 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1013 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1014 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1015 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1016 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1017 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1020 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1022 static void
1023 csum(void)
1025 unsigned int i;
1026 unsigned short fcs;
1027 unsigned char v;
1029 if (!scanhex(&adrs))
1030 return;
1031 if (!scanhex(&ncsum))
1032 return;
1033 fcs = 0xffff;
1034 for (i = 0; i < ncsum; ++i) {
1035 if (mread(adrs+i, &v, 1) == 0) {
1036 printf("csum stopped at %x\n", adrs+i);
1037 break;
1039 fcs = FCS(fcs, v);
1041 printf("%x\n", fcs);
1045 * Check if this is a suitable place to put a breakpoint.
1047 static long check_bp_loc(unsigned long addr)
1049 unsigned int instr;
1051 addr &= ~3;
1052 if (!is_kernel_addr(addr)) {
1053 printf("Breakpoints may only be placed at kernel addresses\n");
1054 return 0;
1056 if (!mread(addr, &instr, sizeof(instr))) {
1057 printf("Can't read instruction at address %lx\n", addr);
1058 return 0;
1060 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1061 printf("Breakpoints may not be placed on mtmsrd or rfid "
1062 "instructions\n");
1063 return 0;
1065 return 1;
1068 static char *breakpoint_help_string =
1069 "Breakpoint command usage:\n"
1070 "b show breakpoints\n"
1071 "b <addr> [cnt] set breakpoint at given instr addr\n"
1072 "bc clear all breakpoints\n"
1073 "bc <n/addr> clear breakpoint number n or at addr\n"
1074 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1075 "bd <addr> [cnt] set hardware data breakpoint\n"
1078 static void
1079 bpt_cmds(void)
1081 int cmd;
1082 unsigned long a;
1083 int mode, i;
1084 struct bpt *bp;
1085 const char badaddr[] = "Only kernel addresses are permitted "
1086 "for breakpoints\n";
1088 cmd = inchar();
1089 switch (cmd) {
1090 #ifndef CONFIG_8xx
1091 case 'd': /* bd - hardware data breakpoint */
1092 mode = 7;
1093 cmd = inchar();
1094 if (cmd == 'r')
1095 mode = 5;
1096 else if (cmd == 'w')
1097 mode = 6;
1098 else
1099 termch = cmd;
1100 dabr.address = 0;
1101 dabr.enabled = 0;
1102 if (scanhex(&dabr.address)) {
1103 if (!is_kernel_addr(dabr.address)) {
1104 printf(badaddr);
1105 break;
1107 dabr.address &= ~7;
1108 dabr.enabled = mode | BP_DABR;
1110 break;
1112 case 'i': /* bi - hardware instr breakpoint */
1113 if (!cpu_has_feature(CPU_FTR_IABR)) {
1114 printf("Hardware instruction breakpoint "
1115 "not supported on this cpu\n");
1116 break;
1118 if (iabr) {
1119 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1120 iabr = NULL;
1122 if (!scanhex(&a))
1123 break;
1124 if (!check_bp_loc(a))
1125 break;
1126 bp = new_breakpoint(a);
1127 if (bp != NULL) {
1128 bp->enabled |= BP_IABR | BP_IABR_TE;
1129 iabr = bp;
1131 break;
1132 #endif
1134 case 'c':
1135 if (!scanhex(&a)) {
1136 /* clear all breakpoints */
1137 for (i = 0; i < NBPTS; ++i)
1138 bpts[i].enabled = 0;
1139 iabr = NULL;
1140 dabr.enabled = 0;
1141 printf("All breakpoints cleared\n");
1142 break;
1145 if (a <= NBPTS && a >= 1) {
1146 /* assume a breakpoint number */
1147 bp = &bpts[a-1]; /* bp nums are 1 based */
1148 } else {
1149 /* assume a breakpoint address */
1150 bp = at_breakpoint(a);
1151 if (bp == NULL) {
1152 printf("No breakpoint at %x\n", a);
1153 break;
1157 printf("Cleared breakpoint %x (", BP_NUM(bp));
1158 xmon_print_symbol(bp->address, " ", ")\n");
1159 bp->enabled = 0;
1160 break;
1162 default:
1163 termch = cmd;
1164 cmd = skipbl();
1165 if (cmd == '?') {
1166 printf(breakpoint_help_string);
1167 break;
1169 termch = cmd;
1170 if (!scanhex(&a)) {
1171 /* print all breakpoints */
1172 printf(" type address\n");
1173 if (dabr.enabled) {
1174 printf(" data "REG" [", dabr.address);
1175 if (dabr.enabled & 1)
1176 printf("r");
1177 if (dabr.enabled & 2)
1178 printf("w");
1179 printf("]\n");
1181 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1182 if (!bp->enabled)
1183 continue;
1184 printf("%2x %s ", BP_NUM(bp),
1185 (bp->enabled & BP_IABR)? "inst": "trap");
1186 xmon_print_symbol(bp->address, " ", "\n");
1188 break;
1191 if (!check_bp_loc(a))
1192 break;
1193 bp = new_breakpoint(a);
1194 if (bp != NULL)
1195 bp->enabled |= BP_TRAP;
1196 break;
1200 /* Very cheap human name for vector lookup. */
1201 static
1202 const char *getvecname(unsigned long vec)
1204 char *ret;
1206 switch (vec) {
1207 case 0x100: ret = "(System Reset)"; break;
1208 case 0x200: ret = "(Machine Check)"; break;
1209 case 0x300: ret = "(Data Access)"; break;
1210 case 0x380: ret = "(Data SLB Access)"; break;
1211 case 0x400: ret = "(Instruction Access)"; break;
1212 case 0x480: ret = "(Instruction SLB Access)"; break;
1213 case 0x500: ret = "(Hardware Interrupt)"; break;
1214 case 0x600: ret = "(Alignment)"; break;
1215 case 0x700: ret = "(Program Check)"; break;
1216 case 0x800: ret = "(FPU Unavailable)"; break;
1217 case 0x900: ret = "(Decrementer)"; break;
1218 case 0xc00: ret = "(System Call)"; break;
1219 case 0xd00: ret = "(Single Step)"; break;
1220 case 0xf00: ret = "(Performance Monitor)"; break;
1221 case 0xf20: ret = "(Altivec Unavailable)"; break;
1222 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1223 default: ret = "";
1225 return ret;
1228 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1229 unsigned long *endp)
1231 unsigned long size, offset;
1232 const char *name;
1234 *startp = *endp = 0;
1235 if (pc == 0)
1236 return;
1237 if (setjmp(bus_error_jmp) == 0) {
1238 catch_memory_errors = 1;
1239 sync();
1240 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1241 if (name != NULL) {
1242 *startp = pc - offset;
1243 *endp = pc - offset + size;
1245 sync();
1247 catch_memory_errors = 0;
1250 static int xmon_depth_to_print = 64;
1252 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1253 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1255 #ifdef __powerpc64__
1256 #define REGS_OFFSET 0x70
1257 #else
1258 #define REGS_OFFSET 16
1259 #endif
1261 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1262 unsigned long pc)
1264 unsigned long ip;
1265 unsigned long newsp;
1266 unsigned long marker;
1267 int count = 0;
1268 struct pt_regs regs;
1270 do {
1271 if (sp < PAGE_OFFSET) {
1272 if (sp != 0)
1273 printf("SP (%lx) is in userspace\n", sp);
1274 break;
1277 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1278 || !mread(sp, &newsp, sizeof(unsigned long))) {
1279 printf("Couldn't read stack frame at %lx\n", sp);
1280 break;
1284 * For the first stack frame, try to work out if
1285 * LR and/or the saved LR value in the bottommost
1286 * stack frame are valid.
1288 if ((pc | lr) != 0) {
1289 unsigned long fnstart, fnend;
1290 unsigned long nextip;
1291 int printip = 1;
1293 get_function_bounds(pc, &fnstart, &fnend);
1294 nextip = 0;
1295 if (newsp > sp)
1296 mread(newsp + LRSAVE_OFFSET, &nextip,
1297 sizeof(unsigned long));
1298 if (lr == ip) {
1299 if (lr < PAGE_OFFSET
1300 || (fnstart <= lr && lr < fnend))
1301 printip = 0;
1302 } else if (lr == nextip) {
1303 printip = 0;
1304 } else if (lr >= PAGE_OFFSET
1305 && !(fnstart <= lr && lr < fnend)) {
1306 printf("[link register ] ");
1307 xmon_print_symbol(lr, " ", "\n");
1309 if (printip) {
1310 printf("["REG"] ", sp);
1311 xmon_print_symbol(ip, " ", " (unreliable)\n");
1313 pc = lr = 0;
1315 } else {
1316 printf("["REG"] ", sp);
1317 xmon_print_symbol(ip, " ", "\n");
1320 /* Look for "regshere" marker to see if this is
1321 an exception frame. */
1322 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1323 && marker == STACK_FRAME_REGS_MARKER) {
1324 if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
1325 != sizeof(regs)) {
1326 printf("Couldn't read registers at %lx\n",
1327 sp + REGS_OFFSET);
1328 break;
1330 printf("--- Exception: %lx %s at ", regs.trap,
1331 getvecname(TRAP(&regs)));
1332 pc = regs.nip;
1333 lr = regs.link;
1334 xmon_print_symbol(pc, " ", "\n");
1337 if (newsp == 0)
1338 break;
1340 sp = newsp;
1341 } while (count++ < xmon_depth_to_print);
1344 static void backtrace(struct pt_regs *excp)
1346 unsigned long sp;
1348 if (scanhex(&sp))
1349 xmon_show_stack(sp, 0, 0);
1350 else
1351 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1352 scannl();
1355 static void print_bug_trap(struct pt_regs *regs)
1357 #ifdef CONFIG_BUG
1358 const struct bug_entry *bug;
1359 unsigned long addr;
1361 if (regs->msr & MSR_PR)
1362 return; /* not in kernel */
1363 addr = regs->nip; /* address of trap instruction */
1364 if (addr < PAGE_OFFSET)
1365 return;
1366 bug = find_bug(regs->nip);
1367 if (bug == NULL)
1368 return;
1369 if (is_warning_bug(bug))
1370 return;
1372 #ifdef CONFIG_DEBUG_BUGVERBOSE
1373 printf("kernel BUG at %s:%u!\n",
1374 bug->file, bug->line);
1375 #else
1376 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1377 #endif
1378 #endif /* CONFIG_BUG */
1381 static void excprint(struct pt_regs *fp)
1383 unsigned long trap;
1385 #ifdef CONFIG_SMP
1386 printf("cpu 0x%x: ", smp_processor_id());
1387 #endif /* CONFIG_SMP */
1389 trap = TRAP(fp);
1390 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1391 printf(" pc: ");
1392 xmon_print_symbol(fp->nip, ": ", "\n");
1394 printf(" lr: ", fp->link);
1395 xmon_print_symbol(fp->link, ": ", "\n");
1397 printf(" sp: %lx\n", fp->gpr[1]);
1398 printf(" msr: %lx\n", fp->msr);
1400 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1401 printf(" dar: %lx\n", fp->dar);
1402 if (trap != 0x380)
1403 printf(" dsisr: %lx\n", fp->dsisr);
1406 printf(" current = 0x%lx\n", current);
1407 #ifdef CONFIG_PPC64
1408 printf(" paca = 0x%lx\n", get_paca());
1409 #endif
1410 if (current) {
1411 printf(" pid = %ld, comm = %s\n",
1412 current->pid, current->comm);
1415 if (trap == 0x700)
1416 print_bug_trap(fp);
1419 static void prregs(struct pt_regs *fp)
1421 int n, trap;
1422 unsigned long base;
1423 struct pt_regs regs;
1425 if (scanhex(&base)) {
1426 if (setjmp(bus_error_jmp) == 0) {
1427 catch_memory_errors = 1;
1428 sync();
1429 regs = *(struct pt_regs *)base;
1430 sync();
1431 __delay(200);
1432 } else {
1433 catch_memory_errors = 0;
1434 printf("*** Error reading registers from "REG"\n",
1435 base);
1436 return;
1438 catch_memory_errors = 0;
1439 fp = &regs;
1442 #ifdef CONFIG_PPC64
1443 if (FULL_REGS(fp)) {
1444 for (n = 0; n < 16; ++n)
1445 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1446 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1447 } else {
1448 for (n = 0; n < 7; ++n)
1449 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1450 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1452 #else
1453 for (n = 0; n < 32; ++n) {
1454 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1455 (n & 3) == 3? "\n": " ");
1456 if (n == 12 && !FULL_REGS(fp)) {
1457 printf("\n");
1458 break;
1461 #endif
1462 printf("pc = ");
1463 xmon_print_symbol(fp->nip, " ", "\n");
1464 printf("lr = ");
1465 xmon_print_symbol(fp->link, " ", "\n");
1466 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1467 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1468 fp->ctr, fp->xer, fp->trap);
1469 trap = TRAP(fp);
1470 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1471 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1474 static void cacheflush(void)
1476 int cmd;
1477 unsigned long nflush;
1479 cmd = inchar();
1480 if (cmd != 'i')
1481 termch = cmd;
1482 scanhex((void *)&adrs);
1483 if (termch != '\n')
1484 termch = 0;
1485 nflush = 1;
1486 scanhex(&nflush);
1487 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1488 if (setjmp(bus_error_jmp) == 0) {
1489 catch_memory_errors = 1;
1490 sync();
1492 if (cmd != 'i') {
1493 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1494 cflush((void *) adrs);
1495 } else {
1496 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1497 cinval((void *) adrs);
1499 sync();
1500 /* wait a little while to see if we get a machine check */
1501 __delay(200);
1503 catch_memory_errors = 0;
1506 static unsigned long
1507 read_spr(int n)
1509 unsigned int instrs[2];
1510 unsigned long (*code)(void);
1511 unsigned long ret = -1UL;
1512 #ifdef CONFIG_PPC64
1513 unsigned long opd[3];
1515 opd[0] = (unsigned long)instrs;
1516 opd[1] = 0;
1517 opd[2] = 0;
1518 code = (unsigned long (*)(void)) opd;
1519 #else
1520 code = (unsigned long (*)(void)) instrs;
1521 #endif
1523 /* mfspr r3,n; blr */
1524 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1525 instrs[1] = 0x4e800020;
1526 store_inst(instrs);
1527 store_inst(instrs+1);
1529 if (setjmp(bus_error_jmp) == 0) {
1530 catch_memory_errors = 1;
1531 sync();
1533 ret = code();
1535 sync();
1536 /* wait a little while to see if we get a machine check */
1537 __delay(200);
1538 n = size;
1541 return ret;
1544 static void
1545 write_spr(int n, unsigned long val)
1547 unsigned int instrs[2];
1548 unsigned long (*code)(unsigned long);
1549 #ifdef CONFIG_PPC64
1550 unsigned long opd[3];
1552 opd[0] = (unsigned long)instrs;
1553 opd[1] = 0;
1554 opd[2] = 0;
1555 code = (unsigned long (*)(unsigned long)) opd;
1556 #else
1557 code = (unsigned long (*)(unsigned long)) instrs;
1558 #endif
1560 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1561 instrs[1] = 0x4e800020;
1562 store_inst(instrs);
1563 store_inst(instrs+1);
1565 if (setjmp(bus_error_jmp) == 0) {
1566 catch_memory_errors = 1;
1567 sync();
1569 code(val);
1571 sync();
1572 /* wait a little while to see if we get a machine check */
1573 __delay(200);
1574 n = size;
1578 static unsigned long regno;
1579 extern char exc_prolog;
1580 extern char dec_exc;
1582 static void super_regs(void)
1584 int cmd;
1585 unsigned long val;
1587 cmd = skipbl();
1588 if (cmd == '\n') {
1589 unsigned long sp, toc;
1590 asm("mr %0,1" : "=r" (sp) :);
1591 asm("mr %0,2" : "=r" (toc) :);
1593 printf("msr = "REG" sprg0= "REG"\n",
1594 mfmsr(), mfspr(SPRN_SPRG0));
1595 printf("pvr = "REG" sprg1= "REG"\n",
1596 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1597 printf("dec = "REG" sprg2= "REG"\n",
1598 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1599 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1600 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1601 #ifdef CONFIG_PPC_ISERIES
1602 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1603 struct paca_struct *ptrPaca;
1604 struct lppaca *ptrLpPaca;
1606 /* Dump out relevant Paca data areas. */
1607 printf("Paca: \n");
1608 ptrPaca = get_paca();
1610 printf(" Local Processor Control Area (LpPaca): \n");
1611 ptrLpPaca = ptrPaca->lppaca_ptr;
1612 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1613 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1614 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1615 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1616 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1618 #endif
1620 return;
1623 scanhex(&regno);
1624 switch (cmd) {
1625 case 'w':
1626 val = read_spr(regno);
1627 scanhex(&val);
1628 write_spr(regno, val);
1629 /* fall through */
1630 case 'r':
1631 printf("spr %lx = %lx\n", regno, read_spr(regno));
1632 break;
1634 scannl();
1638 * Stuff for reading and writing memory safely
1640 static int
1641 mread(unsigned long adrs, void *buf, int size)
1643 volatile int n;
1644 char *p, *q;
1646 n = 0;
1647 if (setjmp(bus_error_jmp) == 0) {
1648 catch_memory_errors = 1;
1649 sync();
1650 p = (char *)adrs;
1651 q = (char *)buf;
1652 switch (size) {
1653 case 2:
1654 *(u16 *)q = *(u16 *)p;
1655 break;
1656 case 4:
1657 *(u32 *)q = *(u32 *)p;
1658 break;
1659 case 8:
1660 *(u64 *)q = *(u64 *)p;
1661 break;
1662 default:
1663 for( ; n < size; ++n) {
1664 *q++ = *p++;
1665 sync();
1668 sync();
1669 /* wait a little while to see if we get a machine check */
1670 __delay(200);
1671 n = size;
1673 catch_memory_errors = 0;
1674 return n;
1677 static int
1678 mwrite(unsigned long adrs, void *buf, int size)
1680 volatile int n;
1681 char *p, *q;
1683 n = 0;
1684 if (setjmp(bus_error_jmp) == 0) {
1685 catch_memory_errors = 1;
1686 sync();
1687 p = (char *) adrs;
1688 q = (char *) buf;
1689 switch (size) {
1690 case 2:
1691 *(u16 *)p = *(u16 *)q;
1692 break;
1693 case 4:
1694 *(u32 *)p = *(u32 *)q;
1695 break;
1696 case 8:
1697 *(u64 *)p = *(u64 *)q;
1698 break;
1699 default:
1700 for ( ; n < size; ++n) {
1701 *p++ = *q++;
1702 sync();
1705 sync();
1706 /* wait a little while to see if we get a machine check */
1707 __delay(200);
1708 n = size;
1709 } else {
1710 printf("*** Error writing address %x\n", adrs + n);
1712 catch_memory_errors = 0;
1713 return n;
1716 static int fault_type;
1717 static int fault_except;
1718 static char *fault_chars[] = { "--", "**", "##" };
1720 static int handle_fault(struct pt_regs *regs)
1722 fault_except = TRAP(regs);
1723 switch (TRAP(regs)) {
1724 case 0x200:
1725 fault_type = 0;
1726 break;
1727 case 0x300:
1728 case 0x380:
1729 fault_type = 1;
1730 break;
1731 default:
1732 fault_type = 2;
1735 longjmp(bus_error_jmp, 1);
1737 return 0;
1740 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1742 static void
1743 byterev(unsigned char *val, int size)
1745 int t;
1747 switch (size) {
1748 case 2:
1749 SWAP(val[0], val[1], t);
1750 break;
1751 case 4:
1752 SWAP(val[0], val[3], t);
1753 SWAP(val[1], val[2], t);
1754 break;
1755 case 8: /* is there really any use for this? */
1756 SWAP(val[0], val[7], t);
1757 SWAP(val[1], val[6], t);
1758 SWAP(val[2], val[5], t);
1759 SWAP(val[3], val[4], t);
1760 break;
1764 static int brev;
1765 static int mnoread;
1767 static char *memex_help_string =
1768 "Memory examine command usage:\n"
1769 "m [addr] [flags] examine/change memory\n"
1770 " addr is optional. will start where left off.\n"
1771 " flags may include chars from this set:\n"
1772 " b modify by bytes (default)\n"
1773 " w modify by words (2 byte)\n"
1774 " l modify by longs (4 byte)\n"
1775 " d modify by doubleword (8 byte)\n"
1776 " r toggle reverse byte order mode\n"
1777 " n do not read memory (for i/o spaces)\n"
1778 " . ok to read (default)\n"
1779 "NOTE: flags are saved as defaults\n"
1782 static char *memex_subcmd_help_string =
1783 "Memory examine subcommands:\n"
1784 " hexval write this val to current location\n"
1785 " 'string' write chars from string to this location\n"
1786 " ' increment address\n"
1787 " ^ decrement address\n"
1788 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1789 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1790 " ` clear no-read flag\n"
1791 " ; stay at this addr\n"
1792 " v change to byte mode\n"
1793 " w change to word (2 byte) mode\n"
1794 " l change to long (4 byte) mode\n"
1795 " u change to doubleword (8 byte) mode\n"
1796 " m addr change current addr\n"
1797 " n toggle no-read flag\n"
1798 " r toggle byte reverse flag\n"
1799 " < count back up count bytes\n"
1800 " > count skip forward count bytes\n"
1801 " x exit this mode\n"
1804 static void
1805 memex(void)
1807 int cmd, inc, i, nslash;
1808 unsigned long n;
1809 unsigned char val[16];
1811 scanhex((void *)&adrs);
1812 cmd = skipbl();
1813 if (cmd == '?') {
1814 printf(memex_help_string);
1815 return;
1816 } else {
1817 termch = cmd;
1819 last_cmd = "m\n";
1820 while ((cmd = skipbl()) != '\n') {
1821 switch( cmd ){
1822 case 'b': size = 1; break;
1823 case 'w': size = 2; break;
1824 case 'l': size = 4; break;
1825 case 'd': size = 8; break;
1826 case 'r': brev = !brev; break;
1827 case 'n': mnoread = 1; break;
1828 case '.': mnoread = 0; break;
1831 if( size <= 0 )
1832 size = 1;
1833 else if( size > 8 )
1834 size = 8;
1835 for(;;){
1836 if (!mnoread)
1837 n = mread(adrs, val, size);
1838 printf(REG"%c", adrs, brev? 'r': ' ');
1839 if (!mnoread) {
1840 if (brev)
1841 byterev(val, size);
1842 putchar(' ');
1843 for (i = 0; i < n; ++i)
1844 printf("%.2x", val[i]);
1845 for (; i < size; ++i)
1846 printf("%s", fault_chars[fault_type]);
1848 putchar(' ');
1849 inc = size;
1850 nslash = 0;
1851 for(;;){
1852 if( scanhex(&n) ){
1853 for (i = 0; i < size; ++i)
1854 val[i] = n >> (i * 8);
1855 if (!brev)
1856 byterev(val, size);
1857 mwrite(adrs, val, size);
1858 inc = size;
1860 cmd = skipbl();
1861 if (cmd == '\n')
1862 break;
1863 inc = 0;
1864 switch (cmd) {
1865 case '\'':
1866 for(;;){
1867 n = inchar();
1868 if( n == '\\' )
1869 n = bsesc();
1870 else if( n == '\'' )
1871 break;
1872 for (i = 0; i < size; ++i)
1873 val[i] = n >> (i * 8);
1874 if (!brev)
1875 byterev(val, size);
1876 mwrite(adrs, val, size);
1877 adrs += size;
1879 adrs -= size;
1880 inc = size;
1881 break;
1882 case ',':
1883 adrs += size;
1884 break;
1885 case '.':
1886 mnoread = 0;
1887 break;
1888 case ';':
1889 break;
1890 case 'x':
1891 case EOF:
1892 scannl();
1893 return;
1894 case 'b':
1895 case 'v':
1896 size = 1;
1897 break;
1898 case 'w':
1899 size = 2;
1900 break;
1901 case 'l':
1902 size = 4;
1903 break;
1904 case 'u':
1905 size = 8;
1906 break;
1907 case '^':
1908 adrs -= size;
1909 break;
1910 break;
1911 case '/':
1912 if (nslash > 0)
1913 adrs -= 1 << nslash;
1914 else
1915 nslash = 0;
1916 nslash += 4;
1917 adrs += 1 << nslash;
1918 break;
1919 case '\\':
1920 if (nslash < 0)
1921 adrs += 1 << -nslash;
1922 else
1923 nslash = 0;
1924 nslash -= 4;
1925 adrs -= 1 << -nslash;
1926 break;
1927 case 'm':
1928 scanhex((void *)&adrs);
1929 break;
1930 case 'n':
1931 mnoread = 1;
1932 break;
1933 case 'r':
1934 brev = !brev;
1935 break;
1936 case '<':
1937 n = size;
1938 scanhex(&n);
1939 adrs -= n;
1940 break;
1941 case '>':
1942 n = size;
1943 scanhex(&n);
1944 adrs += n;
1945 break;
1946 case '?':
1947 printf(memex_subcmd_help_string);
1948 break;
1951 adrs += inc;
1955 static int
1956 bsesc(void)
1958 int c;
1960 c = inchar();
1961 switch( c ){
1962 case 'n': c = '\n'; break;
1963 case 'r': c = '\r'; break;
1964 case 'b': c = '\b'; break;
1965 case 't': c = '\t'; break;
1967 return c;
1970 static void xmon_rawdump (unsigned long adrs, long ndump)
1972 long n, m, r, nr;
1973 unsigned char temp[16];
1975 for (n = ndump; n > 0;) {
1976 r = n < 16? n: 16;
1977 nr = mread(adrs, temp, r);
1978 adrs += nr;
1979 for (m = 0; m < r; ++m) {
1980 if (m < nr)
1981 printf("%.2x", temp[m]);
1982 else
1983 printf("%s", fault_chars[fault_type]);
1985 n -= r;
1986 if (nr < r)
1987 break;
1989 printf("\n");
1992 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1993 || ('a' <= (c) && (c) <= 'f') \
1994 || ('A' <= (c) && (c) <= 'F'))
1995 static void
1996 dump(void)
1998 int c;
2000 c = inchar();
2001 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2002 termch = c;
2003 scanhex((void *)&adrs);
2004 if (termch != '\n')
2005 termch = 0;
2006 if (c == 'i') {
2007 scanhex(&nidump);
2008 if (nidump == 0)
2009 nidump = 16;
2010 else if (nidump > MAX_DUMP)
2011 nidump = MAX_DUMP;
2012 adrs += ppc_inst_dump(adrs, nidump, 1);
2013 last_cmd = "di\n";
2014 } else if (c == 'l') {
2015 dump_log_buf();
2016 } else if (c == 'r') {
2017 scanhex(&ndump);
2018 if (ndump == 0)
2019 ndump = 64;
2020 xmon_rawdump(adrs, ndump);
2021 adrs += ndump;
2022 last_cmd = "dr\n";
2023 } else {
2024 scanhex(&ndump);
2025 if (ndump == 0)
2026 ndump = 64;
2027 else if (ndump > MAX_DUMP)
2028 ndump = MAX_DUMP;
2029 prdump(adrs, ndump);
2030 adrs += ndump;
2031 last_cmd = "d\n";
2035 static void
2036 prdump(unsigned long adrs, long ndump)
2038 long n, m, c, r, nr;
2039 unsigned char temp[16];
2041 for (n = ndump; n > 0;) {
2042 printf(REG, adrs);
2043 putchar(' ');
2044 r = n < 16? n: 16;
2045 nr = mread(adrs, temp, r);
2046 adrs += nr;
2047 for (m = 0; m < r; ++m) {
2048 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2049 putchar(' ');
2050 if (m < nr)
2051 printf("%.2x", temp[m]);
2052 else
2053 printf("%s", fault_chars[fault_type]);
2055 for (; m < 16; ++m) {
2056 if ((m & (sizeof(long) - 1)) == 0)
2057 putchar(' ');
2058 printf(" ");
2060 printf(" |");
2061 for (m = 0; m < r; ++m) {
2062 if (m < nr) {
2063 c = temp[m];
2064 putchar(' ' <= c && c <= '~'? c: '.');
2065 } else
2066 putchar(' ');
2068 n -= r;
2069 for (; m < 16; ++m)
2070 putchar(' ');
2071 printf("|\n");
2072 if (nr < r)
2073 break;
2077 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2079 static int
2080 generic_inst_dump(unsigned long adr, long count, int praddr,
2081 instruction_dump_func dump_func)
2083 int nr, dotted;
2084 unsigned long first_adr;
2085 unsigned long inst, last_inst = 0;
2086 unsigned char val[4];
2088 dotted = 0;
2089 for (first_adr = adr; count > 0; --count, adr += 4) {
2090 nr = mread(adr, val, 4);
2091 if (nr == 0) {
2092 if (praddr) {
2093 const char *x = fault_chars[fault_type];
2094 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2096 break;
2098 inst = GETWORD(val);
2099 if (adr > first_adr && inst == last_inst) {
2100 if (!dotted) {
2101 printf(" ...\n");
2102 dotted = 1;
2104 continue;
2106 dotted = 0;
2107 last_inst = inst;
2108 if (praddr)
2109 printf(REG" %.8x", adr, inst);
2110 printf("\t");
2111 dump_func(inst, adr);
2112 printf("\n");
2114 return adr - first_adr;
2117 static int
2118 ppc_inst_dump(unsigned long adr, long count, int praddr)
2120 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2123 void
2124 print_address(unsigned long addr)
2126 xmon_print_symbol(addr, "\t# ", "");
2129 void
2130 dump_log_buf(void)
2132 const unsigned long size = 128;
2133 unsigned long end, addr;
2134 unsigned char buf[size + 1];
2136 addr = 0;
2137 buf[size] = '\0';
2139 if (setjmp(bus_error_jmp) != 0) {
2140 printf("Unable to lookup symbol __log_buf!\n");
2141 return;
2144 catch_memory_errors = 1;
2145 sync();
2146 addr = kallsyms_lookup_name("__log_buf");
2148 if (! addr)
2149 printf("Symbol __log_buf not found!\n");
2150 else {
2151 end = addr + (1 << CONFIG_LOG_BUF_SHIFT);
2152 while (addr < end) {
2153 if (! mread(addr, buf, size)) {
2154 printf("Can't read memory at address 0x%lx\n", addr);
2155 break;
2158 printf("%s", buf);
2160 if (strlen(buf) < size)
2161 break;
2163 addr += size;
2167 sync();
2168 /* wait a little while to see if we get a machine check */
2169 __delay(200);
2170 catch_memory_errors = 0;
2174 * Memory operations - move, set, print differences
2176 static unsigned long mdest; /* destination address */
2177 static unsigned long msrc; /* source address */
2178 static unsigned long mval; /* byte value to set memory to */
2179 static unsigned long mcount; /* # bytes to affect */
2180 static unsigned long mdiffs; /* max # differences to print */
2182 static void
2183 memops(int cmd)
2185 scanhex((void *)&mdest);
2186 if( termch != '\n' )
2187 termch = 0;
2188 scanhex((void *)(cmd == 's'? &mval: &msrc));
2189 if( termch != '\n' )
2190 termch = 0;
2191 scanhex((void *)&mcount);
2192 switch( cmd ){
2193 case 'm':
2194 memmove((void *)mdest, (void *)msrc, mcount);
2195 break;
2196 case 's':
2197 memset((void *)mdest, mval, mcount);
2198 break;
2199 case 'd':
2200 if( termch != '\n' )
2201 termch = 0;
2202 scanhex((void *)&mdiffs);
2203 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2204 break;
2208 static void
2209 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2211 unsigned n, prt;
2213 prt = 0;
2214 for( n = nb; n > 0; --n )
2215 if( *p1++ != *p2++ )
2216 if( ++prt <= maxpr )
2217 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2218 p1[-1], p2 - 1, p2[-1]);
2219 if( prt > maxpr )
2220 printf("Total of %d differences\n", prt);
2223 static unsigned mend;
2224 static unsigned mask;
2226 static void
2227 memlocate(void)
2229 unsigned a, n;
2230 unsigned char val[4];
2232 last_cmd = "ml";
2233 scanhex((void *)&mdest);
2234 if (termch != '\n') {
2235 termch = 0;
2236 scanhex((void *)&mend);
2237 if (termch != '\n') {
2238 termch = 0;
2239 scanhex((void *)&mval);
2240 mask = ~0;
2241 if (termch != '\n') termch = 0;
2242 scanhex((void *)&mask);
2245 n = 0;
2246 for (a = mdest; a < mend; a += 4) {
2247 if (mread(a, val, 4) == 4
2248 && ((GETWORD(val) ^ mval) & mask) == 0) {
2249 printf("%.16x: %.16x\n", a, GETWORD(val));
2250 if (++n >= 10)
2251 break;
2256 static unsigned long mskip = 0x1000;
2257 static unsigned long mlim = 0xffffffff;
2259 static void
2260 memzcan(void)
2262 unsigned char v;
2263 unsigned a;
2264 int ok, ook;
2266 scanhex(&mdest);
2267 if (termch != '\n') termch = 0;
2268 scanhex(&mskip);
2269 if (termch != '\n') termch = 0;
2270 scanhex(&mlim);
2271 ook = 0;
2272 for (a = mdest; a < mlim; a += mskip) {
2273 ok = mread(a, &v, 1);
2274 if (ok && !ook) {
2275 printf("%.8x .. ", a);
2276 } else if (!ok && ook)
2277 printf("%.8x\n", a - mskip);
2278 ook = ok;
2279 if (a + mskip < a)
2280 break;
2282 if (ook)
2283 printf("%.8x\n", a - mskip);
2286 static void proccall(void)
2288 unsigned long args[8];
2289 unsigned long ret;
2290 int i;
2291 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2292 unsigned long, unsigned long, unsigned long,
2293 unsigned long, unsigned long, unsigned long);
2294 callfunc_t func;
2296 if (!scanhex(&adrs))
2297 return;
2298 if (termch != '\n')
2299 termch = 0;
2300 for (i = 0; i < 8; ++i)
2301 args[i] = 0;
2302 for (i = 0; i < 8; ++i) {
2303 if (!scanhex(&args[i]) || termch == '\n')
2304 break;
2305 termch = 0;
2307 func = (callfunc_t) adrs;
2308 ret = 0;
2309 if (setjmp(bus_error_jmp) == 0) {
2310 catch_memory_errors = 1;
2311 sync();
2312 ret = func(args[0], args[1], args[2], args[3],
2313 args[4], args[5], args[6], args[7]);
2314 sync();
2315 printf("return value is %x\n", ret);
2316 } else {
2317 printf("*** %x exception occurred\n", fault_except);
2319 catch_memory_errors = 0;
2322 /* Input scanning routines */
2324 skipbl(void)
2326 int c;
2328 if( termch != 0 ){
2329 c = termch;
2330 termch = 0;
2331 } else
2332 c = inchar();
2333 while( c == ' ' || c == '\t' )
2334 c = inchar();
2335 return c;
2338 #define N_PTREGS 44
2339 static char *regnames[N_PTREGS] = {
2340 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2341 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2342 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2343 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2344 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2345 #ifdef CONFIG_PPC64
2346 "softe",
2347 #else
2348 "mq",
2349 #endif
2350 "trap", "dar", "dsisr", "res"
2354 scanhex(unsigned long *vp)
2356 int c, d;
2357 unsigned long v;
2359 c = skipbl();
2360 if (c == '%') {
2361 /* parse register name */
2362 char regname[8];
2363 int i;
2365 for (i = 0; i < sizeof(regname) - 1; ++i) {
2366 c = inchar();
2367 if (!isalnum(c)) {
2368 termch = c;
2369 break;
2371 regname[i] = c;
2373 regname[i] = 0;
2374 for (i = 0; i < N_PTREGS; ++i) {
2375 if (strcmp(regnames[i], regname) == 0) {
2376 if (xmon_regs == NULL) {
2377 printf("regs not available\n");
2378 return 0;
2380 *vp = ((unsigned long *)xmon_regs)[i];
2381 return 1;
2384 printf("invalid register name '%%%s'\n", regname);
2385 return 0;
2388 /* skip leading "0x" if any */
2390 if (c == '0') {
2391 c = inchar();
2392 if (c == 'x') {
2393 c = inchar();
2394 } else {
2395 d = hexdigit(c);
2396 if (d == EOF) {
2397 termch = c;
2398 *vp = 0;
2399 return 1;
2402 } else if (c == '$') {
2403 int i;
2404 for (i=0; i<63; i++) {
2405 c = inchar();
2406 if (isspace(c)) {
2407 termch = c;
2408 break;
2410 tmpstr[i] = c;
2412 tmpstr[i++] = 0;
2413 *vp = 0;
2414 if (setjmp(bus_error_jmp) == 0) {
2415 catch_memory_errors = 1;
2416 sync();
2417 *vp = kallsyms_lookup_name(tmpstr);
2418 sync();
2420 catch_memory_errors = 0;
2421 if (!(*vp)) {
2422 printf("unknown symbol '%s'\n", tmpstr);
2423 return 0;
2425 return 1;
2428 d = hexdigit(c);
2429 if (d == EOF) {
2430 termch = c;
2431 return 0;
2433 v = 0;
2434 do {
2435 v = (v << 4) + d;
2436 c = inchar();
2437 d = hexdigit(c);
2438 } while (d != EOF);
2439 termch = c;
2440 *vp = v;
2441 return 1;
2444 static void
2445 scannl(void)
2447 int c;
2449 c = termch;
2450 termch = 0;
2451 while( c != '\n' )
2452 c = inchar();
2455 static int hexdigit(int c)
2457 if( '0' <= c && c <= '9' )
2458 return c - '0';
2459 if( 'A' <= c && c <= 'F' )
2460 return c - ('A' - 10);
2461 if( 'a' <= c && c <= 'f' )
2462 return c - ('a' - 10);
2463 return EOF;
2466 void
2467 getstring(char *s, int size)
2469 int c;
2471 c = skipbl();
2472 do {
2473 if( size > 1 ){
2474 *s++ = c;
2475 --size;
2477 c = inchar();
2478 } while( c != ' ' && c != '\t' && c != '\n' );
2479 termch = c;
2480 *s = 0;
2483 static char line[256];
2484 static char *lineptr;
2486 static void
2487 flush_input(void)
2489 lineptr = NULL;
2492 static int
2493 inchar(void)
2495 if (lineptr == NULL || *lineptr == 0) {
2496 if (xmon_gets(line, sizeof(line)) == NULL) {
2497 lineptr = NULL;
2498 return EOF;
2500 lineptr = line;
2502 return *lineptr++;
2505 static void
2506 take_input(char *str)
2508 lineptr = str;
2512 static void
2513 symbol_lookup(void)
2515 int type = inchar();
2516 unsigned long addr;
2517 static char tmp[64];
2519 switch (type) {
2520 case 'a':
2521 if (scanhex(&addr))
2522 xmon_print_symbol(addr, ": ", "\n");
2523 termch = 0;
2524 break;
2525 case 's':
2526 getstring(tmp, 64);
2527 if (setjmp(bus_error_jmp) == 0) {
2528 catch_memory_errors = 1;
2529 sync();
2530 addr = kallsyms_lookup_name(tmp);
2531 if (addr)
2532 printf("%s: %lx\n", tmp, addr);
2533 else
2534 printf("Symbol '%s' not found.\n", tmp);
2535 sync();
2537 catch_memory_errors = 0;
2538 termch = 0;
2539 break;
2544 /* Print an address in numeric and symbolic form (if possible) */
2545 static void xmon_print_symbol(unsigned long address, const char *mid,
2546 const char *after)
2548 char *modname;
2549 const char *name = NULL;
2550 unsigned long offset, size;
2552 printf(REG, address);
2553 if (setjmp(bus_error_jmp) == 0) {
2554 catch_memory_errors = 1;
2555 sync();
2556 name = kallsyms_lookup(address, &size, &offset, &modname,
2557 tmpstr);
2558 sync();
2559 /* wait a little while to see if we get a machine check */
2560 __delay(200);
2563 catch_memory_errors = 0;
2565 if (name) {
2566 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2567 if (modname)
2568 printf(" [%s]", modname);
2570 printf("%s", after);
2573 #ifdef CONFIG_PPC_BOOK3S_64
2574 static void dump_slb(void)
2576 int i;
2577 unsigned long esid,vsid,valid;
2578 unsigned long llp;
2580 printf("SLB contents of cpu %x\n", smp_processor_id());
2582 for (i = 0; i < mmu_slb_size; i++) {
2583 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2584 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2585 valid = (esid & SLB_ESID_V);
2586 if (valid | esid | vsid) {
2587 printf("%02d %016lx %016lx", i, esid, vsid);
2588 if (valid) {
2589 llp = vsid & SLB_VSID_LLP;
2590 if (vsid & SLB_VSID_B_1T) {
2591 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2592 GET_ESID_1T(esid),
2593 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2594 llp);
2595 } else {
2596 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2597 GET_ESID(esid),
2598 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2599 llp);
2601 } else
2602 printf("\n");
2607 static void dump_stab(void)
2609 int i;
2610 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2612 printf("Segment table contents of cpu %x\n", smp_processor_id());
2614 for (i = 0; i < PAGE_SIZE/16; i++) {
2615 unsigned long a, b;
2617 a = *tmp++;
2618 b = *tmp++;
2620 if (a || b) {
2621 printf("%03d %016lx ", i, a);
2622 printf("%016lx\n", b);
2627 void dump_segments(void)
2629 if (cpu_has_feature(CPU_FTR_SLB))
2630 dump_slb();
2631 else
2632 dump_stab();
2634 #endif
2636 #ifdef CONFIG_PPC_STD_MMU_32
2637 void dump_segments(void)
2639 int i;
2641 printf("sr0-15 =");
2642 for (i = 0; i < 16; ++i)
2643 printf(" %x", mfsrin(i));
2644 printf("\n");
2646 #endif
2648 #ifdef CONFIG_44x
2649 static void dump_tlb_44x(void)
2651 int i;
2653 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2654 unsigned long w0,w1,w2;
2655 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2656 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2657 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2658 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2659 if (w0 & PPC44x_TLB_VALID) {
2660 printf("V %08x -> %01x%08x %c%c%c%c%c",
2661 w0 & PPC44x_TLB_EPN_MASK,
2662 w1 & PPC44x_TLB_ERPN_MASK,
2663 w1 & PPC44x_TLB_RPN_MASK,
2664 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2665 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2666 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2667 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2668 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2670 printf("\n");
2673 #endif /* CONFIG_44x */
2675 static void xmon_init(int enable)
2677 #ifdef CONFIG_PPC_ISERIES
2678 if (firmware_has_feature(FW_FEATURE_ISERIES))
2679 return;
2680 #endif
2681 if (enable) {
2682 __debugger = xmon;
2683 __debugger_ipi = xmon_ipi;
2684 __debugger_bpt = xmon_bpt;
2685 __debugger_sstep = xmon_sstep;
2686 __debugger_iabr_match = xmon_iabr_match;
2687 __debugger_dabr_match = xmon_dabr_match;
2688 __debugger_fault_handler = xmon_fault_handler;
2689 } else {
2690 __debugger = NULL;
2691 __debugger_ipi = NULL;
2692 __debugger_bpt = NULL;
2693 __debugger_sstep = NULL;
2694 __debugger_iabr_match = NULL;
2695 __debugger_dabr_match = NULL;
2696 __debugger_fault_handler = NULL;
2698 xmon_map_scc();
2701 #ifdef CONFIG_MAGIC_SYSRQ
2702 static void sysrq_handle_xmon(int key, struct tty_struct *tty)
2704 /* ensure xmon is enabled */
2705 xmon_init(1);
2706 debugger(get_irq_regs());
2709 static struct sysrq_key_op sysrq_xmon_op =
2711 .handler = sysrq_handle_xmon,
2712 .help_msg = "Xmon",
2713 .action_msg = "Entering xmon",
2716 static int __init setup_xmon_sysrq(void)
2718 #ifdef CONFIG_PPC_ISERIES
2719 if (firmware_has_feature(FW_FEATURE_ISERIES))
2720 return 0;
2721 #endif
2722 register_sysrq_key('x', &sysrq_xmon_op);
2723 return 0;
2725 __initcall(setup_xmon_sysrq);
2726 #endif /* CONFIG_MAGIC_SYSRQ */
2728 static int __initdata xmon_early, xmon_off;
2730 static int __init early_parse_xmon(char *p)
2732 if (!p || strncmp(p, "early", 5) == 0) {
2733 /* just "xmon" is equivalent to "xmon=early" */
2734 xmon_init(1);
2735 xmon_early = 1;
2736 } else if (strncmp(p, "on", 2) == 0)
2737 xmon_init(1);
2738 else if (strncmp(p, "off", 3) == 0)
2739 xmon_off = 1;
2740 else if (strncmp(p, "nobt", 4) == 0)
2741 xmon_no_auto_backtrace = 1;
2742 else
2743 return 1;
2745 return 0;
2747 early_param("xmon", early_parse_xmon);
2749 void __init xmon_setup(void)
2751 #ifdef CONFIG_XMON_DEFAULT
2752 if (!xmon_off)
2753 xmon_init(1);
2754 #endif
2755 if (xmon_early)
2756 debugger(NULL);
2759 #ifdef CONFIG_SPU_BASE
2761 struct spu_info {
2762 struct spu *spu;
2763 u64 saved_mfc_sr1_RW;
2764 u32 saved_spu_runcntl_RW;
2765 unsigned long dump_addr;
2766 u8 stopped_ok;
2769 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2771 static struct spu_info spu_info[XMON_NUM_SPUS];
2773 void xmon_register_spus(struct list_head *list)
2775 struct spu *spu;
2777 list_for_each_entry(spu, list, full_list) {
2778 if (spu->number >= XMON_NUM_SPUS) {
2779 WARN_ON(1);
2780 continue;
2783 spu_info[spu->number].spu = spu;
2784 spu_info[spu->number].stopped_ok = 0;
2785 spu_info[spu->number].dump_addr = (unsigned long)
2786 spu_info[spu->number].spu->local_store;
2790 static void stop_spus(void)
2792 struct spu *spu;
2793 int i;
2794 u64 tmp;
2796 for (i = 0; i < XMON_NUM_SPUS; i++) {
2797 if (!spu_info[i].spu)
2798 continue;
2800 if (setjmp(bus_error_jmp) == 0) {
2801 catch_memory_errors = 1;
2802 sync();
2804 spu = spu_info[i].spu;
2806 spu_info[i].saved_spu_runcntl_RW =
2807 in_be32(&spu->problem->spu_runcntl_RW);
2809 tmp = spu_mfc_sr1_get(spu);
2810 spu_info[i].saved_mfc_sr1_RW = tmp;
2812 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2813 spu_mfc_sr1_set(spu, tmp);
2815 sync();
2816 __delay(200);
2818 spu_info[i].stopped_ok = 1;
2820 printf("Stopped spu %.2d (was %s)\n", i,
2821 spu_info[i].saved_spu_runcntl_RW ?
2822 "running" : "stopped");
2823 } else {
2824 catch_memory_errors = 0;
2825 printf("*** Error stopping spu %.2d\n", i);
2827 catch_memory_errors = 0;
2831 static void restart_spus(void)
2833 struct spu *spu;
2834 int i;
2836 for (i = 0; i < XMON_NUM_SPUS; i++) {
2837 if (!spu_info[i].spu)
2838 continue;
2840 if (!spu_info[i].stopped_ok) {
2841 printf("*** Error, spu %d was not successfully stopped"
2842 ", not restarting\n", i);
2843 continue;
2846 if (setjmp(bus_error_jmp) == 0) {
2847 catch_memory_errors = 1;
2848 sync();
2850 spu = spu_info[i].spu;
2851 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2852 out_be32(&spu->problem->spu_runcntl_RW,
2853 spu_info[i].saved_spu_runcntl_RW);
2855 sync();
2856 __delay(200);
2858 printf("Restarted spu %.2d\n", i);
2859 } else {
2860 catch_memory_errors = 0;
2861 printf("*** Error restarting spu %.2d\n", i);
2863 catch_memory_errors = 0;
2867 #define DUMP_WIDTH 23
2868 #define DUMP_VALUE(format, field, value) \
2869 do { \
2870 if (setjmp(bus_error_jmp) == 0) { \
2871 catch_memory_errors = 1; \
2872 sync(); \
2873 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2874 #field, value); \
2875 sync(); \
2876 __delay(200); \
2877 } else { \
2878 catch_memory_errors = 0; \
2879 printf(" %-*s = *** Error reading field.\n", \
2880 DUMP_WIDTH, #field); \
2882 catch_memory_errors = 0; \
2883 } while (0)
2885 #define DUMP_FIELD(obj, format, field) \
2886 DUMP_VALUE(format, field, obj->field)
2888 static void dump_spu_fields(struct spu *spu)
2890 printf("Dumping spu fields at address %p:\n", spu);
2892 DUMP_FIELD(spu, "0x%x", number);
2893 DUMP_FIELD(spu, "%s", name);
2894 DUMP_FIELD(spu, "0x%lx", local_store_phys);
2895 DUMP_FIELD(spu, "0x%p", local_store);
2896 DUMP_FIELD(spu, "0x%lx", ls_size);
2897 DUMP_FIELD(spu, "0x%x", node);
2898 DUMP_FIELD(spu, "0x%lx", flags);
2899 DUMP_FIELD(spu, "%d", class_0_pending);
2900 DUMP_FIELD(spu, "0x%lx", class_0_dar);
2901 DUMP_FIELD(spu, "0x%lx", class_1_dar);
2902 DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
2903 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2904 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2905 DUMP_FIELD(spu, "0x%lx", irqs[2]);
2906 DUMP_FIELD(spu, "0x%x", slb_replace);
2907 DUMP_FIELD(spu, "%d", pid);
2908 DUMP_FIELD(spu, "0x%p", mm);
2909 DUMP_FIELD(spu, "0x%p", ctx);
2910 DUMP_FIELD(spu, "0x%p", rq);
2911 DUMP_FIELD(spu, "0x%p", timestamp);
2912 DUMP_FIELD(spu, "0x%lx", problem_phys);
2913 DUMP_FIELD(spu, "0x%p", problem);
2914 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2915 in_be32(&spu->problem->spu_runcntl_RW));
2916 DUMP_VALUE("0x%x", problem->spu_status_R,
2917 in_be32(&spu->problem->spu_status_R));
2918 DUMP_VALUE("0x%x", problem->spu_npc_RW,
2919 in_be32(&spu->problem->spu_npc_RW));
2920 DUMP_FIELD(spu, "0x%p", priv2);
2921 DUMP_FIELD(spu, "0x%p", pdata);
2925 spu_inst_dump(unsigned long adr, long count, int praddr)
2927 return generic_inst_dump(adr, count, praddr, print_insn_spu);
2930 static void dump_spu_ls(unsigned long num, int subcmd)
2932 unsigned long offset, addr, ls_addr;
2934 if (setjmp(bus_error_jmp) == 0) {
2935 catch_memory_errors = 1;
2936 sync();
2937 ls_addr = (unsigned long)spu_info[num].spu->local_store;
2938 sync();
2939 __delay(200);
2940 } else {
2941 catch_memory_errors = 0;
2942 printf("*** Error: accessing spu info for spu %d\n", num);
2943 return;
2945 catch_memory_errors = 0;
2947 if (scanhex(&offset))
2948 addr = ls_addr + offset;
2949 else
2950 addr = spu_info[num].dump_addr;
2952 if (addr >= ls_addr + LS_SIZE) {
2953 printf("*** Error: address outside of local store\n");
2954 return;
2957 switch (subcmd) {
2958 case 'i':
2959 addr += spu_inst_dump(addr, 16, 1);
2960 last_cmd = "sdi\n";
2961 break;
2962 default:
2963 prdump(addr, 64);
2964 addr += 64;
2965 last_cmd = "sd\n";
2966 break;
2969 spu_info[num].dump_addr = addr;
2972 static int do_spu_cmd(void)
2974 static unsigned long num = 0;
2975 int cmd, subcmd = 0;
2977 cmd = inchar();
2978 switch (cmd) {
2979 case 's':
2980 stop_spus();
2981 break;
2982 case 'r':
2983 restart_spus();
2984 break;
2985 case 'd':
2986 subcmd = inchar();
2987 if (isxdigit(subcmd) || subcmd == '\n')
2988 termch = subcmd;
2989 case 'f':
2990 scanhex(&num);
2991 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
2992 printf("*** Error: invalid spu number\n");
2993 return 0;
2996 switch (cmd) {
2997 case 'f':
2998 dump_spu_fields(spu_info[num].spu);
2999 break;
3000 default:
3001 dump_spu_ls(num, subcmd);
3002 break;
3005 break;
3006 default:
3007 return -1;
3010 return 0;
3012 #else /* ! CONFIG_SPU_BASE */
3013 static int do_spu_cmd(void)
3015 return -1;
3017 #endif